Tag Archives: Sencha

Fig Leaf Software’s Ext JS 5 Fiddles

We’ve been developing a bunch of Sencha Ext JS 5 examples lately, and we decided to share them with the community. Hopefully these will prove helpful to the newbies!

Finishing up Fast Track to Sencha Touch 2.2 Course Updates

I‘m wrapping up delivered  on my latest courseware collaboration with the Sencha training team to update their Fast Track to Sencha Touch 2.2 coursebook. They’ve really done an awesome job with this release. I couldn’t find a single major bug and the performance improvements are quite phenomenal. They also now support the new Windows phones, which is pretty cool.

As with previous releases of the courseware, you’ll learn how to develop a complex, custom-themed production-ready app named “CrimeFinder” that brings information about criminal activity in the DC area to your mobile device. As indicated by the screenshots below, you’ll use a single codebase to easily support multiple device profiles. With over 45 exercises spread over five days, you cannot find more comprehensive instruction on how to develop cross-platform mobile apps!

Image

Sencha has a really skilled network of instructors (including myself) ready to teach a private class to your development team. Contact Fig Leaf or Sencha for more information.

You can also sign up for open-enrollment training courses (offered worldwide) at http://www.sencha.com/training/.

I’ll be teaching the next open enrollment class in Washington, DC on June 17. The course is starting to fill, so sign up today! I love showing off the latest and greatest stuff that I’ve been working on for The Fig’s consulting services group as well as counsel students on how to apply concepts taught in class apply to their work-related projects. SO BRING YOUR CODE TO CLASS!

What are you waiting for? Sign up now and join the mobile revolution!

Tap and Drag Animation Domination Part 2: Implementing Custom Animations with Ext.Anim


Note: This is part of a three-part series on drag and drop animation in Sencha Touch 2. Click here to read part 1.

Use the Ext.Anim.run() method to execute custom animations from your Sencha Touch apps. Note that Ext.Anim.run() can only operate on DOM elements. Therefore, if you wanted to define a custom fade effect on an Ext.Container component, your code would need to appear similar to the following:


Ext.Viewport.add(
 {
  xtype: 'component',
  html: 'Beam me up, scotty!',
  style: 'background-color: silver; opacity: 0.0',
  height: 200,
  width: 200,
  listeners: {
    show: function(cmp) {

     // define custom fade animation on the component
      Ext.Anim.run(cmp.element, new Ext.Anim({
          autoClear: true,    // clear final animation effect
          easing: 'ease-in',
          duration: 1000,     // transition over 1 sec
          from: {
           'opacity': 0.0     // fade from fully transparent
          },
          to: {
           'opacity' : 1.0    // end effect will be opaque
          },
          after: function(el) {
            // after animation is complete,
            // set the component to be fully opaque
            var cmp =  Ext.getCmp(el.getId());
            cmp.setStyle('background-color: silver; opacity: 1.0');
          }
       }));
     }
   }
}

Note that prior to invoking the Ext.Anim singleton, you must load the class into memory using either the Ext.require() method or the requires config property of a component.

You can put any CSS3 property that is supported by your device into the from/to config blocks. Note, however, that any property that is present in the from config object must also be specified in the to object.

Before you consider implementing all kinds of zany CSS-3 based animations, consider that not all CSS3 animations are performant across all devices. Performance in Desktop Chrome and the iOS Simulator is not indicative of how well your animation will perform on an actual iPhone 5, iPad, or Android device. I strongly urge you to set up a small test harness, as indicated above, to test complex animations on physical devices before dropping them into your app’s codebase.

Orchestrating Login and Roles-Based Security in Ext JS and Sencha Touch

The issue of logins and roles-based security often comes up in my Ext JS and Sencha Touch classes. The sad reality is that anyone who knows how to open the browser’s JavaScript debugger is able to “hack” your application. Therefore, security is something that *must& be handled at the application-server level as there is no current method to adequately secure your JavaScript code.

Having said that, most corporate apps still require logins and roles-based security as functional requirements. A user must enter credentials and their button/menu selections need to be tailored to a specified role as illustrated by the following video:

Typically, your app.js file simply invokes a login dialog as illustrated by the following code snippet:

// code listing 1: app.js
Ext.application({
    controllers: ["Main"],
    views: ["Main"],
    name: 'LoginAppDemo',
    autoCreateViewport: false,
    launch: function() {
    	Ext.create("LoginAppDemo.view.LoginForm")
    }
});

Let’s also assume that we’re going to put together a simple login form inside of a floating window. Why a floating window, you ask? Because login forms are always cooler if they float and are draggable, of course!

// code listing 2: LoginForm.js
Ext.define("LoginAppDemo.view.LoginForm", {
 extend: 'Ext.window.Window',
 alias: 'widget.loginform',
 requires: ['Ext.form.Panel'],
 title: 'Please Log In',
 autoShow: true,
 height: 150,
 width: 300,
 closable: false,
 resizable: false,
 layout: 'fit',
 items: [
  {
   xtype: 'form',
   bodyPadding: 5,
   defaults: {
    xtype: 'textfield',
    anchor: '100%'
   },
   items: [
    {
     fieldLabel: 'User Name:',
     name: 'username',
     allowBlank: false
    },
    {
     fieldLabel: 'Password:',
     name: 'password',
     allowBlank: false
    },
   ],
   buttons: [
    {
     text: 'Log in',
     formBind: true,
     disabled: true,
     handler: function(b,e) {
      var formDialog = b.up('loginform');
      var form = b.up('form');
      
      // fire custom event for the controller to handle
      formDialog.fireEvent('login',formDialog,form,form.getValues());
     } // handler
    } // login button
   ] // buttons 
  } // form
 ] // items
}) 

Note that in the preceding example, when the user clicks the ‘Log in’ button, I fire a custom ‘login’ event and pass references to the login window, the login credentials form, and the data that the user entered into the form up to the controller (listed below).

From within the login handler, I make an Ajax call to the server in order to retrieve information about the user profile. In a production environment you would make this call via HTTPS to your application server (.php,.aspx,.jsp,.cfc, etc.).

// code listing 3
Ext.define('LoginAppDemo.controller.Main', {
 extend: 'Ext.app.Controller',
 requires: ['LoginAppDemo.user.Profile'],
 views: ['LoginForm','Viewport'],
    
 init: function(application) {
  this.control({
   "loginform": {
     login: this.onLogin
    }
  });
 },

 onLogin: function(loginDialog,loginForm,loginCredentials) {
   
   var me = this;

   // authenticate
   Ext.Ajax.request({
    url: 'resources/sampledata/cred.json',
    params: {
     username: loginCredentials.username,
     password: loginCredentials.password
    },
    success: function(response) {
     
     // convert text response to javascript object
     var data = Ext.decode(response.responseText);
    
     // if server response contains "firstName" node, then success!			
     if (data.firstName) {
      // instantiate user info in global scope for easy referencing
      LoginAppDemo.User = Ext.create("LoginAppDemo.user.Profile", {
    					firstName: data.firstName,
    					lastName: data.lastName,
    					roles: data.roles
      });
     
      // destroy login dialog
      loginDialog.destroy();


      Ext.Msg.alert("Login Successful",
    		    Ext.String.format("Welcome {0} {1}",
    				      LoginAppDemo.User.getFirstName(),
    				      LoginAppDemo.User.getLastName())
      );

      // load main UI
      Ext.create("LoginAppDemo.view.Viewport");


  } else { // login failed
    Ext.Msg.alert("Invalid credentials",
                  "You entered invalid credentials.", 
                  function() {
    		   loginForm.getForm().reset();
                  }
    );
  }
 }
});
}
});

Your app server would subsequently run a custom sql query to ensure that the passed username and password were valid and return a response similar to the following:

// code listing 4: cred.json
{
 firstName: 'Steve',
 lastName: 'Drucker',
 roles: 'admin'
}

Your app server would also set up session management for the user, typically consisting of some sort of session-based cookie hack since not every browser supports the establishment of persistent (html5 websocket) connections. Each subsequent data request to the server would use this cookie to determine whether the user had the appropriate rights to download the data that was requested.

From a UI perspective, however, we are simply concerned with caching the user’s identity and roles information in a location that could be easily accessed by our view and controller logic. Lines 33-37 of code listing 3 above instantiate the custom component described in code listing 5 at the root of your application’s namespace for easy global access.

// code listing 5
Ext.define("LoginAppDemo.user.Profile", {
	
  config: {
    firstName: '',
    lastName: '',
    roles: []
  },

  isUserInRole: function(roles) {
   for (var i=0; i<roles.length; i++) {
    if (Ext.Array.contains(this.getRoles(),roles[i])) {
     return true
    }
   }
   return false;
  },

  constructor: function(config) {
    this.initConfig(config);
    this.callParent(arguments);
  }

});

As illustrated by the following toolbar class, once the framework described above is in place, you can simply test the features of your app before outputting them to the user.

Ext.define("LoginAppDemo.view.MainToolbar", {
 extend: 'Ext.toolbar.Toolbar',
 alias: 'widget.maintoolbar',
 requires: ['Ext.toolbar.TextItem'],
	
 initComponent: function() {
  var items = [
   {
    xtype: 'tbtext',
    text: 'Login and Roles-Based Security Simulator'
   }, 
   {
    xtype: 'tbfill'
   }
  ];

  if (LoginAppDemo.User.isUserInRole(["admin"])) {
   items.push({ xtype: 'button', text: 'For Admins'});
  }

  if (LoginAppDemo.User.isUserInRole(["admin","users"])) {
   items.push({xtype: 'button', text: 'For Admins or Users' });
  }

  if (LoginAppDemo.User.isUserInRole(["nobody"])) {
   items.push({xtype: 'button', text: 'For nobody' });
  }

  Ext.apply(this, {items: items});
  this.callParent(arguments);
 }
});