0

I have an Aura component with an aura:iteration that each iteration generates a lightning:formattedNumber, a hidden lightning:input (both for the same field), and a lightning:buttonIcon that calls a controller method that hides the first and shows the second one.

I want to show and focus the lightning:input after I click the button, but I'm not able to use the .focus() method, because I can't get the component with .find(), since It seems I can't dynamically set aura:id.

Also, I tried to use a parent span with an id to access the input tag generated by the lightning:input with something like document.querySelector('#myDynamicIdValue input'), but it returns only null.

How could I focus this input?

enter image description here




Update: The solution I ended up, based on the answers and some specific needs, was to set a generic value in the aura:Id and unique value in the name of the lightning:input (mixing the name field + item Id, that's because I also have multiple inputs in each iteration, and each block generated by the loop can be sorted, so in this case numeric indexes might not be the best fit), and set the same unique value in some attribute where the event starts, then in the event handler I can filter the input list by this unique value:

markup:

<aura:iteration items="{!v.items}" var="item">
    <label class="slds-form-element__label slds-p-around_none">Quantity</label>
    <span class="slds-grid slds-grid_align-spread ps-itemInlineOutput" id="{! 'itemQuantity' + item.Id}" ondblclick="{!c.onShowInlineEdit}">
        <lightning:formattedNumber value="{!item.Quantity}" />
        <lightning:buttonIcon iconName="utility:edit" variant="bare" class="slds-m-left_x-small" name="{! 'itemQuantity' + item.Id}" onclick="{!c.onShowInlineEdit}" />
    </span>
    <span class="slds-grid slds-grid_align-spread ps-itemInlineInput slds-hide" id="{! 'itemQuantity' + item.Id}" onkeyup="{!c.onHideInlineEdit}">
        <lightning:input type="number" variant="label-hidden" value="{!item.Quantity}" aura:id="itemInput" name="{! 'itemQuantity' + item.Id}" onblur="{!c.onHideInlineEdit}" />
    </span>
</aura:iteration>

controller:

onShowInlineEdit: function (component, event, helper) {
    var itemId = event.currentTarget.id != null ? event.currentTarget.id : event.getSource().get('v.name');
    document.querySelector("#" + itemId + ".ps-itemInlineOutput").classList.add('slds-hide');
    document.querySelector("#" + itemId + ".ps-itemInlineInput").classList.remove('slds-hide');
    component.find('itemInput').find(itemInput => itemInput.get('v.name')==itemId).focus();
},

result:

enter image description here

Thanks!

0

You can attach an iteration value to each row, then use that to figure out which input to focus.

<aura:iteration items="{!v.items}" var="item" indexVar="index">
  <div class="..." data-index="{!index}">
    ...
    <lightning:input aura:id="itemInput" ... />

Then, for your click handler:

onShowInlineEdit: function(component, event, helper) {
  let index = parseInt(event.target.closest("[data-index]").dataset.index);
  let inputs = component.find("itemInput");
  inputs[index].focus();
}

This is essentially a version of my own problem that I had.

1
  • I used this idea of getting the list of inputs, but modified a little bit to filter by a string Id. Thank you! Mar 10 at 10:56
0

One option is to create a component to contain the markup inside of aura:iteration.

This way there will be only one instance of lightning:input per inner component, thus the aura:id won't need to be dynamic and you can use component.find() to locate the lightning:input.

1
  • Thank you for the answer! That's seems a clean solution. As this UI grows, I'll eventually ending doing this, to organize better the things. Mar 10 at 11:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.