Saturday 16 May 2015

Login As another User from Sidebar link - For System Administrators and Developers

Whenever we do some customization or VF page development for a specific profile users, there will be a need to test the development by logging in with that profile.

By doing so, we can track or identify the issues making our development totally error free.

To do this, we need to search for a user and click "Login" button on user detail page every time assuming if the access is already granted or if the setting Administrators Can Log in as Any User is enabled.

This post guides you an easiest way of handling the process, by logging in as another user directly from the sidebar link and if the access is granted.



Create a Custom Link by following the below path,

Your Name ➤ App Setup ➤ Home ➤ Custom Links ➤ New

Label : Contract Operations

Name : Contract_Operations
Behaviour : Execute Javascript

Paste the below code,



{!REQUIRESCRIPT("/soap/ajax/18.0/connection.js")}
sforce.connection.query("SELECT Id,Name,Profile.Name FROM User where Profile.Name=\'Contract Operations\' LIMIT 1",{onSuccess: handleSuccess,onFailure: handleFailure});

function handleSuccess(queryresult)
{
    try
    {
        records = queryresult.getArray("records");
        var user = sforce.connection.getUserInfo();
        window.location.href = '/servlet/servlet.su oid='+user.organizationId+'&suorgadminid='+records[0].Id.substring(0,15)+
'&retURL=%2Fhome%2Fhome.jsp'+'&targetURL=%2Fhome%2Fhome.jsp';
    }
    catch(error)
    {
        alert(error);
    }
}
function handleFailure(error)
{
    alert(error);
}

You can have as may have links created for different profiles also.

Create a Custom Component using below path,


Your Name ➤ App Setup ➤ Home ➤ Home Page Components ➤ New


Name : Login As.....

Type  :  Links

- Include the Custom Link that was created previously.

- Finally include this Custom Component in the System Administrator Home Page Layout under Narrow(Left) column.

Wednesday 13 May 2015

Basic Search Page using Angular JS

This post explains using of Visualforce Remote Objects with Angular JS.

Salesforce explanation on Visualforce Remote Objects:

"JavaScript remoting is a popular, powerful, and efficient method for building Web apps with Visualforce, especially for creating pages for use in Salesforce1 or working with JavaScript libraries such as jQuery or AngularJS. Visualforce Remote Objects are proxy objects that enable basic DML operations on sObjects directly from JavaScript. Remote Objects remove some of the complexity from JavaScript remoting by reducing the need for @RemoteAction methods in an Apex controller or extension.

Behind the scenes, the Remote Objects controller handles sharing rules, field level security, and other data accessibility concerns. Pages that use Remote Objects are subject to all the standard Visualforce limits, but like JavaScript remoting, Remote Objects calls don’t count toward API request limits. Using Visualforce Remote Objects consists of implementing two separate pieces of functionality on the same page.

Access definitions, written in Visualforce with the Remote Objects components. These components generate a set of JavaScript proxy objects that you can use in step 2.

Data access functions, written in JavaScript. These functions use the proxy objects that are made available by the access definitions to perform create, retrieve, update, and delete operations on your data.

Your page then uses the data access functions to respond to user interaction, such as form submissions or controls changes, or to perform periodic actions in response to timers, or most anything that you can write in JavaScript."

Please read Visualforce Remote Objects article for more details.

Visualforce Page : AngularMVC


<apex:page >
<script src="{!URLFOR($Resource.angulardemo,'jssrc/angular.min.js')}"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"/>
<script src="{!URLFOR($Resource.angulardemo,'app/app.js')}"></script>
<div ng-app="myAngularMVC">
    <apex:remoteObjects >
        <apex:remoteObjectModel name="Contact" jsShorthand="contact" fields="Id,Name">
            <apex:remoteObjectField name="Phone" jsShorthand="phone"/>
        </apex:remoteObjectModel>
    </apex:remoteObjects>    
    <div ng-controller="myAngularMVCController">
        <input type="text" name="txtSearch" class="form-control" placeholder="Enter Name to search" ng-model="contactName"/>           
        <button type="button" class="btn btn-default" ng-click="fetch(contactName)">Search</button>
        <table class="table table-striped table-hover table-bordered">
        <thead>
            <tr>
                <th>Id</th>
                <th>Name</th>
                <th>Phone</th>             
            </tr>
        </thead>
        <tfoot>
        </tfoot>
        <tbody>
            <tr ng-repeat="contact in contactList">
                <td>
                    {{contact.id}}
                </td>
                <td>
                    {{contact.Name}}
                </td>
                <td>
                    {{contact.Phone}}
                </td>
            </tr>
        </tbody>
    </table>
    </div>
</div>   
</apex:page>

app.js


var myapp = angular.module("myAngularMVC",[]);
myapp.controller("myAngularMVCController",function($scope)
{ 
 $scope.contactList = [];
 $scope.fetch = function(contactName)
 { 
     var wh = new SObjectModel.contact();     
     wh.retrieve({where: {Name: {eq: contactName }}}, function(err, records, event)
     {
         if(err) 
         {
             alert(err.message);
         }
         else 
         {
          $scope.contactList=[];            
             records.forEach(function(record) 
             {              
              $scope.contactList.push(ContactWrapper.contact(record));
             });
             $scope.$apply();
         }
     });
 };
});
var ContactWrapper = function() 
{

};

ContactWrapper.contact = function(model) 
{
 var wrap = new ContactWrapper();
 wrap.id = model.get('Id');
 wrap.Name = model.get('Name');
 wrap.Phone = model.get('Phone');
 return wrap;
}


Preview



Static Resource Structure



Running your first Angular App in Salesforce

This post explains you a simple HelloWorld program in Salesforce using AngularJS

Visualforce page:



 
 
 
{{message}}

Angular Basics to start with...in Salesforce

This post expalins few basic angular directives and binding concepts to start with. Use contact id in the URL. For example,

https://c.na24.visual.force.com/apex/AngularBasics?Id=0031a000001YveQ

Visualforce Page: AngularBasics
<apex:page applybodytag="false" doctype="html-5.0" showheader="false" standardstylesheets="false" standardController="Contact">
<!--
applybodytag[DEFAULT this to false]: 
A Boolean value that specifies whether or not Visualforce should automatically add a <body> tag to the generated HTML output. Set to false to disable adding the <body> tag to the response.
For example, when the <body> tag is statically set in your markup. If not specified, this value defaults to the value of the applyHtmlTag attribute if it's set, or true, if applyHtmlTag isn't set.

applyHtmlTag:
A Boolean value that specifies whether or not Visualforce should automatically add an <html> tag to the generated HTML output. 
Set to false to disable adding the <html> tag to the response, for example, when the <html> tag is statically set in your markup. If not specified, this value defaults to true.

doctype[DEFAULT this to html-5.0]:
The HTML document type definition (DTD), or doctype, that describes the structure of the rendered page. If not specified, this value defaults to "html-4.01-transitional", which results in a doctype of . 
Possible values for this attribute include "html-4.01-strict", "xhtml-1.0-transitional", "xhtml-1.1-basic", and "html-5.0", among others.

showheader[DEFAULT this to false]:
A Boolean value that specifies whether the Salesforce tab header is included in the page. If true, the tab header is displayed. If not specified, this value defaults to true.

standardStylesheets[DEFAULT this to false]:
A Boolean value that specifies whether the standard Salesforce stylesheets are added to the generated page header if the showHeader attribute is set to false.
If set to true, the standard stylesheets are added to the generated page header. If not specified, this value defaults to true.
By setting this to false, components that require Salesforce.com CSS may not display correctly, and their styling may change between releases.
/-->

<!-- Include Angular SRC using direct script tag or using apex:component -->
<script src="https://code.angularjs.org/1.4.0-beta.6/angular.js"></script>

<script>
    <!-- Defining angular app here. App is named as AngularBasicsApp -->    
    var app = angular.module("AngularBasicsApp",[]);
    <!-- Defining angular controller here. Controller is named as AngularBasicsController taking $scope as parameter -->
    app.controller("AngularBasicsController",function($scope)
    {
        <!-- attach helloworldmessage to scope -->
        $scope.helloworldmessage = "Hello! This is my first angular app..."
        $scope.contactname = "{!Contact.Name}";
        $scope.email = "{!contact.email}";
        $scope.imgurl = "{!Contact.PhotoUrl}";
        $scope.phonedetails = function(){
                                  var phone = "Phone: {!Contact.Phone}";
                                  var otherphone = "OtherPhone:{!Contact.OtherPhone}";
                                  return phone+"-----"+otherphone;
                              }
        $scope.printfunction = function(testinput){
                                   return testinput; 
                               }
    });
</script>
<div ng-app="AngularBasicsApp" ng-init="contactid='{!Contact.Id}'">
    <div ng-controller="AngularBasicsController">
        <fieldset>
            <legend>Binding using braces:</legend>
                <!-- Angular Binding using double braces  -->
                <h4>{{helloworldmessage}}</h4>            
        </fieldset>
        
        <fieldset>
            <legend>Binding using ng-bind directive:</legend>
            <!-- Angular Binding using ng-bind directive  -->
            <h4 ng-bind="helloworldmessage"></h4>
        </fieldset>
        
        <fieldset>
            <legend>SFDC Contact Name:</legend>        
            <span><image ng-src="{{imgurl}}"/></span>
            <span ng-bind="contactname"></span><br/>
            <span ng-bind="email"></span>
        </fieldset>
        
        <fieldset>
            <legend>Sample Input and Output Text Display</legend>
            <p>
                <input type="text" ng-model="myinputtext"/>
                <span ng-bind="myinputtext"></span>            
            </p>
        </fieldset>
        
        <fieldset>
            <legend>Simple Maths</legend>
            <p>
                {{500/21}}           
            </p>
        </fieldset>    
        
        <fieldset>
            <legend>Simple Maths using dynamic input</legend>
            <p>Enter Distance: <input type="text" ng-model="distance"/></p>
            <p>Enter Time: <input type="text" ng-model="time"/></p>
            <p>Velocity Is: {{distance/time}}</p>
        </fieldset>    
        
        <fieldset>
            <legend>Contact ID display using ng-init</legend>
            <p>
                {{contactid}}           
            </p>
        </fieldset>  
        
        <fieldset>
            <legend>Binding output of a function</legend>
            <p>
                {{phonedetails()}}           
            </p>
        </fieldset>
        
        <fieldset>
            <legend>Passing parameter to a function and binding the output</legend>
            <p>
                {{printfunction("Sample Print")}}           
            </p>
        </fieldset>
        
        <fieldset>
            <legend>ng-disabled</legend>
            <p>
                <button ng-disabled="switch">UnCheck to enable me</button>
                <input type="checkbox" ng-model="switch" ng-init="switch=true"/>
            </p>
        </fieldset>
        
        <fieldset>
            <legend>ng-show</legend>
            <p>
                <button ng-show="switchVisibility">UnCheck to Hide Me!</button>
                <input type="checkbox" ng-model="switchVisibility" ng-init="switchVisibility=true"/>
            </p>
        </fieldset>
        
        <fieldset>
            <legend>ng-hide</legend>
            <p>
                <button ng-hide="hideMe">Check to Hide Me!</button>
                <input type="checkbox" ng-model="hideMe" ng-init="hideMe=false"/>
            </p>
        </fieldset>
              
    </div>
</div>
</apex:page>
Preview: