• SkipSauls
  • NEWBIE
  • 205 Points
  • Member since 2013
  • Director of Product Management - Force Platform UI
  • Salesforce

  • Chatter
    Feed
  • 4
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 0
    Questions
  • 12
    Replies
<ui:inputDate aura:id="dateValue" label="d" change="c.dateHandler" displayDatePicker="true"/> , I noticed the change event is not fired if you select the date via the date picker. ? any other suggestion 
I realize this is a relativly new thing but I am new to the salesforce platform in general and not sure if my questions are lightning component specific, or more a general salesforce question, so here goes.
I am working through the workbook: http://www.salesforce.com/us/developer/docs/lightning/lightning.pdf and ran into a couple things I just can't make sense of.

1. Prefix's.
    a. I know in visualforce the "c:" prefix means you're using a component. I posted the code below as a reference. In the formhelper.js line "  var action = component.get("c.getExpenses");" what is the "c." referencing?
   b. in the line "action.setCallback(this, function(a){" what is the "a"? is it related to the "A" in "$A.enqueueAction(action);"?
   c. What is the "v" prefix referencing in "var expenses = component.get( "v.expenses");"?

My best guess is that "v"  is for accessing a variable, and "c" for a component, while the "a" passed into the function is a generic placeholder for something (but Idk what...). I don't see anywhere in the code where these 3 prefixes are initialed or declared, which is throwing me off. I'm a Java guy and learning javascript as well as salesforce, so i'm sure it's something obvious that I just don't know yet. I just want to thouroughly understand the example and this piece is giving me grief.


FormHelper.js:
({
    getExpenses : function(component) {
        var action = component.get("c.getExpenses");
        var self = this;
        action.setCallback(this, function(a){
            component.set("v.expenses", a.getReturnValue());
            self.updateTotal(component);
        });
        $A.enqueueAction(action);
    },
    updateTotal : function(component){
        var expenses = component.get( "v.expenses");
        var total = 0;
        for(var i=0; i<expenses.length; i++){
            var e = expenses[i];
            total += e.zoidberg__Amount__c;
        }
        //Update counters
        component.set("v.total",total);
        component.set("v.exp" ,expenses.length);
    },
    createExpense : function(component, expense){
        
        this.upsertExpense(component, expense, function(a) {
            
            var expenses = component.get("v.expenses");
            expenses.push(a.getReturnValue());
            component.set("v.expenses",expenses);
            this.updateTotal(component);
            
        });
    },
    upsertExpense : function(component, expense, callback){
        var action = component.get("c.saveExpense");
        action.setParams({
            "expense":expense
        });
        if(callback){
            action.setCallback(this,callback);
        }
        $A.enqueueAction(action);
    }
})

formController.js:
({
    doInit : function(component, event, helper) {
        helper.getExpenses(component);
    },
    createExpense : function (component,event,helper){
        var amtField = component.find("amount");
        var amt = amtField.get("v.value");
        if(isNaN(amt)||amt==''){
            amtField.setValid("v.value",false);
            amtField.addErrors("v.value",[{message:"Enter an expense amount."}]);
        }
        else{
            amtField.setValid("v.value",true);
            var newExpense = component.get("v.newExpense");
            helper.createExpense(component,newExpense);
        }
    },
    updateEvent : function(component, event, helper){
        helper.upsertExpense(component,event.getParam("expense"));
    },
    waiting : function(component, event, helper){
        component.set("v.wait","updating...");
    },
     doneWaiting : function(component, event, helper){
        component.set("v.wait","");
    },
})

form.cmp:
<aura:component controller="zoidberg.ExpenseController">
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <aura:handler event="zoidberg:updateExpenseItem" action="{!c.updateEvent}"/>
    <aura:handler event="aura:waiting" action="{!c.waiting}"/>
    <aura:handler event="aura:doneWaiting" action="{!c.doneWaiting}"/>
    <aura:attribute name="wait" type="String"/>
    <aura:attribute name="expenses" type="zoidberg.Expense__c[]"/>
    <aura:attribute name="newExpense"
                    type="zoidberg.Expense__c"
                    default="{ 'sobjectType': 'zoidberg__Expense__c',
                                 'Name': '',
                                 'zoidberg__Amount__c': 0,
                                 'zoidberg__Client__c': '',
                                 'zoidberg__Date__c': '',
                                 'zoidberg__Reimbursed__c': false
                             }"/>
    
    <!-- Attributes for Expense Counters -->
    <aura:attribute name= "total" type="Double" default="0.00"/>
    <aura:attribute name="exp" type="Double" default="0" />
    <div class="wait">
        {!v.wait}
    </div>
    <!-- Input from using components -->
    <form>
        <fieldset>
            <ui:inputText aura:id="expname" label="Expense Name"
                          class="form-control"
                          value="{!v.newExpense.name}"
                          placeholder="My Expense" required="true"/>
            <ui:inputNumber aura:id="amount" label="Amount"
                          class="form-control"
                          value="{!v.newExpense.zoidberg__Amount__c}"
                          placeholder="20.80" required="true"/>
            <ui:inputText aura:id="client" label="Client"
                          class="form-control"
                          value="{!v.newExpense.zoidberg__Client__c}"
                          placeholder="ABC Co."/>
            <ui:inputDateTime aura:id="expdate" label="Expense Date"
                          class="form-control"
                          value="{!v.newExpense.zoidberg__Date__c}"
                          displayDatePicker="true"/>
            <ui:inputCheckbox aura:id="reimbursed" label="Reimbursed?"
                          class="form-control"
                          value="{!v.newExpense.zoidberg__Reimbursed__c}"/>
            <ui:button label="Submit" press="{!c.createExpense}"/>
        </fieldset>
    </form>
    
    <!--Expense Counters -->
    <div class="row">
        <!--Change the counter color to red if total amount is more than 100 -->
        <div class= "{!v.total >= 100 ? 'alert alert-danger' : 'alert alert-success'}">
            <h3>Total Expenses</h3>$
            <ui:outputNumber value="{!v.total}" format=".00" />
        </div>
        <div class="alert alert-success">
            <h3>No. of Expenses </h3>
            <ui:outputNumber value="{!v.exp}"/>
        </div>
    </div>
    <!--Display expense records -->
    <div class="row">
        <aura:iteration items="{!v.expenses}" var="expense">
           <zoidberg:expenseList expense="{!expense}"/>
        </aura:iteration>
    </div>
</aura:component>
Hi,
I was playing around with Lightning components and created an input field which on the onchange event through the client contoller and helper calls the server controller to get a list of accounts which are returned to the helper via the callback function and then set to an attribute in the component page. I am printing these in the controller using the aura:iteration tag. For each of the accounts I am displaying I want to link them to open the account page layout in Salesforce1.

Is there an aura ui component for this? I solved it by using the below syntax, but it doesn't seem right. And although it works I don't get a back arrow to go back to the list which you can see if you are looking at an account record that you have navigated to from the 'All Accounts' list for example,
<aura:iteration items="{!v.accs}" var="a">
    <a href="{!'/one/one.app#/sObject/' + a.Id + '/view?t=1414009941155'}">{!a.Name}</a>
</aura:iteration>
Currently I am using this aura reference (https://eu3.lightning.force.com/auradocs/reference.app#) but it is not very extensive.
So is this coming later or am I missing something that I should be aware of?

Thanks / Niklas
 
Hi big audience!
I've developer several components since the release of Lightning framework but I still have a strange problem.
When I load external libraries (most common case is Bootstrap and jQuery) sometimes the jQuery library is not correctly loaded on startup, thus causing problems on dynamically loaded UI.
The docs say I should use the "renderer" with the afterRender event, but doing this I don't see any trace of jQuery (like it is not yet loaded, the $ plugin is undefined), so I can't init my UI from that method.
This leads to random crash of the app on first load, because sometimes the jQUery library is not loaded on startup.
Do you have any suggestions on this?
I'm currently using "setTimeout" to run the UI initializazione asynchronously, but I don't think this is a clean and good solution.
Thanks
Enrico
 
Hi guys,

I'm playing with lightning components and I'm having a problem with switching between components.
I was able to accomplish the switch from component A to B by using $A.get("e.force:navigateToComponent") which worked like a charm. But I cannot find another way except window.history.back() to get back from B to A. This kind of works but shows some strange behaviour with the back button in SF1 and if I go back from A to B again I have to press the back button two times to get back from B to A again ... so kind of strange :)

Does anyone know how to do this the right way?
Thank you!
<ui:inputDate aura:id="dateValue" label="d" change="c.dateHandler" displayDatePicker="true"/> , I noticed the change event is not fired if you select the date via the date picker. ? any other suggestion 
Hi All,

I am facing one issue with lightening components, when i am working with lightening app look and feel is good
User-added image
if i added form component to Tab trying with SF1 simulator look and feel changing,
User-added image
Do we required to do additional customization to compact with SF1

Thanks 
Raja
Hello,

I wish to include :-
<script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>
extenal library for Google maps in a lightning component.

It doesnt allow me to do so , it gives me the following error:-
Content Security Policy: The page's settings blocked the loading of a resource at http://maps.google.com/maps/api/js?sensor=false ("script-src https://ap1.lightning.force.com https://ssl.gstatic.com chrome-extension: 'unsafe-eval' 'unsafe-inline'").

I tried loading this script asynchronously as well , by creating dynamic <script> tag and loading the src. Still doesnt work.

Kindly let me know how I can get Google Maps to work in a Lightning Component.

Thanks in advance
 
I noticed when I got the event working on the Expense example that clicking the check box did save the data, but it also when to the page layout for the expense record.  I'm not sure why the code had the <a> tag span all the fields in the expense record.  I changed my example code to move the </a> up to just cover the name.

Anyeone else notice this behavior and have an opinion as to whether this is the correct fix?
<div class="{!v.expense.learn2turn__reimbursed__c == true 
                   ? 'listRecord recordLayout blue' : 'listRecord recordLayout white'}">
    <a aura:id="expense" href="{!'/' + v.expense.id}">
      <div class="itemTitle">{!v.expense.name}</div>
    </a>
      <div class="recordItem">Amount: 
          <ui:outputNumber 
           value="{!v.expense.learn2turn__amount__c}" format=".00"/>
      </div>
      <div class="recordItem">Reason: 
          <ui:outputText 
           value="{!v.expense.learn2turn__Reason__c}"/>
      </div>
      <div class="recordItem">Date: 
          <ui:outputDateTime
           value="{!v.expense.learn2turn__date__c}" />
      </div>
      <div class="recordItem">Reimbursed? 
          <ui:inputCheckbox 
           value="{!v.expense.learn2turn__processed__c}" click="{!c.myUpdate}"/>
      </div>
  </a>
  </div>

 
Hello,
 I have created a Lightning Component , I can only access the lightning tab when accessing Salesforce1 from my iPhone browser .If I start the Salesforce1 iPhone app it also shows up in the left navigation, but when I click it I just see a loading spinner and nothing ever happens. how to deploy it to salesforce1 mobile app
I realize this is a relativly new thing but I am new to the salesforce platform in general and not sure if my questions are lightning component specific, or more a general salesforce question, so here goes.
I am working through the workbook: http://www.salesforce.com/us/developer/docs/lightning/lightning.pdf and ran into a couple things I just can't make sense of.

1. Prefix's.
    a. I know in visualforce the "c:" prefix means you're using a component. I posted the code below as a reference. In the formhelper.js line "  var action = component.get("c.getExpenses");" what is the "c." referencing?
   b. in the line "action.setCallback(this, function(a){" what is the "a"? is it related to the "A" in "$A.enqueueAction(action);"?
   c. What is the "v" prefix referencing in "var expenses = component.get( "v.expenses");"?

My best guess is that "v"  is for accessing a variable, and "c" for a component, while the "a" passed into the function is a generic placeholder for something (but Idk what...). I don't see anywhere in the code where these 3 prefixes are initialed or declared, which is throwing me off. I'm a Java guy and learning javascript as well as salesforce, so i'm sure it's something obvious that I just don't know yet. I just want to thouroughly understand the example and this piece is giving me grief.


FormHelper.js:
({
    getExpenses : function(component) {
        var action = component.get("c.getExpenses");
        var self = this;
        action.setCallback(this, function(a){
            component.set("v.expenses", a.getReturnValue());
            self.updateTotal(component);
        });
        $A.enqueueAction(action);
    },
    updateTotal : function(component){
        var expenses = component.get( "v.expenses");
        var total = 0;
        for(var i=0; i<expenses.length; i++){
            var e = expenses[i];
            total += e.zoidberg__Amount__c;
        }
        //Update counters
        component.set("v.total",total);
        component.set("v.exp" ,expenses.length);
    },
    createExpense : function(component, expense){
        
        this.upsertExpense(component, expense, function(a) {
            
            var expenses = component.get("v.expenses");
            expenses.push(a.getReturnValue());
            component.set("v.expenses",expenses);
            this.updateTotal(component);
            
        });
    },
    upsertExpense : function(component, expense, callback){
        var action = component.get("c.saveExpense");
        action.setParams({
            "expense":expense
        });
        if(callback){
            action.setCallback(this,callback);
        }
        $A.enqueueAction(action);
    }
})

formController.js:
({
    doInit : function(component, event, helper) {
        helper.getExpenses(component);
    },
    createExpense : function (component,event,helper){
        var amtField = component.find("amount");
        var amt = amtField.get("v.value");
        if(isNaN(amt)||amt==''){
            amtField.setValid("v.value",false);
            amtField.addErrors("v.value",[{message:"Enter an expense amount."}]);
        }
        else{
            amtField.setValid("v.value",true);
            var newExpense = component.get("v.newExpense");
            helper.createExpense(component,newExpense);
        }
    },
    updateEvent : function(component, event, helper){
        helper.upsertExpense(component,event.getParam("expense"));
    },
    waiting : function(component, event, helper){
        component.set("v.wait","updating...");
    },
     doneWaiting : function(component, event, helper){
        component.set("v.wait","");
    },
})

form.cmp:
<aura:component controller="zoidberg.ExpenseController">
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <aura:handler event="zoidberg:updateExpenseItem" action="{!c.updateEvent}"/>
    <aura:handler event="aura:waiting" action="{!c.waiting}"/>
    <aura:handler event="aura:doneWaiting" action="{!c.doneWaiting}"/>
    <aura:attribute name="wait" type="String"/>
    <aura:attribute name="expenses" type="zoidberg.Expense__c[]"/>
    <aura:attribute name="newExpense"
                    type="zoidberg.Expense__c"
                    default="{ 'sobjectType': 'zoidberg__Expense__c',
                                 'Name': '',
                                 'zoidberg__Amount__c': 0,
                                 'zoidberg__Client__c': '',
                                 'zoidberg__Date__c': '',
                                 'zoidberg__Reimbursed__c': false
                             }"/>
    
    <!-- Attributes for Expense Counters -->
    <aura:attribute name= "total" type="Double" default="0.00"/>
    <aura:attribute name="exp" type="Double" default="0" />
    <div class="wait">
        {!v.wait}
    </div>
    <!-- Input from using components -->
    <form>
        <fieldset>
            <ui:inputText aura:id="expname" label="Expense Name"
                          class="form-control"
                          value="{!v.newExpense.name}"
                          placeholder="My Expense" required="true"/>
            <ui:inputNumber aura:id="amount" label="Amount"
                          class="form-control"
                          value="{!v.newExpense.zoidberg__Amount__c}"
                          placeholder="20.80" required="true"/>
            <ui:inputText aura:id="client" label="Client"
                          class="form-control"
                          value="{!v.newExpense.zoidberg__Client__c}"
                          placeholder="ABC Co."/>
            <ui:inputDateTime aura:id="expdate" label="Expense Date"
                          class="form-control"
                          value="{!v.newExpense.zoidberg__Date__c}"
                          displayDatePicker="true"/>
            <ui:inputCheckbox aura:id="reimbursed" label="Reimbursed?"
                          class="form-control"
                          value="{!v.newExpense.zoidberg__Reimbursed__c}"/>
            <ui:button label="Submit" press="{!c.createExpense}"/>
        </fieldset>
    </form>
    
    <!--Expense Counters -->
    <div class="row">
        <!--Change the counter color to red if total amount is more than 100 -->
        <div class= "{!v.total >= 100 ? 'alert alert-danger' : 'alert alert-success'}">
            <h3>Total Expenses</h3>$
            <ui:outputNumber value="{!v.total}" format=".00" />
        </div>
        <div class="alert alert-success">
            <h3>No. of Expenses </h3>
            <ui:outputNumber value="{!v.exp}"/>
        </div>
    </div>
    <!--Display expense records -->
    <div class="row">
        <aura:iteration items="{!v.expenses}" var="expense">
           <zoidberg:expenseList expense="{!expense}"/>
        </aura:iteration>
    </div>
</aura:component>
Hi,
I was playing around with Lightning components and created an input field which on the onchange event through the client contoller and helper calls the server controller to get a list of accounts which are returned to the helper via the callback function and then set to an attribute in the component page. I am printing these in the controller using the aura:iteration tag. For each of the accounts I am displaying I want to link them to open the account page layout in Salesforce1.

Is there an aura ui component for this? I solved it by using the below syntax, but it doesn't seem right. And although it works I don't get a back arrow to go back to the list which you can see if you are looking at an account record that you have navigated to from the 'All Accounts' list for example,
<aura:iteration items="{!v.accs}" var="a">
    <a href="{!'/one/one.app#/sObject/' + a.Id + '/view?t=1414009941155'}">{!a.Name}</a>
</aura:iteration>
Currently I am using this aura reference (https://eu3.lightning.force.com/auradocs/reference.app#) but it is not very extensive.
So is this coming later or am I missing something that I should be aware of?

Thanks / Niklas
 
Hi big audience!
I've developer several components since the release of Lightning framework but I still have a strange problem.
When I load external libraries (most common case is Bootstrap and jQuery) sometimes the jQuery library is not correctly loaded on startup, thus causing problems on dynamically loaded UI.
The docs say I should use the "renderer" with the afterRender event, but doing this I don't see any trace of jQuery (like it is not yet loaded, the $ plugin is undefined), so I can't init my UI from that method.
This leads to random crash of the app on first load, because sometimes the jQUery library is not loaded on startup.
Do you have any suggestions on this?
I'm currently using "setTimeout" to run the UI initializazione asynchronously, but I don't think this is a clean and good solution.
Thanks
Enrico
 
Hello All,

Can someone please help me with answers for the following questions :-

1) Can we embed a VF page in an Lightning Component ?
2) Does Aura have inbuilt components to show Google maps?
3) Can we have mobile features like Location services , make a call, take a picture etc. inside SF1 app, using lightning components?

Thanks!!
I know that some functionalities of Salesforce are already using Aura, and there is also the version for Java: https://github.com/forcedotcom/aura.

I am starting a new project, and I wonder if I need to consider Aura in a short term.

Does anybody know when Aura will be available on production Orgs?

Thanks in advance.