ZCrud tutorial - Getting started

Introduction

Downloading ZCrud and its dependencies

Go to Download section and follow the intructions to download ZCrud and its dependencies.

Configuring HTML header

You must add to your web page the javascript code of ZCrud (and its dependencies) and the CSS file. For example:

<head>
    ...
    <link rel="stylesheet" type="text/css" href="/zcrud/themes/basic/theme.css" media="all">
    <script src="/zcrud/zcrud.min.js" type="text/javascript"></script>
    ...
</head>
        

Creating a container

Zcrud needs a container to include all the generated HTML code. It can be a simple div tag:

<body>
    ...
    <div id="container">
        <div id="zcrud-busy-message">
            Starting ZCrud...
        </div>
    </div>
    ...
</body>
        

Internal div (with id 'zcrud-busy-message') is optional but recommended. It shows a tipical busy message while starting ZCrud:

Starting ZCrud message

Creating a ZCrud instance and building the list

Let's take a look at this:

// Build this object to configure ZCrud instance
var options = {

    entityId: 'people',
    saveUserPreferences: false,

    pageConf: {
        defaultPageConf: {
            updateURL: 'http://your-domain/CRUDManager.do?cmd=BATCH_UPDATE&table=people',
            getRecordURL: 'http://your-domain/CRUDManager.do?cmd=GET&table=people'
        },
        pages: {
            list: {
                getGroupOfRecordsURL: 'http://your-domain/CRUDManager.do?cmd=LIST&table=people',
                fields: [ 'id', 'name', 'datetime', 'country', 'city', 'browser' ],
                components: {
                    sorting: {
                        isOn: true,
                        default: {
                            fieldId: 'name',
                            type: 'asc'
                        },
                        allowUser: false
                    },
                    filtering: {
                        isOn: true,
                        fields: [ 'id', 'name' ]
                    },
                    selecting: {
                        isOn: true,
                        multiple: true,
                        mode: [ 'checkbox', 'onRowClick' ] // Options are checkbox and onRowClick
                    }
                }
            }, 
            create: {
                fields: [
                    {
                        type: 'fieldsGroup'
                    }
                ]
            }, 
            update: {
                fields: [
                    {
                        type: 'fieldsGroup'
                    }
                ]
            }, 
            delete: {
                fields: [
                    {
                        type: 'fieldsGroup'
                    }
                ]
            }
        }
    },

    key : 'id',
    fields: {
        id: {
        },
        name: {
            attributes:{
                rowHeader: {
                    style: 'width:30%'
                }
            }
        },
        description: {
            type: 'textarea'
        },
        date: {
            type: 'date',
            inline: false
        },
        time: {
            type: 'time'
        },
        datetime: {
            type: 'datetime'
        },
        phoneType: {
            type: 'radio',
            translateOptions: true,
            options: [
                { value: '1', displayText: 'homePhone_option' }, 
                { value: '2', displayText: 'officePhone_option' }, 
                { value: '3', displayText: 'cellPhone_option' } 
            ]
        },
        country: {
            type: 'select',
            translateOptions: false,
            options: [
                { value: 1, displayText: 'France' }, 
                { value: 2, displayText: 'Italy' },
                { value: 3, displayText: 'Portugal' }, 
                { value: 4, displayText: 'Spain' }, 
                { value: 5, displayText: 'UK' }
            ],
            defaultValue: '4'
        },
        city: {
            type: 'select',
            sorting: false,
            dependsOn: 'country',
            options: function( data ){

                if ( ! data.dependedValues.country ){
                    return [];
                }

                switch ( parseInt( data.dependedValues.country ) ) {
                    case 1:
                        return [ 
                            { value: 1, displayText: 'Paris' }, 
                            { value: 2, displayText: 'Marseille' }, 
                            { value: 3, displayText: 'Lyon' }, 
                            { value: 4, displayText: 'Toulouse' },
                            { value: 5, displayText: 'Nice' }
                        ];
                    case 2:
                        return [ 
                            { value: 1, displayText: 'Roma' }, 
                            { value: 2, displayText: 'Milano' }, 
                            { value: 3, displayText: 'Napoli' }, 
                            { value: 4, displayText: 'Torino' },
                            { value: 5, displayText: 'Paliemmu' }
                        ];
                    case 3:
                        return [ 
                            { value: 1, displayText: 'Lisboa' }, 
                            { value: 2, displayText: 'Oporto' }, 
                            { value: 3, displayText: 'Vila Nova de Gaia' }, 
                            { value: 4, displayText: 'Amadora' },
                            { value: 5, displayText: 'Braga' }
                        ];
                    case 4:
                        return [ 
                            { value: 1, displayText: 'Madrid' }, 
                            { value: 2, displayText: 'Barcelona' }, 
                            { value: 3, displayText: 'Valencia' }, 
                            { value: 4, displayText: 'Sevilla' },
                            { value: 5, displayText: 'Zaragoza' }
                        ];
                    case 5:
                        return [ 
                            { value: 1, displayText: 'London' }, 
                            { value: 2, displayText: 'Birmingham' }, 
                            { value: 3, displayText: 'Glasgow' }, 
                            { value: 4, displayText: 'Liverpool' },
                            { value: 5, displayText: 'Leeds' }
                        ];
                    default:
                        throw 'Unknown country: ' + data.dependedValues.country;
                }
            }
        },
        browser: {
            type: 'datalist',
            options: [ 'Edge', 'Firefox', 'Chrome', 'Opera', 'Safari' ]
        },
        important: {
            type: 'checkbox'
        },
        hobbies: {
            type: 'checkboxes',
            translateOptions: true,
            options: [ 'reading_option', 'videogames_option', 'sports_option', 'cards_option' ]
        }
    },

    validation: {
        modules: 'security, date',
        rules: {
            '#zcrud-name': {
                validation: 'length',
                length: '3-12'
            }
        }
    },

    i18n: {
        language: 'en',
        files: { 
            en: [ 'en-common.json', 'en-people.json' ],
            es: [ 'es-common.json', 'es-people.json' ] 
        }
    }
};

$( '#container' ).zcrud( 
    'init',
    options,
    function( options ){
        $( '#container' ).zcrud( 'renderList' );
    }
);
        

There are 2 calls to methods of ZCrud:

  1. The first call is 'init' method. This method initializes ZCrud (using the options object) and loads external resources (templates) using HTTP. When it has finished it calls to the callback function.
  2. The second call is 'renderList'. It sends a request to the server to retrieve records and then build the HTML of the list.

ZCrud uses the URL in pageConf/pages/list/url at options as the URL to send the request and to retrieve the records. ZCrud send a request in JSON format like this:

{
    "command": "listRecords",
    "filter":{},
    "pageNumber":1,
    "pageSize":10,
    "sortFieldId":"name",
    "sortType":"asc"
}
        

Let's see them:

ZCrud expects a response in JSON format like this:

{
	"result":"OK",
	"message":"",
	"records":[
        {
            "id":"110",
            "name":"Aaron Good",
            "description":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur sed tortor. Integer aliquam adipiscing lacus. Ut",
            "date":"2011-10-03T00:00:00.000Z",
            "datetime":"2017-02-15T23:22:12.000Z",
            "time":"09:07",
            "phoneType":3,
            "country":4,
            "city":1,
            "browser":"Safari",
            "important":"true",
            "hobbies":["reading_option","videogames_option","sports_option"]
        },
        {
            "id":"77",
            "name":"Addison Guerra",
            "description":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur sed",
            "date":"2017-06-05T00:00:00.000Z",
            "datetime":"2010-07-02T00:01:13.000Z",
            "time":"13:26",
            "phoneType":3,
            "country":4,
            "city":1,
            "browser":"Opera",
            "important":"true",
            "hobbies":["videogames_option","sports_option","cards_option"]
        },
        {
            "id":"109",
            "name":"Adrienne Douglas",
            "description":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur sed tortor. Integer aliquam adipiscing lacus. Ut nec urna et arcu",
            "date":"2013-02-10T00:00:00.000Z",
            "datetime":"2019-07-24T19:06:34.000Z",
            "time":"18:53",
            "phoneType":3,
            "country":1,
            "city":2,
            "browser":"Opera",
            "important":"true",
            "hobbies":["reading_option","videogames_option","cards_option"]
        },
        {
            "id":"59",
            "name":"Alan Chandler",
            "description":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur sed",
            "date":"2013-06-14T00:00:00.000Z",
            "datetime":"2010-01-20T14:59:40.000Z",
            "time":"05:22",
            "phoneType":3,
            "country":3,
            "city":2,
            "browser":"Opera",
            "important":"false",
            "hobbies":["videogames_option","sports_option","cards_option"]
        },
        {
            "id":"42",
            "name":"Amaya Burton",
            "description":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur sed tortor. Integer",
            "date":"2013-05-08T00:00:00.000Z",
            "datetime":"2017-07-07T05:48:53.000Z",
            "time":"17:38",
            "phoneType":2,
            "country":3,
            "city":2,
            "browser":"Safari",
            "important":"false",
            "hobbies":["reading_option","videogames_option","cards_option"]
        },
        {
            "id":"12",
            "name":"Amos Norton",
            "description":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur sed tortor. Integer aliquam adipiscing lacus. Ut nec",
            "date":"2013-12-05T00:00:00.000Z",
            "datetime":"2017-05-06T10:45:39.000Z",
            "time":"09:28",
            "phoneType":2,
            "country":4,
            "city":3,
            "browser":"Opera",
            "important":"true",
            "hobbies":["reading_option","videogames_option","cards_option"]
        },
        {
            "id":"60",
            "name":"Aurora Russo",
            "description":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur sed tortor. Integer aliquam adipiscing lacus. Ut nec urna et",
            "date":"2014-02-26T00:00:00.000Z",
            "datetime":"2017-01-12T23:58:14.000Z",
            "time":"03:12",
            "phoneType":2,
            "country":2,
            "city":1,
            "browser":"Opera",
            "important":"false",
            "hobbies":["reading_option","videogames_option","cards_option"]
        },
        {
            "id":"17",
            "name":"Ava Mendez",
            "description":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur sed tortor. Integer aliquam adipiscing lacus. Ut nec urna et arcu",
            "date":"2017-01-10T00:00:00.000Z",
            "datetime":"2012-05-29T20:00:40.000Z",
            "time":"04:53",
            "phoneType":3,
            "country":3,
            "city":2,
            "browser":"Opera",
            "important":"false",
            "hobbies":["reading_option","videogames_option","cards_option"]
        },
        {
            "id":"100",
            "name":"Basia Alvarez",
            "description":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur sed",
            "date":"2013-05-04T00:00:00.000Z",
            "datetime":"2016-10-08T01:23:06.000Z",
            "time":"11:10",
            "phoneType":1,
            "country":1,
            "city":1,
            "browser":"Edge",
            "important":"true",
            "hobbies":["videogames_option","sports_option","cards_option"]
        },
        {
            "id":"50",
            "name":"Beau Roach",
            "description":"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur sed tortor.",
            "date":"2018-10-15T00:00:00.000Z",
            "datetime":"2010-08-08T22:59:55.000Z",
            "time":"20:25",
            "phoneType":1,
            "country":4,
            "city":1,
            "browser":"Chrome",
            "important":"false",
            "hobbies":["reading_option","sports_option","cards_option"]
        }
	],
	"totalNumberOfRecords":129
}
        

4 properties are expected:

Creating a new record

When an user click the Add new record button, a new form is rendered. Then the user fills the form and click the Save changes button. Zcrud sends to the url in pageConf/pages/create/url a message in JSON like this:

{
    "command":"batchUpdate",
    "existingRecords":{},
    "newRecords":[
        {
            "id": 129,
            "name": "Dalton Suarez",
            "description": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur sed tortor. Integer aliquam",
            "date":"2018-10-15T00:00:00.000Z",
            "datetime":"2010-08-08T22:59:55.000Z",
            "time": "05:12",
            "phoneType": 2,
            "country": 2,
            "city": 2,
            "browser": "Safari",
            "important": "true",
            "hobbies": [ 'reading_option', 'sports_option', 'cards_option' ]
        }
    ],
    "recordsToRemove":[],
    "updateURL":"http://your-domain/CRUDManager.do?cmd=BATCH_UPDATE&table=people"
}
        

ZCrud expects the server to return a JSON response like this:

{
    "message":"",
    "newRecords":[
        {
            "id": 129,
            "name": "Dalton Suarez",
            "description": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur sed tortor. Integer aliquam",
            "date":"2018-10-15T00:00:00.000Z",
            "datetime":"2010-08-08T22:59:55.000Z",
            "time": "05:12",
            "phoneType": 2,
            "country": 2,
            "city": 2,
            "browser": "Safari",
            "important": "true",
            "hobbies": [ 'reading_option', 'sports_option', 'cards_option' ]
        }
    ],
    "result":"OK"
}
        

It is important to know that server must update the new records with the key (if not set by user)!

Updating a record

When an user click the Edit record button of a record, ZCrud sends to the url in pageConf/pages/update/getRecordURL a message in JSON like this:

{
    "command": "getRecord",
    "key":"129"
}
        

So ZCrud requests to server the record with key 1. The response of the server must be like:

{
    "result":"OK",
    "message":"",
    "record":{
        "id": 129,
        "name": "Dalton Suarez",
        "description": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur sed tortor. Integer aliquam",
        "date":"2018-10-15T00:00:00.000Z",
        "datetime":"2010-08-08T22:59:55.000Z",
        "time": "05:12",
        "phoneType": 2,
        "country": 2,
        "city": 2,
        "browser": "Safari",
        "important": "true",
        "hobbies": [ 'reading_option', 'sports_option', 'cards_option' ]
    },
    "fieldsData":{}
}
        

When ZCrud receives the server response a new form is rendered. Then the user edits the form and click the Save changes button. Zcrud sends to the url in pageConf/pages/update/url a message in JSON like this:

{
    "command":"batchUpdate",
    "existingRecords":{
        "129":{
            "name": "Dalton Suares",
        }
    },
    "newRecords":[],
    "recordsToRemove":[],
    "updateURL":"http://your-domain/CRUDManager.do?cmd=BATCH_UPDATE&table=people"
}
        

By default ZCrud only sends data from modified fields. The server response must be like:

{
    "message":"",
    "newRecords":[],
    "result":"OK"
}
        

Deleting a record

When an user click the Delete record button of a record, ZCrud sends to the url in pageConf/pages/delete/getRecordURL a message in JSON like this:

{
    "command": "getRecord",
    "key":"129"
}
        

So ZCrud requests to server the record with key 129. The response of the server must be like:

{
    "result":"OK",
    "message":"",
    "record":{
        "id": 129,
        "name": "Dalton Suarez",
        "description": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur sed tortor. Integer aliquam",
        "date":"2018-10-15T00:00:00.000Z",
        "datetime":"2010-08-08T22:59:55.000Z",
        "time": "05:12",
        "phoneType": 2,
        "country": 2,
        "city": 2,
        "browser": "Safari",
        "important": "true",
        "hobbies": [ 'reading_option', 'sports_option', 'cards_option' ]
    },
    "fieldsData":{}
}
        

When ZCrud receives the server response a new form is rendered. Then the user view the form and click the Delete button. Zcrud sends to the url in pageConf/pages/delete/url a message in JSON like this:

{
    "command":"batchUpdate",
    "existingRecords":{},
    "newRecords":[],
    "recordsToRemove":["129"],
    "updateURL":"http://your-domain/CRUDManager.do?cmd=BATCH_UPDATE&table=people"
}
        

If everything is OK the server response must be like:

{
    "message":"",
    "newRecords":[],
    "result":"OK"
}
        

If an error occurs the server response must be like:

{
    "message":"Your error message here!",
    "newRecords":[],
    "result":"Error"
}
        

Demo

Let's take a look at ZCrud in action:

Starting ZCrud...