• Charles Thompson
  • NEWBIE
  • 45 Points
  • Member since 2017
  • Program Architect
  • Salesforce Singapore


  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 2
    Questions
  • 21
    Replies

I am going through the SLDS trail as follows:
Trailhead > Develop for Lightning Experience > Lightning Design System > Use Images, Icons, and Avatars
https://trailhead.salesforce.com/trails/lex_dev/modules/lightning_design_system/units/lightning-design-system5

In the Page Header section, a box is supposed to display an avatar alongside the header text "Accounts / My Accounts".  What I get is a missing image indicator and the brower console gives me a 404 error.

The code in question looks like this:

<img src="{!URLFOR($Asset.SLDS, '/assets/images/avatar1.jpg')}" alt="" />

(along with appropriate spans and divs)   Looking into the Visualforce documentation, I see that the path to assets should be without the leading slash, so the code should look like this:

<img src="{!URLFOR($Asset.SLDS, 'assets/images/avatar1.jpg')}" alt="" />
but that doesn't work, either.

Question:  how do you reference Salesforce assets in this context?

My full code is below.  (This whole module is very difficult to use because the code samples appear all on one (long) line without line breaks, making them very difficult to copy/paste.)
 

<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" /> 
            <!-- Import the Design System style sheet --> 
            <apex:slds /> 
        </head> 
        <apex:remoteObjects > 
            <apex:remoteObjectModel name="Account" fields="Id,Name,LastModifiedDate"/> 
        </apex:remoteObjects> 
        <body>            
            <!-- REQUIRED SLDS WRAPPER --> 
            <div class="slds-scope"> 
                <!-- MASTHEAD --> 
                <p class="slds-text-heading--label slds-m-bottom--small"> 
                    Salesforce Lightning Design System Trailhead Module 
                </p> 
                <!-- / MASTHEAD --> 
                <!-- PAGE HEADER --> 
                <div class="slds-page-header" role="banner"> 
                    <div class="slds-grid"> 
                        <div class="slds-col slds-has-flexi-truncate"> 
                            <!-- HEADING AREA --> 
                            <div class="slds-media slds-no-space slds-grow"> 
                                <div class="slds-media__figure"> 
                                    <span class="slds-avatar slds-avatar--medium"> 
                                        <img src="{!URLFOR($Asset.SLDS, 'assets/images/avatar1.jpg')}" 
                                             alt="" />
                                    </span> 
                                </div> 
                                <div class="slds-media__body"> 
                                    <p class="slds-text-title--caps slds-line-height--reset">
                                        Accounts
                                    </p> 
                                    <h1 class="slds-page-header__title slds-m-right--small slds-align-middle slds-truncate" 
                                        title="My Accounts">
                                        My Accounts
                                    </h1> 
                                </div> 
                            </div> 
                            <!-- / HEADING AREA -->
                        </div> 
                        <div class="slds-col slds-no-flex slds-grid slds-align-top"> 
                            <button class="slds-button slds-button--neutral">
                                New Account
                            </button> 
                        </div> 
                    </div> 
                    <div class="slds-grid"> 
                        <div class="slds-col slds-align-bottom slds-p-top--small"> 
                            <p class="slds-text-body--small page-header__info">
                                COUNT items
                            </p> 
                        </div> 
                    </div> 
                </div> 
                <!-- / PAGE HEADER -->                
                <!-- PRIMARY CONTENT WRAPPER --> 
                <div class="myapp"> 
                    <!-- CREATE NEW ACCOUNT --> 
                    <div aria-labelledby="newaccountform"> 
                        <!-- CREATE NEW ACCOUNT FORM --> 
                        <form class="slds-form--stacked" id="add-account-form"> 
                            <!-- BOXED AREA --> 
                            <fieldset class="slds-box slds-theme--default slds-container--small"> 
                                <legend id="newaccountform" class="slds-text-heading--medium slds-p-vertical--medium">
                                    Add a new account
                                </legend> 
                                <div class="slds-form-element"> 
                                    <label class="slds-form-element__label" for="account-name">
                                        Name
                                    </label> 
                                    <div class="slds-form-element__control"> 
                                        <input id="account-name" class="slds-input" type="text" 
                                               placeholder="New account"/> 
                                    </div> 
                                </div> 
                                <button class="slds-button slds-button--brand slds-m-top--medium" type="submit">
                                    Create Account
                                </button> 
                            </fieldset> 
                            <!-- / BOXED AREA --> 
                        </form> 
                        <!-- CREATE NEW ACCOUNT FORM --> 
                    </div> 
                    <!-- / CREATE NEW ACCOUNT -->
                    <!-- ACCOUNT LIST TABLE --> 
                    <div id="account-list" class="slds-p-vertical--medium">
                        
                    </div> 
                    <!-- / ACCOUNT LIST TABLE --> 
                </div> 
                <!-- / PRIMARY CONTENT WRAPPER -->
                
                <!-- FOOTER --> 
                <footer role="contentinfo" class="slds-p-around--large"> 
                    <!-- LAYOUT GRID --> 
                    <div class="slds-grid slds-grid--align-spread"> 
                        <p class="slds-col">Salesforce Lightning Design System Example</p> 
                        <p class="slds-col">&copy; Your Name Here</p> 
                    </div> 
                    <!-- / LAYOUT GRID --> 
                </footer> 
                <!-- / FOOTER -->            
            </div> 
            <!-- / REQUIRED SLDS WRAPPER --> 
            <!-- JAVASCRIPT --> 
            <script> 
            (function() { 
                var account = new SObjectModel.Account(); 
                var outputDiv = document.getElementById('account-list'); 
                var updateOutputDiv = function() { 
                    account.retrieve( { 
                        orderby: [{ LastModifiedDate: 'DESC'}, 
                                  { Name: 'ASC'}
                                 ]//, 
                        //limit: 10 
                    }, function(error, records) { 
                        if (error) { 
                            alert(error.message); 
                        } else { 
                            // create data table 
                            var dataTable = document.createElement('table'); 
                            dataTable.className = 'slds-table slds-table--bordered slds-table--cell-buffer slds-no-row-hover'; 
                            // add header row 
                            var tableHeader = dataTable.createTHead(); 
                            var tableHeaderRow = tableHeader.insertRow(); 
                            var tableHeaderRowCell1 = tableHeaderRow.insertCell(0); 
                            tableHeaderRowCell1.appendChild(document.createTextNode('Account name')); 
                            tableHeaderRowCell1.setAttribute('scope', 'col'); 
                            tableHeaderRowCell1.setAttribute('class', 'slds-text-heading--label'); 
                            var tableHeaderRowCell2 = tableHeaderRow.insertCell(1); 
                            tableHeaderRowCell2.appendChild(document.createTextNode('Account ID')); 
                            tableHeaderRowCell2.setAttribute('scope', 'col'); 
                            tableHeaderRowCell2.setAttribute('class', 'slds-text-heading--label'); 
                            var tableHeaderRowCell3 = tableHeaderRow.insertCell(2); 
                            tableHeaderRowCell3.appendChild(document.createTextNode('Last Mod')); 
                            tableHeaderRowCell3.setAttribute('scope', 'col'); 
                            tableHeaderRowCell3.setAttribute('class', 'slds-text-heading--label'); 
                            // build table body 
                            var tableBody = dataTable.appendChild(document.createElement('tbody')); 
                            var dataRow, dataRowCell1, dataRowCell2, dataRowCell3, recordName, recordId; 
                            records.forEach(function(record) { 
                                dataRow = tableBody.insertRow(); 
                                dataRowCell1 = dataRow.insertCell(0); 
                                recordName = document.createTextNode(record.get('Name')); 
                                dataRowCell1.appendChild(recordName); 
                                dataRowCell2 = dataRow.insertCell(1); 
                                recordId = document.createTextNode(record.get('Id')); 
                                dataRowCell2.appendChild(recordId); 
                                dataRowCell3 = dataRow.insertCell(2); 
                                lastMod = document.createTextNode(record.get('LastModifiedDate')); 
                                dataRowCell3.appendChild(lastMod); 
                            }); 
                            if (outputDiv.firstChild) { 
                                // replace table if it already exists 
                                // see later in tutorial 
                                outputDiv.replaceChild(dataTable, outputDiv.firstChild); 
                            } else { 
                                outputDiv.appendChild(dataTable); 
                            } 
                        } 
                    } ); 
                } 
                updateOutputDiv(); 
            })(); 
            var accountForm = document.getElementById('add-account-form'); 
            var accountNameField = document.getElementById('account-name'); 
            var createAccount = function() { 
                var account = new SObjectModel.Account(); 
                account.create({ Name: accountNameField.value }, 
                               function(error, records) { 
                                   if (error) { 
                                       alert(error.message); 
                                   } else { 
                                       updateOutputDiv(); 
                                       accountNameField.value = ''; 
                                   } 
                               }); 
            } 
            accountForm.addEventListener('submit', 
                                         function(e) { 
                                             e.preventDefault(); 
                                             createAccount(); 
                                         }
                                        );
            </script> 
            <!-- / JAVASCRIPT -->
        </body> 
    </html> 
</apex:page>
User-added image
I have come up with a way to replace Classic related lists on a page layout, so you can get past some of the limitations of page layouts. I hope this post will be helpful to our global ohana.

Why would you want to do this?
Related Lists can only have up to 10 columns.  My customer has a related custom object with 14 fields that should be displayed on a single line:  Year, Jan ... Dec, and Year Total.  Each monthly value is a currency field, and multi-currency is on for the Org, meaning that the currency ISO code is displayed for each of these fields.  So we also want to display the values without the ISO code.

What did I do to get around this?
My solution includes two Visualforce (VF) pages and a controller extension.
  1. View page:  A page thatdisplays the fields in a table, as read-only. On this page is a single button, [Edit] to switch to Edit mode.
  2. Edit page: A page that displays the fields in a table, as editable fields. It has three buttons: [Add] [Save] [Cancel]
  3. Apex controller extension. I used an extension because it adds to the functionality of the standard controller, which could be helpful in more complex use cases.
In my example, I have a new custom object, Budget, related to Contact in a master/detail relationship. I declined to put the related list on the Contact page layouts because I added my own VF page to the layout details section.  If you want to duplicate my code exactly in your DevEd org, you'll need to create this object and relate it to Contact.

Apex Controller Extension (BudgetExt.apxc):
public with sharing class BudgetExt {
    
/*************************************************
 * Controller extension to provide functionality required for the Budgets
 * section of Contact detail page.  The business requirement was to allow
 * the Budgets related list on Contact to display 14 columns (year
 * + 12 months + total).  The end result is an embedded VF page component on the Contact
 * page layout that displays the Budget related rows in view mode 
 * (read only), with an edit button local to the component.  Clicking Edit 
 * switches the component to Edit Mode by changing the PageReference to
 * the related Edit mode VF page.  On that page are three buttons (Add Row, 
 * Save and Cancel) plus a Delete button on each row.  Hitting Save or Cancel
 * brings you back to the View mode page.
 * 
 * Related VF pages:
 * - BudgetEdit.vfp
 * - BudgetView.vfp
 * 
 * Author: Charles Thompson, Salesforce, Nov 2017
 * *************************************************/
    
    private final Id contactID; // store the parent (Contact) ID
    public Integer index {get;set;} // store the current row being deleted
    
    // List to represent each row of the pageBlockTable of Budgets 
    // related to the parent Sub Project
    public List<Budget__c> budgets {get; set;}

    // List to hold those rows being deleted
    public List<Budget__c> budgetsToDel = new List<Budget__c>();
    
    // Variable to hold the Sub Project (parent) record
    public Contact theContact {get; set;}
    
    // Initial load of the pageBlockTable
    public BudgetExt(ApexPages.StandardController stdController){
        contactID = stdController.getId();
        this.index = 0;
        theContact = [SELECT Id
                      FROM   Contact
                      WHERE  Id = :contactID
                      LIMIT 1
                     ];
        budgets =    [SELECT Id,
                             Year__c,
                               Jan__c, Feb__c, Mar__c, Apr__c,
                               May__c, Jun__c, Jul__c, Aug__c,
                              Sep__c, Oct__c, Nov__c, Dec__c,
                             Year_Total__c
                      FROM   Budget__c
                      WHERE  Contact__c = :contactID
               ORDER BY Year__c
              ];
    }
                              
    public String getIndex(){
        return String.valueOf(index);
    }
    
    public void setIndex(String indexIn){
        this.index = Integer.valueOf(indexIn);
    }
            
    // Add an empty budget row to the table 
    // (not saved to the database until saveBuds() is called)
    public void addRow(){
        Budget__c row = new Budget__c();
        row.Contact__c = contactID;
        budgets.add(row); 
    }
    
    // delete a forecast from the table (not saved to the db until later)
    public void delRow(){
        
        Integer i = this.index-1; // Rows start at one, Lists start at zero
        
        // If the row is an existing row then add it to the list 
        // to delete from the database
        if (budgets[i].Id != null){
            budgetsToDel.add(budgets[i]);
        }
        //Remove the forecast from the table    
        budgets.remove(i);
    }
    
    public PageReference saveBuds(){
        // update and insert forecasts as per the current list
        upsert budgets;
        
        // delete any rows in the list of deletions
        if ((budgetsToDel != null) && (budgetsToDel.size() > 0)){
            delete budgetsToDel;
        }
        
        return cancelEdit();
    }
    
    public PageReference editBuds(){
        // switch to Edit mode
        PageReference editPage = new PageReference('/apex/BudgetEdit?id=' + contactID);
        return editPage;
    }

    public PageReference cancelEdit(){
        // switch back to View mode without saving anything
        PageReference viewPage = new PageReference('/apex/BudgetView?id=' + contactID);
        viewPage.setRedirect(true);
        return viewPage;
    }   
}

View VF page (BudgetView.vfp):
<apex:page standardController="Contact" extensions="BudgetExt">
<!------------------------------------------------------------------------ 
    This page is designed to fit as a component on the detail page of 
    the Contact page layout.  This is the View Mode version of the page, 
    containing output fields and a button for Edit.
    
    Note that the currency ISO code doesn't appear and is assumed to be 
    carried through from the parent record.
     
    The related Edit Mode page is called "BudgetEdit".
     
    Author: Charles Thompson, Salesforce Singapore, Nov 2017 
--------------------------------------------------------------------------> 

    <apex:form >
        <apex:pageBlock mode="maindetail">

            <table width="100%">
                <tr>
                    <td style="text-align:center">
                        <!-- Button... Edit (switch to Edit Mode) -->
                        <apex:commandButton value="Edit" action="{!editBuds}" 
                                            id="editButton" />
                    </td>
                </tr>
            </table>
            
            <!-- Table displaying the Annual Forecast related records -->
            <apex:pageBlockTable value="{!budgets}" var="row" id="budgetTbl" >
            
                <apex:column headerValue="Year">
                    <apex:outputText id="Year" value="{!row.Year__c}" style="width:40px" />
                </apex:column>
 
                 <!-- Currency fields from Budget (formatted as number without currency) -->               
                <apex:column headerValue="Jan" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Jan" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Jan__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="Feb" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Feb" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Feb__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="Mar" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Mar" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Mar__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="Apr" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Apr" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Apr__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="May" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="May" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.May__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="Jun" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Jun" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Jun__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="Jul" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Jul" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Jul__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="Aug" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Aug" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Aug__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="Sep" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Sep" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Sep__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="Oct" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Oct" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Oct__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="Nov" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Nov" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Nov__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="Dec" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Dec" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Dec__c}"/>
                    </apex:outputText>
                </apex:column>
                
                <!-- Total (sum) for the year -->
                <apex:column headerValue="Total" style="text-align:right" 
                             headerClass="CurrencyElement" >
                    <apex:outputText id="yearTotal" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Year_Total__c}"/>
                    </apex:outputText>
               </apex:column>

            </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>

</apex:page>

Edit VF page (BudgetEdit.vfp):
<apex:page id="thepage" standardController="Contact" extensions="BudgetExt">
<!------------------------------------------------------------------------ 
    This page is designed to fit as a component on the detail page of 
    the Contact page layout.  This is the Edit Mode version of the page, 
    containing input fields and buttons for Add Row, Save, Cancel and Delete.
    
    Note that the currency ISO code doesn't appear and is assumed to be 
    carried through from the parent record.
     
    The related View Mode page is called "BudgetView".
     
    Author: Charles Thompson, Salesforce Singapore, Nov 2017 
--------------------------------------------------------------------------> 
    <apex:form>
        <apex:pageBlock mode="maindetail">

            <table width="100%">
                <tr>
                    <td style="text-align:center">
                        <!-- Buttons... Add Row / Save / Cancel -->
                        <apex:commandButton value="Add Row" action="{!addRow}" 
                                            id="addButton" />
                        <apex:commandButton value="Save" action="{!saveBuds}" 
                                            id="saveButton" />
                        <apex:commandButton value="Cancel" action="{!cancelEdit}" 
                                            id="cancelButton" />
                    </td>
                </tr>
            </table>
            
            <!-- Table displaying the related records -->
            <apex:pageBlockTable value="{!budgets}" var="row" id="budgets" >

                <!-- Counter variable to store an index value for each line -->
                <apex:variable var="i" value="{!0}" />
                <!-- Delete button -->
                <apex:column >
                    <apex:commandButton value="X" style="color: red" 
                                        action="{!delRow}" reRender="budgets"
                                        immediate="true" >
                        <!-- populate Apex index variable -->
                        <apex:param name="index" value="{!i}" assignTo="{!index}"/> 
                    </apex:commandButton>
                    <apex:variable var="i" value="{!i + 1}" />
                </apex:column>
                <apex:column headerValue="Year" 
                             title="Enter the forecast by month for this year and next year">
                    <apex:inputField value="{!row.Year__c}" style="width:60px"  />
                </apex:column>
 
                 <!-- Currency fields from Annual Forecast (the currency indicator doesn't appear) -->               
                <apex:column headerValue="Jan" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Jan__c}" 
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="Feb" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Feb__c}" 
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="Mar" style="text-align:right"  
                                     headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Mar__c}"  
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="Apr" style="text-align:right"  
                                     headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Apr__c}"  
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="May" style="text-align:right"  
                                     headerClass="CurrencyElement">
                    <apex:inputField value="{!row.May__c}"  
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="Jun" style="text-align:right"  
                                     headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Jun__c}"  
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="Jul" style="text-align:right"  
                                     headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Jul__c}"  
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="Aug" style="text-align:right"  
                                     headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Aug__c}"  
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="Sep" style="text-align:right"  
                                     headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Sep__c}"  
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="Oct" style="text-align:right"  
                                     headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Oct__c}"  
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="Nov" style="text-align:right"  
                                     headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Nov__c}"  
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="Dec" style="text-align:right"  
                                     headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Dec__c}"  
                                     style="text-align:right; width:65px" />
               </apex:column>
                <!-- Total (sum) for the year -->
                <apex:column headerValue="Total" style="text-align:right" 
                             headerClass="CurrencyElement" >
                    <apex:outputText id="yearTotal" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Year_Total__c}"/>
                    </apex:outputText>
               </apex:column>

            </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>

</apex:page>

I hope this helps someone in the future, even if Lightning Experience makes this solution somewhat useless.
 

I am going through the SLDS trail as follows:
Trailhead > Develop for Lightning Experience > Lightning Design System > Use Images, Icons, and Avatars
https://trailhead.salesforce.com/trails/lex_dev/modules/lightning_design_system/units/lightning-design-system5

In the Page Header section, a box is supposed to display an avatar alongside the header text "Accounts / My Accounts".  What I get is a missing image indicator and the brower console gives me a 404 error.

The code in question looks like this:

<img src="{!URLFOR($Asset.SLDS, '/assets/images/avatar1.jpg')}" alt="" />

(along with appropriate spans and divs)   Looking into the Visualforce documentation, I see that the path to assets should be without the leading slash, so the code should look like this:

<img src="{!URLFOR($Asset.SLDS, 'assets/images/avatar1.jpg')}" alt="" />
but that doesn't work, either.

Question:  how do you reference Salesforce assets in this context?

My full code is below.  (This whole module is very difficult to use because the code samples appear all on one (long) line without line breaks, making them very difficult to copy/paste.)
 

<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" /> 
            <!-- Import the Design System style sheet --> 
            <apex:slds /> 
        </head> 
        <apex:remoteObjects > 
            <apex:remoteObjectModel name="Account" fields="Id,Name,LastModifiedDate"/> 
        </apex:remoteObjects> 
        <body>            
            <!-- REQUIRED SLDS WRAPPER --> 
            <div class="slds-scope"> 
                <!-- MASTHEAD --> 
                <p class="slds-text-heading--label slds-m-bottom--small"> 
                    Salesforce Lightning Design System Trailhead Module 
                </p> 
                <!-- / MASTHEAD --> 
                <!-- PAGE HEADER --> 
                <div class="slds-page-header" role="banner"> 
                    <div class="slds-grid"> 
                        <div class="slds-col slds-has-flexi-truncate"> 
                            <!-- HEADING AREA --> 
                            <div class="slds-media slds-no-space slds-grow"> 
                                <div class="slds-media__figure"> 
                                    <span class="slds-avatar slds-avatar--medium"> 
                                        <img src="{!URLFOR($Asset.SLDS, 'assets/images/avatar1.jpg')}" 
                                             alt="" />
                                    </span> 
                                </div> 
                                <div class="slds-media__body"> 
                                    <p class="slds-text-title--caps slds-line-height--reset">
                                        Accounts
                                    </p> 
                                    <h1 class="slds-page-header__title slds-m-right--small slds-align-middle slds-truncate" 
                                        title="My Accounts">
                                        My Accounts
                                    </h1> 
                                </div> 
                            </div> 
                            <!-- / HEADING AREA -->
                        </div> 
                        <div class="slds-col slds-no-flex slds-grid slds-align-top"> 
                            <button class="slds-button slds-button--neutral">
                                New Account
                            </button> 
                        </div> 
                    </div> 
                    <div class="slds-grid"> 
                        <div class="slds-col slds-align-bottom slds-p-top--small"> 
                            <p class="slds-text-body--small page-header__info">
                                COUNT items
                            </p> 
                        </div> 
                    </div> 
                </div> 
                <!-- / PAGE HEADER -->                
                <!-- PRIMARY CONTENT WRAPPER --> 
                <div class="myapp"> 
                    <!-- CREATE NEW ACCOUNT --> 
                    <div aria-labelledby="newaccountform"> 
                        <!-- CREATE NEW ACCOUNT FORM --> 
                        <form class="slds-form--stacked" id="add-account-form"> 
                            <!-- BOXED AREA --> 
                            <fieldset class="slds-box slds-theme--default slds-container--small"> 
                                <legend id="newaccountform" class="slds-text-heading--medium slds-p-vertical--medium">
                                    Add a new account
                                </legend> 
                                <div class="slds-form-element"> 
                                    <label class="slds-form-element__label" for="account-name">
                                        Name
                                    </label> 
                                    <div class="slds-form-element__control"> 
                                        <input id="account-name" class="slds-input" type="text" 
                                               placeholder="New account"/> 
                                    </div> 
                                </div> 
                                <button class="slds-button slds-button--brand slds-m-top--medium" type="submit">
                                    Create Account
                                </button> 
                            </fieldset> 
                            <!-- / BOXED AREA --> 
                        </form> 
                        <!-- CREATE NEW ACCOUNT FORM --> 
                    </div> 
                    <!-- / CREATE NEW ACCOUNT -->
                    <!-- ACCOUNT LIST TABLE --> 
                    <div id="account-list" class="slds-p-vertical--medium">
                        
                    </div> 
                    <!-- / ACCOUNT LIST TABLE --> 
                </div> 
                <!-- / PRIMARY CONTENT WRAPPER -->
                
                <!-- FOOTER --> 
                <footer role="contentinfo" class="slds-p-around--large"> 
                    <!-- LAYOUT GRID --> 
                    <div class="slds-grid slds-grid--align-spread"> 
                        <p class="slds-col">Salesforce Lightning Design System Example</p> 
                        <p class="slds-col">&copy; Your Name Here</p> 
                    </div> 
                    <!-- / LAYOUT GRID --> 
                </footer> 
                <!-- / FOOTER -->            
            </div> 
            <!-- / REQUIRED SLDS WRAPPER --> 
            <!-- JAVASCRIPT --> 
            <script> 
            (function() { 
                var account = new SObjectModel.Account(); 
                var outputDiv = document.getElementById('account-list'); 
                var updateOutputDiv = function() { 
                    account.retrieve( { 
                        orderby: [{ LastModifiedDate: 'DESC'}, 
                                  { Name: 'ASC'}
                                 ]//, 
                        //limit: 10 
                    }, function(error, records) { 
                        if (error) { 
                            alert(error.message); 
                        } else { 
                            // create data table 
                            var dataTable = document.createElement('table'); 
                            dataTable.className = 'slds-table slds-table--bordered slds-table--cell-buffer slds-no-row-hover'; 
                            // add header row 
                            var tableHeader = dataTable.createTHead(); 
                            var tableHeaderRow = tableHeader.insertRow(); 
                            var tableHeaderRowCell1 = tableHeaderRow.insertCell(0); 
                            tableHeaderRowCell1.appendChild(document.createTextNode('Account name')); 
                            tableHeaderRowCell1.setAttribute('scope', 'col'); 
                            tableHeaderRowCell1.setAttribute('class', 'slds-text-heading--label'); 
                            var tableHeaderRowCell2 = tableHeaderRow.insertCell(1); 
                            tableHeaderRowCell2.appendChild(document.createTextNode('Account ID')); 
                            tableHeaderRowCell2.setAttribute('scope', 'col'); 
                            tableHeaderRowCell2.setAttribute('class', 'slds-text-heading--label'); 
                            var tableHeaderRowCell3 = tableHeaderRow.insertCell(2); 
                            tableHeaderRowCell3.appendChild(document.createTextNode('Last Mod')); 
                            tableHeaderRowCell3.setAttribute('scope', 'col'); 
                            tableHeaderRowCell3.setAttribute('class', 'slds-text-heading--label'); 
                            // build table body 
                            var tableBody = dataTable.appendChild(document.createElement('tbody')); 
                            var dataRow, dataRowCell1, dataRowCell2, dataRowCell3, recordName, recordId; 
                            records.forEach(function(record) { 
                                dataRow = tableBody.insertRow(); 
                                dataRowCell1 = dataRow.insertCell(0); 
                                recordName = document.createTextNode(record.get('Name')); 
                                dataRowCell1.appendChild(recordName); 
                                dataRowCell2 = dataRow.insertCell(1); 
                                recordId = document.createTextNode(record.get('Id')); 
                                dataRowCell2.appendChild(recordId); 
                                dataRowCell3 = dataRow.insertCell(2); 
                                lastMod = document.createTextNode(record.get('LastModifiedDate')); 
                                dataRowCell3.appendChild(lastMod); 
                            }); 
                            if (outputDiv.firstChild) { 
                                // replace table if it already exists 
                                // see later in tutorial 
                                outputDiv.replaceChild(dataTable, outputDiv.firstChild); 
                            } else { 
                                outputDiv.appendChild(dataTable); 
                            } 
                        } 
                    } ); 
                } 
                updateOutputDiv(); 
            })(); 
            var accountForm = document.getElementById('add-account-form'); 
            var accountNameField = document.getElementById('account-name'); 
            var createAccount = function() { 
                var account = new SObjectModel.Account(); 
                account.create({ Name: accountNameField.value }, 
                               function(error, records) { 
                                   if (error) { 
                                       alert(error.message); 
                                   } else { 
                                       updateOutputDiv(); 
                                       accountNameField.value = ''; 
                                   } 
                               }); 
            } 
            accountForm.addEventListener('submit', 
                                         function(e) { 
                                             e.preventDefault(); 
                                             createAccount(); 
                                         }
                                        );
            </script> 
            <!-- / JAVASCRIPT -->
        </body> 
    </html> 
</apex:page>

Hi. Working through the Visualforce Mobile module, and im haivng throuble with the 3rd unit. 

Im getting this issue:
"Challenge Not yet complete... here's what's wrong: 
The 'MobileContactList' Visualforce page does not appear be displaying the contact name or contact phone."


The code I am using is:

<apex:page showHeader="true" sidebar="true" standardController="Contact" recordSetVar="contacts">
	<head>
	<apex:slds />
	</head>


	<apex:repeat value="{!contacts}" var="c">
		<dl class="slds-list_horizontal slds-wrap">
			<dt class="slds-item_label slds-text-color_weak slds-truncate" title="Contact Name:">{!c.Name}</dt>
			<dd class="slds-item_detail slds-truncate" title="Mobile Phone Number:">{!c.MobilePhone}</dd>
		</dl>
	</apex:repeat>

</apex:page>
Which then displays this;

User-added image
Which looks like it works, as long as the Contacts list view is set to view all (otherwise nothing displays).

Is this just another case of the trailhead looking for a very specific solution? I can't seem to find much help on this one.

Thanks
User-added image
I have come up with a way to replace Classic related lists on a page layout, so you can get past some of the limitations of page layouts. I hope this post will be helpful to our global ohana.

Why would you want to do this?
Related Lists can only have up to 10 columns.  My customer has a related custom object with 14 fields that should be displayed on a single line:  Year, Jan ... Dec, and Year Total.  Each monthly value is a currency field, and multi-currency is on for the Org, meaning that the currency ISO code is displayed for each of these fields.  So we also want to display the values without the ISO code.

What did I do to get around this?
My solution includes two Visualforce (VF) pages and a controller extension.
  1. View page:  A page thatdisplays the fields in a table, as read-only. On this page is a single button, [Edit] to switch to Edit mode.
  2. Edit page: A page that displays the fields in a table, as editable fields. It has three buttons: [Add] [Save] [Cancel]
  3. Apex controller extension. I used an extension because it adds to the functionality of the standard controller, which could be helpful in more complex use cases.
In my example, I have a new custom object, Budget, related to Contact in a master/detail relationship. I declined to put the related list on the Contact page layouts because I added my own VF page to the layout details section.  If you want to duplicate my code exactly in your DevEd org, you'll need to create this object and relate it to Contact.

Apex Controller Extension (BudgetExt.apxc):
public with sharing class BudgetExt {
    
/*************************************************
 * Controller extension to provide functionality required for the Budgets
 * section of Contact detail page.  The business requirement was to allow
 * the Budgets related list on Contact to display 14 columns (year
 * + 12 months + total).  The end result is an embedded VF page component on the Contact
 * page layout that displays the Budget related rows in view mode 
 * (read only), with an edit button local to the component.  Clicking Edit 
 * switches the component to Edit Mode by changing the PageReference to
 * the related Edit mode VF page.  On that page are three buttons (Add Row, 
 * Save and Cancel) plus a Delete button on each row.  Hitting Save or Cancel
 * brings you back to the View mode page.
 * 
 * Related VF pages:
 * - BudgetEdit.vfp
 * - BudgetView.vfp
 * 
 * Author: Charles Thompson, Salesforce, Nov 2017
 * *************************************************/
    
    private final Id contactID; // store the parent (Contact) ID
    public Integer index {get;set;} // store the current row being deleted
    
    // List to represent each row of the pageBlockTable of Budgets 
    // related to the parent Sub Project
    public List<Budget__c> budgets {get; set;}

    // List to hold those rows being deleted
    public List<Budget__c> budgetsToDel = new List<Budget__c>();
    
    // Variable to hold the Sub Project (parent) record
    public Contact theContact {get; set;}
    
    // Initial load of the pageBlockTable
    public BudgetExt(ApexPages.StandardController stdController){
        contactID = stdController.getId();
        this.index = 0;
        theContact = [SELECT Id
                      FROM   Contact
                      WHERE  Id = :contactID
                      LIMIT 1
                     ];
        budgets =    [SELECT Id,
                             Year__c,
                               Jan__c, Feb__c, Mar__c, Apr__c,
                               May__c, Jun__c, Jul__c, Aug__c,
                              Sep__c, Oct__c, Nov__c, Dec__c,
                             Year_Total__c
                      FROM   Budget__c
                      WHERE  Contact__c = :contactID
               ORDER BY Year__c
              ];
    }
                              
    public String getIndex(){
        return String.valueOf(index);
    }
    
    public void setIndex(String indexIn){
        this.index = Integer.valueOf(indexIn);
    }
            
    // Add an empty budget row to the table 
    // (not saved to the database until saveBuds() is called)
    public void addRow(){
        Budget__c row = new Budget__c();
        row.Contact__c = contactID;
        budgets.add(row); 
    }
    
    // delete a forecast from the table (not saved to the db until later)
    public void delRow(){
        
        Integer i = this.index-1; // Rows start at one, Lists start at zero
        
        // If the row is an existing row then add it to the list 
        // to delete from the database
        if (budgets[i].Id != null){
            budgetsToDel.add(budgets[i]);
        }
        //Remove the forecast from the table    
        budgets.remove(i);
    }
    
    public PageReference saveBuds(){
        // update and insert forecasts as per the current list
        upsert budgets;
        
        // delete any rows in the list of deletions
        if ((budgetsToDel != null) && (budgetsToDel.size() > 0)){
            delete budgetsToDel;
        }
        
        return cancelEdit();
    }
    
    public PageReference editBuds(){
        // switch to Edit mode
        PageReference editPage = new PageReference('/apex/BudgetEdit?id=' + contactID);
        return editPage;
    }

    public PageReference cancelEdit(){
        // switch back to View mode without saving anything
        PageReference viewPage = new PageReference('/apex/BudgetView?id=' + contactID);
        viewPage.setRedirect(true);
        return viewPage;
    }   
}

View VF page (BudgetView.vfp):
<apex:page standardController="Contact" extensions="BudgetExt">
<!------------------------------------------------------------------------ 
    This page is designed to fit as a component on the detail page of 
    the Contact page layout.  This is the View Mode version of the page, 
    containing output fields and a button for Edit.
    
    Note that the currency ISO code doesn't appear and is assumed to be 
    carried through from the parent record.
     
    The related Edit Mode page is called "BudgetEdit".
     
    Author: Charles Thompson, Salesforce Singapore, Nov 2017 
--------------------------------------------------------------------------> 

    <apex:form >
        <apex:pageBlock mode="maindetail">

            <table width="100%">
                <tr>
                    <td style="text-align:center">
                        <!-- Button... Edit (switch to Edit Mode) -->
                        <apex:commandButton value="Edit" action="{!editBuds}" 
                                            id="editButton" />
                    </td>
                </tr>
            </table>
            
            <!-- Table displaying the Annual Forecast related records -->
            <apex:pageBlockTable value="{!budgets}" var="row" id="budgetTbl" >
            
                <apex:column headerValue="Year">
                    <apex:outputText id="Year" value="{!row.Year__c}" style="width:40px" />
                </apex:column>
 
                 <!-- Currency fields from Budget (formatted as number without currency) -->               
                <apex:column headerValue="Jan" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Jan" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Jan__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="Feb" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Feb" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Feb__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="Mar" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Mar" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Mar__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="Apr" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Apr" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Apr__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="May" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="May" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.May__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="Jun" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Jun" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Jun__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="Jul" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Jul" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Jul__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="Aug" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Aug" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Aug__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="Sep" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Sep" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Sep__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="Oct" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Oct" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Oct__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="Nov" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Nov" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Nov__c}"/>
                    </apex:outputText>
                </apex:column>
                <apex:column headerValue="Dec" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:outputText id="Dec" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Dec__c}"/>
                    </apex:outputText>
                </apex:column>
                
                <!-- Total (sum) for the year -->
                <apex:column headerValue="Total" style="text-align:right" 
                             headerClass="CurrencyElement" >
                    <apex:outputText id="yearTotal" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Year_Total__c}"/>
                    </apex:outputText>
               </apex:column>

            </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>

</apex:page>

Edit VF page (BudgetEdit.vfp):
<apex:page id="thepage" standardController="Contact" extensions="BudgetExt">
<!------------------------------------------------------------------------ 
    This page is designed to fit as a component on the detail page of 
    the Contact page layout.  This is the Edit Mode version of the page, 
    containing input fields and buttons for Add Row, Save, Cancel and Delete.
    
    Note that the currency ISO code doesn't appear and is assumed to be 
    carried through from the parent record.
     
    The related View Mode page is called "BudgetView".
     
    Author: Charles Thompson, Salesforce Singapore, Nov 2017 
--------------------------------------------------------------------------> 
    <apex:form>
        <apex:pageBlock mode="maindetail">

            <table width="100%">
                <tr>
                    <td style="text-align:center">
                        <!-- Buttons... Add Row / Save / Cancel -->
                        <apex:commandButton value="Add Row" action="{!addRow}" 
                                            id="addButton" />
                        <apex:commandButton value="Save" action="{!saveBuds}" 
                                            id="saveButton" />
                        <apex:commandButton value="Cancel" action="{!cancelEdit}" 
                                            id="cancelButton" />
                    </td>
                </tr>
            </table>
            
            <!-- Table displaying the related records -->
            <apex:pageBlockTable value="{!budgets}" var="row" id="budgets" >

                <!-- Counter variable to store an index value for each line -->
                <apex:variable var="i" value="{!0}" />
                <!-- Delete button -->
                <apex:column >
                    <apex:commandButton value="X" style="color: red" 
                                        action="{!delRow}" reRender="budgets"
                                        immediate="true" >
                        <!-- populate Apex index variable -->
                        <apex:param name="index" value="{!i}" assignTo="{!index}"/> 
                    </apex:commandButton>
                    <apex:variable var="i" value="{!i + 1}" />
                </apex:column>
                <apex:column headerValue="Year" 
                             title="Enter the forecast by month for this year and next year">
                    <apex:inputField value="{!row.Year__c}" style="width:60px"  />
                </apex:column>
 
                 <!-- Currency fields from Annual Forecast (the currency indicator doesn't appear) -->               
                <apex:column headerValue="Jan" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Jan__c}" 
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="Feb" style="text-align:right" 
                             headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Feb__c}" 
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="Mar" style="text-align:right"  
                                     headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Mar__c}"  
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="Apr" style="text-align:right"  
                                     headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Apr__c}"  
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="May" style="text-align:right"  
                                     headerClass="CurrencyElement">
                    <apex:inputField value="{!row.May__c}"  
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="Jun" style="text-align:right"  
                                     headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Jun__c}"  
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="Jul" style="text-align:right"  
                                     headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Jul__c}"  
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="Aug" style="text-align:right"  
                                     headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Aug__c}"  
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="Sep" style="text-align:right"  
                                     headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Sep__c}"  
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="Oct" style="text-align:right"  
                                     headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Oct__c}"  
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="Nov" style="text-align:right"  
                                     headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Nov__c}"  
                                     style="text-align:right; width:65px" />
                </apex:column>
                <apex:column headerValue="Dec" style="text-align:right"  
                                     headerClass="CurrencyElement">
                    <apex:inputField value="{!row.Dec__c}"  
                                     style="text-align:right; width:65px" />
               </apex:column>
                <!-- Total (sum) for the year -->
                <apex:column headerValue="Total" style="text-align:right" 
                             headerClass="CurrencyElement" >
                    <apex:outputText id="yearTotal" value="{0, number, ###,###,##0}" >
                        <apex:param value="{!row.Year_Total__c}"/>
                    </apex:outputText>
               </apex:column>

            </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>

</apex:page>

I hope this helps someone in the future, even if Lightning Experience makes this solution somewhat useless.
 
I've added all these line of code in the Save() method to try to satisfy the "Modify the save() function to implement CRUD/FLS check on the Name field of the Encrypt_Decrypt__c object." requirement but nothing seems to pass it's check.  Anyone else run into this or have any ideas?

        if (!Schema.sObjectType.EnCrypt_Decrypt__c.fields.Name.isCreateable()) { 
            return NULL; 
        }
        if (!Schema.sObjectType.EnCrypt_Decrypt__c.fields.Name.isUpdateable()) { 
            return NULL; 
        }        
        if (!Schema.sObjectType.EnCrypt_Decrypt__c.fields.Name.isAccessible()) { 
            return NULL; 
        }        

Thanks,
Deb
Did anyone have this issue with challenge 6.

Challenge Not yet complete... here's what's wrong: 
Didn't find a Lightning page named Key Sales Data. This page must include: 1. List of new Accounts this week, 2. Recent items showing an "Opportunity", "Lead" and "Contact", 3. Log A Call and New Opportunity actions. Don't use the CreateOppty custom Lightning component for this challenge.

My Key Sales Data Lightning page screenshots:
User-added image

User-added image
Hi,
I am having trouble with the Trailhead project Build a Community with Knowledge and Chat, specfically the Enable and Configure Lightning Knowledge. The badge says to create a Knowledge Record Type of 'FAQ'. I do not see anywhere, where you can create a Record Type for the Knowledge Object.

There are Knowledge Article types, which have the fields that are displayed in the example. But there is no way to create a Record Type for them.

I can create Record Types for the Linked Articles, which I did, but when I verify this step, the error message comes back and says:
Challenge Not yet complete... here's what's wrong: 
Could not find a Knowledge recordtype named 'FAQ'.

Am I doing this correctly or are there issues with this Trail due to Summer '17? It's a brand new badge, so it must be me.

Thanks!
Hello,

There is a LiveChat sample given in the developer guide and we reused the same set of code as a PreChat page. The code is as follows
 
<!-- This script takes the endpoint URL parameter passed from the deployment 
      page and makes it the action for the form -->
    <script type="text/javascript">
    (function() { 
        function handlePageLoad() {
            var endpointMatcher = new RegExp("[\\?\\&]endpoint=([^&#]*)");
            document.getElementById('prechatForm').setAttribute('action',
            decodeURIComponent(endpointMatcher.exec(document.location.search)[1]));
        }
        if (window.addEventListener) {
            window.addEventListener('load', handlePageLoad, false);
        } else {
            window.attachEvent('onload', handlePageLoad, false);
        }
    })(); 
    function setName() {
            document.getElementById("windowName").value =  
                document.getElementById("firstName").value;
                return true;
            }
    </script>

But the static code analyzer tool gives an error saying Possible Cross-site script (XSS) vulnerability when accessing location.search. How do I fix this issue? The endpoint parameter returned in the URL is already in encoded format and a sample value is
 ?endpoint=https%3A%2F%2F45r.la3-c2cs-chi.salesforceliveagent.com%2Fcontent%2Fs%2Fchat%3Flanguage%3Den_US%23deployment_id%3Dxxxx%26org_id%3Dyyyy%26button_id%3Dzzzz%26session_id%3Daaaaaaa

which is equivalent to 

?endpoint=https://45r.la3-c2cs-chi.salesforceliveagent.com/content/s/chat?language=en_US#deployment_id=xxxx&org_id=yyyy&button_id=zzzz&session_id=aaaaaaa

Can you please let me know how to fix this code?
I'm currently workng my way through Explore Custom Transaction Security Policies : Test the Apex for the Policy.
Perhaps at the time this module was written, the example code was valid.

However, presently: 
1. If I try to set the value of LoginHistory.platform, the Apex code is rejected with 
Error: Compile Error: Field is not writeable: LoginHistory.Platform at line 6 column 5

2. If I try to insert a LoginHistory record, the Apex code is rejected with
Error: Compile Error: DML operation INSERT not allowed on LoginHistory at line 7 column 5

I don't want to litter my production code with Test.isRunningTest().

While I could refactor the code to replace both the SOQL and the evaluation with injected dependency(s), such would leave the most critical portions of the class actually untested, which is likewise unsatisfactory.

Is it still possible to test the PolicyCondition?
Is there some trick I'm overlooking?





 
For whatever reason the Lightning app built during the above Trailhead project does not work when previewed.  I keep getting this error:

This page has an error. You might just need to refresh it. Error during init [Cannot read property 'apply' of undefined]

No issues with the project chanllenges, in fact I have completed the project trail.  Checked my code, exact same as given during the project steps.
Hi

How to generate a batch class that is generic that
 can accept all the sObjects and some criteria?
@AuraEnabled
public static List<Contact> getContacts() {
    return [Select Id, Name, Email, Title, Phone From Contact];
}
I'm receiving the following error: unexpected token: 'List'
 
I am unable to view the results on Preview.
The list of contacts is not  being diaplyed
I've completed the challenge, it has 100% coverage. I've checked all the method names. The URL is valid. I've used Work Bench and curl to test and even tested with multiple Accounts with and without contacts.

I know on other challenges, punctionation was important.  What about the defination of the return? Are there expected names?

I built a class to hold Account ID & Name along with a List of Contact names and IDs. Is this my issue?  Anyone else have a challenge with this challenge?


Any help or hints will be appreciated.

Here are snippets of my code:

@RestResource(urlMapping='/Accounts/*/contacts')
global with sharing class AccountManager {

....

global class APIAccount {
        public ID Id;
        public String Name;
        List<APIContact> Contacts;

...

@HttpGet
    global static APIAccount getAccount() {
        RestRequest request = RestContext.request;
...
 

 The use case is the generation of an invoice from a modified Opportunity. One of the required fields on the invoice is a custom field called “Fill Date/Time” which is of the a date datatype.

 

The issue is that the user enters a Fill Date/Time on the opportunity screen in Pacific Time (eg: 9/30/2011 2:44PM), however when the invoice is generated, the Time appears as GMT (eg: 9/30/2011, 21:44:00 GMT).

 

The invoice is generated as a PDF via a Visualforce page – I have copied the relevant code below:

 

<tr>

    <td></td>

        <td width="70%">Fill Date/Time:

               <apex:outputText value="{0,date,MM'/'dd'/'yyyy, HH:mm:ss z}">

                <apex:param value="{!Opportunity.Fill_Date_Time__c}"/>

        </apex:outputText> </td>   

</tr>

<tr>

<td></td>

 

 

I'm new to coding and have referenced the pages below but still don't understand how to fix this. Do I need to save the Opportunity.Fill_Date_Time to some new variable and then format that? Thanks for your help!

 

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_datetime.htm

http://www.salesforce.com/us/developer/docs/pages/Content/pages_compref_outputText.htm

Hello,

 

I found a previous post referencing this but cannot seem to get it to work in my org.  I am already using an Extension on this page to reference users information from names in a picklist.  I have tried to put two extensions, such as extensions="ProjectConfirmationEXT,timeZone" but get the following error,  "Error: Unknown constructor 'timeZone.timeZone(ApexPages.StandardController controller)'"

 

Can someone help me figure out what I am doing wrong?

 

VisualForce page

 

<apex:page standardController="Job__c" extensions="ProjectConfirmationEXT" showHeader="false" renderAs="pdf">

<apex:dataTable style="font-family: Calibri, sans-serif;" id="EventTable" value="{!Job__c.Events}" var="e" width="100%" rowClasses="odd,even" styleClass="tableClass" cellpadding="4" border="1">     
        
        <apex:column headerValue="Date">
            <apex:outputField value="{0,date,MM/dd/yyyy}">
                <apex:param value="{!e.StartDateTime}" />
            </apex:outputField>
        </apex:column>
        <apex:column headerValue="Start Time">
            <apex:outputText value="{0,time,HH:MM}">
                <apex:param value="{!e.StartDateTime}" />
            </apex:outputText>
        </apex:column>
        <apex:column headerValue="End Time">
            <apex:outputText value="{0,time,HH:MM}">
                <apex:param value="{!e.EndDateTime}" />
            </apex:outputText>
        </apex:column>
        
    </apex:dataTable>

 

timeZone EXT

 

public class timeZone {
        public String dateTimeValue { get; set; }
        public timeZone() {
            dateTimeValue = System.Now().format('MM/dd/yy HH:mm a', 'PST');//GMT
        }
}

 

 

 

 

 

Hi all,

 

I have a question is it possible to show visualforce page on the page layout when I hit edit button ? My case is I want to show the visualforce page and standar page layout at the same time on page layout in edit mode. Is is possible to do that? Or maybe there is other suggestions for may case would be great.

 

Thanks

 

Regards,

 

Edwin

We've been struggling with getting a zipped static resource to work for weeks now. We got Salesforce Support involved from the beginning, but they've gotten us nowhere. If we can't get a resolution to this issue soon, we might just find a platform that wastes less of our time...

 

Here is the situation - we are trying to upload a portion of the YUI library as a static resource, but no matter what we try, we can't get the files to render in our VisualForce pages. Salesforce Support can get it to work (sometimes), but we can't. The difference seems to be around the MIME Type that is set when the file is uploaded. When we upload the file, it gets set to a MIME Type of 'application/zip', but when SFDC Support uploads the file, it gets set to a MIME Type of 'application/x-zip-compressed' or 'application/octet-stream'. Salesforce can't explain to us exactly why or how these different MIME Types get set. They're looking into why our uploads don't work, but I'm not expecting much from them at this point.

 

To reproduce our steps:

 

Download the file from here after clicking the radio button labeled "Full developer kit":

Steps:
  1. Download "Full developer kit"
  2. Open zip and remov the documentation and examples folders (to reduce size)
  3. Change file name from "yui_3.0.0.zip" to "yui.zip"
  4. Upload as a static resource named "testyui"
  5. In component "header" (where all other JS files are included) add:
    • <apex:includeScript value="{!URLFOR($Resource.testyui, 'yui/build/yui/yui-min.js')}" />
  6. If we refresh the page we get a 404 error for this resource.
 
If anyone has experienced a similar issue, any help you could provide would be greatly appreciated.