Thursday 8 December 2016

Apex Design Patterns


Domain Model, "An object model of the domain that incorporates both behavior and data." “At its worst business logic can be very complex. Rules and logic describe many different cases and slants of behavior, and it's this complexity that objects were designed to work with.” Martin Fowler, EAA Patterns

Like the Service layer, the Domain Model provides a more granular level of code encapsulation and reuse within your application, such as complex validation, defaulting, and other logic relating to complex calculation and manipulation.

Apex triggers - Create, read, update, and delete (CRUD) operations, including undelete, occur on your custom objects as users or tools interact via the standard Salesforce UIs or one of the platform’s APIs. The operations are routed to the appropriate Domain class code corresponding to that object and operation.

Apex services - Service layer code should be easy to identify and make it easy to reuse code relating to one or more of the objects that each of its operations interacts with via Domain classes. This approach keeps the code in the service layer focused on orchestrating whatever business process or task it is exposing.

The Apex Domain class is consumed by the Apex trigger handler and Apex service method call.

Important: Remember that code relating to Visualforce controllers, Batch Apex, and API classes that you develop is encouraged to use functionality solely exposed via the Service layer operations. Thus, code written in the Domain layer is always indirectly invoked. Domain layer code is typically an internal business logic aspect of your application.


Design Considerations

Essentially, the Domain layer opens up OOP capabilities within Apex to your application but does so in a way that is aligned (mostly by naming conventions) with your application’s domain terms and concepts and the platform’s own best practices.

Bulkification - As with the Service layer, bulkification is a key design consideration on Force.com and has bearing on the domain layer’s design guidelines to ensure that domain class constructors, parameters, methods, and properties deal with data in terms of lists and not singular instances. This approach helps promote, and thus propagate further down the layers, this critical best practice more visibly. After all, no point in having a bulkified service if the rest of your application code does not support it.

Extension by containment - Domain logic must encapsulate both data and behavior. Apex represents data as sObjects. You can’t extend an sObject, but you can wrap it or contain it with another class that complements the data with appropriate behavioral code (methods, properties, and so on).

Naming conventions - Because the domain data is a data set or list as per the bulkification convention, your domain class ideally reflects this in its name, for example, public class Invoices.

OOP - In Force.com, one custom object cannot extend another in the same way classes do in OOP languages such as Java. Therefore, you often end up creating a number of custom objects that share similar aspects, sets of fields, and relationships. When defining your Domain classes for such objects, consider using inheritance or interfaces to abstract common behavioral aspects into a shared base class or interface, allowing you to create and reuse logic that applies across such objects. This unit uses some aspects of OOP. Ideally, you are familiar with some of the basics, such as inheritance and method overriding.

Security - Avoid using the with sharing or without sharing keywords on Domain Apex classes to ensure that the calling context drives this aspect. Typically, this is the Service class logic that, as per its design guidelines, must specify with sharing.

Separation of Concerns - Be consistent regarding where common types of domain logic, such as validation, defaulting, and calculations go. While it is possible to mix this in with other Domain logic solely related to database and trigger events, you have the option to split this logic across different methods in the Domain class. Consider if it is useful to expose this code to make it accessible in contexts not driven by database operations., such as services that provide validation or defaulting-only behavior.

Service layer is a key entry point to other layers and consumers(such as APIs).

Who Uses the Service Layer?

You might be tempted to say "all the cool kids" use a service layer, but technically the consumer of a service layer is called the "client." A client invokes your service layer code. These are not human interactions with the Service layer, but other pieces of code that interact with the user or system, such as a UI controller or Batch Apex.

Note: 

Apex triggers are missing because the logic belongs to your application’s Domain layer, which is closely aligned with the objects and thus manipulation of the records in your application. Domain logic is called both directly and indirectly within the Service layer and, of course, via the platform UI and APIs.

Design Considerations

Naming conventions - The Service layer must be abstract enough to be meaningful to a number of clients. This aspect often falls to the verbs and nouns you use in class, methods, and parameter names. Ensure that they are expressed in general terms of the application or task rather than relating to a specific client caller. For example, this method name is based on business operation InvoiceService.calculateTax(...) while this method name is based on a specific client usage operation InvoiceService.handleTaxCodeForACME(...). The second method name should leave you feeling a little uneasy.

Platform / Caller sympathy - Design method signatures that support the platform’s best practices, especially bulkification. One of the main concerns of all code on Force.com is bulkificaiton. Consider services that can be called with lists versus single parameter sets. For example, this method's parameters allow for bulkification InvoiceService.calculateTax(List<TaxCalulation> taxCalulations) while this method forces callers to call the method repeatedly InvoiceService.calculateTax(Invoice invoice, TaxInfo taxCodeInfo). Again, the second one should make you feel a little uneasy.

SOC considerations - Service layer code encapsulates task or process logic typically utilizing multiple objects in your application. Think of this as an orchestrator. In contrast, code relating specifically to validation, field values or calculations, which occur during record inserts, updates, and deletes, is the concern of the related object. Such code is typically written in Apex triggers and can remain there. Don't worry, we’ll introduce the Domain pattern for this type of code shortly

Security - Service layer code and the code it calls should by default run with user security applied. To ensure that this is the case, utilize the with sharing modifier on your Apex Service classes (especially important if you’re exposing such code via the global modifier). If Apex logic must access records outside of the user’s visibility, the code must explicitly elevate the execution context as briefly as possible. A good approach is to use a private Apex inner class with the without sharing modifier applied.

Marshalling - Avoid prescribing how aspects of interacting with the service layer are handled because certain aspects are better left to the callers of your service, for example, semantics like error handling and messaging. Callers often have their own means to interpret and handle these. For example, Visualforce uses <apex:pagemessages>, and Schedule jobs will likely use emails, Chatter posts, or logs to communicate errors. So in this case, it is typically best to leverage the default error-handling semantics of Apex by throwing exceptions. Alternatively, your service can provide partial database update feedback to the caller. In this case, devise an appropriate Apex class and return a list of that type. The system Database.insert method is a good example of this type of method signature.

Compound services - Although clients can execute multiple service calls one after another, doing so can be inefficient and cause database transactional issues. It’s better to create compound services that internally group multiple service calls together in one service call. It is also important to ensure that the service layer is as optimized as possible in respect to SOQL and DML usage. This does not mean that more granular services cannot be exposed; it just means that you should give the callers the option to use a more specific single service if needed.
.
Transaction management and statelessness - Clients of the service layer often have different requirements regarding the longevity of the process being undertaken and the information being managed. For example, a single request to the server and multiple requests split into separate scopes: the manage state (such as Batch Apex) or a complex UI that maintains its own page state across several requests. Given these variations on state management, it’s best to encapsulate database operations and service state within the method call to the service layer. In other words, make the service stateless to give calling contexts the flexibility to employ their own state management solutions. The scope of a transaction with the database should also be contained within each service method so that the caller does not have to consider this with its own SavePoints, for example.

Configuration - You might have common configuration or behavioral overrides in a service layer, such as providing control to allow the client to instruct the server layer not to commit changes or send emails. This scenario might be useful in cases where the client is implementing preview or what-if type functionality. Be sure to consider how you implement this consistently, perhaps as a method overload that takes a shared Options parameter, similar to the DML methods in Apex.

Note:
In Apex, database transactions are auto-committed if the request completes without error and rolled back in the event of an unhandled exception. However, allowing a request to complete with errors being thrown is not a desired user experience because the platform handling of these exceptions is often not all that accessible (Batch Apex jobs) or aesthetically pleasing (white page, black text) to end users. For this reason, developers often catch exceptions and route them accordingly. A potential side effect with this approach is that the platform sees this is a valid completion of the request and commits records that have been inserted or updated leading up to the error that occurred. By following the above service layer design principles regarding statelessness and transaction management, you can avoid this problem.

Important Points On Service Layer

1) Service layer should not have the error handling capability, only the caller should have the error handling capability
2) In salesforce if error occurs and it is not handled then salesforce will rollback the transaction. But from end user perspective we need to handle the errors and show user messages when any exception occurs.
3) Hence we need to use savepoint and try/catch semantics in the caller class method(for example: controller)

above point covered from below link 

https://trailhead.salesforce.com/apex_patterns_sl/apex_patterns_sl_learn_uow_principles


Unit Of Work

The Unit of Work is a design pattern that reduces repetitive code when implementing transaction management and the coding overheads of adhering to DML bulkification through extensive use of maps and lists.

The Unit of Work pattern used in this module is based on the pattern described by Martin Fowler: "Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems."


Apex Implementation of the Unit of Work Pattern

To include the Unit of Work in your service code methods, follow these steps.
  • Initialize a single Unit of Work and use it to scope all the work done by the service method.
          First we need to initilize the unit of work class with list or map of sobjects as shown below

04    fflib_SObjectUnitOfWork uow = new fflib_SObjectUnitOfWork(
05        new List<SObjectType> { OpportunityLineItem.SObjectType, Opportunity.SObjectType  }
06    );
  • Have the service layer logic register records with the Unit of Work when it executes.
          Second we have register the list to methods in unit of work class as mentioned below

          uow.registerDirty(oppLineItem);
  • Call the Unit of Work commitWork method to bulkify and execute the DML.
           Third commit the unit of work
            
28    // Commit Unit of Work
29    uow.commitWork();


To get more details on above points, please refer to below link

https://trailhead.salesforce.com/apex_patterns_sl/apex_patterns_sl_learn_uow_principles


Important Points On Domain Layer

We can implement below things in domain layer

1) Implementing field defaulting logic
2) Implementing validation logic
3) Implementing apex trigger logic
4) Implementing complex custom logic

Business Logic in the Domain Class vs. Service Class


Type of Application ConcernService or DomainExample
Making sure that fields are validated and defaulted consistently as record data is manipulated.DomainApply default discount policy to products as they are added.
Responding to a user or system action that involves pulling together multiple pieces of information or updating multiple objects. Mostly provides actions that can occur to a collection of records and coordinates everything that is needed to complete that action (potentially with other supporting services).ServiceCreate and calculate invoices from work orders. Might pull in price book information.
Handling changes to records that occur in the application as part of other related records changing or through the execution of a user or system action. For example, defaulting values as required. If changing one field affects another, it’s also updated.DomainHow the Account object reacts when an Opportunity is created or how the Discount is applied when the Opportunity discount process is run. Note: This sort of logic might start in the Service layer, but be better served in the Domain layer to manage the size and complexity of the service method size or improve reuse.
Handling of common behavior that applies across a number of different objects.DomainCalculate price on the opportunity product or work order product lines. Note: You could place this in a shared Domain base class, overriding the fflib_SObjectDomain method to hook into the Apex trigger events, with concrete Domain classes extending this class in turn with their behaviors.



Friday 25 November 2016

Salesforce Lightning Design System



The SLDS is a robust, flexible, and comprehensive system for implementing the Lighting Experience style in your apps

SLDS can be used in Lightning Components, Visualforce and even in plain markup

Debugging

We covered only the most primitive debugging techniques. Learning to debug your Lightning Components apps, using several different sophisticated tools for doing so, is something that will pay dividends, in the form of hours of your life back, and hair not pulled out.

In particular, we recommend learning Chrome’s rich DevTools suite, and the Salesforce Lightning Inspector that works within it. Apex developers will also want to learn about the debugging tools available for Apex, many of them directly in the Developer Console.

  • Google Chrome DevTools
  • Salesforce Lightning Inspector Chrome Extension
  • Lightning Components Debugging

What is the name of the open-source framework that Lightning Components is based on?

  • The Lightning Component framework is a UI framework for developing dynamic web apps for mobile and desktop devices. It’s a modern framework for building single-page applications engineered for growth.
  • The framework supports partitioned multi-tier component development that bridges the client and server. It uses JavaScript on the client side and Apex on the server side.

Using the new Design System(SLDS) markup results in pages which have the Lightning look and feel without writing any CSS


The Design System bundles four types of resources to help you build applications.

CSS framework — Defines the UI components, such as page headers, labels, and form elements, a grid layout system, and a single-purpose helper classes, to assist with spacing, sizing, and other visual adjustments.

Icons — Includes PNG and SVG (both individual and spritemap) versions of our action, custom, doctype, standard, and utility icons.

Font — Typography is at the core of our product. We’ve designed the new Salesforce Sans font from the ground up to give our product a distinct visual voice and personality, and we’re making it available to you as part of the Design System.

Design Tokens — These design variables allow you to tailor aspects of the visual design to match your brand. Customizable variables include colors, fonts, spacing, and sizing.


Where You Can Use the Design System

The new Design System makes it straightforward to build Lightning-compliant Salesforce apps across a range of technology stacks.

  • Visualforce pages accessing Salesforce data via remote objects or JavaScript remoting. The Design System is not yet compatible with <apex> tags, but watch this space.
  • Lightning pages and components made available to Salesforce1 and Lightning Experience
  • Mobile apps accessing Salesforce through the Mobile SDK or another API
  • Standalone web apps served by Heroku or a similar platform

Back in Visualforce, the Design System resources will now be available in markup using the URLFOR directive. 

For example, the Visualforce version of the CSS is located at assets/styles/salesforce-design-system-vf.min.css inside the static resource. To access it in Visualforce you would therefore use the following syntax:

<code><apex:stylesheet value="{!URLFOR($Resource.REPLACE_WITH_NAME_OF_SLDS_STATIC_RESOURCE, 'assets/styles/salesforce-lightning-design-system-vf.min.css')}" />
</code>


First SLDS Example


<apex:page showHeader="false" standardStylesheets="false" sidebar="false" applyHtmlTag="false" applyBodyTag="false" docType="html-5.0">

<html xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" lang="en">
<head>
  <meta charset="utf-8" />
  <meta http-equiv="x-ua-compatible" content="ie=edge" />
  <title>Salesforce Lightning Design System Trailhead Module</title>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <apex:stylesheet value="{!URLFOR($Resource.REPLACE_WITH_NAME_OF_SLDS_STATIC_RESOURCE, 'assets/styles/salesforce-lightning-design-system-vf.min.css')}" />
</head>
<body>

  <!-- REQUIRED SLDS WRAPPER -->
  <div class="REPLACE_WITH_NAME_OF_CUSTOM_SCOPING_CLASS">

    <!-- MASTHEAD -->
    <p class="slds-text-heading--label slds-m-bottom--small">
      Salesforce Lightning Design System Trailhead Module
    </p>
    <!-- / MASTHEAD -->

    <!-- PRIMARY CONTENT WRAPPER -->
    <div class="myapp">

      <!-- SECTION - BADGE COMPONENTS -->
      <section aria-labelledby="badges">
        <h2 id="badges" class="slds-text-heading--large slds-m-vertical--large">Badges</h2>
        <div>
          <span class="slds-badge">Badge</span>
          <span class="slds-badge slds-theme--inverse">Badge</span>
        </div>
      </section>
      <!-- / SECTION - BADGE COMPONENTS -->

    </div>
    <!-- / PRIMARY CONTENT WRAPPER -->

  </div>
  <!-- / REQUIRED SLDS WRAPPER -->

</body>
</html>
</apex:page>



Although the example is very straightforward, it introduces a lot of Design System concepts. We’ll review these before getting into more exciting layouts.

Like all Visualforce pages, the outer wrapper for your markup is the <apex:page> element.

On your html tag, be sure to include the xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" attributes. This is important to enable support for the SVG icon sprite maps within Visualforce. Note: Our example shows the header, sidebar and built-in stylesheets turned off. Currently, if you need to use the Salesforce header or sidebar, you can not specify the extra attributes on the <html> element. In this case, the SVG icons are not supported.

<code><!-- REQUIRED SLDS WRAPPER -->
<div class="REPLACE_WITH_NAME_OF_CUSTOM_SCOPING_CLASS">
...
</div>
<!-- / REQUIRED SLDS WRAPPER -->
</code>



Every time you use Design System markup in Visualforce, it should be placed inside an outer wrapper <div> with the scoping class you created using the CSS Customizer tool above. Every time. Whether you have a Visualforce header and left nav, or not. Got it? It’ll be in the quiz later.

SLDS Class Naming

Before we move on, let’s talk about those double hyphens you were asking about in the Design System class names. Our CSS uses a standard class naming convention called Block-Element-Modifier syntax (BEM) to make the class names less ambiguous:

  • A block represents a high-level component (e.g. .car)
  • An element represents a descendent of a component (e.g. .car__door)
  • A modifier represents a particular state or variant of a block or element (e.g. .car__door--red)

Now the burning question, why the double hyphens and underscores? First they make it easier to see what the CSS rule is being applied to (by separating out block/element and modifier). Furthermore, using double rather than single hyphens and underscores means that the block or modifier can itself contain hyphens or underscores, for example .slds-button__icon--x-small . Give it a go, we think you’ll find it as useful as we do once you get used to it.


What is a Grid System?

The Design System grid is based on CSS Flexbox and provides a flexible, mobile-first, device-agnostic scaffolding system. The Design System also includes helper classes that you can use to alter the look and behavior of your grid, such as alignment, order, flow, and padding.

How to use the Grid System

The grid system is based on two key building blocks: the grid wrapper (specified with the slds-grid class) and the columns within it (specified with the slds-col or the slds-col--padded classes). Here's an example:

To start, add the slds-grid class to an outer wrapper element. Then inside it add the required number of columns by adding the slds-col class to the child elements. We’ll use <div> elements in this case. For example, here is a simple grid with three columns:

<div class="slds-grid">
  <div class="slds-col">Column 1</div>
  <div class="slds-col">Column 2</div>
  <div class="slds-col">Column 3</div>
</div>


By default, the columns are sized relative to their contents. In this simple example, we should therefore see three identically spaced columns because they hold equal an amount of content. If more content was added to one of the columns, it would grow relative to the others.

You can also specify the sizes of the columns manually using the sizing helper classes. These use a slds-size--X-of-Y format where X represents a fraction of the total space Y. For example, slds-size--1-of-2 represents a width that is 50% of the available space. Using the manual sizing class helpers, you can specify column ratios across the following grids – 2, 3, 4, 5, 6, and 12.

<!-- BASIC GRID EXAMPLE -->
<div class="slds-grid">
  <div class="slds-col slds-size--4-of-6">Column 1</div>
  <div class="slds-col slds-size--1-of-6">Column 2</div>
  <div class="slds-col slds-size--1-of-6">Column 3</div>
</div>

Design System is Primarily for building applications


Adding Data to the Mix

Let’s face it, web applications aren’t that exciting unless they contain some data. This unit is all about making our list view real and populating with some sample data from your developer org.

We’ll be using JavaScript Remote Objects to access Salesforce data but you could just as well use JavaScript Remoting. Note that Apex tags are not yet supported by the Design System, however the Trailhead unit on Visualforce visual design considerations explains options for styling legacy code to look like the new Lightning UI.

The JavaScript in this unit is outside the bounds of the Design System but it will help bring some of our key components to life and show how they are used. Plus it’ll make things that much more fun.

Populating a Data Table with Dynamic Data

As we noted above, in this release the Design System doesn’t support built-in Visualforce components — the <apex:*>, <chatter:*> and other components you know and love — for laying out pages and accessing data. That’s important to note. Don’t expect to apply the Design System to your legacy Visualforce pages and have them instantly transform into the most beautiful UI on the Internet.

For now, use Remote Objects, JavaScript Remoting or the REST API to access Salesforce data from your Visualforce pages based on Design System markup.



Creating Avatar

An Avatar is created by wrapping your <img /> element in a <span> element with the class slds-avatar. Additional sizing helper classes can be applied, for example slds-avatar--large

An avatar can be circular or a rounde rectangle, depending on usage. The default is a rounded rectangle and requires .slds-avatar as the base class. Use a circle for all people-oriented objects that could potentially render as avatars. For a fully round avatar, add the .slds-avatar--circle class. Four additional classes are available for sizing.

<span class="slds-avatar slds-avatar--x-small">

<img src="/assets/images/avatar1.jpg" alt="meaningful text" />

</span>

Media Objects


A common pattern for including images in web apps is to include an image and text side by side. The Design System has a component to make this super easy, the Media Object.

The base class of the Media Object component is slds-media. It can be applied to any container element, here we use a <div>. Inside the container, we provide a figure (the image) and a body (the content).

The figure, i.e. our avatar, is contained inside a <span> with the class slds-media__figure.The avatar image is specified with a standard <img /> element. You could also include an icon here (see below).

The body is a <div> with class slds-media__body. This wraps the header text we used earlier.


The icons are supplied both as individual PNGs and SVGs, as well packaged up inside SVG sprite maps. Each of the above icon categories has its own sprite map under /assets/icons. Sprite maps are our recommended technique for including icons in pages. The advantages of SVG sprite maps over traditional icon fonts include more fine-grained CSS control and easier positioning in components, as well as better resizability of vector-based SVGs. This final advantage is a boon for responsive design. Vector-based images make clean art at any size.

PLEASE NOTE: Current versions of Google Chrome, Safari and Firefox already support SVG sprite maps. To use SVG spritemap image icons with Microsoft Internet Explorer 11 you will need to download a small script called svg4everybody. After you download svg4everybody, add the svg4everybody.js script as a static resource, include it in your pages, and call it in a <script> tag. Please refer to the full instructions on the svg4everybody website for more details. The advantages of using this icon technique (as outlined in the previous paragraph) more than make up for this extra step.

SVG sprite maps are also why we had you add the xmlns and xmlns:xlink attributes to your <html> element. The reason for this is to configure the SVG and xlink namespaces within Visualforce. Again, a tiny bit of work for a big payoff.


Sunday 20 November 2016

Salesforce Communities



Points to consider before enabling Salesforce Communities

Each community member will be a contact. Enable the contact to be a member in the community. When contact is enabled to become a community member then the contact will become a user. Then user will have a profile and role assignment.

Community user will be assigned with Role and Profile to control access to objects and sharing rules.

There are two types of communities
1) Customer Community
2) Partner Community

***Once we establish domain for the community, then it cannot be changed

1) Ensure that you have all you need before creating a community. New communities start in preview mode, allowing to test them internally before publishing.


External Members

  1. Create Profiles / Permission Sets
  2. Consider tabs
  3. Consider Login Method
    1. User Name
    2. - Self-registration
    3. - Authentication Provider


Steps for enabling communities
  1. Got to Setup
  2. Admin Area
  3. Build -> Customize
  4. Communities section
  5. Click on Settings
  6. Select the Enable Communities checkbox
  7. Provide domain name for the community
  8. Click Save

Steps for enabling view global header
  1. Go to System Administrator Profile
  2. Click on system permissions
  3. Edit System permissions
  4. Check the check box next to View Global Header

Steps for creating communities
  1. Go to Setup
  2. Admin Area
  3. Build->Customize
  4. Communities Section
  5. Click on manage communities
  6. Click new communities button
  7. Provide name and url
  8. Click on Create button
***Once you create a community it will only be visible to administrators initially.

Configure the newly created community before publishing

After community is created click on edit button and perform below settings
  1. Go to Members section
  2. Identify the profiles that needs to be given access to community
  3. Identify the permission sets that need access to community
  4. Tabs and Pages Section - Identify the tabs that needs to be part of the community
  5. Go to Login Page section and configure the logo on the login page
  6. Configure email section and mention the template for welcome email

Adding External Members to a community

External community members can be enabled directly from their contact records. Each member has a user record where the profile determines what tabs and features are accessible in the community. Partner community members also have a role which determines records access.

Controlling access on visibility of records created by other users in community
  1. Go to Setup
  2. Security controls area
  3. Click on sharing settings
  4. Go to user visibility settings section
  5. Verify community user visibility checkbox is checked or unchecked

Steps to publish the community

  1. Go to setup
  2. Go to customize section
  3. Click on communities link
  4. Click on manage communities link
  5. Click on edit the community
  6. Click on publish

Permission required to Create Communities Users from Contacts

To allow an external user to access your community, enable the user’s contact record as a customer user or partner user, depending on the user’s license type. Your community can contain users with Partner Community, Customer Community, and Customer Community Plus licenses.

Provide below user permissions to the user from which new contact is promoted to community user.

To create customer users : "Manage External Users" or "Edit Self-Service Users"
To login as an external user : "Manage Users" or "Edit" on Accounts.


Promoting contact to community user

  1. Go to any contact record detail page
  2. Click on manage external user button
  3. Click on enable customer user link
  4. System will redirect to New user record with data prepopulated with user details
  5. Please notice the user license field will have value as Customer Community
  6. Select the required profile and save the user record


Steps for logging into contact as community user

  1. Drill down the user contact record and navigate to contact detail page
  2. Click on manage external user button
  3. Select log into community as user


Customer Community Plus License

The Customer Community Plus license is similar to a Customer Portal — Enterprise Administration license and is well-suited for business-to-consumer communities focused on managing customer support.

The CCP license is more powerful than the Customer Community license. It provides:

  • Roles and Sharing
  • Delegated Administration capabilities
  • Reports and Dashboards (read only)
  • Tasks
  • Additional storage (1MB for login-based license; 2MB for member-based license) 

***10 Custom Object can be created per CCP license.

Monday 14 November 2016

Salesforce Lightning Custom Events Simplified Version



Below are the steps for creating lightning custom events and handling methods. I have explained custom event creation and handler with a very simple example. But there very complex usages of custom events and handlers.

I will explain more complex example in another post.

1) Define Custom Event.


From Developer Console -> Open File Menu - > New -> Lightning Event

Mention the name of the event for example : AccountEvent

There are two kinds of events 

1) Application 2) Component

Use Component event, when we want an ancestor component to catch and handle the event. An ancestor is a component “above” this one in the component hierarchy. If we wanted a “general broadcast” kind of event, where any component could receive it, we’d use an application event instead.

Below is the sample code in the AccountEvent.evt

<aura:event type="COMPONENT"  description="Event template">
    
    <aura:attribute name="AccountName" type="String" />
    
</aura:event>

In the above code, attribute is used for handling data from the event. This is called as event attribute. 

Use event.getParam(<attributeName>) to get the details of the attribute. Attribute can be of any type including sObject.

2) Register Event

Register the event we have created in step1 in the component. Below is the markup code for registering the event. 

<aura:registerEvent name="AccountRegister" type="c:AccountEvent" />

In the markup, please note the type. the value for type is name of the custom event given in step 1.

3) Event Handler

Mention event handler markup in the component. Below is the markup code for providing event handler

<aura:handler name="AccountRegister" event="c:AccountEvent" action="{!c.displayAccount}" />

In the above markup, Please note the name of the register event and name of the handler is same. 

Event has been assigned custom event name

Action is assigned the actual handler in the js controller.

Below is the code snippet for sample AccountDisplayComponent.cmp


<aura:component>    
    
    <aura:attribute name="myAccountName" type="string" />
    
    <aura:registerEvent name="AccountRegister" type="c:AccountEvent" />
    
    <aura:handler name="AccountRegister" event="c:AccountEvent" action="{!c.displayAccount}" />
    <ui:button press="{!c.accountDisplay}" label="Click Me!!!!" />    
     
    <p> "{!v.myAccountName}" </p>               
    
</aura:component>


4) Fire Event

From the code snippet mentioned in Step 3. there are two handler methods 1) accountDisplay 2) displayAccount

accountDisplay handler method is called when button is clicked. This method is called through standard click event.

Custom event is actually fired from the standard click event as mentioned in the code snippet below.

component.getEvent("AccountRegister") will actually fetch the instance for the registered event in the component.

accevent.setParams({ "AccountName" : "Donald Trump"}) is used to set the parameters for the event.

accevent.fire(); is used to fire the event

Once the event is fired. the event handler markup mentioned in the component will get triggered and the action method associated to the event handler markup will get invoked. which is in our example displayAccount 

Below is the AccountDisplayComponentController.js code snippet


({
accountDisplay : function(component, event, helper) {
        
        var accevent = component.getEvent("AccountRegister");
        
        accevent.setParams({
           
            "AccountName" : "Donald Trump"
            
        });
        
        accevent.fire();
},
    
    displayAccount : function(component, event, helper) {
     
        var maccount = event.getParam("AccountName");
        
        component.set("v.myAccountName",maccount);
        
    }
})


Component Events

A component event is fired from an instance of a component. A component event can be handled by the component that fired the event or by a component in the containment hierarchy that receives the event.


Component Event Propagation

The framework supports capture and bubble phases for the propagation of component events. These phases are similar to DOM handling patterns and provide an opportunity for interested components to interact with an event and potentially control the behavior for subsequent handlers.

The component that fires an event is known as the source component. The framework allows you to handle the event in different phases. These phases give you flexibility for how to best process the event for your application.

The phases are:

Capture

The event is captured and trickles down from the application root to the source component. The event can be handled by a component in the containment hierarchy that receives the captured event.
Event handlers are invoked in order from the application root down to the source component that fired the event.

Any registered handler in this phase can stop the event from propagating, at which point no more handlers are called in this phase or the bubble phase.


Bubble

The component that fired the event can handle it. The event then bubbles up from the source component to the application root. The event can be handled by a component in the containment hierarchy that receives the bubbled event.

Event handlers are invoked in order from the source component that fired the event up to the application root.

Any registered handler in this phase can stop the event from propagating, at which point no more handlers are called in this phase.

Here’s the sequence of component event propagation.

1. Event fired—A component event is fired.
2. Capture phase—The framework executes the capture phase from the application root to the source component until all components
are traversed. Any handling event can stop propagation by calling stopPropagation() on the event.
3. Bubble phase—The framework executes the bubble phase from the source component to the application root until all components are traversed or stopPropagation() is called.

Application events have a separate default phase. There’s no separate default phase for component events. The default phase for component event is the bubble phase.

Handling Bubbled or Captured Component Events

Event propagation rules determine which components in the containment hierarchy can handle events by default in the bubble or capture phases. Learn about the rules and how to handle events in the bubble or capture phases.

The framework supports capture and bubble phases for the propagation of component events. These phases are similar to DOM handling patterns and provide an opportunity for interested components to interact with an event and potentially control the behavior for subsequent handlers. The capture phase executes before the bubble phase.


Default Event Propagation Rules

By default, every parent in the containment hierarchy can’t handle an event during the capture and bubble phases. Instead, the event propagates to every owner in the containment hierarchy.

A component’s owner is the component that is responsible for its creation. For declaratively created components, the owner is the outermost component containing the markup that references the component firing the event. For programmatically created components, the owner component is the component that invoked $A.createComponent to create it.

Bubble Event Propagation Example:

1) Create bubbleEvent

***bubbleEvent*****

<aura:event type="COMPONENT" description="Event template" />


2) Create bubbleEmitter Component

***bubbleEmitter****

<aura:component >
 
    <aura:registerEvent name="bubbleEventReg" type="c.bubbleEvent" />
 
    <ui:button label="Bubble Emitter" press="{!c.bubbleEmitter}" />
 
</aura:component>


****bubbleEmitterController.js****


({
bubbleEmitter : function(component, event, helper) {

        var myEvt = component.getEvent("bubbleEventReg");
     
        myEvt.fire();
     
}
})



3) Create bubbleChild component


****bubbleChild ******

<aura:component >

    <aura:handler name="bubbleEventReg" event="c.bubbleEvent" action="{!c.bubbleChildHandler}" />  
 
    <c:bubbleEmitter />
 
</aura:component>

***bubbleChildController.js****

({
bubbleChildHandler : function(component, event, helper) {
console.log("From Bubble Child Handler");
}
})



4) Create bubbleParent component

****bubbleParent ******

<aura:component>

    <aura:handler name="bubbleEventReg" event="c.bubbleEvent" action="{!c.bubbleParentHandler}" />
 
    <c:bubbleChild />
 
</aura:component>

*****bubbleParentController.js*****

({
bubbleParentHandler : function(component, event, helper) {

        console.log('From Bubble Parent Handler');
     
}
})


5) Create bubbleApp

****bubbleApp****

<aura:application >
    <c:bubbleParent />
</aura:application>



Please note in the above example the event handler and event registration name attribute is name. It should be same to bind the event registration with event handler.

Please note capture event handler is fired first before bubble event handler. if event.stopPropagation is called from capture event handler then all other event handler including all bubble event handler are cancelled and not executed.


Application Events

Default Event Propagation Rules

By default, every parent in the containment hierarchy can’t handle an event during the capture and bubble phases. Instead, the event propagates to every owner in the containment hierarchy.
A component’s owner is the component that is responsible for its creation. For declaratively created components, the owner is the outermost component containing the markup that references the component firing the event. For programmatically created components, the owner component is the component that invoked $A.createComponent to create it.


Propagation to All Container Components\

The default behavior doesn’t allow an event to be handled by every parent in the containment hierarchy. Some components contain other components but aren’t the owner of those components. These components are known as container components. In the example, c:container is a container component because it’s not the owner for c:eventSource. By default, c:container can’t handle events fired by c:eventSource.


Propagation to All Container Components

The default behavior doesn’t allow an event to be handled by every parent in the containment hierarchy. Some components contain other components but aren’t the owner of those components. These components are known as container components. In the example,
c:container is a container component because it’s not the owner for c:eventSource. By default, c:container can’t handle events fired by c:eventSource.

A container component has a facet attribute whose type is Aura.Component[], such as the default body attribute. The container component includes those components in its definition using an expression, such as {!v.body}. The container component isn’t the owner of the components rendered with that expression.

To allow a container component to handle the event, add includeFacets="true" to the <aura:handler> tag of thecontainer component. For example, adding includeFacets="true" to the handler in the container component, c:container,enables it to handle the component event bubbled from c:eventSource.

Please note by default the container component will not be able to handle events in order provide that ability to container components use includeFacets="true" in the aura:handler.

<aura:handler name="bubblingEvent" event="c:compEvent" action="{!c.handleBubbling}"
includeFacets="true" />

Handle Bubbled Event

To add a handler for the bubble phase, set phase="bubble".

<aura:handler event="c:appEvent" action="{!c.handleBubbledEvent}"
phase="bubble" />

The event attribute specifies the event being handled. The format is namespace:eventName.
The action attribute of <aura:handler> sets the client-side controller action to handle the event.

Handle Captured Event

To add a handler for the capture phase, set phase="capture".

<aura:handler event="c:appEvent" action="{!c.handleCapturedEvent}"
phase="capture" />

Pausing Event Propagation for Asynchronous Code Execution

Use event.pause() to pause event handling and propagation until event.resume() is called. This flow-control mechanism is useful for any decision that depends on the response from the execution of asynchronous code. For example, you might make a decision about event propagation based on the response from an asynchronous call to native mobile code.

You can call pause() or resume() in the capture or bubble phases.



Sunday 13 November 2016

TrailHead Help

TrailHead Exercise -  Lightning Component Basics - Input Data Using Forms

Below code will help in completing the Input Data Using Forms exercise


Camping List Component

<aura:component >

    <aura:attribute name="items" type="Camping_Item__c[]" />
 
    <aura:attribute name="newItem" type="Camping_Item__c" default="{'sObjectType':'Camping_Item__c','Quantity__c':0,'Price__c':0}" />
     
    <br/><br/>
    <p>Name:
    <ui:inputText aura:id="name" value="{!v.newItem.Name}" Label="Name" />
    </p><br/>
    <p>Quantity:
    <ui:inputNumber aura:id="quantity" value="{!v.newItem.Quantity__c}" Label="Quantity" />
    </p><br/>
    <p>Price:
    <ui:inputCurrency aura:id="price" value="{!v.newItem.Price__c}" Label="Price" />
    </p><br/>
    <p>Packed?:
    <ui:inputCheckBox value="{!v.newItem.Packed__c}" Label="Packed" />
    </p><br />
 
    <ui:button label="Submit" press="{!c.PushItems}" />
 
    <aura:iteration items="{!v.items}" var="item">
 
    <c:campingListItem item="{!item}" />
     
    </aura:iteration>
     

</aura:component>


Camping List Controller

({
PushItems : function(component, event, helper) {
     
        var validItem = true;

        var ilist = component.get("v.items");
        var nitem = component.get("v.newItem");
     
        var iName = component.find("name");
        var iQuantity = component.find("quantity");
        var iPrice = component.find("price");
     
        if($A.util.isEmpty(iName.get("v.value"))){
        console.log('Checking Name is null');  
            validItem = false;
            iName.set("v.errors",[{message:"Item Name cannot be blank"}]);
         
         
        }else if($A.util.isEmpty(iQuantity.get("v.value"))){
         
            validItem = false;
            iQuantity.set("v.errors",[{message:"Item Quantity cannot be blank"}]);
         
        }else if($A.util.isEmpty(iPrice.get("v.value"))){          
         
            validItem = false;
            iPrice.set("v.errors",[{message:"Item Price cannot be blank"}]);
         
        }
     
        if(validItem){
         
            var pitem = JSON.parse(JSON.stringify(nitem));
         
            ilist.push(pitem);
         
            component.set("v.items",ilist);
         
            console.log('pushed list : ' + pitem);
         
            component.set("v.newItem",{'sObjectType':'Camping_Item__c','Name':' ','Quantity__c':0,'Price__c':0});
         
        }
     
     
}

})


CampingListItem Component

<aura:component >
 
    <aura:attribute name="item" type="Camping_Item__c" />
 
    <p> <ui:outputText value="{!v.item.Name}" /> </p>
 
    <p> <ui:outputNumber value="{!v.item.Quantity__c}" /> </p>
 
    <p> <ui:outputCurrency value="{!v.item.Price__c}" />  </p>
 
    <p> <ui:outputCheckbox value="{!v.item.Packed__c}" /> </p>


</aura:component>


TrailHead Exercise -  Lightning Component Basics - Connect to Salesforce with Server-Side Controllers

Below code will help in completing the Connect to Salesforce with Server-Side Controllers exercise


CampingList Component

<aura:component controller="CampingListController" >

    <aura:attribute name="items" type="Camping_Item__c[]" />
   
    <aura:handler name="init" action="{!c.doInit}" value="{!this}"/>
   
    <aura:attribute name="newItem" type="Camping_Item__c" default="{'sObjectType':'Camping_Item__c','Quantity__c':0,'Price__c':0}" />
     
    <br/><br/>
    <p>Name:
    <ui:inputText aura:id="name" value="{!v.newItem.Name}" Label="Name" />
    </p><br/>
    <p>Quantity:
    <ui:inputNumber aura:id="quantity" value="{!v.newItem.Quantity__c}" Label="Quantity" />
    </p><br/>
    <p>Price:
    <ui:inputCurrency aura:id="price" value="{!v.newItem.Price__c}" Label="Price" />
    </p><br/>
    <p>Packed?:
    <ui:inputCheckBox value="{!v.newItem.Packed__c}" Label="Packed" />
    </p><br />
   
    <ui:button label="Submit" press="{!c.PushItems}" />
   
    <aura:iteration items="{!v.items}" var="item">
   
    <p> <ui:outputText value="{!item.Name}" /> </p>
   
    <p> <ui:outputNumber value="{!item.Quantity__c}" /> </p>
   
    <p> <ui:outputCurrency value="{!item.Price__c}" />  </p>
   
    <p> <ui:outputCheckbox value="{!item.Packed__c}" /> </p>  
       
    </aura:iteration>
     

</aura:component>


CampingList Controller


({

    doInit : function(component,event,helper){
       
       var action = component.get("c.getItems");
       
        action.setCallback(this,function(response){
           
           var state = response.getState();
           
            if(component.isValid() && state === "SUCCESS"){
               
                console.log('From action variable : '+JSON.parse(JSON.stringify(response.getReturnValue())));
               
               
                component.set("v.items",JSON.parse(JSON.stringify(response.getReturnValue())));
               
            }
            else{
               
                console.log("Failed with State : " + state);
            }
           
        });
       
       
        $A.enqueueAction(action);
       
    },
   
   
   
    PushItems : function(component, event, helper) {
       
        var validItem = true;

       
        var nitem = component.get("v.newItem");
       
        var iName = component.find("name");
        var iQuantity = component.find("quantity");
        var iPrice = component.find("price");
       
        if($A.util.isEmpty(iName.get("v.value"))){
        console.log('Checking Name is null');  
            validItem = false;
            iName.set("v.errors",[{message:"Item Name cannot be blank"}]);
           
           
        }else if($A.util.isEmpty(iQuantity.get("v.value"))){
           
            validItem = false;
            iQuantity.set("v.errors",[{message:"Item Quantity cannot be blank"}]);
           
        }else if($A.util.isEmpty(iPrice.get("v.value"))){          
           
            validItem = false;
            iPrice.set("v.errors",[{message:"Item Price cannot be blank"}]);
           
        }
       
        if(validItem){
           
            var pitem = JSON.parse(JSON.stringify(nitem));
           
helper.createItem(component,pitem);
           
           
        }
       
       
}

})



CampingList Helper

({
createItem : function(component,strcamp) {

       
        var action = component.get("c.saveItem");
       
        action.setParams({
           
            "strcamp" : strcamp
           
        });
       
        action.setCallback(this,function(response){
           
            var state = response.getState();
           
            console.log('Status of the response is : ' + state);
           
            if(state === "SUCCESS"){
           
                var ilist = component.get("v.items");
               
                ilist.push(strcamp);
               
                component.set("v.items",ilist);
                                     
                component.set("v.newItem",{'sObjectType':'Camping_Item__c','Name':' ','Quantity__c':0,'Price__c':0});
                   
            }
            else{
               
                console.log('Errored Out');
               
            }
           
        });
       
        $A.enqueueAction(action);
       
       
}

})



CampingListController APEX Class


public class CampingListController{

@AuraEnabled
public static list<Camping_Item__c> getItems(){

    System.debug('Method is invoked');

    return ([select Name,Packed__c,Price__c,Quantity__c from Camping_Item__c]);

}


@AuraEnabled
public static void saveItem(Camping_Item__c strcamp){

    //Camping_Item__c ci     = (Camping_Item__c)JSON.deserialize(strcamp,Camping_Item__c.class);
   
    //System.debug('Inserted Camping Item  : ' + ci);
   
    insert strcamp;

}



}