3

I'm currently trying to refactor the Discover Lightning Actions source code into something which wouldn't make my eyes bleed on a professional project.

Most especially, I wish to reduce all the redundant presentation code in CreateUser.cmp.

My present version of CreateUser.cmp looks like this:

<aura:component implements="force:lightningQuickActionWithoutHeader,force:hasRecordId" controller="LTNG_CaseStudyAuraCtrl">
<!-- Public attributes -->
<aura:attribute name="testUser" type="Test_User__c" default="{sobjectType: 'Test_User__c'}" access="global"/>
<aura:attribute name="hasErrors" type="Boolean" description="Indicate whether there were failures or not" />
<aura:attribute name="caseStudyName" type="String" />
<aura:attribute name="recordId" type="String" description="Case Study id"/>

<!-- "Private" attributes, for binding with input componets -->
<aura:attribute name="firstName" type="String" />
<aura:attribute name="lastName" type="String" />
<aura:attribute name="nickName" type="String" />
<aura:attribute name="email" type="String" />

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

<div class="slds-page-header" role="banner">
    <p class="slds-text-heading--label">Case Study</p>
    <h1 class="slds-page-header__title slds-m-right-small slds-truncate slds-align-left" title="Case Study Title">{!v.caseStudyName}</h1>
</div>
<br/>

<aura:if isTrue="{!v.hasErrors}">
    <div class="userCreateError">
        <ui:message title="Error" severity="error" closable="true">
            Please review the error messages.
        </ui:message>
    </div> 
</aura:if>

<div class="slds-form--stacked">
    <c:LTNG_SldsInput label="first name" fieldName="firstName" value="{!v.testUser.firstName}" required="true" updateForm="{!c.updateNickname}" />
    <c:LTNG_SldsInput label="last name" fieldName="lastName" value="{!v.testUser.lastName}" required="true" />
    <c:LTNG_SldsInput label="nickname" fieldName="nickName" value="{!v.testUser.Nickname__c}" />
    <c:LTNG_SldsInput label="user's email" fieldName="email" value="{!v.testUser.Email__c}" required="true" />
    <c:LTNG_SldsInput label="user's password" fieldName="password" value="{!v.testUser.Password__c}" required="true" secret="true" />

    <div class="slds-form-element">
        <ui:button class="slds-button slds-button--neutral" press="{!c.cancel}" label="Cancel" />
        <c:LTNG_SaveTestUserButton testUser="{!v.testUser}" />
    </div>
</div>

The component I've called "LTNG_SldsInput" (which I'll probably rename later) currently looks like this:

<aura:component >
<aura:attribute name="label" type="String" />
<aura:attribute name="fieldName" type="String" />
<aura:attribute name="value" type="String" />
<aura:attribute name="required" type="Boolean" default="false" />
<aura:attribute name="secret" type="Boolean" default="false" />

<aura:registerEvent name="updateForm" type="c:LTNG_TestUserUpdateEvent" />

<aura:handler event="c:LTNG_TestUserInputErrorsEvent" action="{!c.handleInputErrors}"  />

<div class="slds-form-element">
    <label class="slds-form-element__label" for="{!v.fieldName}">Enter {!v.label}:</label>
    <div class="slds-form-element__control">
        <aura:if isTrue="{!v.secret}">
            <ui:inputSecret class="slds-input" aura:id="{!v.fieldName}" value="{!v.value}" required="{!v.required}" change="{!c.onChange}" /> 
            <aura:set attribute="else">
                <ui:inputText class="slds-input" aura:id="{!v.fieldName}" value="{!v.value}" required="{!v.required}" change="{!c.onChange}" /> 
            </aura:set>
        </aura:if>
    </div>
</div>

Presently, I am working on reimplementing the error handling and this latter component has a handler which looks like this:

    handleInputErrors: function(component, event, helper) {
    var eventFieldName = event.getParam('fieldName');
    var componentFieldName = component.get('v.fieldName');

    if (eventFieldName === componentFieldName) {
        var component = component.find(componentFieldName)
        component.set('v.errors', [{message: event.getParam('errorMessage')}]);
    }
},

As the code stands above, this presently does not work. But, if replace the instances of aura:id="{!v.fieldName}" with "password" and "email" respectively, this will work.

Hard coding the values is not an acceptable solution (if it isn't obvious, imagine one of the other text fields also needed validation, or there were some other reason to reference the element by id).

Am I doing something wrong? Is this a known bug in Lightning/Aura? Are there any workarounds?

  • I think there are other posts confirming aura:id does not take dynamic ids..Either you should go with plain html elements and use slds styling or create a custom component and pass custom attributes. – javanoob Mar 4 '17 at 21:26
  • @javanoob, I'd really rather not reinvent the wheel if it can be avoided. The ui:input fields, if nothing else, give me nice error handling and consistency with standard Lightning development practices. – Brian Kessler Mar 4 '17 at 22:50
  • 1
    When I need to to dynamic Ids I switch from using the Id as a selector to using a class name that I set instead. Another way of doing it is adding a data- attribute set to the value you want and use that as a selector – Eric Mar 5 '17 at 20:54
2

Lightning aura:id attribute will not allow any dynamic/run time evaluated values, it just allows literal string.

Alternate to this is include standard id attribute of html and access these in controller.js as below.

var selectedItem = event.currentTarget;
 var dynamicallyGenId = electedItem.id;

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.