Wednesday, March 12, 2014

Backbone.js For Salesforce1

Backbone js tutorial for beginners

http://youtu.be/HsEw2i4wQMM
http://www.youtube.com/watch?v=2BDGBJUtAmo
http://adrianmejia.com/blog/2012/09/11/backbone-dot-js-for-absolute-beginners-getting-started
http://backbonejs.org/
http://www.youtube.com/watch?v=_6pBvMK1Qgo

Backbone force

Backbone js Script URLS (Can downloaded from http://cdnjs.com/)
Underscore js : 
          http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js
Backbone js : 
          http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js

Jquery js:
         Normal all jquery plug ins

Libraries

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <title>Hello World in Backbone.js</title>
</head>
<body> 
  <!-- Your HTML --> 
  <!-- Libraries -->  
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.3/underscore-min.js" type="text/javascript"></script>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js" type="text/javascript"></script>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/backbone-localstorage.js/1.0/backbone.localStorage-min.js" type="text/javascript"></script>
  <!-- Javascript code -->  
  <script type="text/javascript">
    // your JS code goes here
  </script>
  
</body>
</html>

Example code for Model
=================

<apex:page docType="html-5.0" standardStylesheets="false" showHeader="false" sidebar="false">
<head> 
  <link href="{!URLFOR($Resource.MobileSample_Resources_Backbone, 'resources/css/jquery.mobile-1.3.0.min.css')}" rel="stylesheet" />
  <script src="{!URLFOR($Resource.MobileSample_Resources_Backbone, 'resources/lib/jquery-2.0.0.min.js')}" type="text/javascript"></script>
  <script src="{!URLFOR($Resource.MobileSample_Resources_Backbone, 'resources/lib/underscore-1.4.4.min.js')}" type="text/javascript"></script>
  <script src="{!URLFOR($Resource.MobileSample_Resources_Backbone, 'resources/lib/backbone-1.0.0.min.js')}" type="text/javascript"></script>
  <script src="{!URLFOR($Resource.MobileSample_Resources_Backbone, 'resources/lib/forcetk.js')}" type="text/javascript"></script>
  <script src="{!URLFOR($Resource.MobileSample_Resources_Backbone, 'resources/lib/force.entity.js')}" type="text/javascript"></script>
  
  <script>      
      var book = Backbone.Model.extend({ 
          //x.get('Author') - if we trying to access the record, before creating the record, it gives the error. To avoid this situvation we can use the defaults function
          defaults: function(){
              return{
                  Author: 'Raja',
                  Book: 'BackBone'
              }
          },           
          // initialize method used to run the code in onload         
          initialize: function(){
              alert('called');
          }
      });
      
      //If we create the list of records, we need the initialize the variable for Backbone.Collection
      var bookListTemp = Backbone.Collection.extend({
          model:book
      });
      
      var bookLists = new bookListTemp();
      var x = new book({Author: $('author-name').val(), Book: $('book-name').val()}); 
      bookLists.add(x);    
      // toJSON() - used to dispaly the list of elemets
      // x.get('Author') - used to display the author of a single record 
      console.log(bookLists.toJSON());
  </script>  
  </head>
  <form>
      Author : <input type="text" name ="author" id="author-name"/>
      Book : <input type="text" name ="book" id="book-name"/>
   </form>
  
</apex:page>

HTML Example code for view
<html>
<body>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.3/underscore-min.js" type="text/javascript"></script>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js" type="text/javascript"></script>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/backbone-localstorage.js/1.0/backbone.localStorage-min.js" type="text/javascript"></script>
  <div id="div1">Loading...</div>
  <script>
    var viewVar = Backbone.View.extend({    
        el : '#div1',
        initialize: function(){      
       
          this.render();
        },
     
        render: function(){        
          this.$el.html('test');
        }
    });
    var ins = new viewVar();
  </script>
</body>
</html>

 Backbone’s Templates
_.js templates have the following syntax

_.template(templateString, [data], [settings])

where in the templateString you use the place holder <%= %> and <%- %> to dynamically insert data. The later allows for HTML escape while the first one doesn’t. Moreover, you can use <% %> to run any javascript code.

Example for Backbone view with template


    var AppView = Backbone.View.extend({
      el: $('#container'),
      // template which has the placeholder 'who' to be substitute later 
      template: _.template("<h3>Hello <%= who %><h3>"),
      initialize: function(){
        this.render();
      },
      render: function(){
        // render the function using substituting the varible 'who' for 'world!'. 
        this.$el.html(this.template({who: 'world!'}));
        //***Try putting your name instead of world.
      }
    });

    var appView = new AppView();

Backbone events

Events are written in the following format: {"<EVENT_TYPE> <ELEMENT_ID>": "<CALLBACK_FUNTION>"} E.g. events: {'keypress #new-todo': 'createTodoOnEnter'} in jQuery it would be something like: $('#new-todo').keypress(createTodoOnEnter);


Backbone js code for show the list of websites in button click
==============================================================
<apex:page > 
    <head>
        <link href="{!URLFOR($Resource.MobileSample_Resources_Backbone, 'resources/css/jquery.mobile-1.3.0.min.css')}" rel="stylesheet" />
        <script src="{!URLFOR($Resource.MobileSample_Resources_Backbone, 'resources/lib/jquery-2.0.0.min.js')}" type="text/javascript"></script>
        <script src="{!URLFOR($Resource.MobileSample_Resources_Backbone, 'resources/lib/underscore-1.4.4.min.js')}" type="text/javascript"></script>
        <script src="{!URLFOR($Resource.MobileSample_Resources_Backbone, 'resources/lib/backbone-1.0.0.min.js')}" type="text/javascript"></script>
        <script src="{!URLFOR($Resource.MobileSample_Resources_Backbone, 'resources/lib/forcetk.js')}" type="text/javascript"></script>
        <script src="{!URLFOR($Resource.MobileSample_Resources_Backbone, 'resources/lib/force.entity.js')}" type="text/javascript"></script>
    </head>
    <body>       
        <div id="container">
            <button> Load</button>
            <ul id="list">             
            </ul>
        </div>
        <div id="list-template">
            <li> <a href=""> </a> </li>
        </div>
        <script type="text/javascript">
            var model = new Backbone.Model({
                data:[
                    {text: 'Google', href: 'www.google.com'},
                    {text: 'Yahoo', href: 'www.yahoo.com'}
                ]
            }); 
            
            var viewVar = Backbone.View.extend({
                initialize: function(){
                    this.template = $('#list-template').children();    
                },
                
                el:'#container',
                
                events: {'click button': 'render'},
                
                render: function(){
                    var data = this.model.get('data'); 
                    var l = data.length;                    
                    for(var i= 0;  i < l; i++){
                    var li = this.template.clone().find('a').attr('href', data[i].href).text(data[i].text).end();
                        this.$el.find('ul').append(li);
                    }  
                }
                
            });  
            var view1 = new viewVar({model: model});                      
        </script>        
    </body>
</apex:page>

Call the controller method in backbone.js visualforce page

//Use VF Remoting to send values to be
//queried in the associated Apex Class


In the following example 

CallEditControllerMobileVersion -Apex Controller Name
updateApprovedCallsTest - Apex Controller method name
callId - Parameter for the method updateApprovedCallsTest (We can send more parameters with , separator)

Example:
------------
app.ContactView = Backbone.View.extend({
        events : {
            "click #approveButton" : "approveCalls"
        },
        approveCalls: function (event){  
            var callId = $(event.currentTarget).find('input[type=hidden]').val();  
            alert(callId);
            Visualforce.remoting.Manager.invokeAction(
                '{!$RemoteAction.CallEditControllerMobileVersion.updateApprovedCallsTest}',
                    callId,
                    function(result, x){
                        console.log(result);
                        
                        if (x.status) {
                            console.log(result);
                            
                        } else if (x.type ==='exception') {
                            console.log('exception');
                        } 
                        
                    },
                {escape: true}
            );
        },
        tagName: 'li',
        template: _.template($('#contact-template').html()),
        render: function(){
          this.$el.html(this.template(this.model.toJSON()));
          return this; // enable chained calls
        },
        initialize: function(){
        }
      });   


How to Built the redirect URL for one app
===============================
Example:
------------
* sforce.one - returns true if the page loaded from mobile, otherwise it returns false

var warehouseNavUrl;
try{
    if(sforce.one){
 
        warehouseNavUrl = 'javascript:sforce.one.navigateToSObject(\'' + warehouse.Id + '\')';
    }
} catch(err) {
    console.log(err);
    warehouseNavUrl = '\\' + warehouse.Id;
}


Salesforce - Generate dynamic inner query to fetch parent and related child records

Use Case: In many scenarios, we need to clone the records with related child records. Issue / Limitation: We may simply use the "cl...