Posted by on in iDevelop, PHP | 24 comments

This question came up in a forum where I drop by now & then. It is also something that I recall answering previously on one or two occasions. So I thought I’d write about it here with a rudimentary example to provide a gist of how it works.

There’s no mystery or secret voodoo involved in having AJAX work in a Laravel app. On its own Laravel 4 (current version) doesn’t have any API for implementing AJAX, so you’ll need to do the footwork yourself. The basic concept that applies everywhere else applies here as well; grab the data from a HTML form, create an AJAX request and send it to server to a URL on which data is expected. Form data is retrieved on server just like any normal form data would be, the only key part is since you’re dealing with an AJAX request you can’t send back a normal View as response, you’ll need to make your own response with proper headers.

Note: I’ve assumed availability of jQuery in this example to avoid writing too much boilerplate. If you use any other library then you can use that as well, usage of jQuery is just to demonstrate the concept.

Lets add example routes to our routes.php file:

php
/app/routes.php

  1. //Settings: show form to create settings
  2. Route::get( '/settings/new', array(
  3.     'as' => 'settings.new',
  4.     'uses' => 'SettingsController@add'
  5. ) );
  6.  
  7. //Settings: create a new setting
  8. Route::post( '/settings', array(
  9.     'as' => 'settings.create',
  10.     'uses' => 'SettingsController@create'
  11. ) );

Then we create a view which has a form for adding a new setting:

php
…views/settings/new.blade.php

  1. {{ Form::open( array(
  2.     'route' => 'settings.create',
  3.     'method' => 'post',
  4.     'id' => 'form-add-setting'
  5. ) ) }}
  6.  
  7. {{ Form::label( 'setting_name', 'Setting Name:' ) }}
  8. {{ Form::text( 'setting_name', '', array(
  9.     'id' => 'setting_name',
  10.     'placeholder' => 'Enter Setting Name',
  11.     'maxlength' => 20,
  12.     'required' => true,
  13. ) ) }}
  14. {{ Form::label( 'setting_value', 'Setting Value:' ) }}
  15. {{ Form::text( 'setting_value', '', array(
  16.     'id' => 'setting_value',
  17.     'placeholder' => 'Enter Setting Value',
  18.     'maxlength' => 30,
  19.     'required' => true,
  20. ) ) }}
  21.  
  22. {{ Form::submit( 'Add Setting', array(
  23.     'id' => 'btn-add-setting',
  24. ) ) }}
  25.  
  26. {{ Form::close() }}

After this comes the Javascript which is loaded into our view which makes the AJAX call:

javascript
/public/js/settings/new.js

  1. jQuery( document ).ready( function( $ ) {
  2.  
  3.     $( '#form-add-setting' ).on( 'submit', function() {
  4.  
  5.         //.....
  6.         //show some spinner etc to indicate operation in progress
  7.         //.....
  8.  
  9.         $.post(
  10.             $( this ).prop( 'action' ),
  11.             {
  12.                 "_token": $( this ).find( 'input[name=_token]' ).val(),
  13.                 "setting_name": $( '#setting_name' ).val(),
  14.                 "setting_value": $( '#setting_value' ).val()
  15.             },
  16.             function( data ) {
  17.                 //do something with data/response returned by server
  18.             },
  19.             'json'
  20.         );
  21.  
  22.         //.....
  23.         //do anything else you might want to do
  24.         //.....
  25.  
  26.         //prevent the form from actually submitting in browser
  27.         return false;
  28.     } );
  29.  
  30. } );

And now that Javascript and form UI are in place, its time to do the backend stuff in our controller:

php
…llers/SettingsController.php

  1. class SettingsController extends BaseController {
  2.  
  3.     /**
  4.      * show a view with form to create settings
  5.      */
  6.     public function add() {
  7.         return View::make( 'settings/new' );
  8.     }
  9.  
  10.     /**
  11.      * handle data posted by ajax request
  12.      */
  13.     public function create() {
  14.         //check if its our form
  15.         if ( Session::token() !== Input::get( '_token' ) ) {
  16.             return Response::json( array(
  17.                 'msg' => 'Unauthorized attempt to create setting'
  18.             ) );
  19.         }
  20.  
  21.         $setting_name = Input::get( 'setting_name' );
  22.         $setting_value = Input::get( 'setting_value' );
  23.  
  24.         //.....
  25.         //validate data
  26.         //and then store it in DB
  27.         //.....
  28.  
  29.         $response = array(
  30.             'status' => 'success',
  31.             'msg' => 'Setting created successfully',
  32.         );
  33.  
  34.         return Response::json( $response );
  35.     }
  36.  
  37. //end of class
  38. }

 
As you can see, it is quite straightforward. You create a POST request to the URI with data and the controller method on server receives data as nomral form data. It then parses it, do with it whatever it wants and responds back with the header of content type application/json (or it can be XML or any other data format) which the Javascript in browser is expecting.

Just the usual AJAX stuff. You can ofcourse find and use PHP/Javascript libraries which will do the heavy lifting for you so you can just make few API calls instead of writing your own Javascript boilerplate.

 
UPDATE: Updated the code example above to use Response::json() instead of the custom function which created a Response object and set the content type header to application/json.