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;

}



}

Wednesday 9 November 2016

Salesforce Lightning

Understanding Important Visual Design Considerations

Visualforce pages look the same whether they are running in Salesforce Classic or Lightning Experience, unless you rework them to adapt to the appropriate user interface context. Built-in Visualforce components that display user interface elements aren’t easily restyled to match the Lightning Experience look-and-feel.

Specifically, the HTML that’s rendered by the built-in Visualforce components doesn’t change when the page displays in Lightning Experience, and the Salesforce Classic stylesheets those components use is, by default, loaded by the page. The effect is that pages that use <apex:inputField>, <apex:outputField>, the <apex:pageBlock> components, and other coarse- and fine-grained components that match the Salesforce Classic visual design, still match that visual design. You get a little slice of Salesforce Classic in the middle of your Lightning Experience.

It’s our general recommendation that—for now, for existing pages—you don’t try to adapt them to match the visual design of Lightning Experience. There are two reasons for this. First, Lightning Experience is still evolving, and matching its styling yourself means you’re chasing a moving target. That’s work.

Second, it’s even more work if you don’t have the tools to do it. In the current release, the tools are mostly not there. We have a number of ideas here and, Safe Harbor, we’re already hard at work at bringing them to you in a future release. So if you can wait, that’s our recommendation.

Nevertheless, in some cases you’ll want some pages to match more closely with Lightning Experience visuals. For new pages, or if you’re willing to do some work, there are some great tools for creating pages that fit in perfectly with Lightning Experience.

Adding a Custom Stylesheet

You can add your own custom stylesheets to any Visualforce page using static resources and the <apex:stylesheet> tag. For example, to add a stylesheet that’s been uploaded as a static resource named “AppStylesheet”, add the following to your page.

<apex:stylesheet value="{!$Resource.AppStylesheet}"/>

You can then refer to any of the styles contained in the stylesheet, and reference them in Visualforce tag styleClass attributes, as we did with the asideText style previously.
This is the recommended method for adding CSS style definitions to Visualforce pages, because it shares the stylesheet between pages, and minimizes the markup you need to add to each page.

Styling Strategies and Recommendations

In the current release there’s only one supported method for creating Visualforce pages that match the Lightning Experience visual design, and that’s to create new pages using the Lightning Design System. Before we get to specifics, let’s think at a higher level and consider the different strategies for applying Lightning Experience styling to your pages. In particular, let’s talk about your existing pages.

There are two ways to affect the styling of existing pages to make them look more like Lightning Experience.

Change the markup to apply new styling—make changes in your pages.
Change the styling rules for existing markup—make changes in your stylesheets.
These aren’t either / or. You can use them individually or in combination.

The Lightning Design System is a fantastic all-new toolkit for styling your pages, and we’ll talk about it in detail shortly. Correctly using the Lightning Design System means using the Lightning Design System stylesheets with all-new markup for your Visualforce pages. Again, this is the only supported method for matching the Lightning Experience visual design.

However, it is possible to add the Lightning Design System stylesheets, and revise your pages to use them. How much work this is depends on how closely you want to match Lightning Experience as well as the specific markup and components in your code. While it’s possible to achieve decent results this way, it’s not an approach we recommend. The Lightning Design System was designed to be applied to specific markup, and that’s simply not what Visualforce emits. There’s an “impedance mismatch” that, while not fatal, is definitely a serious rock in your shoe when you take this path.

Finally, there’s the other approach: adding new rules and styles to your existing (or a new) stylesheet to make your existing markup look more like Lightning Experience. If your page is already mostly styled with your own stylesheets, this approach might work well for you. If instead you’re mostly using the built-in Visualforce components and the Salesforce Classic styling, it requires you to override the styles from the Salesforce Classic stylesheet.

While this is technically possible, we want to discourage you from taking this approach. It introduces dependencies into your markup and styles that you don’t want to have. These dependencies are on the structure, IDs, and classes of the HTML rendered by the built-in Visualforce components. We want to be really clear here: the HTML rendered by the built-in Visualforce components is an internal implementation detail, subject to change without notice. If you have dependencies on it in your own stylesheets, your styling will eventually break


Knowing Which Features to Avoid in Lightning Experience

Lightning Experience Header and Navigation Menu Can’t Be Suppressed

Visualforce pages always display with the standard Lightning Experience user interface when they run in Lightning Experience. There’s no way to suppress or alter the Lightning Experience header or sidebar. In particular, the showHeader and showSidebar attributes of <apex:page> have no effect on Visualforce pages when displayed in Lightning Experience.

This behavior is intentional. Apps that display in Lightning Experience are Lightning Experience apps. If you need to provide a completely custom interface for your app, you’ll need to run it in Salesforce Classic.


sforce.one Isn’t Salesforce1-Only

The sforce.one JavaScript utility object is available to Visualforce pages in both Salesforce1 and Lightning Experience. If you’ve been using the presence of the sforce.one object as a way to tell if your page is running in a mobile or desktop context, you need to update your code.