Results 1 to 7 of 7

Thread: Server-Validation with JSON Response

  1. #1
    Touch Premium Member
    Join Date
    Sep 2011
    Posts
    6
    Vote Rating
    0
      0  

    Default Answered: Server-Validation with JSON Response

    Hi,

    how should the server return the validation data when validated through the server?

    Code:
    {"success":false,"message":"Fehler im Formular",
    "error":{"reason":"Fehler im Formular","code":10},
    "errors":[
      {"field":"name","msg":"You have to supply a Username."}
    ]}
    http://dev.sencha.com/deploy/ext-4.0.../xml-form.html
    The JSON Example is gone.

    In my record.save() failure routine how should I mark the fields as invalid?
    What is done automatically by ExtJs and what do I have to do myself?

  2. Hi again,


    Did some refactoring. Let me know what you think. (Sorry if my code is too verbose.)


    Model
    Code:
    Ext.define("MyApp.model.Subscription", {
        extend:"Ext.data.Model",
        fields:["id","first_name","last_name","address","zip_code","city","service"],
        proxy:{
            type:"rest",
            url:"/subscriptions",
            listeners:{
                exception:function(proxy, response, operation) {
                    var json = Ext.decode(response.responseText);
                    if (json && json.errors) {
                        operation.setException(json.errors);
                    }
                }
            }
        }
    });

    Controller
    Code:
    Ext.define("MyApp.controller.Subscriptions", {
        extend:"Ext.app.Controller",
    
    
        models:["Subscription"],
        views:["subscription.Form"],
    
    
        refs: [{
            ref:"subscriberForm",
            selector:"subscriberform > form"
        }],
    
    
        init:function() {
            this.control({
                "subscriberform > button":{
                    click:this.onSubmitForm,
                    scope:this
                }
            });
        },
        
        onSubmitForm:function() {
            var form = this.getSubscriberForm(),
                record = form.getRecord(),
                values = form.getValues();
                
            record.set(values);
            record.save({
                success:function(records, operation) {
                    console.log("success");
                },
                failure:function(records, operation) {
                    console.log("failure");
                    form.getForm().markInvalid(operation.getError());
                }
            });
        }
    });

  3. #2
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,791
    Answers
    585
    Vote Rating
    394
      0  

    Default

    The example you've referenced uses a form submit to save the fields. This provides an automatic mechanism for marking fields as invalid. For a JSON equivalent see here:

    http://docs.sencha.com/ext-js/4-0/#!....action.Submit

    If you use record.save() then I don't believe you'll get anything for free. You can provide handlers for success, failure or callback and set whatever invalidity markings are required.

  4. #3
    Touch Premium Member
    Join Date
    Sep 2011
    Posts
    6
    Vote Rating
    0
      0  

    Default

    Thank you very much!
    I now tried both ways simple submit and record.save(). It seems that for our approach the record.save() is more suited.

    We need the Exception Listeners inside the proxy to handle if the session was timed out or other things send from the server during any request. At a first look the form submit did not seem to offer a way.

    Anyway I haven't figured out so far on how to access the error properties from my server response.
    Code:
    record.save( {
                    success: function() {
                        Ext.Msg.show( {
                            title: 'Profile Saved',
                            msg: 'The Profile was saved',
                            buttons: Ext.Msg.OK,
                            icon: Ext.Msg.INFO
                        } );
                        me.cancelWindow();
                    },
                    failure: function( records, operation ) {
                        if( !operation.hasException() ) {
                            Ext.Msg.error( {
                                title: 'Error',
                                msg: 'Error',
                                buttons: Ext.Msg.OK,
                                icon: Ext.Msg.ERROR
                            } );
                        }
                        me.getFormPanel().getEl().unmask();
                        console.log( operation );
                        console.log( records );
                        var form = me.getFormPanel().getForm();
                        form.getFields();
    [...] Invalidate Fields
                    },
                    callback: function( records, operation ) {
                        me.getFormPanel().getEl().unmask();
                        console.log( operation );
                        console.log( records );
                    }
                } );

  5. #4
    Sencha User
    Join Date
    Oct 2011
    Location
    Sweden
    Posts
    36
    Answers
    10
    Vote Rating
    0
      0  

    Default

    Hi infarbe,

    Here is some controller code I use to incorporate server-side validation into my form using a more MVC-like structure than using form.submit:

    Code:
    Ext.define("MyApp.controller.Subscriptions", {
        extend:"Ext.app.Controller",
    
        models:["Subscription"],
        views:["subscription.Form"],
    
        refs: [{
            ref:"subscriberForm",
            selector:"subscriberform > form"
        }],
    
        init:function() {
            var model = this.getSubscriptionModel(),
                proxy = model.getProxy();
                
            proxy.on("exception", function(proxy, response, operation) {
                console.log("exception");
                var json = Ext.decode(response.responseText);
                if (json && json.errors) {
                    this.getSubscriberForm().getForm().markInvalid(json.errors);
                }
            }, this);
            
            this.control({
                "subscriberform > button":{
                    click:this.onSubmitForm,
                    scope:this
                }
            });
        },
        
        onSubmitForm:function() {
            var form = this.getSubscriberForm(),
                record = form.getRecord(),
                values = form.getValues();
                
            record.set(values);
            record.save({
                success:function(records, operation) {
                    console.log("success");
                },
                failure:function(records, operation) {
                    console.log("failure");
                }
            });
        }
    });
    I found almost the exact same approach in this post: http://www.sencha.com/forum/showthread.php?137580-ExtJS-4-Sync-and-success-failure-processing&p=615838&viewfull=1#post615838

  6. #5
    Sencha User
    Join Date
    Oct 2011
    Location
    Sweden
    Posts
    36
    Answers
    10
    Vote Rating
    0
      0  

    Default

    Hi again,


    Did some refactoring. Let me know what you think. (Sorry if my code is too verbose.)


    Model
    Code:
    Ext.define("MyApp.model.Subscription", {
        extend:"Ext.data.Model",
        fields:["id","first_name","last_name","address","zip_code","city","service"],
        proxy:{
            type:"rest",
            url:"/subscriptions",
            listeners:{
                exception:function(proxy, response, operation) {
                    var json = Ext.decode(response.responseText);
                    if (json && json.errors) {
                        operation.setException(json.errors);
                    }
                }
            }
        }
    });

    Controller
    Code:
    Ext.define("MyApp.controller.Subscriptions", {
        extend:"Ext.app.Controller",
    
    
        models:["Subscription"],
        views:["subscription.Form"],
    
    
        refs: [{
            ref:"subscriberForm",
            selector:"subscriberform > form"
        }],
    
    
        init:function() {
            this.control({
                "subscriberform > button":{
                    click:this.onSubmitForm,
                    scope:this
                }
            });
        },
        
        onSubmitForm:function() {
            var form = this.getSubscriberForm(),
                record = form.getRecord(),
                values = form.getValues();
                
            record.set(values);
            record.save({
                success:function(records, operation) {
                    console.log("success");
                },
                failure:function(records, operation) {
                    console.log("failure");
                    form.getForm().markInvalid(operation.getError());
                }
            });
        }
    });

  7. #6
    Touch Premium Member
    Join Date
    Sep 2011
    Posts
    6
    Vote Rating
    0
      0  

    Default

    That is wonderful I now have faith in ExtJs 4 MVC again.

    Code:
    var defaultProxyException = function( proxy, response, operation ) {
    
        if( response.aborted ) {
            return;
        }
    
        var text = response.responseText;
        var data = null;
        if( text ) {
            data = Ext.JSON.decode( text, false );
        }
    
        if( !data ) {
            Ext.MessageBox.show( {
                title: 'Unknown Error',
                msg: operation.getError(),
                icon: Ext.MessageBox.ERROR,
                buttons: Ext.Msg.OK,
                closable: false
            } );
            return;
        }
    
        var error = operation.getError();
        var errorTitle = data.error.title ? data.error.title : 'Error';
        var errorCode = data.error.code ? data.error.code : -1;
        var errorReason = data.error.reason ? data.error.reason : operation
                .getError();
        var destination = data.destination ? data.destination : null;
        var message = data.message ? data.message : operation.getError();
    
        switch (errorCode) {
        default:
        case 10:
            // Validation
            if( data && data.errors ) {
                operation.setException( data.errors );
            }
        break;
        case 500:
        case 401:
        case 403:
            var global = Ext.create( 'Ext.window.MessageBox', {
                renderTo: Ext.getBody(),
                autoDestroy: true
            } );
    
            global.show( {
                title: errorTitle,
                msg: errorReason,
                icon: Ext.MessageBox.ERROR,
                buttons: Ext.Msg.OK,
                closable: false,
                modal: true,
                fn: function( buttonId ) {
                    if( destination !== null ) {
                        window.location = destination;
                    }
                }
            } );
            global.toFront();
        break;
        }
    };

  8. #7
    Sencha User
    Join Date
    May 2009
    Posts
    300
    Answers
    6
    Vote Rating
    2
      0  

    Default

    JambaFun:

    It appears that your approach fires off two PUTS (one for the set and one for the save). Is this what you are seeing?

    TB55

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •