I have worked on simple things with lightning components I am trying to make things more complex but with lockerservices I see that everything is more difficult because I can not access the DOM

For example in angular 2 create a dynamic form based on fieldset in one day I want to migrate it to lightning but I see that it is complicated I already have part of the code

The problem is that with lightning: input I can not access the value of the fields and try in different ways but I can not access it.

Example 1 aura:id

<aura: attribute name = "obj" type = "sobject" />
var val = "{! v.obj." + fi.name + "}";

["lightning:input", {"label": fi.label, "name": fi.name, "aura: id": val}]

When using expression the form is generated but something strange happens the input can not be edited and is blocked.

EXAMPLE 2 try to use class

var val = "fi.name";
arrayForm.push (["lightning:input", {"label": fi.label, "name": fi.name, "class": val}]);

lightning:input does not support add class I don't see in the DOM

EXAMPLE 3 getElementsByName

use document.getElementsByName ("City__c") to get the value. I get this error "Illegal invocation at NodeList.remoteFunction"

If I do it with UI or normal input text it works but it does not make sense because I have to add all the HTML and the SLDS.


    getFieldSetHelper : function(component) {
    var action = component.get("c.getFieldSetApex");
    var objectName=component.get("v.objectName");
    var fieldSetName=component.get("v.fieldSetName");
    var spinner = component.find("mySpinner");
    $A.util.toggleClass(spinner, "slds-hide");
    action.setParams({ "objectName" : objectName,"fieldSetName":fieldSetName });
    action.setCallback(this, function(response) {
        var state = response.getState();
        if (component.isValid() && state === "SUCCESS") {
            var retValues=response.getReturnValue();
            component.set("v.fieldsLst", retValues.fields);
        $A.util.toggleClass(spinner, "slds-hide");
close: function(component) {
save: function(component) {
    //var data = document.getElementsByName("City__c");
    //var data = document.querySelector("City__c");
    //var data = component.find("City__c");
    //var data = component.get("v.obj");
doInit : function(component) {
    var fieldsLst=component.get("v.fieldsLst");
    var obj=component.get("v.obj");
    var arrayForm=[];
    var objectName=component.get("v.objectName");
    for(var fi of fieldsLst){
        var val="{!v.obj."+fi.name+"}";
        var idy=objectName+"_"+fi.name;

    //Here I try in different ways

                        function(components, status, errorMessage){
                            if (status === "SUCCESS") {
                                var body = component.get("v.body");
                                component.set("v.body", components);
                                component.set("v.obj", components);
                            else if (status === "INCOMPLETE") {
                                console.log("No response from server or client is offline.")
                                else if (status === "ERROR") {
                                    console.log("Error: " + errorMessage);



<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" controller="FieldSetToForm">
<aura:handler name="init" value="{!this}" action="{!c.getFieldSetInit}" />
<aura:attribute name="objectName" type="string" default="Account"/>
<aura:attribute name="fieldSetName" type="string" default="accountFS"/>
<aura:attribute name="fieldsLst" type="FieldSetToForm.Inputx[]"/>

<aura:attribute name="obj" type="sobject"/>

<lightning:button variant="brand" label="Close" iconName="utility:download" iconPosition="left" onclick="{!c.close}" />
 <lightning:button variant="brand" label="Save" iconName="utility:download" iconPosition="left" onclick="{!c.save}" />

<input type="hidden" name="valuesData" value="" id="valuesData"/>

<div class="holder">
    <lightning:spinner variant="brand" size="large" aura:id="mySpinner" alternativeText="..."/>


getFieldSetInit : function(component, event, helper) {
close : function(component, event, helper) {
save : function(component, event, helper) {

I Love Angular

I feel that lightning is not mature but I want to use it ...

  • Lightning is mature, you're simply trying to apply Angular directly to Lightning, which is not how it works. You need to follow the rules, or you'll not get very far.
    – sfdcfox
    Commented Sep 1, 2017 at 3:36

1 Answer 1


In order to bind to something dynamically, you need a reference. Here is a very basic, no-frills, slightly buggy implementation that demonstrates that this basically works.

Notice how I use component.getReference to dynamically link to a field. Also notice how I can bind to the same field twice, which literally lets me modify the same field more than once in real-time, just to prove that they are real references.

With a little more error checking and fact-gathering, this could indeed be a dynamic form with some basic describe data, etc. Notice how I do not use aura:id at all. I simply bound all the fields to a common object, and I could get and retrieve the values at will (in this case, demonstrated through Object.keys). I could also bind this object to, say, a force:recordData to dynamically save the data back to the server, or send it through a server action in Apex.

<aura:application extends="force:slds">
    <aura:attribute name="accountRecord" type="Account" default="{ 'sobjectType': 'Account' }" />
    <aura:attribute name="edits" type="Aura.Component[]" />
    <aura:attribute name="fieldName" type="String" />
    <aura:attribute name="output" type="String" />

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


    <hr />


    <ui:inputText value="{!v.fieldName}" />
    <ui:button press="{!c.addField}" label="Add" />
    <ui:button press="{!c.display}" label="Show Data" />

    init: function(component, event, helper) {
        component.set("v.edits", []);
    addField: function(component, event, helper) {
        var field = component.get("v.fieldName"), 
            obj = component.get("v.accountRecord");
        obj[field] = "";
        component.set("v.accountRecord", obj);
            "lightning:input", {
                value: component.getReference("v.accountRecord."+component.get("v.fieldName")),
                label: component.get("v.fieldName"),
                type: "Text"
            $A.getCallback(function(newCmp, status, error) {
                var edits = component.get("v.edits");
                component.set("v.edits", edits);
    display: function(component, event, helper) {
        var obj = component.get("v.accountRecord");
        var results = [];
        Object.keys(obj).forEach(function(key) { results.push(key+":"+obj[key])});
        component.set("v.output", results.join('\n'));

Here's a demo of me dynamically binding stuff:

Dynamic Component Generation


You must log in to answer this question.

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