With the introduction of ColdFusion 11 it brought many new features to developers.  These new features will allow developers to be more productive than ever before.  Enhancements like these will again assist developers in staying ahead of the curve and develop the next great thing.

Among the many new features in ColdFusion 11 one of the biggest was the Mobile Feature Set.  This set of features is designed to help the developer go from idea to installed application all from a single IDE.  These features included an integrated line debugger, remote debugging, application packaging and deployment. These features and more allows developers to build mobile applications with what they already know, ColdFusion.  

In order for someone to truly appreciate the mobile features of CF 11 an example was needed.  So, to show off some of the mobile feature set, CFInventory App was built.  This app, written by Dave Ferguson, was written completely in ColdFusion Builder 3 using the Mobile Features of ColdFusion 11.

 

 

The app was designed to do the following:

  1. Add / Edit inventory items.

    1. Add image of inventory

    2. Add on hand counts and alert counts.

  2. Search and Browse current inventory.

  3. View state of inventory and current inventory counts.

  4. Add / Edit Inventory locations.

  5. Add / Edit Suppliers.

  6. Receive low inventory count alerts.

  7. Automatically order new inventory from suppliers.


Technical Aspects

  1. Uses Bootstrap 3 for layout and theme.

  2. Uses Handlebars for dynamic templating.

  3. Uses local datastore via ColdFusion 11 queries.

  4. Custom and 3rd party jquery plugins for various UI elements.


Phonegap APIs used:

  1. Camera

  2. Local Data Storage

  3. Local File Storage




Application Development

The mobile  application was written entirely in ColdFusion Builder 3.  The changes to CFB3 made doing this type of development very easy.  Also, the changes to CF11 made debugging the application much easier as well.


When it came to debugging the application the line debugger was not used.  Instead the Weinre inspector was used as well as the Phonegap Shell application.  The shell application allowed the app to be loaded on the phone without the need to package the app every time.  Weinre allows for remote inspection such as Chrome Dev Tools in the browser.  This is a new feature of CF11 and it is built right in.  


To make things easier and all in one interface the internal browser of CFB was used.  This allowed the loading of the Weinre debugging interface right in the IDE.  A plugin that enabled a terminal window in CFB was also used so that the Android log could be tailed to see deep errors that didn’t bubble to the interface.

 

Application design

The application itself is a multi-page mobile app with templates for dynamic sections. The majority of the javascript in the application is in external js files. All the data interaction is done via CFCs. This was done as the the CFCs are exposed to the interface as namespaced functions.

 

 

Data CRUD

As previously stated, all the data interaction was done via CFCs.  This allowed them to be exposed as namespaced functions to the UI and made the complicated task of doing data read/write a breeze.  


Here is an example of one of the CRUD CFCs used in the application.   To expose this CFC to the client required the component attribute of “client” to be set to true.  Beyond that, all the code is the same as it would be if the cfc was being used for a non-mobile app.

 

 

Status.cfc: (code)

 

component client="true" output="false" {	
   public function getStatus(id)
    {
  q = queryExecute("select * FROM status where id = '#id#'", 
					null, {"datasource"="cfds"});       
  return q;
    }
   public function getStatusByType(type)
    {
    // always include type 0 status as they are global
  q = queryExecute("select * from status where type = '#type#' 
					or type = 0", null, {"datasource"="cfds"});       
  return q;
    }
}

 

To interact with the cfc it is necessary to use the cfclient tag (new to CF11) in the CFM file being loaded. For example, below is how you could interact with the cfc example above.

 

<cfclient>
<cfscript>
statusObj = new cfcs.status();
statusData = statusObj.getStatusByType(3);
</cfscript>
</cfclient>

 

In the above example, the data returned would be JSON formated so it can be easily handed in JavaScript.  

 

Camera API

One feature of the app was to give the user the ability to add a picture of the inventory item.  This is done by either taking a photo or selecting a photo from the library.

 

The UI to add the image is very simple.  The user will either select to take a picture or get a photo. The user experience after that selection is device specific.  So, if you are on Android or Ios you would get the camera / image gallery native to the device.


 

Client Code:

 

<cfclient>
  <cfscript>
  public void function getPicFromCam(){
 
       opt = cfclient.camera.getOptions();
       res = cfclient.camera.getPicture(opt,true);
       imgB64 ='data:image/jpeg;base64,'+res;
       inventoryNS.setNewInvImage(res);
       document.getElementById('invSampleImg').src = imgB64;
 
  }
 
  public void function getPicFromLib(){
 
       opt = cfclient.camera.getOptions();
       res = cfclient.camera.getPictureFromPhotoLibrary(opt,true);
       imgB64 ='data:image/jpeg;base64,'+res;
       inventoryNS.setNewInvImage(res);
       document.getElementById('invSampleImg').src = imgB64;
 
  }  
  </cfscript>
</cfclient>

 

Depending on the user section on of the two functions is fired.  These run the necessary API and convert the image result to a base64 image.  This image is then stored in the local database for the inventory item.  Since this code needs to interact with the Phonegap API the code needs to be inside CFClient.   


Overall the application is pretty straight forward. The use of the mobile features of ColdFusion 11 made parts of the mobile development process just easier.  The ease of use in dealing with data that matched how it would be done in a standard web application made the transition to mobile development very seamless.  

 

The packaging features of ColdFusion Builder 3 also made the process very seemless as well.  The integration with PhoneGap Build made another complicated part of the process very simple.  The ability to go from development to installable application without leaving the same IDE saves loads of time and frustration.

 

This application was built from scratch using the CF Mobile features and the entire source code is being made available so that CF developers can get to visualize the advantages the new feature set brings to the table. The code for the app can be freely used within any of your mobile apps as well.  Free to check it out and if you have any questions just ask. Dave and the members of the ColdFusion team will be happy to answer.  If you are looking to build your next mobile application give the mobile features of ColdFusion 11 a serious look.


CFInventory Source

 


13 Comments to “CFInventory Mobile Application”

  1. Adam Cameron
    [subscribe]
  2. Adam Cameron
    I think this is an excellent effort from Dave, and is a far better demonstration than anything the Adobe dudes had come up with. I guess this just goes to show the benefit of actually involving web practitioners - rather than just engineers who might write the stuff but don't use it on a daily basis - in this sort of thing.


    I mentioned this to Dave on Twitter but he suggested posting it here instead, a coupla notes regarding the code quality (for people looking at it from a neophyte's point of view):
    * Dave's used a lot of hard-coded data values in his queries. This is really poor form, and one should never do that. Alway, ALWAYS parameterise your queries properly. Data does not belong in the SQL statement.
    * the site architecture is a bit 1990s. One should take a more MVC approach to things... all the CFCLIENT logic @ the top of what amounts to view files isn't great. Even without an MVC framework in place (overkill for this sort of thing, probably), at least separate the code out into controller, model and view components.

    I realise this is just a sample app and I think Dave has done a good job purely in that context, but I also think that demonstration code should always be written with best practices in mind, and this code has some room for improvement. It needs to be driven home to CFML devs to *always* do a good job of the code they write. Especially if it's going on show.

    Overall, I think it's a win for CFCLIENT though.

    Good work Dave.

    --
    Adam
  3. CF Mitrah
    Posting it in GitHub or BitBucket, that could help others to review it easily.
  4. Dave Ferguson
    @Adam

    Thanks for the feedback. Let me address a couple of the points you have made so hopefully the design / development choices make sense.

    I fully agree with using query params for everything. However, when I initially built the app there was issues with the early implementation of using queries. I had started down the road of not using them to get around some issues and never went back to fix it. Also, there is almost no risk on not using params. The app is installed and only interacts with its own data so if someone tried to inject a query they only hurt themselves.

    The architecture is the way it is by design. Since I knew from the start that the code as to be shared I didn't want it to be overly confusing to the laymen. I didn't want to confuse matters for someone looking at the code and have to figure out what parts are MVC framework and what parts are CF11 mobile features. After all the goal was to showcase the mobile features.

    I did work in a few things like Handlebars and some JQuery plug-ins but I tried to keep all that at a minimum at best.

    Thanks,

    --Dave
  5. Dave Ferguson
    @cfMithra Agreed... Code will eventually be posted on git something. But that is not setup yet. Didn't want to delay getting article out while waiting for that.
  6. Adam Cameron
    Fair enough re how the code grew.

    Just regarding parameterising queries... it's not primarily about SQL injection, it's *primarily* about DB performance (also not so important here), and just doing things properly. It's just *bad practice* to hard-code values into SQL statements. Just like it's bad to hard-code magic numbers into code, etc. One should simply never do it. Ever.


    Your comment about "issues with the early implementation of using queries" reminds me something that we also mentioned on Twitter... perhaps it would be nice to get a "war stories" blog entry (or CFHour podcast), of the hassles you had getting this to work... I'm sure there were "gotchas" along the way.


    What I meant by MVC was - specifically - not a framework, bt just this:

    // myPage.cfm - basically the controller
    include "theModelStuff.cfm"
    include "theViewStuff.cfm"

    Nothing more than that. Just a nudge in the right direction re separation of concerns. And not overcomplicating things.

    Cheers fella. Again: good work.

    --
    Adam
  7. Henry Ho
    I asked this on twitter as well but let's ask here again as suggested.

    What are some of the more annoying bugs in CFClient / CF Mobile in your opinion, and what are the workarounds?

    I asked this because when ORM Was introduced it took CF team a few updates and some took next major version to have them fixed.

    Thanks
  8. Gary F
    Thanks for the demo code. As I don't use MVC frameworks it would have complicated the essence of the functionality being demonstrated. I would feel uncomfortable writing client code in this way and haven't yet grasped the advantages if you're already familiar with writing JavaScript client code in Dreamweaver, Sublime, etc. It all goes through PhoneGap(Build) just the same, but writing your own code directly surely gives you much greater control? If I wrote our mobile apps using CF11 but later had to pass it on to another app developer they'd really struggle if they're unfamiliar with CF. Just my view. Has someone done a presentation on the advantages/disadvantages?
  9. Aaron
    @Adam

    I agree Dave needs to use parameters for dynamic values in his queries.

    Hard coding non-dynamic strings / numbers into SQL is a good thing performance-wise

    select count( product_id )
    from
    products
    where active = 1

    will product a better execution plan than

    select count( product_id )
    from
    products
    where active = <cfqueryparam value="1" >
  10. Peter Boughton
    Aaron: that's not a magic number, it's a boolean flag.
  11. Peter Boughton
    Dave wrote:
    > if someone tried to inject a query they only hurt themselves

    Yeah, people used to say that about JavaScript too.

    Even if there's guaranteed no security risk at all, and even putting aside the performance reasons for it, it's still bad code in a context where code should be good, because it's setting an example to other developers.


    > The architecture is the way it is by design. Since I
    > knew from the start that the code as to be shared I
    > didn't want it to be overly confusing to the laymen

    Don't write code for newbies!

    Write *good* code, then document/explain it so they can understand and *learn* from it.
  12. Adam Cameron
    Well said Peter.

    Another consideration is that one should never consider one's "tutorial" code in a silo.

    People - not knowing better - will lift code from a tutorial and just assume "that's how it should be done", and then use those techniques elsewhere in their code, perhaps in situations where code that was originally innocuous is now dangerous.

    One should not bring one's code down to the lowest-common-denominator: bring *them* up to the higher level. One is not doing anyone any favours by dumbing everything down.


    --
    Adam
  13. Steve Sommers
    @Adam Cameron, In your first response above you mentioned "One should take a more MVC approach to things..." I am just starting out with this mobile development stuff and would prefer to learn/adopt an MVC approach but I am having difficulties finding ColdFusion CFClient examples even though most of the examples I have found make similar "MVC would be better" references. Can you or anyone post some good links CFClient based mobile examples using MVC (hopefully somewhat small).

Leave a Comment

Leave this field empty: