[SalesForce] Lightning – Select All Checkboxes

Right now I'm trying to do something that requires having a checkbox that allows selecting all checkboxes in a list for some other functionality later. The problem is that I'm not quite sure how to make select all work. I thought I would be able to do so through the controller, but then to use component.find, I might need to set aura:id on all the checkboxes and know them in advance. The problem is that I might not know the id in advance.

The second option I considered was possibly having an boolean attribute and possibly update all checkboxes by setting their value to the boolean attribute (false by default). Doing the update either via controller, helper or maybe event. Unsure of the correct approach in doing a select all with a "master" checkbox in Lightning.

<label class="slds-checkbox" 
       for="select-all" 
       onclick="{!c.doSelectAllContacts}">
    <input name="checkbox" type="checkbox" id="select-all" />
    <span class="slds-checkbox--faux"></span>
    <span class="slds-form-element__label slds-assistive-text">select all</span>
</label>
<button onclick="{!c.myArbitaryActionWithAllContactsSelected}">Action</button> 

<aura:iteration var="con" items="{!v.contacts}">
    <tr>
        <td class="slds-row-select">
            <label class="slds-checkbox" for="{!'select-row-' + index}">
            <input name="{!'select-row-' + index}" type="checkbox" id="{!'select-row-' + index}"/>
            <span class="slds-checkbox--faux"></span>
            <span class="slds-form-element__label slds-assistive-text">select row {!index}</span>
            </label>
        </td>
        <td>{!con.Name}</td>
    </tr>
</aura:iteration>

Best Answer

You could also consider having the checkboxes in a second component that subscribes to an application event that you fire when you push the master button.

<aura:application >
    <ui:button label="CheckAllBoxes" press="{!c.fireCheckAllCheckboxes}" />
    <!-- iteration -->
        <analysis:ComponentWithCheckbox />
    <!-- /iteration -->
</aura:application>

controller

({
    fireCheckAllCheckboxes : function(component, event, helper) {
        var appevent = $A.get("e.analysis:CheckAllCheckboxes");
        appevent.fire();
    }
})

CheckAllCheckboxes event

<aura:event type="APPLICATION" description="CheckAllCheckboxes" />

ComponentWithCheckbox

<aura:component >
    <aura:handler event="analysis:CheckAllCheckboxes" action="{!c.checkTheBox}" />
    <ui:inputCheckbox aura:id="TheCheckBox" label="Checkbox" />
</aura:component>

ComponentWithCheckboxController

({
    checkTheBox : function(component, event, helper) {
        var TheCheckBox = component.find("TheCheckBox");
        TheCheckBox.set("v.value",true);
    }
})

Also, if the checkboxes all have the same aura:id, calling find() on the component will return an array with all of those components. If that works for you, you could do something like this:

<aura:application >
    <aura:attribute name="numbers" type="Integer[]" default="[0,1,2,3,4,5,6,7]" />

    <ui:button label="CheckAllBoxes" press="{!c.checkAllCheckboxes}" />

    <aura:iteration items="{!v.numbers}" var="number">
        <ui:inputCheckbox label="{!number}" aura:id="DependentCheckbox" />
    </aura:iteration>

</aura:application>

Controller

({
    checkAllCheckboxes : function(component, event, helper) {
        var checkboxes = component.find("DependentCheckbox");
        for (var i = 0; i < checkboxes.length; i++){
            checkboxes[i].set("v.value",true);
        }
    }
})