2

<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.)

2 Answers 2

4

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.

1
  • Hi Mike, instead of using a "contact.Id" and struggling with the problem of ID collisions, make use of the globalId. You can add this to your template code, e.g. <input ... id="{#globalId+'_input'}" ... Reference the same ID in the "for" attribute of the label. The globalId is automatically generated at runtime. Jan 4, 2022 at 8:05
0

I have got the same problem, I need to set the "for" property for a checkbox dynamically generated. Any lucky?

Ok, I found a solution. Simply, when I create my new component, I retrieve the global ID and I write it to an attribute in my component. So, I can use it in the page!

component:

<aura:attribute name="globalId" type="String" access="private"/>
<label class="slds-checkbox__label" for="{!v.globalId}">

in the controller:

    $A.createComponents(
        newComponentList,
        function(createdNewComponentList,status, errorMessage){
            if (status === "SUCCESS") {

                var divComponent = component.find("placeholderItem");
                var divBody = divComponent.get("v.body");

                for(var i in createdNewComponentList){
                    //HERE IT IS THE MAGIC!
                    component.set('v.globalId', createdNewComponentList[i].getGlobalId()); 
                    divBody.unshift(createdNewComponentList[i]);
                }

                divComponent.set("v.body", divBody);
            }

            else if (status === "INCOMPLETE") {
                console.log("No response from server or client is offline.")
                // Show offline error
            }
            else if (status === "ERROR") {
                console.log("Error: " + JSON.stringify(errorMessage));
                // Show error message
            }
        }
    );

You must log in to answer this question.

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