Controlling our user views

The glue that links the three user views together is the UserController. It is here that we place all logic for managing user maintenance. You have seen that each view defined earlier is dumb in that there is only presentation logic defined. Actions, validations, and selections are all handled within the UserController and are explained in the following code:

Ext.define('TTT.controller.UserController', {
    extend: 'Ext.app.Controller',
    views: ['user.ManageUsers'],
    refs: [{
        ref: 'userList',
        selector: 'manageusers userlist'
    }, {
        ref: 'userForm',
        selector: 'manageusers userform'
    }, {
        ref: 'addUserButton',
        selector: 'manageusers #addUserBtn'
    }, {
        ref: 'saveUserButton',
        selector: 'manageusers userform #saveBtn'
    }, {
        ref: 'deleteUserButton',
        selector: 'manageusers userform #deleteBtn'
    }, {
        ref: 'userFormFieldset',
        selector: 'manageusers userform fieldset'
    }, {
        ref: 'usernameField',
        selector: 'manageusers userform textfield[name=username]'
    }],
    init: function(application) {
        this.control({
            'manageusers #addUserBtn': {
                click: this.doAddUser
            },
            'userlist': {
                itemclick: this.doSelectUser,
                viewready: this.doInitStore
            },
            'manageusers userform #saveBtn': {
                click: this.doSaveUser
            },
            'manageusers userform #deleteBtn': {
                click: this.doDeleteUser
            },
            'manageusers userform': {
                afterrender: this.doAddUser
            },
            'userlist header tool[type="refresh"]': {
                click: this.doRefreshUserList
            }
        });
    },
    doInitStore: function() {
        this.getUserList().getStore().load();
    },
    doAddUser: function() {
        var me = this;
        me.getUserFormFieldset().setTitle('Add New User'),
        me.getUsernameField().enable();
        var newUserRec = Ext.create('TTT.model.User', {
            adminRole: 'N'
        });
        me.getUserForm().loadRecord(newUserRec);
        me.getDeleteUserButton().disable();
    },
    doSelectUser: function(grid, record) {
        var me = this;
        me.getUserForm().loadRecord(record);
        me.getUserFormFieldset().setTitle('Edit User ' + record.get('username'));
        me.getUsernameField().disable();
        me.getDeleteUserButton().enable();
    },
    doSaveUser: function() {
        var me = this;
        var rec = me.getUserForm().getRecord();
        if (rec !== null) {
            me.getUserForm().updateRecord();
            var errs = rec.validate();
            if (errs.isValid()) {
                rec.save({
                    success: function(record, operation) {
                        if (typeof record.store === 'undefined') {
                            // the record is not yet in a store 
                            me.getUserList().getStore().add(record);
                        }
                        me.getUserFormFieldset().setTitle('Edit User ' + record.get('username'));
                        me.getUsernameField().disable();
                        me.getDeleteUserButton().enable();
                    },
                    failure: function(rec, operation) {
                        Ext.Msg.alert('Save Failure', operation.request.scope.reader.jsonData.msg);
                    }
                });
            } else {
                me.getUserForm().getForm().markInvalid(errs);
                Ext.Msg.alert('Invalid Fields', 'Please fix the invalid entries!'),
            }
        }
    },
    doDeleteUser: function() {
        var me = this;
        var rec = me.getUserForm().getRecord();
        Ext.Msg.confirm('Confirm Delete User', 'Are you sure you want to delete user ' + rec.get('fullName') + '?', function(btn) {
            if (btn === 'yes') {
                rec.destroy({
                    failure: function(rec, operation) {
                        Ext.Msg.alert('Delete Failure', operation.request.scope.reader.jsonData.msg);
                    }
                });
                me.doAddUser();
            }
        });
    },
    doRefreshUserList: function() {
        this.getUserList().getStore().load();
    }
});

The UserController is defined with a single view to manage users as shown in the following code:

views: [
  'user.ManageUsers'
]

This allows us to define a set of references using the component query language starting with the manageusers root selector. We can hence reference the save button on the UserForm by the selector:

'manageusers userform #saveBtn'

The #saveBtn refers to the component with itemId saveBtn on the userform within the manageusers component.

Note

Only define references that are used by the controller to process business logic. Do not create a reference for components that are never accessed within your code. Keep your code simple and clean!

The init function defines the listeners that should be processed in the interface. Each button click is matched to an appropriate handler function. The user list itemclick event is handled by the doSelectUser function. The viewready event on the userlist triggers the initial load of the grid's store. Each listener event is handled by a single function with a clear purpose. Let's now examine the core functions in detail.

The doAddUser function

The doAddUser function is called when the Add User button is clicked. We set the title on the form fieldset to display Add New User and then enable the username field as shown in the following code:

me.getUserFormFieldset().setTitle('Add New User'),
me.getUsernameField().enable();

We only enable the username field when adding a new user; the username field is not editable for existing users as it represents the primary key. We then create a new User model and load the record into the user form:

var newUserRec = Ext.create('TTT.model.User', {
    adminRole: 'N'
});
me.getUserForm().loadRecord(newUserRec);

At this stage the user form would look like the following screenshot:

The doAddUser function

The Delete button serves no useful purpose for adding a new user and hence we disable it as shown in the following code:

me.getDeleteUserButton().disable();

This gives us the following Add New User interface as shown in the following screenshot:

The doAddUser function

We could just as easily have hidden the delete button instead of disabling it; your approach will depend on your client specifications.

The form is now ready for entering a new user.

The doSelectUser function

The doSelectUser function handles the itemclick event on the userlist grid panel. The arguments to this function are the grid itself and the selected record. This makes loading the form with the selected user record a simple task:

var me = this;
me.getUserForm().loadRecord(record);
me.getUserFormFieldset().setTitle('Edit User ' + record.data.username);
me.getUsernameField().disable();
me.getDeleteUserButton().enable();

The fieldset title is changed to reflect the user being edited and the username field is disabled. We also ensure the Delete button is enabled as we require the option to delete an existing record. Clicking on the Betty Jones record in the user list would then display the following screenshot:

The doSelectUser function

Note

Readers will note that the Password field is empty. This means that saving a user record via the form will require a password to be set. The backend handler method and service layer also require a valid password when saving a user. In the real world this would not be the case; you do not want an administrator changing the password every time they save user details! A Change Password form, perhaps in a pop-up window, would normally trigger a separate AJAX request to change the user's password.

It is now time to code the Save button action.

The doSaveUser function

The doSaveUser function processes the saving of a user record. In most applications the save function will contain the most code as validations and user feedback are important steps in the process.

The first step is to retrieve the user record instance that was loaded in the form as shown in the following code:

var rec = me.getUserForm().getRecord();

If valid, the record is updated with the values entered in the form text fields as shown in the following code:

me.getUserForm().updateRecord();

At this stage the user record will be in sync with the fields entered in the form. This means all fields in the form will have been copied to the model instance. We can now validate the user record as given in the following code:

var errs = rec.validate();

If there are no validation errors, the record is saved using the save() function on the record itself. There are two possible callbacks depending on the returned JSON response. A successful save will trigger the success handler as shown in the following code:

success: function(record, operation) {
    if (typeof record.store === 'undefined') {
        // the record is not yet in a store 
        me.getUserList().getStore().add(record);
       // select the user in the grid
       me.getUserList().getSelectionModel().select(record,true);
    }
    me.getUserFormFieldset().setTitle('Edit User ' + record.data.username);
    me.getUsernameField().disable();
    me.getDeleteUserButton().enable();
}

The success callback will check if the record exists in the store. If not, the record is added to the User store and selected in the user list. The Delete button will then be enabled and the fieldset title set appropriately.

The failure action will simply inform the user of the cause as shown in the following code:

failure: function(rec, operation) {
    Ext.Msg.alert('Save Failure', operation.request.scope.reader.jsonData.msg);
}

If there are errors encountered during validation, we mark the invalid fields and display a generic error message as shown in the following code:

me.getUserForm().getForm().markInvalid(errs);
Ext.Msg.alert('Invalid Fields', 'Please fix the invalid entries!'),

Trying to save a user record without a valid e-mail or password would then display a message as follows:

The doSaveUser function

The doDeleteUser function

The final handler processes the delete action. The doDeleteUser function prompts the user for confirmation before triggering the destroy function on the record if required:

Ext.Msg.confirm('Confirm Delete User', 'Are you sure you want to delete user ' + rec.data.fullName + '?', function(btn) {
    if (btn === 'yes') {
  rec.destroy({
      failure: function(rec, operation) {
    Ext.Msg.alert('Delete Failure', operation.request.scope.reader.jsonData.msg);
      }
  });
  me.doAddUser();
    }
});

The User store will automatically remove the successfully destroyed user model from the store itself. Any failure will inform the user of the reason. Attempting to delete the record for John Smith will result in the message shown in the following code:

The doDeleteUser function

Where is this message coming from? It is generated in the service layer UserServiceImpl.remove method that was coded when implementing the business logic for the delete action. What about trying to delete the currently logged-on user? This will result in the following message:

The doDeleteUser function

Once again this is coming from the service layer business logic.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.218.151.44