[SalesForce] Getting id of ui:inputCheckbox to set for attribute on label

<ui:inputCheckbox/> always generates the label to the left of the checkbox in the markup, like so:

<ui:inputCheckbox aura:id="reimbursed" label="Reimbursed?" class="slds-checkbox" labelClass="slds-form-element__label" value="{!v.newExpense.Reimbursed__c}" />

becomes

<div class="uiInput uiInputCheckbox uiInput--default uiInput--checkbox">
  <label class="slds-form-element__label uiLabel-left form-element__label uiLabel" for="427:2;a">
    <span class="">Reimbursed?</span>
  </label><input class="slds-checkbox" type="checkbox" id="427:2;a">
</div>

In order to get the pretty checkboxes in SLDS, the checkbox needs to be inside the <label/> tag, with an additional faux span to do the CSS rendering, like so:

<label class="slds-checkbox" for="checkboxSample1">
  <input name="checkbox" type="checkbox" id="checkboxSample1" />
  <span class="slds-checkbox--faux"></span>
  <span class="slds-form-element__label">Checkbox Label</span>
</label>

In order to achieve this, I need to be able to set the for attribute on the label to the same value as the aura-generated id attribute on the checkbox. So I'm trying something like this:

<aura:component implements="force:appHostable" controller="CheckboxTestController">
  <aura:attribute name="contacts" type="Contact[]" />
  <aura:attribute name="checkedContacts" type="String[]" />
  <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
  <div class="slds-form--stacked">
    <fieldset class="slds-form-element">
      <span class="slds-form-element__label slds-form-element__label-top">
        <legend>Choose contacts to add:</legend>
      </span>
      <div class="slds-form-element__control">
        <aura:iteration var="con" items="{!v.contacts}">
          <label for="?????" class="slds-checkbox">
            <ui:inputCheckbox class="" text="{!con.Id}" aura:id="{!con.Id}" change="{!c.updateCheckboxes}"/>
            <span class="slds-checkbox--faux"></span>
            <span class="slds-form-element__label">{!con.Name}</span>
          </label>
        </aura:iteration>
      </div>
    </fieldset>
  </div>
</aura:component>

The problem I'm having is figuring out how to populate the for on the label. I'm pretty sure setting {!con.Id} as the aura:id on the checkbox isn't working (when I tried a cmp.find('anId') it came back undefined), and I believe this is because only string literals can be used for the aura:id attribute. And I can't figure out how to get the resulting id for the for attribute in the label.

(This is similar to ui:inputCheckbox and lightning design system, but the accepted answer on that question doesn't actually resolve anything – simply removing the app.css stylesheet doesn't make <ui:inputCheckbox/> reorder the markup.)

Best Answer

It looks like http://documentation.auraframework.org/auradocs#reference?descriptor=ui:inputCheckbox&defType=component , has an attribute called "domId" which sounds like what we want, unfortunately when trying to use it I get [ERROR]: No ATTRIBUTE named domId found: Source .

However, this attribute is not listed in the ui:inputCheckbox docs located at /auradocs . I guess because it hasn't made it over quite yet.

I'm not sure what ui:inputCheckbox really buys us in this situation, as we aren't using the div and label wrappers the component generates (it only seems to do that when we specify a label attribute, which we don't want to do since we want the slds classes and layout).

Something like this seems to work for right now:

<label for="{!contact.Id}" class="slds-checkbox"> <input type="checkbox" id="{!contact.Id}" onchange="{!c.checkboxChange}"/> <span class="slds-checkbox--faux"></span> <span class="slds-form-element__label">{!contact.Name}</span> </label>

({checkboxChange: function(component, event, helper){ console.log(event.target.id); })

Problems with this approach:

1) There can be id collisions. A temporary workaround could be adding a namespace to the id.

2) There could also be more built into the ui:inputCheckbox change event than the html5 change event, but the html5 change event seems pretty robust: https://developer.mozilla.org/en-US/docs/Web/Events/change .

Long term, I bet this is problem could be solved by the domId attribute.

Related Topic