Skip to content

Instantly share code, notes, and snippets.

@jeffdonthemic
Last active December 29, 2022 17:11
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save jeffdonthemic/39791ab40112a81f0168 to your computer and use it in GitHub Desktop.
Save jeffdonthemic/39791ab40112a81f0168 to your computer and use it in GitHub Desktop.
Salesforce1 Lightning Demo for Spring '15
<aura:event type="APPLICATION" description="Add to cart event.">
<aura:attribute name="product" type="Product__c"/>
</aura:event>
public class AwesomeProductController {
@AuraEnabled
public static List<Product__c> getProducts() {
return [select id, name, photo__c, description__c, points__c from product__c];
}
@AuraEnabled
public static Product__c getProductByName(String name) {
return [select id, name, photo__c, color__c,
points__c, description__c,
(select name from product_sizes__r order by name)
from product__c where name = :name];
}
}
<aura:application >
<c:load filesInSeries="/resource/companystore/jquery-1.11.2.min.js,/resource/companystore/bootstrap/bootstrap.js,/resource/companystore/bootstrap/bootstrap.css,/resource/companystore/style.css"/>
<c:ProductViewer />
</aura:application>
<aura:component >
<aura:attribute name="filesInSeries" type="String[]"/>
<aura:attribute name="filesInParallel" type="String[]"/>
<aura:handler name="init" value="{!this}" action="{!c.init}"/>
<aura:registerEvent name="staticResourcesLoaded" type="c:staticResourcesLoaded"/>
</aura:component>
({
init: function(component, event, helper) {
//Modified version of https://github.com/malko/l.js to support resource files without JS or CSS extensions.
!(function(t,e){var r=function(e){(t.execScript||function(e){t["eval"].call(t,e)})(e)},i=function(t,e){return t instanceof(e||Array)},s=document,n="getElementsByTagName",a="length",c="readyState",l="onreadystatechange",u=s[n]("script"),o=u[u[a]-1],f=o.innerHTML.replace(/^\s+|\s+$/g,"");if(!t.ljs){var h=o.src.match(/checkLoaded/)?1:0,d=s[n]("head")[0]||s.documentElement,p=function(t){var e={};e.u=t.replace(/#(=)?([^#]*)?/g,function(t,r,i){e[r?"f":"i"]=i;return""});return e},v=function(t,e,r){var i=s.createElement(t),n;if(r){if(i[c]){i[l]=function(){if(i[c]==="loaded"||i[c]==="complete"){i[l]=null;r()}}}else{i.onload=r}}for(n in e){e[n]&&(i[n]=e[n])}d.appendChild(i)},m=function(t,e){if(this.aliases&&this.aliases[t]){var r=this.aliases[t].slice(0);i(r)||(r=[r]);e&&r.push(e);return this.load.apply(this,r)}if(i(t)){for(var s=t[a];s--;){this.load(t[s])}e&&t.push(e);return this.load.apply(this,t)}if(t.match(/\.js\b/)||t.match(/\.sfjs\b/)){t=t.replace(".sfjs","");return this.loadjs(t,e)}else if(t.match(/\.css\b/)||t.match(/\.sfcss\b/)){t=t.replace(".sfcss","");return this.loadcss(t,e)}else{return this.loadjs(t,e)}},y={},g={aliases:{},loadjs:function(t,r){var i=p(t);t=i.u;if(y[t]===true){r&&r();return this}else if(y[t]!==e){if(r){y[t]=function(t,e){return function(){t&&t();e&&e()}}(y[t],r)}return this}y[t]=function(e){return function(){y[t]=true;e&&e()}}(r);r=function(){y[t]()};v("script",{type:"text/javascript",src:t,id:i.i,onerror:function(t){if(i.f){var e=t.currentTarget;e.parentNode.removeChild(e);v("script",{type:"text/javascript",src:i.f,id:i.i},r)}}},r);return this},loadcss:function(t,e){var r=p(t);t=r.u;y[t]||v("link",{type:"text/css",rel:"stylesheet",href:t,id:r.i});y[t]=true;e&&e();return this},load:function(){var t=arguments,r=t[a];if(r===1&&i(t[0],Function)){t[0]();return this}m.call(this,t[0],r<=1?e:function(){g.load.apply(g,[].slice.call(t,1))});return this},addAliases:function(t){for(var e in t){this.aliases[e]=i(t[e])?t[e].slice(0):t[e]}return this}};if(h){var j,b,x,A;for(j=0,b=u[a];j<b;j++){(A=u[j].getAttribute("src"))&&(y[A.replace(/#.*$/,"")]=true)}x=s[n]("link");for(j=0,b=x[a];j<b;j++){(x[j].rel==="stylesheet"||x[j].type==="text/css")&&(y[x[j].getAttribute("href").replace(/#.*$/,"")]=true)}}t.ljs=g}f&&r(f)})(window);
var loadInSeries = function(filesInSeries, cb) {
filesInSeries.push(cb);
ljs.load.apply(ljs, filesInSeries)
}
var loadInParallel = function(filesInParallel, cb) {
ljs.load(filesInParallel, cb);
}
var finalCB = function() {
$A.get("e.c:staticResourcesLoaded").fire();
}
var filesInSeries = component.get("v.filesInSeries");
var filesInParallel = component.get("v.filesInParallel");
if (filesInParallel.length > 0) {
loadInParallel(filesInParallel, function() {
if (filesInSeries.length > 0) {
loadInSeries(filesInSeries, finalCB);
} else {
finalCB();
}
});
} else if (filesInSeries.length > 0) {
loadInSeries(filesInSeries, finalCB);
}
}
})
<aura:component >
<aura:attribute name="message" type="String"/>
<aura:handler event="c:AddToCart" action="{!c.handleShowMessage}"/>
<div class="text-center" style="padding-bottom:25px">
{!v.message}
</div>
</aura:component>
({
handleShowMessage : function(component, event, helper) {
var product = event.getParam("product");
component.set('v.message', 'Thanks for adding ' + product.Name);
},
})
<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
<deploymentStatus>Deployed</deploymentStatus>
<fields>
<fullName>Color__c</fullName>
<label>Color</label>
<length>25</length>
<required>true</required>
<type>Text</type>
</fields>
<fields>
<fullName>Description__c</fullName>
<label>Description</label>
<required>true</required>
<type>TextArea</type>
</fields>
<fields>
<fullName>Photo__c</fullName>
<label>Photo</label>
<required>true</required>
<type>Url</type>
</fields>
<fields>
<fullName>Points__c</fullName>
<label>Points</label>
<precision>18</precision>
<required>true</required>
<scale>0</scale>
<type>Number</type>
</fields>
<label>Product</label>
<listViews>
<fullName>All</fullName>
<filterScope>Everything</filterScope>
<label>All</label>
</listViews>
<nameField>
<label>Name</label>
<type>Text</type>
</nameField>
<pluralLabel>Products</pluralLabel>
<searchLayouts/>
<sharingModel>ReadWrite</sharingModel>
</CustomObject>
<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
<deploymentStatus>Deployed</deploymentStatus>
<fields>
<fullName>Product__c</fullName>
<label>Product</label>
<referenceTo>Product__c</referenceTo>
<relationshipLabel>Product Sizes</relationshipLabel>
<relationshipName>Product_Sizes</relationshipName>
<relationshipOrder>0</relationshipOrder>
<type>MasterDetail</type>
</fields>
<label>Product Size</label>
<nameField>
<label>Product Size Name</label>
<type>Text</type>
</nameField>
<pluralLabel>Product Sizes</pluralLabel>
<searchLayouts/>
<sharingModel>ControlledByParent</sharingModel>
</CustomObject>
<aura:component controller="AwesomeProductController">
<aura:attribute name="product" type="Product__c" default="{'sobjectType': 'Product__c'}"/>
<aura:attribute name="products" type="Product__c[]"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
<aura:registerEvent name="addToCartEvent" type="c:AddToCart"/>
<div class="container">
<div class="row">
<div class="col-lg-3 col-md-4 col-sm-5">
<div class="well">
<div class="btn-group btn-group-cart">
<select onchange="{!c.change}">
<aura:iteration items="{!v.products}" var="p">
<option>{!p.Name}</option>
</aura:iteration>
</select>
</div>
</div>
</div>
</div>
</div>
<div class="container main-container">
<div class="row">
<div class="col-lg-3 col-md-3 col-sm-12">
<div class="col-lg-12 col-md-12 col-sm-12">
<div class="no-padding">
<span class="title">{!v.product.Name}</span>
</div>
<div class="thumbnail col-lg-12 col-md-12 col-sm-6 text-center">
<a href="detail.html" class="link-p">
<img src="{!v.product.Photo__c}" alt=""/>
</a>
<div class="caption prod-caption">
<p>{!v.product.Description__c}</p>
<p>
<div class="btn-group">
<a href="#" class="btn btn-default">{!v.product.Points__c} pts</a>
<a href="#" onclick="{!c.addToCart}" class="btn btn-primary"><i class="fa fa-shopping-cart"></i> Add</a>
</div>
</p>
</div>
</div>
</div>
</div>
<div class="clearfix visible-sm"></div>
<c:ShoppingCart />
<c:MessageArea />
</div>
</div>
</aura:component>
({
doInit : function(component, event, helper) {
// for demo, just grab this product by name
helper.getProduct(component, 'Always Be Yourself');
helper.getProducts(component);
},
change : function(component, event, helper) {
// get the value of the select option
selectedName = event.target.value;
helper.getProduct(component, selectedName);
},
addToCart : function(component, event, helper) {
var product = component.get("v.product");
var evt = $A.get("e.c:AddToCart");
evt.setParams({
"product": product
});
evt.fire();
},
})
({
getProducts: function(component) {
var action = component.get("c.getProducts");
action.setCallback(this, function(a) {
component.set("v.products", a.getReturnValue());
});
$A.enqueueAction(action);
},
getProduct: function(component, productName) {
var action = component.get("c.getProductByName");
action.setParams({
"name": productName
});
action.setCallback(this, function(a) {
// display the product to the chrome dev console (for fun)
console.log(a.getReturnValue());
component.set("v.product", a.getReturnValue());
});
$A.enqueueAction(action);
},
})
<aura:component >
<aura:attribute name="items" type="Product__c[]"/>
<aura:attribute name="total" type="Integer" default="0"/>
<aura:handler event="c:AddToCart" action="{!c.handleAddToCartEvent}"/>
<div class="col-lg-9 col-md-9 col-sm-12">
<div class="col-lg-12 col-sm-12">
<span class="title">COMPANY STORE BASKET</span>
</div>
<aura:renderIf isTrue="{!v.items.length > 0}">
<div class="col-lg-12 col-sm-12 hero-feature">
<table class="table table-bordered tbl-cart">
<thead>
<tr>
<td class="hidden-xs">Image</td>
<td>Product Name</td>
<td>Size</td>
<td>Color</td>
<td>Points</td>
</tr>
</thead>
<tbody>
<aura:iteration items="{!v.items}" var="item">
<tr>
<td class="hidden-xs"><img src="{!item.Photo__c}" alt="{!item.Name}" title="" width="47" height="47" /></td>
<td>{!item.Name}
</td>
<td>
<select>
<aura:iteration items="{!item.Product_Sizes__r}" var="size">
<option>{!size.Name}</option>
</aura:iteration>
</select>
</td>
<td>{!item.Color__c}</td>
<td>{!item.Points__c}</td>
</tr>
</aura:iteration>
<tr>
<td colspan="3" align="right">Total Points</td>
<td class="total" colspan="2"><b>{!v.total}</b>
</td>
</tr>
</tbody>
</table>
<a href="#" class="btn btn-primary"><i class="fa fa-shopping-cart"></i> Confirm your order</a>
</div>
</aura:renderIf>
<aura:renderIf isTrue="{!v.items.length == 0}">
<div class="col-lg-12 col-sm-12 hero-feature">
<p>Your basket is empty. So sad. Use your points to redeem something #awesome!</p>
</div>
</aura:renderIf>
</div>
</aura:component>
({
handleAddToCartEvent : function(component, event, helper) {
var product = event.getParam("product");
var items = component.get("v.items");
if (!items) items = [];
items.push(product);
component.set("v.total", parseInt(component.get("v.total")) + product.Points__c);
component.set("v.items", items);
},
})
<aura:event type="APPLICATION" description="Event template" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment