Upload

Editor 1.5 introduces two new field types to give the end user the ability to upload files as part of your Editor form:

  • upload - upload a single file per field
  • uploadMany - upload one or more files per field

File upload is an important part of any modern CRUD library such as Editor and these new field types make it super easy to provide upload options to your end users. The images below show how these two field types might be presented to end users for image uploads (note that any file type can be used, not just images!):

upload field type

uploadMany field type

The file upload options in Editor require tight coupling between the server-side and the client-side in order to ensure that both have the information they each require - the documentation presented here assumes that you are using the PHP or .NET libraries that are part of the Editor distribution.

Uploads overview

The upload field types are similar to other fields in Editor in that all they require is a single value to represent a file (normally this is a database table id). However, they can also a little more complicated than the other field types in that they typically require additional meta information to make that id useful for display to the end user!

As such, the upload files require additional configuration for display of the file (or information about the file) on the client-side, and additional instructions on the server-side for how to handle the file upload: where to save the file and what meta information to save about the file on a database.

The recommended set up for uploading files to a server with Editor is to store files in the file system (rather than in the database, although that is also possible - see the PHP | .NET documentation) and also store meta information about the file in a database table. At a minimum it is suggested that you store an id that will identify the file and the location of the file on the server - the location can take two forms (both should be stored):

  • Web path - the URL that a web-browser would use to access the file - e.g. /uploads/1
  • System path - the absolute path to the file on the server's file system - e.g.-path /var/www/htdocs/uploads/1` - this is used to be able to find the file at a later delete to perform file system operations - for example deleting the file.

In the Editor libraries this meta information is configured using the db() method of the Upload class - see the PHP and .NET documentation for full details on how to configure what data is stored.

On the client-side Editor will automatically retrieve the meta information defined by the db() method and make it accessible through the two API methods:

  • file() - get meta information about a specific file
  • files() - get meta information about multiple files

That meta information can then be used to display the file information to the end user, as described below.

Client-side

On the client-side, we need to consider how the uploaded file(s) are displayed to the end user in two different aspects:

  • The Editor form
  • The DataTables table

During the following discussion of how Editor and DataTables can display the file information in different ways, consider the following database table for file meta data storage:

Table: image
+----+-----------------+----------+------------+--------------------------------+
| id | fileName        | fileSize | webPath    | systemPath                     |
+----+-----------------+----------+------------+--------------------------------+
| 1  | Allan.png       | 4532     | /uploads/1 | /home/datatables/www/uploads/1 |
| 4  | Charlie-CTO.png | 9408     | /uploads/4 | /home/datatables/www/uploads/4 |
| 9  | Photo.png       | 2054     | /uploads/9 | /home/datatables/www/uploads/9 |
+----+-----------------+----------+------------+--------------------------------+

It is worth noting that some of this information is potentially redundant - the full webPath and systemPath can be inferred from the id and a path prefix, but this approach keeps data access simple.

Editor

For Editor we want to be able to display the image uploaded, a thumbnail or some other representation of the file, which can be done using the display option of the upload and uploadMany field types. This option allows a function to be defined which will convert the file identifier (the id) into something the user understands. Since it is a function we can use the file() method to get information about the file(s) needed for the display.

Consider the following Editor configuration:

var editor = new $.fn.dataTable.Editor( {
    ajax: "../php/upload.php",
    table: "#example",
    fields: [ {
            label: "Image:",
            name: "users_images.imageId",
            type: "upload",
            display: function ( id ) {
                return '<img src="'+editor.file( 'images', id ).webPath+'"/>';
            },
            noImageText: 'No image'
        }
    ]
} );

In this case the display function is used to create an img tag with the information contained in the webPath property from the database table shown above. We could equally have used return editor.file( 'images', id ).fileName; to just display the file name and likewise any other meta information from the database.

DataTables

DataTables has the ability to render data from one form into another form that is suitable for the end user to make sense of - in this case, as with Editor, the file id should be converted into a thumbnail, file name or similar. This rendering is done using the columns.render option, used as a function in which we can again call the file() method to get information about the file needed for the display.

Building on the data structure and the Editor initialisation shown above, consider the following DataTable initialisation:

var table = $('#myTable').DataTable( {
    ajax: 'imagesData',
    columns: [
        { data: 'imageId' },
        { data: 'imageId', render: function ( data ) {
            return data ?
                editor.file( 'image', data ).fileName :
                'No image';
        } },
        { data: 'imageId', render: function ( data ) {
            return data ?
                editor.file( 'image', data ).fileSize :
                'No image';
        } },
        { data: 'imageId', render: function ( data ) {
            return data ?
                '<img src="'+editor.file( 'image', data ).webPath+'" />' :
                'No image';
        } },
        { data: 'imageId', render: function ( data, type ) {
            var file = editor.file( 'image', data );

            if ( file ) {
                return type === 'display' ?
                    '<img src="'+file.webPath+'" />' :
                    file.fileName;
            }
            return 'No image';
        } }
    ]
} );

The table has five columns all showing the file information different ways:

  • Column 1: Simply shows an image id (which would reference the id column in the above table from a table join)
  • Column 2: Use file() to get the file name (i.e. this column would show Allan.png etc). Note that we check for the data being non-falsy before using the file information, otherwise there is no file assigned.
  • Column 3: Shows the file size (i.e. 4532)
  • Column 4: Shows the image in the column (i.e. <img src="/uploads/1" />)
  • Column 5: This column makes use of DataTables orthogonal data ability - the image is used for the display HTML, but the file name is used for sorting and filtering.

The above assumes that the singular upload field type is used and a scalar argument is passed into the rendering function. The uploadMany field type uses an array value and the rendering function must be appropriately updated to take account of that for columns which show such data (e.g. use return data.length+' file(s)' to show the number of files, or loop over the the array to access the meta data for each file to display multiple files).

Server-side

For information about the server-side configuration, please refer to the PHP and .NET documentation as appropriate for the platform you are using.

If you aren't using either of the provided server-side libraries, please refer to the client / server data documentation for a description of the parameters that Editor sends and then expects to receive in reply.