2

My aim is to have a radio checkbox field, my current below implementation worked properly when locker service was disabled. But when locker service is enabled this is not working. Please help me.

<aura:component >
    <ltng:require styles="/resource/slds0122/assets/styles/salesforce-lightning-design-system.min.css" />

    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />

    <aura:attribute name="exampleList" type="String[]"/>
    <aura:attribute name="previousIndex" type="Integer" default="-1"/>

    <table class="slds-table slds-table--bordered slds-table--cell-buffer">
        <tbody>
            <aura:iteration items="{!v.exampleList}" var="item">
                <tr class="slds-hint-parent">
                    <td>
                        <ui:inputRadio change="{!c.radioSelect}" class="radio" />
                    </td>
                    <th>
                        {!item}
                    </th>
                </tr>
            </aura:iteration>
        </tbody>
    </table>
</aura:component>

Controller:

({
    doInit : function(component) {
        var items = [];
        for(var i=0;i<7;i++){
            var item = "Item_"+i;
            items.push(item);
        }
        component.set("v.exampleList",items);
    },

    radioSelect : function(component) {
        var index = component.get("v.previousIndex");
        var elements = document.getElementsByClassName("radio");
        if (index != "-1") {
            elements[index].checked = false;
        }
        for ( var i = 0; i < elements.length; i++) {
            if (elements[i].checked)
                index = i;
        }
        component.set("v.previousIndex", index);
    }
})

When locker service is enabled, document.getElementsByClassName is returning null and the elements length is 0. How to implement this with Locker service enabled. Thank you.

2 Answers 2

2

I will try to reproduce the issue, but there is a different and probably better way to solve your problem.

First, something like document.getElementsByClassName("radio") can become an issue on a multitenancy platform like Lightning. Your component can be on a page where other developers are also using the "radio" class name to tag their elements in order to apply CSS or retrieve them with JavaScript.

Even if you are developing a standalone application, you might want to develop components or at the very least development practices that are suited for such a scenario.

And even if you had a unique name, you probably want to be sure that two instances of the same component will not interfere with each other.

The solution I am proposing does respect encapsulation, and will only return components that exist within your lexical scope (between you opening and closing <aura:component> or <aura:application> tag).

Instead of using this pair:

<ui:inputRadio change="{!c.radioSelect}" class="radio" />

var elements = document.getElementsByClassName("radio");

You can use aura:id:

<ui:inputRadio change="{!c.radioSelect}" aura:id="radio" />

var radioComponents = component.find("radio");

You then interact with the component instead of going to the underlying DOM API by using:

componentList[index].set("v.checked", false);

And

if (componentList[i].get("v.checked"))
            index = i;

Or something along those lines!

2
  • Thank you for your support @Paradis, the information you mentioned about document.getElementsByClassName will be an useful input to me. I have found a more easy solution, please look into my comment. Thank you again. Commented Aug 6, 2016 at 8:19
  • Perfect. It's a cleaner to stay away from the DOM most cases.
    – JF Paradis
    Commented Aug 8, 2016 at 22:16
1

I found the solution, below is the code.

<aura:component >
    <ltng:require styles="/resource/slds0122/assets/styles/salesforce-lightning-design-system.min.css" />

    <aura:attribute name="exampleList" type="String[]" default="item_0,item_1,item_2,item_3,item_4"/>

    <table class="slds-table slds-table--bordered slds-table--cell-buffer">
        <tbody>
            <aura:iteration items="{!v.exampleList}" var="item" indexVar="index">
                <tr class="slds-hint-parent">
                    <td>
                        <ui:inputRadio name="radioElements" text="{!index}" label="{!item}" change="{!c.radioSelect}"/>
                    </td>
                </tr>
            </aura:iteration>
        </tbody>
    </table>
</aura:component>

Controller:

({
    radioSelect : function(cmp, evt) {
        var elem = evt.getSource();
        console.log(elem.get("v.text"));  //To get the index of List
        console.log(elem.get("v.label")); //TO get the label of List
    },
})

I have used aura:iteration attribute indexVar in text attribute of inputRadio to get the index of the selected Item. Thank you!

You must log in to answer this question.

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