Uploading an image using Redactor

There are a few different JavaScript libraries that can turn a form's text area into a WYSIWYG editor. Redactor is a newer library but is very well coded and has gained quite a bit of popularity in a short amount of time. For this recipe, we'll apply Redactor to our Laravel form, and create routes to allow for image uploads through Redactor.

Getting ready

We need to download a copy of Redactor from https://github.com/dybskiy/redactor-js/tree/master/redactor. Download redactor.min.js and save it to the public/js directory. Download redactor.css and save it to the public/css directory.

How to do it...

To complete this recipe, follow these steps:

  1. Create a route in our routes.php file to hold our form with the redactor field:
    Route::get('redactor', function() 
    {
        return View::make('redactor');
    });
  2. Create a view in our app/views directory and name it as redactor.php:
    <!DOCTYPE html>
    <html>
        <head>
            <title>Laravel and Redactor</title>
            <meta charset="utf-8">
            <link rel="stylesheet" href="css/redactor.css" />
            <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
            <script src="js/redactor.min.js"></script>
        </head>
        <body>
            <?= Form::open() ?>
            <?= Form::label('mytext', 'My Text') ?>
            <br>
            <?= Form::textarea('mytext', '', array('id' =>'mytext')) ?>
            <br>
            <?= Form::submit('Send it!') ?>
            <?= Form::close() ?>
            <script type="text/javascript">
                $(function() {
                    $('#mytext').redactor({
                        imageUpload: 'redactorupload'
                    });
                });
            </script>
        </body>
    </html>
  3. Make a route that will handle the image upload:
    Route::post('redactorupload', function()
    {
        $rules = array(
            'file' => 'image|max:10000'
        );
        $validation = Validator::make(Input::all(), $rules);
        $file = Input::file('file');
        if ($validation->fails())
        {
            return FALSE;
        }
        else
        {
            if ($file->move('files', $file->
                getClientOriginalName()))
            {
                return Response::json(array('filelink' =>
                   'files/' . $file->getClientOriginalName()));
            }
            else
            {
                return FALSE;
            }
        }
    });
    
  4. Create another route to show our form input after it's submitted:
    Route::post('redactor', function() 
    {
        return dd(Input::all());
    });

How it works...

After creating our form route, we create the view to hold our form HTML. In the head of the page, we load in the redactor CSS, the jquery library (using Google's CDN), and the redactor JavaScript file.

Our form will only have one field, a text area named mytext. In our script area, we initialize Redactor on the text area field and set the imageUpload parameter to a route or controller that will accept the image upload. Ours is set to redactorupload, so we create a route for it that accepts post data.

In our redactorupload route, we do some validation and, if everything is okay, the image will upload to our images directory. To get the image to display in our text area, it needs a JSON array with a file link as the key and the image path as the value. For this, we'll use Laravel's built-in Response::json method, and pass in an array with the image's location.

On our form page, if the image validated and uploaded correctly, Redactor will display the image inside the text area. If we submit, we'll see the text included the <img> tag and the image path.

There's more...

While this recipe is specifically for image uploads, non-image file uploads work in a very similar manner. The only real difference is that file upload route should also return filename in the JSON output.