Showing posts with label Salesforce. Show all posts
Showing posts with label Salesforce. Show all posts

Access component variable in Callback function Salesforce Lightning component

You might have face issue somewhere in component where you are triggering some JavaScript callback function, and in callback function you want to perform some logic on component variable but you got stuck in accessing component.

Becuase modifiing component outside the normal rerending lifecycle is not allowed. 

for example you using setTimeout().

To resolve this issue wrap your callback function into $A.getCallback(), which modifies a component outside the normal rerendering lifecycle.


window.setTimeout(
    $A.getCallback(function() {
        component.set("v.attribute", "attributevalue");
    })
);

 

Hope this will help! Enjoy Coding!!!

For more information visit here.

Application and Component in Salesforce lightning

 This blog will be focusing on two event types provide by Salesforce. One is Application Events and another is component Events and how we can pass values from one component to another.

Application Events

When you want to pass values between two independent component at that time we will use Application Events. Lets say you have two independent, say SENDER component which takes Name as input from the user and passes its value to say RECEIVER component.

Steps to create Application Event:

1. Create a Event with type as APPLICATION 

<aura:event type="APPLICATION" description="Description for Event">
          <aura:attribute name="param" type="Object" description="Description for parameter"/>
      </aura:event>

2. Register event in SENDER component

<aura:registerEvent name="senderEvent" type="c:EventName">
<aura:attribute type="String" name="firstname" />
<lightning:input type="text" name="firstname" value="{!v.firstname}" />
<button onclick="{!c.callEvent">Send</button>

JS controller 
({
     callEvent : function(cmp, event, helper) {
        var e = $A.get("e.c:EventName");  // get Event 
        e.setParams({ "param" : cmp.get("v.firstname")}; //set param value for event
        e,fire();  // fire event

    }
})

3. Now Handle event in RECEIVER component by adding handler for event
<aura:handler event="c:EventName" action="{!c.receiveParam}" /> //hadler to handler event
JS controller
({
    receiveParam : function(cmp, event, helper) {
        var param = event.getParam("param"); //get param value 
        console.log("Value recieved from SENDER component is: " + param);
    }
})

Every component which has Handler can receive param value send by SENDER component for APPLICATION type event.

Component Event

Lets say you want pass value between child to parent in this case you can use component event. Here sender will be child component and reciever will be parent component.

Steps for it.

1. Create event of type COMPONENT

<aura:event type="COMPONENT" description="Description for Event">
          <aura:attribute name="param" type="Object" description="Description for parameter"/>
      </aura:event>

2. Register event in SENDER component same as in Step 2 of Application Event
    attribute name for aura:registerEvent should be same in aura:handler name attribute.

here: name="senderEvent"

<aura:registerEvent name="senderEvent" type="c:EventName"> 
<aura:attribute type="String" name="firstname" />  
<lightning:input type="text" name="firstname" value="{!v.firstname}" /> 
<button onclick="{!c.callEvent">Send</button>

JS controller 
({
     callEvent : function(cmp, event, helper) {
        var e = $A.get("e.c:EventName");  // get Event 
        e.setParams({ "param" : cmp.get("v.firstname")}; //set param value for event
        e,fire();  // fire event

    }
})

 

3. Add handler with name="senderEvent" 

<aura:handler name="senderEvent" event="c:EventName" action="{!c.receiveParam}" />
//handler to handle event

 

It's mandatory in Component event to set name attribute in event registration and handler, as param can be exchange in parent child component only.


Hope you like the post! Enjoy Coding.

Drag and drop sorting in visualforce page using angularJs


Hello folks,

In this blog I am going to give example to apply drag-drop sorting in visualforce page with use of angularJs.

Lets start with creatting basic Html template to host our app. We will use the ng-app and ng-controller directives to link up the body tag to our Angular application. At the bottom we will include our required libraries.


Prerequisite:

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-sortable/0.15.0/sortable.min.js"></script>


In this code we define an Angular module and name it ngApp, and include the ui.sortable in the requires parameter. This ui.sortable is what wires up angular-ui-sortable to our module. We also define the controller called myController for our module and inject the Angular $scope object. This is where we will set up our Angular sortable.


<script >
      var ngApp = angular.module('myNgApp', ['ui.sortable']);
      ngApp.controller('myController', function ($scope) {

           $scope.names = [ "Test1", "Test2", "Test3" ];

      });


</script>
Now lets use this $scope name variable to display data in Ul by adding ng-model Directive on it and ng-repeat to loop over array.  To make this list sortable, all we need to do is use the ui-sortable directive.
<ul ui-sortable="sortableOptions" ng-model="names">
      <li ng-repeat="person in people" class="list-group-item">{{name}}</li>
</ul>
To see this in action let’s add a pre element and bind it to the people array that will show the order of array in real time.
<pre>{{names}}</pre>

Final code will look like below.
<apex:page standardStylesheets="false" sidebar="false" showHeader="false">
    <apex:slds />
     <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js">
     </script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/
jquery-ui.min.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/
angular.min.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-sortable/
0.15.0/sortable.min.js"></script>
    <script>
          var ngApp = angular.module('ngApp', ['ui.sortable']);
          ngApp.controller('myController', function ($scope) {
    
               $scope.names = [ "Test1", "Test2", "Test3" ];
    
          });
    </script>
    <body ng-app="ngApp" ng-controller="myController">
        <article class="slds-card">
            <div class="slds-card__header slds-grid">
                <div class="slds-media__body">
                    <h2 class="slds-card__header-title">
                      <a href="javascript:void(0);" 
class="slds-card__header-link slds-truncate" title="Names">
                        <span>Name List</span>
                      </a>
                    </h2>
                </div>
                
            </div>
            <div class="slds-card__body slds-card__body_inner">
                <ul ui-sortable="sortableOptions" ng-model="names" 
class="slds-has-dividers_top-space">
                    <li ng-repeat="name in names " class="slds-item">{{name}}</li>
                </ul>
                <pre>{{names}}</pre>
            </div>
        </article>
    </body>
    
</apex:page>

Output:




Hope it will help. Let me know your comments.

Share certain records with only certain users


If you would require to have some records to only be shared with certain users, e.g. based on record level, to a certain group (those selected users), and the rest of the records (e.g. records that are the other recod types) with the rest of the internal users.

It can be done by restricting all objects on OWD(Organization-Wide Defaults) level to private and then share certain records.By default 'Grant Access Using Hierarchies' is selected (checked). If you don't want to share the records with users based on role hierarchy, make sure to uncheck this box for respective objects in OWD settings.

Once the OWD setting for an object is set to Private, applying Sharing rules based on criteria would be the best way to meet your requirement scope.If you want Users to share at record level, you can also enable Manual Sharing.

You can navigate to OWD by searching Sharing settings in Setup > quick search.

You can refer Below link for more sharing Information.
https://developer.salesforce.com/docs/atlas.en-us.securityImplGuide.meta/securityImplGuide/security_data_access.htm

Reset changed user profile permissions

Hi,

There is no way to "Reset" the changes made on your profile.

But there is one way by which you can revert it some what.

you can

look in to the "View Setup Audit Trail" from Setup and see the list of changes made to your profile, and then try to correct it manually.


Hope this helps.

Merge field syntax is correct yet the generated PDF document is not displaying the data : Steelbrick CPQ


This might be because of merge field is not populated on source code. So try to verify your merge field in source code.

If your merge field syntax is correct yet the generated PDF document is not displaying the data or is displaying an error, click the HTML button highlighted below in your template content toolbar to troubleshoot.

Ensure your merge field name was pasted in correctly. Formatting tags can get inserted within the brackets when pasted in from a rich text applications.
Instead, paste from Notepad, which strips out all excess formatting.

Alternatively, click the HTML button on the template content editing toolbar and remove formatting tags manually, making sure that the merge field syntax is not interrupted by these tags.

If still not working click Source Button and check if merge field is populated.


For merge field information visit: https://community.steelbrick.com/t5/Quote-Templates-Knowledge-Base/Merge-Fields/ta-p/299

Custom Picklist lookup using javascript in Visual page

In this post I'm gonna show you how to create simple custom picklist lookup in Visual page using javascript.

We will use window eventlistner to get data from child window open by parent window.

Here is snippet of my simple vf page.

  
<apex:page >
    <script>
        function open_pop_up(idx, field, sObj){
            var child = window.open('/apex/picklistLookup?idx='+idx+'&field='+field+
'&sObj='+sObj+'', '_blank', 
'toolbar=yes,scrollbars=yes,resizable=yes,top=500,left=500,width=400,height=400')
            console.log('==> Child: ' + child);
        }
        
        var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
        var eventer = window[eventMethod];
        var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
    
        //Listen to message from child window
        eventer(messageEvent,function(e) {
            console.log('parent received message!: ',e.data);
            var dataArr = e.data.split(':'); 
            var elmtId = e.data.substring(0, e.data.lastIndexOf(':'));
            var datavalue = e.data.substring(e.data.lastIndexOf(':') + 1,e.data.length);
            document.getElementById(elmtId).value = datavalue;
        },false);  
        
    </script>
    
    <input id="testId" value="" onclick="open_pop_up('testId','CustomerPriority__c',
'Account');"/>
</apex:page>

Let me explain the code.

when we click on input it will open popup lookup window.
Here i have use my custom picklist field CustomerPriority__c of Account Object for test data.

Now new vf page for lookup popup window.

  
<apex:page controller="PicklistLookupCon" showHeader="false">

    <apex:variable value="{!0}" var="rowNum"/>
    
    <table>
        <tr>  
            <td></td>  
            <td>
                <input type="button" value="Insert Selected" onclick="InsertSelected()" class="btn"/>
            </td>
        </tr>
        <apex:repeat value="{!picklistValues}" var="plv">
            <tr>
                <td>
                    <input type="checkbox" onclick="selectValue('{!rowNum}', this.checked, '{!plv}')"/>
                </td>
                <td>{!plv}</td>
            </tr>
            <apex:variable value="{!rowNum+1}" var="rowNum"/>             
        </apex:repeat>            
    </table>
    
    <script type="text/javascript">
        var arrValue  = new Array();
               
        function selectValue(id, isChecked, value){

            if(isChecked == true){
                arrValue[arrValue.length] = value;
            }else{
                var index = arrValue.indexOf(value);
                arrValue.splice(index,1);
           }  
        }
           
        function InsertSelected(){
            console.log(window.parent.opener);
            var win = window.parent.opener;
            var dataStr= '';
            
            for(var k=0;k<arrValue.length;k++){
                if(k==0) dataStr = arrValue[k];
                else dataStr +=','+arrValue[k];
            }
            win.postMessage('{!$CurrentPage.parameters.idx}:'+dataStr, window.parent.opener.location.href); 
            window.parent.close();
        }
  </script> 
</apex:page>

controller:

public without sharing class PicklistLookupCon {

    string sObj = Apexpages.currentpage().getParameters().get('sObj');
    string field = Apexpages.currentpage().getParameters().get('field');

    public picklistLookupCon(){
    
    }
        
    public List picklistValues{
      get{
          if(picklistValues!=null)
              return picklistValues;
          else{
              picklistValues = new List();
              
              Map gd = Schema.getGlobalDescribe(); 
              Schema.SObjectType ctype = gd.get(sObj);
              Map fmap = ctype.getDescribe().fields.getMap();
              Schema.DescribeFieldResult fieldResult = fmap.get(field).getDescribe();
              List ple = fieldResult.getPicklistValues();   
              
              for( Schema.PicklistEntry f : ple){
                  picklistValues.add(f.getValue());
             }
          }
          return picklistValues;
      }
      set;
    }
    
 }

That's it.

Yepppieee you done it.

How to put a static image in a flow designer ?


The Rich text editor on the screen element currently does not support img src tags.
However, the flow run-time interprets any text as HTML. So, you could store the html markup in a custom setting or any database record, fetch it in a variable and use that in the screen.

You can display document image in flow Designer by creating text variable.


Create Variable of type text in flow Designer.

Data Type: text
Input/output type :  Output only
Default value:   
<img src="https://Domain_url/servlet/servlet.FileDownload?file=Your_documentid&oid=Org_id" width="100px" Height="100px"/>

Note: Domain_url  >>>  set your domain url
           Your_documentid >> set your document id.
          Org_id >>> set your org id

You can get your Org id by Navigate to Administration Setup > Company Setup> Company Information.

you will find org id at Salesforce.com Organization ID field.

Now use this newly created variable in Screen.

How To Create chatter feeds (FeedItem) Or SF File From Attachment?

Snippet Code for Creating FeedItem.


- Most of time user easily create feedItem but it seems that file created is not Previewable.

       The only solution to it is add extension to ContentFileName.




for(Attachment att : [SELECT id,body,parentId FROM ]
{
 Blob body = att.body;

            String name = (att.name).substringBeforeLast('.');
            String extension = (att.name).substringAfterLast('.');
            
            FeedItem file = new FeedItem();
            file.ParentId =  String.valueof(att.parentid) ;   // ID of parent object of file (Record Id)
            file.ContentData = body;
            file.ContentFileName = name + '.' + extension;
            file.Title = name;
            System.debug('file::' + file);
            
            feedItemList .add(file);
}

If(feedItemList.size() > 0)
{
insert feedItemList;
}


File will get Show up in File related list of Record(Parent id).