When we released the mobile application for CFSummit 2013, many of you had asked for the source code. And we said that we would make the source code public after the summit. So here is the source code of the application.

The application is developed using new mobile features of ColdFusion Splendor and Thunder. Since there are no public builds  available as yet, you cannot run the application from the source. But this will give you an idea of how you could develop mobile applications using the new mobile development features of ColdFusion. 

The application is not meant to be a reference implementation for developing mobile applications. We developed this app primarily to see how the mobile features we had implemented so far could be used in a real-world application, and at the same time provide a useful application to the conference attendees.

The application is implemented as a single page application. It uses JQuery, Bootstrap3, PathJS, JQuery Raty, Codebird, Cordova (PhoneGap), PhoneGap Build and LESS. index.cfm is the first page that is loaded. It includes index_include.cfm, which contains some initialization code and functions to display different pages in the application. Each page is implemented as a client side custom tag, e.g. session_list.cfm is the custom tag for displaying list of sessions. 
All data access code is in CFCs and in the folder 'cfcs'. db_manager.cfc is the main data access CFC and contains other CFCs to manage schedule, speakers and notifications. There are two server-side CFCs - SurveyManager.cfc and ServerSessionSyncManager.cfc. Take a look at onSurveySubmit method in survey.cfm to see how to call a server side CFC from the client side. 

If you want to know some of the details of how UI for this application was implemented and issues we faced, then take a look at this blog post - "My Experience of building UI of CFSummit2013 mobile app" . 

A few things to keep in mind when you browse the code - 

  1. Again, this is not a reference implementation. We were racing against time to complete this application and submit to app stores so that it would be available before the summit. So we might have taken a few shortcuts when implementing the app.
  2. Naming of functions, variables and file names in inconsistent. This is because when we started working on this, client side code was case sensitive. So we named everything in lower case. Later we made cfclient case-sensitive, but did not change the code we had already written.
  3. Variable scope was not implemented initially. So you might see many variables outside functions not scoped at all - they become global variables.
  4. Exception handling for query (cfquery and queryExecute) was being implemented. So you will not see proper exception handling for query in the code. All query code should ideally be in try-cach block.
  5. LESS files should ideally be pre-compiled to CSS. But we did not do this for two reasons - a) our CSS files were not too big, so performance penalty of converting LESS to CSS at runtime was small and b) setting up LESS compiler (setting up Node.js etc.) would have taken some of our time and our schedule was already very tight.
  6. You will see some of the image files used by Raty in the root of the application. We found that moving those images to images sub folder did not display Raty starts properly. So we had to leave them in the root.
  7. We did not create any relationship between sessions and speakers tables. This was deliberate. This data was pre-defined and not editable. Also we wanted to keep the code and updates simple. 
So browse the source code and if possible (we know it is difficult with no ColdFusion builds to run the application) , let us know how we could improve the mobile development framework. 



35 Comments to “Source code of CFSummit2013 mobile application”

  1. Cage
    Looked at the code. Looks interesting. Is there a forum for feedback on it?

    It appears Splendor will be providing some JS functions that mirror CF functions?

    For client side UI, will you be providing new functions (not preferred) or allow use of existing JS libraries? One thing I worry about is code getting complicated with how you are setting CSS style properties.

    Have you considered working with opensource JS library that does mobile right, like enyojs.com?
  2. Ram Kulkarni
    There is no public forum to discuss mobile features as of now. Features are not yet ready for everyone to use.

    We are not providing any UI functions in this framework.

    I did not know about enyojs. I will give it a try. Thanks for the information.
  3. Sagar Ganatra
    I read the code and had few questions on it:

    1. Since you are using jQuery in cf tags, how different it is from writing simple JavaScript code using jQuery.

    2. I understand that the code was written not keeping code quality in mind. However, have you created a framework where the components are separated; similar to Backbone or Angular? I would really like to see structured code than getting entangled in spaghetti code. It would nice, if you can post another blog entry explaining how CFCLIENT code can be written in a structured way.
  4. Ram Kulkarni
    Sure you can write JQuery in JS block. I just did not want to switch between JS and CFML blocks, so called JS methods in CFML.

    We did have code quality in mind. I don't think code is of good quality only if you use frameworks like Backbone or Angular. For this small application I did not see any need to use those frameworks. We have separated UI in custom tags and non-UI code in CFCs.

    We might post some example of how to create mobile application using CFML and Angular JS in future, but not necessarily the same CFSummit application.
  5. Sagar Ganatra
    "Sure you can write JQuery in JS block. I just did not want to switch between JS and CFML blocks, so called JS methods in CFML"

    - So it's the same; rather than wrapping it in a Script block you can now invoke it inside a cf tag. A use case which can explain how it solves a problem with using CF tag would be a great example.

    "I don't think code is of good quality only if you use frameworks like Backbone or Angular. For this small application I did not see any need to use those frameworks. We have separated UI in custom tags and non-UI code in CFCs"

    - I agree that one need not use any framework as such and hence mentioned 'similar'. The intent was to see how components can be separated and structured.

    I was pointing to the code which had references to window object, direct reference to DOM node using $('##id') or $('.className'). These are clearly bad practices. For a small application it would suffice but a large application would become difficult to maintain.

    I'm looking forward to see an example of how CFML and AngularJS can be used in combination.
  6. existdissolve
    How are arguments in CFClient functions handled?

    For example, let's say I have function foo( arg1, arg2, arg3 ). Now let's say I call foo like so: foo( arg2="blue", arg1="green", arg3="red" ).

    Is the CFClient translated foo() going to understand the named arguments, or do I have to pass them positionally as in JS?
  7. Ram Kulkarni
    @Sagar May be this post (http://ramkulkarni.com/blog/cfsummit2013-day1-and-cfclient/) might answer some of your questions about mobile features in Splendor and Thunder.

    I amy not be as expert in client side programming as probably you are, but I don't consider having references to window object and accessing DOM elements by id or class names are bad practices. Even if you use any framework, it will eventually have to do that.
  8. Ram Kulkarni
    @existdissolve cfclient does not support named arguments. You will have to pass them positionally.
  9. existdissolve

    That's what I thought, and that's one of the things that is quite disturbing about cfclient to me. Regular CF functions can take either positional or named arguments, correct? So if I'm defining and calling functions via CF, I would expect the normal, established conventions of CF to be in play.

    It seems a very bad idea to mess with that, simply because I've wrapped this code in some new tag. I see this creating a lot of confusion and frustration.
  10. existdissolve

    Actually, now that I think about it, what about from/to loops?

    Ex: <cfloop from="1" to="#arrayLen( someArray )#" index="x">...</cfloop>

    Does CFClient translate the "1" to "0", or do a <= in the JS for() notation?

    A: for( var x=0; x<10; x++ ) {} // I would do this in JS normally
    B: for( var x=1; x<=10; x++ ) {} // I would not normally do this is JS
  11. Adam Cameron
  12. Ram Kulkarni
    @existdissolve, yes the framework translates 1 based array index (of CFML) to 0 based in JS. So in your example, it would generate code like in option A
  13. existdissolve

    Thanks for the clarification. But does it always convert to 0-based? What if you need a non-zero-based for-loop in JS?
  14. Ram Kulkarni
    @existdissolve, even if you want to start a loop from somewhere in the middle of an array, array elements will have to be translated with zero based indices in JS. The same way we handle it on the server side when converting CFML to Java, where arrays are zero index based. Loop will work on the client side exactly the same way it works on the server side.
  15. existdissolve

    Right, I get that. But what if I'm not looping over an array? Is it still going to convert to 0-based? That seems incorrect.

    // loop from 1 to 9, printing 1,2,3,4,5,6,7,8,9
    for( var i=1; i<10; i++ ) {
    // something "i" here

    If it automatically converts ALL for loops to 0-based, this breaks loops that aren't related to arrays.
  16. Sagar Ganatra
    window references are global and adding anything to it is generally not recommended. It corrupts the global namespace. Consider jQuery which exposes one interface '$', instead of giving every function out in the window object. When working with apps, jQuery is defined as a dependency and its instance is used only inside the module. See RequireJS, which is an excellent framework for defining dependencies and creating AMDs.

    Most of the client side frameworks will have a reference to the DOM node and access elements by using this DOM node. ex: this.$el.find('.className'); where $el is the reference to the container node and className is searched only within this DOM node. $('<selector>') is way slow and is error prone.

    Again, a modular code sets a great example and makes it easier to understand and maintain.
  17. Ram Kulkarni
    @Sagar, only those global variables that are shared across pages and which needed to be global are stored in window in this application. Not all variables in this app are stored in window.

    Creating encapsulation the way you define is in fact very easy with client side CFML - create CFCs. And we have used CFCs where ever required. The shared JS framework files that we have written do follow the model of JQuery that you quoted.

    I take you point about localizing DOM search. I think wherever possible we start DOM search with an element ID, which is quite fast. But your earlier point was about it being a bad practice to use class names and element ids. And I disagreed with that.

    In any case, the purpose of releasing source code of this app was not to showcase how well we write JS or client side code (though we do take that very seriously), but to show how client side CFML can be used to develop mobile applications. We do not put any restriction on the kind of model/framework you want to follow in developing your apps.
  18. Ram Kulkarni
    @existdissolve, if you are not accessing array elements in loop then we don't touch the variable. As I said, loop works exactly the same way on the client side as it does on the server side.
  19. Miguel_F
    Wow, I was not aware of this as I could not attend CFSummit. Because of that maybe I am missing something but I'm not sure why Adobe felt it necessary to add something like this to ColdFusion. There are already a multitude of JavaScript libraries out there that are very mature and widely accepted at this point. And, in my opinion, it is very easy to develop using any of those JavaScript libraries alongside ColdFusion CFML. So what is the need?

    I fear this will suffer the same fate that other ColdFusion client side features have had; lack of support and maintenance. There is no way Adobe will be able to keep up with the other JavaScript libraries out there.

  20. Sean Corfield
    @Ram, just so I'm clear on what you're saying to @existdissolve:

    <cfloop index=i from=1 to=10>
    <cfset a[i] = i>

    This will create JS that does:

    for (i=0; i<=10; i++) {
    a[i-1] = i;

    Is that correct?

    Also, I see everyone talking about tag syntax - does cfclient support cfscript or just tags?
  21. Ram Kulkarni
    @Sean - no, we won't change the value of index in the for loop, but would decrement array index.

    for (i = 1; i <= 10; i++) {
    a[i-1] = i;

    And yes, you can write cfscript inside cfclient. Client side CFCs can also be written in complete script syntax.
  22. Ram Kulkarni
    @Miguel_F, we don't wrap any JS library for UI as part of mobile features in Splendor. You are free to use any JS library you want.

    Though most of the discussion in comments on this post are around UI and language features, mobile features in Splendor are much more than that (in fact it has no UI elements). They support end to end workflow for developing, debugging, testing and deploying mobile applications.
  23. Sean Corfield
    Thanx Ram. I'll be interested to see how this is received when the public beta becomes available.

    I'll honest, I still think it's a _terrible_ idea. I think providing all the functionality as a pure JS library and documentation about the integration would have been a much better approach than this weird mix of CFML and JS.
  24. Adam Cameron
    "They support end to end workflow for developing, debugging, testing and deploying mobile applications".

    I don't understand how all that stuff are features of CFCLIENT as opposed to features of the IE? Can you pls explain?

    How does CFCLIENT facilitate debugging? How does it facilitate testing? How can a *language construct* facilitate deploying something?

  25. Adam Cameron
    Oops: "I don't understand how all that stuff are features of CFCLIENT as opposed to features of the IE?"

    That should read IDE, obviously (?) sorry.

  26. Ram Kulkarni
    @Sean, I can understand your and many others concern at this point. If you look at this feature only as translation of CFML to JS then you won't see much value. But as I have been saying, it is much more than that. Hopefully once you have a build to play with, you might see benefits.
  27. Ram Kulkarni
    @Adam, cfclient is not a complete feature in itself. It is part of a bigger feature - mobile development support. IDE and server work together to provide many of these features, including debugging, testing and packaging.
  28. Adam Cameron
    Right. So those aren't features of <cfclient> then. They're features of CFBuilder. In the context of the CFML language, and *ColdFusion*, nothing you have done here demonstrates that <cfclient> is anything other than a blight on the CFML language.

    If you wanted to provide a wizard for CFB to create mobile-ready code (and fair enough), you should have done all this *as* a wizard in CFB, and left CML alone. This is *a bad thing* for CFML.

  29. Adam Cameron
    BTW, when one's submission is rejected due to getting the CAPTCHA wrong, saying this "Oops... The following fields are required to post a comment: Sorry, but your comment appears to be spam and could not be submitted." is a pretty bloody rude message. You don't think it's down to shortcomings in your UI (a lot of the CAPTCHA images you use are indecipherable), rather than pre-judging the content of my post?
  30. Ram Kulkarni
    @Adam, Creating just mobile wizard in CFBuilder would not have worked. For the kind of features we have implemented for mobile development, language translation is essential. Even providing JavaScript library as Sean was suggesting would not have made these features possible.

    If you have done any mobile application development then you would probably appreciate these features. If you are not doing mobile dev or do not have any requirement for it then you may not find these be features useful.
  31. Cage
    Looking forward to learning more about them but count me (like the others above) skeptical. I think we've seen CF go down this road before, at the expense of improving the current feature set.

    I hope, as part of Splendor, you'll also be working on expanding the current functionality and fixing current issues. Things like dir/path issues in using CFC vs CFC as REST, getting more tags to work with S3 / cloud services (?dropbox, box, etc), to name a few.

  32. Sean Corfield
    @Ram, FWIW, we have done mobile application development so we've dealt with PhoneGap (and we have extensive Cordova experience in house) and nothing Adobe has said about cfclient so far sounds useful to us - it still sounds like a bad idea.

    Write JS on the front end, write REST services in CFML on the back end, that's how it should be. I'll take a look at the public beta when it comes out but, seriously, expect a public roasting if it still seems as half-baked as everything we've heard so far...
  33. Sean Corfield
    And just so I don't come off as "Adobe-bashing": I like everything I've heard so far about CF12 and I'm very pleased to see all the language enhancements in CF11 (that are mostly compatible with Railo - thank you for that). My only concern about CF12 is your timeline is so far out that by the time it hits the streets, "competing" languages will have also moved on so far that CFML will still look old-fashioned. But I definitely think you're going in the right direction (at last - CFML has seemed pretty directionless for the few years).
  34. Ram Kulkarni
    @Sean - Take a look at http://blogs.coldfusion.com/post.cfm/coldfusion-mobile-features-are-not-just-about-cfclient-but-it-is-necessary

    I have explained why we implemented cfclient and why just creating REST services would not have provided a complete mobile solution.
  35. Sean Corfield
    I've responded to that thread. As many others have said: we really do appreciate your continued attempts to explain what the CF team is doing and why - and I hope you'll take our feedback seriously.

Comments now closed