Reputation: 173
Using Laravel 5.2.45
I have a database set up with a few tables, like "users", "categories" and "contacts".
An User can create a contact and attribute some category to it.
In the contacts table
, I have this schema:
public function up()
{
Schema::create('contacts', function (Blueprint $table)
{
$table->engine = 'InnoDB';
$table->integer('id')->unsigned()->autoIncrement();
$table->integer('user_id')->unsigned();
$table->string('image');
$table->string('name');
$table->string('lastname');
$table->string('email', 191);
$table->string('phone',191);
$table->string('address');
$table->string('description', 255);
$table->integer('category_id')->unsigned()->nullable();
});
Schema::table('contacts', function (Blueprint $table)
{
$table->foreign('user_id')->references('id')->on('users');
$table->foreign('category_id')->references('id')->on('categories');
});
}
Note there is a column that fetches the ID of the category you choose for your contact.
This is the schema for the categories
table:
public function up()
{
Schema::create('categories', function (Blueprint $table)
{
$table->engine = 'InnoDB';
$table->integer('id')->unsigned()->autoIncrement();
$table->string('category')->required()->unique()->index();
});
}
To enter the attributes in the contacts table, I have the following in the ContactsController
controller:
public function create(CreateContactRequest $request)
{
$contact = new Contact;
$contact-> name = $request->get('name');
$contact-> lastname = $request->get('lastname');
$contact-> email = $request->get('email');
$contact-> phone = $request->get('phone');
$contact-> address = $request->get('address');
$contact-> description = $request->get('description');
$contact-> user_id = \Auth::user()->id;
$contact-> category_id = $request->get('category');
// $contact-> category = $request->get('category');
// Checking if input has a file
if ($request->hasFile('image'))
{
// It does, so set name to a random string with 10 chars
$fileName = str_random(10);
// Get the extension of the file (.jpg, .png...)
$fileName .= '.' . $request->file('image')->getClientOriginalExtension();
// Move the file to the storage
$request->file('image')->move(storage_path('app/public/uploads'), $fileName);
$contact->image = $fileName;
}
$contact->save();
$contacts = App\Contact::where('user_id', \Auth::user()->id)->get();
return redirect(route('contacts', compact('contacts')));
}
In the end, you'll get redirected to the contacts
view, where you'll simply see the contacts
table with all columns.
The form to enter the contact is like this:
Contact Form
**Basically, inputs for the columns name, lastname, email, phone, address and description.**
<div class="row">
<div class="col-lg-10 col-lg-offset-1">
<div class="panel">
<div class="panel-heading">
<h2 class="panel-title"> Contact Form </h2>
</div>
{!! Form::open(['route' => ['contacts.create'], 'method' => 'POST', 'enctype' => 'multipart/form-data']) !!}
<div class="panel-body">
<div class="row">
<div class="col-md-4 col-md-offset-1">
<div class="form-group">
{!! Form::label('category', 'Choose Your Contact Category') !!}
<fieldset>
<select name="category" class="form-control" id="category">
<option disabled="true" selected="true">
List
</option>
@foreach ($categories as $category)
<option name="category" id="category" class="category" value="{!! $category->id !!}">
{!! $category->category !!}
</option>
@endforeach
</select>
</fieldset>
</div>
</div>
<div class="col-md-4 col-md-offset-1">
<label>
Create Your Contact Category
</label><br/>
<button type="button" data-toggle="modal" data-target="#demo-default-modal">
<i class="fa fa-plus"></i> Create New Category
</button>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class = "form-group
@if($errors->has('name'))
has-error
@endif">
{!! Form::label('name', 'Name *') !!}
{!! Form::text('name', old('name'),['class'=>'form-control', 'placeholder' => 'Name of your contact']) !!}
@if($errors->has('name'))
<p class = "help-block"><span class="label label-danger">Warning</span> {{ $errors->first('name') }}</p>
@endif
</div>
</div>
<div class="col-md-6">
<div class = "form-group
@if($errors->has('lastname'))
has-error
@endif">
{!! Form::label('lastname', 'Lastname') !!}
{!! Form::text('lastname', old('lastname'),['class'=>'form-control', 'placeholder' => 'Lastname of your contact']) !!}
@if($errors->has('lastname'))
<p class = "help-block"><span class="label label-danger">Warning</span> {{ $errors->first('lastname') }}</p>
@endif
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class = "form-group
@if($errors->has('email'))
has-error
@endif">
{!! Form::label('email', 'E-Mail *') !!}
{!! Form::text('email', null,['class'=>'form-control', 'placeholder' => 'If your contact does not have one use [email protected]']) !!}
@if($errors->has('email'))
<p class = "help-block"><span class="label label-danger">Warning</span> {{ $errors->first('email') }}</p>
@endif
</div>
</div>
<div class="col-md-6">
<div class = "form-group
@if($errors->has('phone'))
has-error
@endif">
{!! Form::label('phone', 'Phone Number *') !!}
{!! Form::text('phone', null,['class'=>'form-control', 'placeholder' => 'If your contact does not have one, just insert three numbers at random']) !!}
@if($errors->has('phone'))
<p class="help-block"><span class="label label-danger">Warning</span> {{ $errors->first('phone') }}</p>
@endif
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class = "form-group">
{!! Form::label('address', 'Address') !!}
{!! Form::text('address', old('address'),['class'=>'form-control', 'placeholder' => 'Street name, number, neighborhood, city, state initials, country']) !!}
</div>
</div>
<div class="col-md-6">
<div class = "form-group">
{!! Form::label('description', 'Description') !!}
{!! Form::text('description', old('description'),['class'=>'form-control', 'placeholder' => 'Something to describe your contact. Use a simple word, like family, work, friend and such']) !!}
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class = "form-group">
{!! Form::label('image', 'Upload an image!') !!}
{!! Form::file('image')!!}
</div>
</div>
</div>
<div class="row">
<div class="col-md-3 col-md-offset-1">
<p class="text-left">
<strong> * = Required field (Can't be blank) </strong>
</p>
</div>
</div>
</div>
<div class="panel-footer text-right">
<div class = "btn">
{!! Form::button(' Submit Information', ['type' => 'submit', 'class' => 'btn btn-primary fa fa-plus-circle']) !!}
</div>
</div>
{!! Form::close() !!}
</div>
</div>
</div>
Please note that the category is inserted from a dropdown select
tag, where the options are permeated using option
tags.
If you need to create a new category for your contact, you press the Create Category
button, which loads a modal with a form to create your category.
**Modal for category**
<div class="modal fade demo-default-modal" name="demo-default-modal" id="demo-default-modal" role="dialog" tabindex="-1" aria-labelledby="demo-default-modal" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button data-dismiss="modal" class="close" type="button">
<span aria-hidden="true">×</span>
</button>
<h3 class="modal-title">
Create Category
</h3>
</div>
{!! Form::open(['route'=>['category.create'], 'method'=>'POST', 'class'=>'modalForm', 'id'=>'modalForm', 'name'=>'modalForm']) !!}
<div class="modal-body">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="form-group">
{!! Form::label('category', 'Category') !!}
{!! Form::text('category', NULL, ['placeholder'=>'Category Name', 'class'=>'form-control']) !!}
</div>
</div>
</div>
</div>
<div class="modal-footer">
{!! Form::button('Close', ['type' => 'button', 'class' => 'btn btn-default', 'data-dismiss'=>'modal']) !!}
{!! Form::submit('Save Category', ['type' => 'submit', 'class' => 'btn btn-primary modalSave', 'name' => 'modalSave', 'id' => 'modalSave']) !!}
</div>
{!! Form::close() !!}
</div>
</div>
</div>
When you insert the category name and click the Save Category
button, the form will go through the route setup as:
Route::post('category/create', [
'as'=>'category.create', 'uses'=>'CategoryController@create', 'redirects'=>'phonebook', 'with'=>'input'
]);
The route calls the parameters at the CategoryController
's method create
, which is:
public function create(CreateCategoryRequest $request)
{
$category = new Category;
$category->category = $request->get('category');
$category->save();
return redirect('phonebook');
}
Everything so far is working fine, no errors are thrown.
The contact is inserted in the right table with the right inputs, even with the category id, which, by the way, is created in the categories
table without any problem as well.
But the thing is, I want to create the category from the modal, but WITHOUT refreshing the page, because let's imagine an user is creating the contact, permeating all input fields and letting the category select for last.
And imagine this user has to create the category for his contact. He'll pop up the modal, input something and click the send button, which will redirect him to the form, but WITHOUT all of his inputs.
Note that in the route for the category creation, I tried to pass the parameter to keep the inputs, but it didn't happened.
MAYBE IMPORTANT
My view is set up using the @include
syntax provided by Laravel, so it looks like this
INSERT CONTACT VIEW
phonebook.blade.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="/js/jquery-2.2.1.min.js"></script>
<script src="/js/modalSaver.js"></script>
<script src="/js/laroute.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/nifty.min.js"></script>
<script src="js/bootbox.min.js"></script>
<script src="js/ui-modals.js"></script>
<link href="{{URL::asset('docs/nifty-v2.4/demo/css/bootstrap.min.css')}}" rel="stylesheet">
<link href="{{URL::asset('docs/nifty-v2.4/demo/css/nifty.min.css')}}" rel="stylesheet">
<link href="{{URL::asset('docs/nifty-v2.4/demo/plugins/font-awesome/css/font-awesome.min.css')}}" rel="stylesheet">
<link rel="stylesheet" href="{{URL::asset('css/infost.css')}}">
<link rel="stylesheet" href="{{URL::asset('css/header.css')}}">
<title>
Phonebook - Add a new contact
</title>
</head>
<body>
@include('partials.header')
@if(Auth::check())
<br/><br/>
@include('partials.contactForm')
@else
@include('partials.info')
@endif
</body>
</html>
The partials.contactForm
partial is where the form to input the contact info and the modal bit are located.
SO I tried AJAX, and, being new to this, I couldn't work something.
Also, note that I have jquery-2.2.1
in a minified file.
These are my tries, which, by the way, are in a separate .js
file (modalSaver.js
) from the view:
**function 1**
var $form = $("#demo-default-modal");
$form.submit(function(e)
{
$.ajax({
method: 'POST',
url: 'category.create',
data: $form.serialize(),
});
e.preventDefault();
});
**function 2**
var form = 'demo-default-modal';
$("form").submit(function(e)
{
e.preventDefault()
{
$.ajax({
method: 'POST',
url: 'category.create',
data: $form.serialize(),
});
}
});
**function 3**
$('form.modalForm').submit(function(event)
{
event.preventDefault();
$.post($(this).attr("action"),
$(this).serialize(),
function(info)
{
$("#result").html(info);
});
});
As stated before, none of these functions seemed to work.
Here is my question, finally (sorry for the long post, but I tried to be really meticulous about it):
How to make an AJAX function to save the category in my database, in the categories
table, show the category I just inserted listed in the dropdown select
tag list, located in the form, and do all of this without refreshing the page, but simply hiding the modal?
Thanks in advance.
Upvotes: 1
Views: 2208
Reputation: 875
change the create category controller to return $category
instead return redirect.
than change your ajax script to this
$('#modalForm').submit(function(e) {
e.preventDefault();
var $form = $(this);
// get url from action attribute
var $url = $(this).attr('action');
$.ajax({
method: 'POST',
url: $url,
data: $form.serialize(),
})
.done(function(res) {
// make new option based on ajax response
var option = '<option class="category" value="' + res.id + '">' + res.category + '</option>';
// append option to catogory select
$('#category').append(option);
});
})
Upvotes: 1