Bootstrap modal, jquery ajax form validation and db insert in laravel - ajax

I'm trying to use a bootstrap modal, with live email checking and validation with finally db insert. I've looked at several tutorials but cant bring it all together. I have 0 js skills. I have a form in a modal which submits and validate the normal laravel way. Only problem is that if it has errors we see the message upon page refresh and not in the modal. :(
I've added some ajax stuff I saw in a post which has enabled my form to submit the data into the db with out refreshing. :) However I can't work out how to correctly return the errors and a success message upon insert.So far the only errors that work are required fields color coded in red but no message is displayed.
What I want to achieve is this but in a modal tutorial
This is the code I have so far:
Form
{{ Former::open('admin/staff/create_staff', 'POST')->rules(User::$rules)->id('add_staff'); }}
{{ Former::token();}}
{{ Former::text('f_name','First Name')->required(); }}
{{ Former::text('l_name','Last Name')->required(); }}
{{ Former::text('username','Username'); }}
{{ Former::text('user_number','User number')->required(); }}
{{ Former::text('email','Email')->required(); }}
{{ Former::password('password','Password')->required(); }}
{{ Former::select('gender','gender')->options(array('man'=>'male','female'=>'female'))->placeholder('Select Gender')->required() }}
{{ Former::select('contractor','contractor')->fromQuery(Contractor::all(), 'contractor', 'contractor')->placeholder('Select Contractor')->required(); }}
{{ Former::select('campus','campus')->fromQuery(Campus::all(), 'campus', 'campus')->placeholder('Select Campus')->required(); }}
{{ Former::select('status','status')->options(array('1'=>'Active','0'=>'In-active'))->placeholder('Select Status')->required() }}
{{ Former::actions (Former::large_primary_submit('Submit')->id('sub'),Former::large_inverse_reset('Reset')->id('clear')) }}
{{ Former::close() }}
Controller:
if(Request::ajax()) {
$rules = [
'f_name' => 'required',
'l_name' => 'required',
'user_number' => 'required',
'email' => 'required|email',
'gender' => 'required',
'campus' => 'required',
'status' => 'required',
'contractor' => 'required',
'password' => 'required',
];
$validation = Validator::make(Input::all(),$rules);
$response = ["error" => ['error'=>'true','status'=>'Sorry there has been an error'],
"success" => ['success'=>true,'message'=>'The new staff member was successfully added to the system']
];
if($validation->fails())
{
return Response::json($response["error"]);
}
else
{
$user = User::find_by_email(Input::get('email'));
if($user) {
// send a message back via ajax that the email already exists
if($user) {
return Redirect::back()->with_input()
->with('status','The email address is already in use');
}
}
$staff = new User(array(
'f_name' => Input::get('f_name'),
'l_name' => Input::get('l_name'),
'user_number' => Input::get('user_number'),
'username' => Input::get('username'),
'email' => Input::get('email'),
'password' => Hash::make(Input::get('password')),
'status' => Input::get('status'),
'gender' => Input::get('gender'),
));$staff->save();
// Automatically create a profile for the new staff member
$staff_profile = new Profile(array(
'user_id' => $teacher->id,
'contractor' => Input::get('contractor'),
'campus' => Input::get('campus'),
));
$staff_profile->save();
return Response::json($response["success"]);
}
}
JQuery
$('#add_staff').submit(function(){
var datas = $(this).serialize();
url = $(this).attr('action');
$.ajax({
type: 'POST',
url: url,
data: datas,
dataType: 'JSON',
success: function(msg,status){
if(msg.error)
{
$(f_name).removeClass('required');
$(f_name).addClass('required field error');
$(l_name).removeClass('required');
$(l_name).addClass('required field error');
$(user_number).removeClass('required');
$(user_number).addClass('required field error');
$(email).removeClass('required');
$(email).addClass('required field error');
$(gender).removeClass('required');
$(gender).addClass('required field error');
$(campus).removeClass('required');
$(campus).addClass('required field error');
$(status).removeClass('required');
$(status).addClass('required field error');
$(contractor).removeClass('required');
$(contractor).addClass('required field error');
$(password).removeClass('required');
$(password).addClass('required field error');
}
else if(msg.success)
{
$("#succesful_message").html(msg);
clearInput();
}
}
});
return false;
});
function clearInput() {
$("#add_staff :input").each( function() {
$(this).val('');
});
}
Any info pointing me in the right direction would be appreciated, thanks

The first thing I noticed is you need to add this:
$('#add_staff').submit(function(e){
e.preventDefault();
...
}
That way your form doesn't refresh the page.

Related

Method not allowed exception while updating a record

Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpExceptionNomessage
I'm getting this error while trying to update a record in the database. Don't know what's the problem. This question might be a duplicate but I've checked all and couldn't find the answer. Please Help me with this.
Controller Update Method:
public function updateEvent(Request $request, $id=''){
$name = $request->name;
$startdate = date_create($request->start_date);
$start_date = $startdate;
$time = $request->start_time;
$start_time = $time;//date("G:i", strtotime($time));
$endDate = date_create($request->end_date);
$end_date =$endDate;
$time_e = $request->end_time;
$end_time = $time_e;//date("G:i", strtotime($time_e));
$location = $request->location;
$description = $request->description;
$calendar_type = $request->calendar_type;
$timezone = $request->timezone;
if ($request->has('isFullDay')) {
$isFullDay = 1;
}else{
$isFullDay = 0;
}
DB::table('events')->where('id', $id)->update(
array(
'name' => $name,
'start_date' => $start_date,
'end_date' => $end_date,
'start_time' => $start_time,
'end_time' => $end_time,
'isFullDay' =>$isFullDay,
'description' => $description,
'calendar_type' => $calendar_type,
'timezone' => $timezone,
'location' => $location,
));
// Event Created and saved to the database
//now we will fetch this events id and store its reminder(if set) to the event_reminder table.
if(!empty($id))
{
if (!empty($request->reminder_type && $request->reminder_number && $request->reminder_duration)) {
DB::table('event_reminders')->where('id', $id)->update([
'event_id' => $id,
'type' => $request->reminder_type,
'number'=> $request->reminder_number,
'duration' => $request->reminder_duration
]);
}
}
else{
DB::table('event_reminders')->insert([
'type' => $request->reminder_type,
'number'=> $request->reminder_number,
'duration' => $request->reminder_duration
]);
}
return redirect()->back();
}
Route:
Route::post('/event/update/{id}', 'EventTasksController#updateEvent');
Form attributes :
<form action="/event/update/{{$event->id}}" method="POST">
{{ method_field('PATCH')}}
i'm calling the same update function inside my calendar page and it working fine there. Don't know why it doesn't work here.
Check the routeing method.
Route::patch('/event/update/{id}', 'EventTasksController#updateEvent');
patch should be the method called on route facade.
Change your route to patch:
Route::patch('/event/update/{id}', 'EventTasksController#updateEvent');
For your comment:
You can send the method to the ajax call by something like data-method attribute on the element you click on,take the method and use it in your ajax call. see this question/answer for help. How to get the data-id attribute?

Laravel 5.1, optional parameter causing blank page

The concerning route:
Route::patch('admin/track/practice/{practice_id}/close-practice-session/{session_id}/{new?}', array(
'as' => 'close-practice-session',
'uses' => 'AdminController#closePracticeSession'
));
new is an optional route parameter.
The Controller method:
public function closePracticeSession($club, $practice_id, $session_id, $new = null)
{
$clubDetails = new ClubDetails();
$club_id = $clubDetails->getClubID($club);
date_default_timezone_set(config('app.timezone'));
$CurrentTime = date("Y-m-d H:i:s");
try
{
DB::table('practice_sessions')
->where('id', $session_id)
->where('club_id', $club_id)
->update(['is_current' => 0, 'updated_at' => $CurrentTime]);
if ($new == 'Y')
{
return redirect()->action('AdminController#getTrackPracticeSession', [$club, $practice_id]);
}
else
{
return redirect()->action('AdminController#getTrackPracticeSession', [$club, $practice_id, $session_id])
->with(array('success'=>'Practice was successfully closed.'));
}
}
catch(\Exception $e)
{
return view('errors.500')->with(self::getRequiredData($club))->with('error', $e->getMessage());
}
}
I have two forms on my view, one has the optional parameter, one doesn't.
When I click on the button on the form which has the optional parameter, I am getting a BLANK screen.
Here are some strange things:
No error message. Checked the laravel.log
Even if I remove all the logic from the controller method and do a
simple var_dump, I still get a blank screen
When I click on the button without the optional parameter, it
behaves as expected
I have been trying for the last two days to resolve this without any luck. I have even tried to make the {new} parameter mandatory. Anytime I am passing the last parameter, I am getting a blank screen.
Any idea? I am sure I am doing something silly. Just can't see it.
Update (the two forms on the view) - the csrf token is in the header.
{!! Form::open([
'method' => 'PATCH',
'route' => ['close-practice-session', $alias, $practiceDetails[0]->practice_id, $practiceDetails[0]->id]
]) !!}
{!! Form::submit('Close Session', ['class' => 'btn btn-primary btn-sm', 'style' => 'width: 160px;margin-left: 0px!important']) !!}
{!! Form::close() !!}
<!-- #2 -->
{!! Form::open([
'method' => 'PATCH',
'route' => ['close-practice-session', $alias, $practiceDetails[0]->practice_id, $practiceDetails[0]->id, "Y"]
]) !!}
{!! Form::submit('Close + Create New', ['class' => 'btn btn-secondary btn-sm', 'style' => 'width: 160px;margin-left: 0px!important']) !!}
{!! Form::close() !!}
As per your route
Route::patch('admin/track/practice/{practice_id}/close-practice-session/{session_id}/{new?}', array(
'as' => 'close-practice-session',
'uses' => 'AdminController#closePracticeSession'
));
Your controller function should be like this
public function closePracticeSession(Request $request, $practice_id, $session_id, $new = null)
{
$clubDetails = new ClubDetails();
$club_id = $clubDetails->getClubID($club);
date_default_timezone_set(config('app.timezone'));
$CurrentTime = date("Y-m-d H:i:s");
try
{
DB::table('practice_sessions')
->where('id', $session_id)
->where('club_id', $club_id)
->update(['is_current' => 0, 'updated_at' => $CurrentTime]);
if ($new == 'Y')
{
return redirect()->action('AdminController#getTrackPracticeSession', [$club, $practice_id]);
}
else
{
return redirect()->action('AdminController#getTrackPracticeSession', [$club, $practice_id, $session_id])
->with(array('success'=>'Practice was successfully closed.'));
}
}
catch(\Exception $e)
{
return view('errors.500')->with(self::getRequiredData($club))->with('error', $e->getMessage());
}
}
Please take a look at this SO post. This gave me a hint to solve my problem. I had an identical GET route in my routes.php file. Once I modified my PATCH route to the following, everything is working as expected.
Route::patch('admin/close-practice-session/{practice_id}/{session_id}/{new?}', array(
'as' => 'close-practice-session',
'uses' => 'AdminController#closePracticeSession'
));

change status active/inactive using ajax in yii2

[
'attribute' => 'status',
'format' => 'html',
'value' => function ($data) {
if($data->status==true) {
return Html::a("Inactive", "#", ['id' => $data->id, 'class' => 'a_status']);
}
else {
return Html::a("Active", "#");
}
]
The problem is, this code is not returning "id" attribute in link. So, wanted to know if this is currect way to put link in grid view or can someone point me correct way?'
Thx in advance.
Your code is missing one closing parenthesis and a change in format key's value -
Try -
[
'attribute' => 'status',
'format' => 'raw', //It was 'html' before
'value' => function ($data) {
if($data->status==true) {
return Html::a("Inactive", "#", ['id' => $data->id, 'class' => 'a_status']);
}
else {
return Html::a("Active", "#");
}
} //missing parenthesis
]
Well, you are missing a lot of code. Here are some observations.
*) I am using this kind of definition for the column
'value'=>function ($model, $key, $index, $widget) {
I am not sure if it makes a difference, try it this way maybe this is the problem.
Other things:
*) why are you using return
Html::a("Inactive", "#", ['id' => $data->id, 'class' => 'a_status']);
and not something like
Html::a("Inactive", ['change-status', 'status' => 'active', 'id' => $data->id], ['class' => 'a_status']);
You are creating in this way the link with the proper url already. If somebody does not have javascript enabled it will still work for them, just with a refresh.
Now you can create a global ajax function that you can reuse with ease for a lot more screens.
Now the actionChangeStatus function can end like this
if(Yii::$app->request->getIsAjax()) {
Yii::$app->response->format = 'json';
return ['success' => true];
} else {
return $this->redirect(['index']);
}
My ajax looks like this
jQuery.ajax({
"type": "GET",
"url": element.attr('href'),
"cache": false,
})
.success(function ( response ) {
$.pjax.reload({container: "#main-pjax", async:false, timeout: 4000});
});

check if value already exists in db

I have an insert form and a dropdownbox which displays all cars names and when selected one it saves the id in column "car_id" which is unique. What I want is to check if this id already exists and if yes to display a validation message:
create controller
public function create() {
$cars = DB::table('cars')->orderBy('Description', 'asc')->distinct()->lists('Description', 'id');
return View::make('pages.insur_docs_create', array(
'cars' => $cars
));
}
insur_docs_blade.php
<div class="form-group">
{{ Form::label('car', 'Car', array('class'=>'control-label col-lg-4')) }}
<div class="col-lg-8">
{{ Form::select('car', $cars, Input::old('class'), array(
'data-validation' => 'required',
'data-validation-error-msg' => 'You did not enter a valid car',
'class' => 'form-control'))
}}
</div>
</div>
You can use Laravel's Validator class for this. These are a few snippits of how it works. This methods works by using your data model. Instead of writing everything out I added a few links that provide you all the information to complete your validation.
$data = Input::all();
$rules = array(
'car_id' => 'unique'
);
$validator = Validator::make($data, $rules);
if ($validator->passes()) {
return 'Data was saved.';
}
http://laravelbook.com/laravel-input-validation
http://laravel.com/docs/validation
http://daylerees.com/codebright/validation
You can use Laravel's "exists" method like this:
if (User::where('email', $email)->exists()) {
// that email already exists in the users table
}

Laravel 4 password reminder: redirection issue

I'm using the Laravel 4 password reminder functionality, as described here: http://four.laravel.com/docs/security#password-reminders-and-reset. In order to generate the token, send the email and create de DB record in the password_reminder table, I use the standard code in my routes file :
Route::post('password/remind', function() {
$credentials = array('email' => Input::get('email'));
return Password::remind($credentials);
});
This code is suppose to send me back to my input form in case of any error (unknown email address for instance). Instead of that, I get a MethodNotAllowedHttpException. The reason is Laravel don't try to send me back to my form URL (which is /password/forgot): he tries to redirect me to /password/remind, in GET, and this route does not exist (of course) in my routes.php file.
I checked the code of the Illuminate\Auth\Reminders\PasswordBroker class, which is responsible of this redirection, and found out this method :
protected function makeErrorRedirect($reason = '')
{
if ($reason != '') $reason = 'reminders.'.$reason;
return $this->redirect->refresh()->with('error', true)->with('reason', $reason);
}
I replaced $this->redirect->refresh() by $this->redirect->back(), and everything is now working as excepted. But as I couldn't find any comment on this bug anywhere, I assume I'm doing something wrong… But I can't find what !
Here is my routes.php file:
Route::get('password/forgot', array('as' => 'forgot', 'uses' => 'SessionsController#forgot'));
Route::post('password/remind', function() {
$credentials = array('email' => Input::get('email'));
return Password::remind($credentials);
});
Route::get('password/reset/{token}', function($token) {
return View::make('sessions.reset')->with('token', $token);
});
Route::post('password/reset/{token}', array('as' => 'reset', 'uses' => 'SessionsController#reset'));
my SessionsController relevant code:
class SessionsController extends BaseController {
[...]
public function forgot() {
return View::make('sessions.forgot');
}
public function reset() {
$credentials = array(
'email' => Input::get('email'),
'password' => Input::get('password'),
'password_confirmation' => Input::get('password_confirmation')
);
Input::flash();
return Password::reset($credentials, function($user, $password) {
$user->password = Hash::make($password);
$user->save();
return Redirect::to('home');
});
}
}
and finally my view code:
{{ Form::open(array('url' => 'password/remind', 'class' => 'form', 'role' => 'form', 'method'=>'post')) }}
<div class="form-group">
{{ Form::label('email', 'E-mail') }}
{{ Form::text('email', '', array('autocomplete'=>'off', 'class' => 'form-control')) }}
</div>
{{ Form::submit("Envoyer", array("class"=>"btn btn-primary")) }}
{{ Form::close() }}
If it is possible, I highly recommend you to upgrade to Laravel 4.1, because it comes with a more flexible (also easier to understand and to work with) solution for password remind/reset.
Check out this example with Laravel 4.1:
https://github.com/laracasts/Laravel-4.1-Password-Resets/blob/master/app/controllers/RemindersController.php

Resources