Salesforce Visualforce Demo with AngularJs and Bootstrap

by :Shaikh Mufizar Rehman 

 206

Hi All
This is a sample demo which will guide you to Fetch, Create, Update, Delete Records by AngularJS on visualforce page. I have used the Bootstrap for the UI to make it device compatibility.

Angularjs+with+Bootstrap


Watch here demo Click here
Unable to display content. Adobe Flash is required.

In this Tutorial we are going to learn following things :
1. How to Fetch Records
2. How to Create Record and Add to List
3. How to Update Record
4. How to Delete a Record

You first need to download or use the Angularjs file as below:
https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js

For using Angularjs we need to create “Application” and “Controller” on visualforce page as below :

<script type="text/javascript">
    <!-- Name your application -->
    var myapp = angular.module('hello', []);
    var contrl=myapp.controller('ctrlRead', function ($scope, $filter) {
    
    })
</scrip>

All work will be under “Controller” visualforce page like below:

<body>     
    <!-- =========== Binding Controller to Body of Page ============= -->
    <div ng-controller="ctrlRead">
        <!-- Here you can write you code -->
    </div>
</body>

 Now let’s start “Fetch, Create, Update, Delete” Records by Angularjs in Apex Controller by using different methods. As below:

global class AngularJSDemoController{ 
    
    public String AccountList { get; set; }
    
    //Subclass : Wrapper Class 
    public class Accountwrap {
        //Static Variables 
        public string id;
        public string name;
        public string Phone;
        public string Fax;
        public string Website;
        
        //Wrapper  Class Controller
        Accountwrap() {
            Phone = '';
            Fax = '';
            Website = '';
        }
        
    }
       
    //Method to bring the list of Account and Serialize Wrapper Object as JSON
    public  static String getlstAccount() {
        List < Accountwrap > lstwrap = new List < Accountwrap > ();
        List < account > lstacc = [SELECT Id, Name, Phone,Fax,Website
                                   FROM Account order by name limit 10
                                  ];
        for (Account a: lstacc) {
            Accountwrap awrap = new Accountwrap();
            awrap.id = a.id;
            awrap.name = a.name;
            if (a.Phone != null) {
                awrap.Phone = a.Phone;
            }
            if (a.Fax != null) {
                awrap.Fax = a.Fax;
            }
            if (a.Website != null) {
                awrap.Website = a.Website;
            }
            lstwrap.add(awrap);
        }
        return JSON.serialize(lstwrap);
     }
    @RemoteAction
    global static string createAccount(string name,string phone,string fax,string website){
        String fax1 = fax == 'null' ? NULL : fax;
        String website1 = website == 'null' ? NULL : website;
        Account acc = new Account(name=name,phone=phone,fax=fax1,website=website1);
        insert acc;
        return acc.id;
    }
    @RemoteAction
    global static void updateAccount(string id,string name,string phone,string fax,string website){
        String fax1 = fax == 'null' ? NULL : fax;
        String website1 = website == 'null' ? NULL : website;
        Account acc = new Account(name=name,phone=phone,id=id,fax=fax1,website=website1);
        update acc;
    }
    @RemoteAction
    global static void deleteAccount(string id){
        Account acc = [select id from account where id =: id];
        delete acc;
    }
}

Now we will use these methods on page with angularjs like this :

<script>
        var myapp = angular.module('myapp', []);
        myapp.controller('MyController',function($scope,$filter){
           $scope.items = {!lstAccount};
           $scope.account = {};
           $scope.account.Name ='';
           $scope.account.Phone ='';
           $scope.account.Website ='';
           $scope.account.Fax ='';
           $scope.account.Id ='';
           $scope.index='';
           
           // Create Account
           $scope.create= function(){
             if($scope.Name !== undefined &&  $scope.Phone !== undefined){
                var Fax = $scope.Fax !== undefined ? $scope.Fax : 'null';
                var Website = $scope.Website !== undefined ? $scope.Website : 'null';
                Visualforce.remoting.Manager.invokeAction(
                    'AngularJSDemoController.createAccount', 
                     $scope.Name,
                     $scope.Phone,
                     Fax,
                     Website,
                     function(result, event) {
                        if (event.status) {
                           var newAccount = {};
                           
                            // Add to list
                            newAccount.name = $scope.Name;
                            newAccount.Phone = $scope.Phone;
                            newAccount.Fax = $scope.Fax;
                            newAccount.Website = $scope.Website;
                            newAccount.id = result;
                            $scope.items.unshift(newAccount); 
                            
                            // Reset Insert form Value
                            $scope.Name = $scope.Phone = $scope.Fax = $scope.Website ='';
                            
                            $scope.$apply();
                            $('tr').eq(1).find('td').toggleClass( "bg-color");
                            setTimeout(function(){
                              $('tr').eq(1).find('td').toggleClass( "bg-color");
                            },3000)
                            // Back to first tab
                           $('#insertModal').modal('hide');
                            
                        } else if (event.type === 'exception') {
                            alert(event.message);
                        } else {
                            alert(event.message);
                        }
                    }     
                 ); 
              }else{
                  // Show Error
                  var msg ='';
                  if( $scope.Name === undefined){
                      msg +='Name is Required! \n';
                  }
                  if( $scope.Phone === undefined){
                      msg +='Phone is Required! \n';
                  }
                  alert(msg);
              }
           }
           
           // Delete Account
           $scope.delete = function(index,id,obj){
               ///$('.loadingDiv').hide();
                  $(obj).closest('tr').find('td').fadeOut(700);
                  setTimeout(function(){
                   $scope.items.splice($scope.items.indexOf(index),1);
                   $scope.$apply();
                   },900);
               Visualforce.remoting.Manager.invokeAction(
                     'AngularJSDemoController.deleteAccount', 
                     id,
                     function(result, event) {
                        if (event.status) {
                          
                          
                        } else if (event.type === 'exception') {
                            alert(event.message);
                        } else {
                            alert(event.message);
                        }
                    }     
                 ); 
                    
           }
           
           // Fill Value to Edit Form
           $scope.edit = function(index){
               $scope.index = index;
               var detail = $scope.items[$scope.items.indexOf($scope.index)];
               ///alert(JSON.stringify(detail));
               $scope.account.Name =detail.name;
               $scope.account.Phone = detail.Phone;
               $scope.account.Fax =detail.Fax;
               $scope.account.Website = detail.Website;
               $scope.account.Id = detail.id;
               $('#updateModal').modal('show');
           }
           // Update Account
            $scope.update = function(){
                if($scope.account.Name !== undefined &&  $scope.account.Phone !== undefined){
                    var Fax = $scope.account.Fax !== undefined ? $scope.account.Fax : 'null';
                    var Website = $scope.account.Website !== undefined ? $scope.account.Website : 'null';
                    Visualforce.remoting.Manager.invokeAction(
                         'AngularJSDemoController.updateAccount',
                         $scope.account.Id, 
                         $scope.account.Name,
                         $scope.account.Phone,
                         Fax,
                         Website,
                         function(result, event) {
                            if (event.status) {
                                $scope.items[$scope.items.indexOf($scope.index)].name = $scope.account.Name;
                                $scope.items[$scope.items.indexOf($scope.index)].Phone= $scope.account.Phone;
                                $scope.items[$scope.items.indexOf($scope.index)].Fax = $scope.account.Fax;
                                $scope.items[$scope.items.indexOf($scope.index)].Website = $scope.account.Website;
                                $scope.$apply();
                                $('#updateModal').modal('hide');
                            } else if (event.type === 'exception') {
                                alert(event.message);
                            } else {
                                alert(event.message);
                            }
                        }     
                     );
                 }else{
                      // Show Error
                      var msg ='';
                      if($scope.account.Name === undefined){
                          msg +='Name is Required! \n';
                      }
                      if($scope.account.Phone === undefined){
                          msg +='Phone is Required! \n';
                      }
                      alert(msg);
                  }
             }
        })
    </script>
 

 Here is the full visualforce page code:

<apex:page showHeader="false" sidebar="false" standardStylesheets="false" controller="AngularJSDemoController">
    <apex:remoteObjects >
        <apex:remoteObjectModel name="Account" jsShorthand="acc" fields="Name,Id,Phone"></apex:remoteObjectModel>
    </apex:remoteObjects>
 <html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <title>Angularjs with Bootstrap</title>

    <!-- Bootstrap -->
    <link href="{!URLFOR($Resource.bootstrap,'css/bootstrap.min.css')}" rel="stylesheet" />
    <link href="{!URLFOR($Resource.bootstrap,'css/bootstrap-theme.css')}" rel="stylesheet" />
    <link href="https://netdna.bootstrapcdn.com/font-awesome/2.0/css/font-awesome.css" rel="stylesheet"/>
            <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js"/>
    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
    <style>
      #account-box{
          display:none
      }
      #account-list{
          display:block
      }
      @media (max-width:400px){
          h1{font-size:20px}
          #account-box{display:block}
          #account-list{
              display:none
          }
      }
      .bg-color{background-color:#19BFE5;transition: opacity 500 ease-in-out;}
    </style>
    <script>
        
        var myapp = angular.module('myapp', []);
        myapp.controller('MyController',function($scope,$filter){
           $scope.items = {!lstAccount};
           $scope.account = {};
           $scope.account.Name ='';
           $scope.account.Phone ='';
           $scope.account.Website ='';
           $scope.account.Fax ='';
           $scope.account.Id ='';
           $scope.index='';
           
           // Create Account
           $scope.create= function(){
             if($scope.Name !== undefined &&  $scope.Phone !== undefined){
                var Fax = $scope.Fax !== undefined ? $scope.Fax : 'null';
                var Website = $scope.Website !== undefined ? $scope.Website : 'null';
                Visualforce.remoting.Manager.invokeAction(
                    'AngularJSDemoController.createAccount', 
                     $scope.Name,
                     $scope.Phone,
                     Fax,
                     Website,
                     function(result, event) {
                        if (event.status) {
                           var newAccount = {};
                           
                            // Add to list
                            newAccount.name = $scope.Name;
                            newAccount.Phone = $scope.Phone;
                            newAccount.Fax = $scope.Fax;
                            newAccount.Website = $scope.Website;
                            newAccount.id = result;
                            $scope.items.unshift(newAccount); 
                            
                            // Reset Insert form Value
                            $scope.Name = $scope.Phone = $scope.Fax = $scope.Website ='';
                            
                            $scope.$apply();
                            $('tr').eq(1).find('td').toggleClass( "bg-color");
                            setTimeout(function(){
                              $('tr').eq(1).find('td').toggleClass( "bg-color");
                            },3000)
                            // Back to first tab
                           $('#insertModal').modal('hide');
                            
                        } else if (event.type === 'exception') {
                            alert(event.message);
                        } else {
                            alert(event.message);
                        }
                    }     
                 ); 
              }else{
                  // Show Error
                  var msg ='';
                  if( $scope.Name === undefined){
                      msg +='Name is Required! \n';
                  }
                  if( $scope.Phone === undefined){
                      msg +='Phone is Required! \n';
                  }
                  alert(msg);
              }
           }
           
           // Delete Account
           $scope.delete = function(index,id,obj){
               ///$('.loadingDiv').hide();
                  $(obj).closest('tr').find('td').fadeOut(700);
                  setTimeout(function(){
                   $scope.items.splice($scope.items.indexOf(index),1);
                   $scope.$apply();
                   },900);
               Visualforce.remoting.Manager.invokeAction(
                     'AngularJSDemoController.deleteAccount', 
                     id,
                     function(result, event) {
                        if (event.status) {
                          
                          
                        } else if (event.type === 'exception') {
                            alert(event.message);
                        } else {
                            alert(event.message);
                        }
                    }     
                 ); 
                    
           }
           
           // Fill Value to Edit Form
           $scope.edit = function(index){
               $scope.index = index;
               var detail = $scope.items[$scope.items.indexOf($scope.index)];
               ///alert(JSON.stringify(detail));
               $scope.account.Name =detail.name;
               $scope.account.Phone = detail.Phone;
               $scope.account.Fax =detail.Fax;
               $scope.account.Website = detail.Website;
               $scope.account.Id = detail.id;
               $('#updateModal').modal('show');
           }
           // Update Account
            $scope.update = function(){
                if($scope.account.Name !== undefined &&  $scope.account.Phone !== undefined){
                    var Fax = $scope.account.Fax !== undefined ? $scope.account.Fax : 'null';
                    var Website = $scope.account.Website !== undefined ? $scope.account.Website : 'null';
                    Visualforce.remoting.Manager.invokeAction(
                         'AngularJSDemoController.updateAccount',
                         $scope.account.Id, 
                         $scope.account.Name,
                         $scope.account.Phone,
                         Fax,
                         Website,
                         function(result, event) {
                            if (event.status) {
                                $scope.items[$scope.items.indexOf($scope.index)].name = $scope.account.Name;
                                $scope.items[$scope.items.indexOf($scope.index)].Phone= $scope.account.Phone;
                                $scope.items[$scope.items.indexOf($scope.index)].Fax = $scope.account.Fax;
                                $scope.items[$scope.items.indexOf($scope.index)].Website = $scope.account.Website;
                                $scope.$apply();
                                $('#updateModal').modal('hide');
                            } else if (event.type === 'exception') {
                                alert(event.message);
                            } else {
                                alert(event.message);
                            }
                        }     
                     );
                 }else{
                      // Show Error
                      var msg ='';
                      if($scope.account.Name === undefined){
                          msg +='Name is Required! \n';
                      }
                      if($scope.account.Phone === undefined){
                          msg +='Phone is Required! \n';
                      }
                      alert(msg);
                  }
             }
        })
    </script>
  </head>
  <body ng-app="myapp">
  <div class="container" ng-controller="MyController">
      <!-- Loading Window -->
       <div class="loadingDiv" style="display:none">
          <div style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; opacity: 0.75; z-index: 100000;">
             <div style="position:fixed;top:250px;height:100%;width:100%;">
               <center>                
                 <img src="http://www.spotlightbusinessbranding.com/wp-content/plugins/use-your-drive/css/clouds/cloud_loading_256.gif" width="120px"/>    
               </center>                      
            </div>                   
         </div>
     </div>
      <!-- Insert Modal -->
      <div class="modal fade" id="insertModal">
          <div class="modal-dialog">
            <div class="modal-content">
              <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title">New Account</h4>
              </div>
              <div class="modal-body">
                  <div class="col-md-12">
                      <form class="form-horizontal">
                            <div class="form-group">
                                <label>Name</label>
                                <div class="input-group">
                                  <span class="input-group-addon">
                                      <i class="glyphicon glyphicon-user"></i>
                                  </span>
                                  <input type="text" class="form-control" placeholder="Name" ng-model="Name" />
                                </div>
                            </div>
                            <div class="form-group">
                                <label>Phone</label>
                                <div class="input-group">
                                  <span class="input-group-addon">
                                      <i class="glyphicon glyphicon-earphone"></i>
                                  </span>
                                  <input type="text" class="form-control" placeholder="Phone" ng-model="Phone" />
                                </div>
                            </div>
                            <div class="form-group">
                                <label>Fax</label>
                                <div class="input-group">
                                  <span class="input-group-addon">
                                      <i class="glyphicon glyphicon-print"></i>
                                  </span>
                                  <input type="text" class="form-control" placeholder="Fax" ng-model="Fax" />
                                </div>
                            </div>
                            <div class="form-group">
                                <label>Website</label>
                                <div class="input-group">
                                  <span class="input-group-addon">
                                      <i class="glyphicon glyphicon-link"></i>
                                  </span>
                                  <input type="text" class="form-control" placeholder="Website" ng-model="Website" />
                                </div>
                            </div>
                        </form>
                  </div>
                  <div class="clearfix"></div>
              </div>
              <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                <input type="button" class="btn btn-success" ng-click="create()" value="Save" />
              </div>
            </div><!-- /.modal-content -->
          </div><!-- /.modal-dialog -->
        </div><!-- /.modal -->
        
      <!-- Edit Modal -->
      <div class="modal fade" id="updateModal">
          <div class="modal-dialog">
            <div class="modal-content">
              <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title">Update</h4>
              </div>
              <div class="modal-body">
                  <div class="col-md-12">
                      <form class="form-horizontal">
                            <input type="hidden" ng-model="account.Id" />
                            <div class="form-group">
                                <label>Name</label>
                                <div class="input-group">
                                  <span class="input-group-addon">
                                      <i class="glyphicon glyphicon-user"></i>
                                  </span>
                                  <input type="text" class="form-control" placeholder="Name" ng-model="account.Name" />
                                </div>
                            </div>
                            <div class="form-group">
                                <label>Phone</label>
                                <div class="input-group">
                                  <span class="input-group-addon">
                                      <i class="glyphicon glyphicon-earphone"></i>
                                  </span>
                                  <input type="text" class="form-control" placeholder="Phone" ng-model="account.Phone" />
                                </div>
                            </div>
                            <div class="form-group">
                                <label>Fax</label>
                                <div class="input-group">
                                  <span class="input-group-addon">
                                      <i class="glyphicon glyphicon-print"></i>
                                  </span>
                                  <input type="text" class="form-control" placeholder="Fax" ng-model="account.Fax" />
                                </div>
                            </div>
                            <div class="form-group">
                                <label>Website</label>
                                <div class="input-group">
                                  <span class="input-group-addon">
                                      <i class="glyphicon glyphicon-link"></i>
                                  </span>
                                  <input type="text" class="form-control" placeholder="Website" ng-model="account.Website" />
                                </div>
                            </div>
                        </form>
                  </div>
                  <div class="clearfix"></div>
              </div>
              <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                <input type="button" class="btn btn-success" ng-click="update()" value="Save" />
              </div>
            </div><!-- /.modal-content -->
          </div><!-- /.modal-dialog -->
        </div><!-- /.modal -->
      <div class="row">
          <div class="col-md-12">
              <h1>Angularjs with Bootstrap
                  <div class="pull-right">
                      <button type="button" class="btn btn-sm btn-success" onclick="$('#insertModal').modal('show')">
                          <i class="glyphicon glyphicon-plus"></i> New
                      </button>
                  </div>
                  <div class="clearfix"></div>
              </h1><hr/>
              <form class="form-horizontal">
                <div class="form-group">
                    <label class="control-label col-md-2 col-md-offset-2">Search</label>
                    <div class="col-md-4">
                        <input type="text" ng-model="search" class="form-control" />
                    </div>
                    
                </div>
                <hr/>
                <div class="form-group">
                    <div class="col-sm-12">
                        <div id="account-box"><!-- Account Box List Start-->
                            <div class="row"  ng-repeat="account in items | filter:search">
                              <div class="col-xs-12">
                                <div class="thumbnail">
                                  <div class="caption">
                                    <dl>
                                      <dt>Name</dt>
                                      <dd>{{account.name}}</dd>
                                      <dt>Phone</dt>
                                      <dd>{{account.Phone}}</dd>
                                      <dt>Fax</dt>
                                      <dd>{{account.Fax}}</dd>
                                      <dt>Website</dt>
                                      <dd>{{account.Website}}</dd>
                                    </dl>
                                    <p>
                                        <button type="button" class="btn btn-sm btn-primary" title="Update" ng-click="edit(account)">
                                            <i class="glyphicon glyphicon-pencil"></i>
                                        </button>
                                        <button type="button" class="btn btn-sm btn-danger" title="Delete" ng-click="delete(account,account.id,$event.target)">
                                            <i class="glyphicon glyphicon-trash"></i>
                                        </button>
                                    </p>
                                  </div>
                                </div>
                              </div>
                            </div>
                        </div><!-- Account Box List End-->
                        <div class="panel panel-primary" id="account-list"><!-- Account List Start-->
                            <div class="panel-heading">Accounts</div>
                            <div class="panel-body" style="padding:0px">
                                <table class="table table-striped table-bordered" style="margin:0">
                                    <thead>
                                    <tr>
                                        <th>Name</th>
                                        <th>Phone</th>
                                        <th>Fax</th>
                                        <th>Website</th>
                                        <th>Action</th>
                                    </tr>
                                    </thead>
                                    <tbody>
                                    <tr ng-repeat="account in items | filter:search">
                                        <td>{{account.name}}</td>
                                        <td>{{account.Phone}}</td>
                                        <td>{{account.Fax}}</td>
                                        <td>{{account.Website}}</td>
                                        <td width="100">
                                            <button type="button" class="btn btn-sm btn-primary" title="Update" ng-click="edit(account)">
                                                <i class="glyphicon glyphicon-pencil"></i>
                                            </button>
                                            <button type="button" class="btn btn-sm btn-danger" title="Delete" ng-click="delete(account,account.id,$event.target)">
                                                <i class="glyphicon glyphicon-trash"></i>
                                            </button>
                                        </td>
                                    </tr>
                                    </tbody>
                                </table>
                            </div>
                        </div><!-- Account List End -->
                    </div>
                </div>
              </form>
          </div>
        </div><!-- Main Row End -->
      </div><!-- Container End -->
    

    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="{!URLFOR($Resource.bootstrap,'js/bootstrap.min.js')}"></script>
  </body>
</html>
</apex:page>
 

For public demo click
http://mufiz12ka4-developer-edition.ap1.force.com/AngularjsWithBootstrap

Feel free to use the code and try it out. Provide me your valuable feedback:

Thanks
Shaikh Mufiz

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.