2

Im working in a Salesforce Community, using the Napili template. Im creating a vertical menu similar to:

enter image description here

Im trying to use slds tabs. I know I need to add the javascript to get the styling updates to work, when I change tabs. But out of all of the examples, I havent seen a simple enough one that makes sense to me.

I have jQuery loaded with ltng:require. It seems jQuery addClass/removeClass is the way to go. But I cant tell if I should use Renderer, or just put the jQuery in my js file?

I feel this should be very simple, but not having used jquery much before, and being new to Lightning components, Ive kinda hit a block.

The examples Ive seen seem convoluted and geared toward VF/Apex, and I want to do it the right way for LComponents. (renderer?) I feel it shouldn't be many lines of code, but may be underestimating the process. I would appreciate some direction if someone has the time.


<div class="slds-grid slds-grid--vertical slds-navigation-list--vertical">
    <ul aura:id="libList">
        <aura:iteration items="{!v.libraries}" var="lib"  indexVar="index">
            <li class="{!index == 0 ? 'fileSource_item  slds-is-active' : 'fileSource_item'}">
                <a class="slds-navigation-list--vertical__action slds-text-link--reset slds-truncate" href="javascript:void(0);" >
                {!lib.Name} </a>
            </li>
        </aura:iteration>    
    </ul>
</div>


For reference, if anyone views this later >> Added my Helper that gets the data for Libraries. I added the '//New Line' to set the first records 'Selected' attribute to true.

    getLibrariesForGrid: function(component, event, helper) {

    var action = component.get("c.getSafeLibraries");
    action.setCallback(this, function(data) {
        component.set("v.libraries", data.getReturnValue());

        //New Line below to set 'selected'
        component.set("v.libraries[0].selected", true);
    });
    $A.enqueueAction(action);
}
5

You don't need jQuery for such a simple task. Here's an example I wrote up for you just tweaking your code a bit. You can copy-paste this directly into an application to test it yourself.

application

<aura:application extends="force:slds">
    <aura:attribute name="libraries" 
                    type="Object[]"
                    default="[{'Name':'Value 1','selected':true},{'Name':'Value 2','selected':false},{'Name':'Value 3','selected':false}]" />
    <div class="slds-grid slds-grid--vertical slds-navigation-list--vertical">
        <ul aura:id="libList">
            <aura:iteration items="{!v.libraries}" var="lib" indexVar="index">
                <li class="{!lib.selected ? 'slds-is-active' : ''}">
                    <a class="slds-navigation-list--vertical__action slds-text-link--reset slds-truncate" data-index="{!index}" aura:id="menuItem" onclick="{!c.setIndex}" >
                        {!lib.Name}
                    </a>
                </li>
            </aura:iteration>    
        </ul>
    </div>
</aura:application>

controller

({
    setIndex: function(component, event, helper) {
        var items = component.get("v.libraries");
        items.forEach(
            function(v, i) {
                v.selected = event.target.dataset.index == i;
            }
        );
        component.set("v.libraries", items);
    }
})

Alternative construction:

application

<aura:application extends="force:slds">
    <aura:attribute name="selected" type="Integer" default="0" />
    <aura:attribute name="libraries" 
                    type="Object[]"
                    default="[{'Name':'Value 1'},{'Name':'Value 2'},{'Name':'Value 3'}]" />
    <div class="slds-grid slds-grid--vertical slds-navigation-list--vertical">
        <ul aura:id="libList">
            <aura:iteration items="{!v.libraries}" var="lib" indexVar="index">
                <li class="{!index == v.selected ? 'slds-is-active' : ''}">
                    <a class="slds-navigation-list--vertical__action slds-text-link--reset slds-truncate" 
                       aura:id="menuItem" onclick="{!c.setIndex}" 
                       data-index="{!index}">
                        {!lib.Name}
                    </a>
                </li>
            </aura:iteration>    
        </ul>
    </div>
</aura:application>

controller

({
    setIndex: function(component, event, helper) {
        component.set("v.selected", parseInt(event.target.dataset.index));
    }
})
  • Thank you sir. Any insight why other examples I come across are using jQuery? Just familiarity for them? --- Also, for anyone else that comes along, I needed to set the 'Selected' attribute to get this to work. I inlcuded this updated Helper code. Change the 'class=' logic in the cmp to match the example sfdcfox gave – ATA1k Mar 4 '17 at 19:32
  • 2
    @ATA1k People don't yet understand Lightning, so they're leaning on jQuery to do all the things they think are too complicated to do in Lightning. With a few exceptions, Lightning is particularly capable all on its own, and doesn't generally need Angular or jQuery. I think as more people learn Lightning, you'll see fewer examples of jQuery in Lightning. It's simply not necessary for most cases. – sfdcfox Mar 4 '17 at 19:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.