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);
}

1 Answer 1

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));
    }
})
2
  • 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, 2017 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, 2017 at 19:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .