0

I've got a controller in which I've got an array called fields. This array has the following structure (with some data as an example):

[
    {
        "name": "Demarcación",
        "type": "multiple",
        "scope": "restricted",
        "icon": "location-arrow",
        "order": 1,
        "id": 1,
        "possible_values": [
            {
                "id": 1,
                "field_id": 1,
                "name": "Demarcación 1"
            },
            {
                "id": 2,
                "field_id": 1,
                "name": "Demarcación 2"
            },
            {
                "id": 3,
                "field_id": 1,
                "name": "Demarcación 3"
            }
        ],
        "values": [
            {
                "id": 3,
                "value": "Demarcación 3"
            }
        ]
    },
    ...
]

Then, I want to create a form where the inputs are consctructed dynamically depending on the fields' type and scope. So, if the scope equals free, for example, then a textarea is added. Otherwise, an input text is added.

I need to perform some Javascript initialization depending on the field type, too, so - for example - if the scope is restricted I need to initialize a JQuery plugin on that input.

I've tried to set a function where I construct the HTML string and then print it in a ngRepeat, but I get the text as plain text (even using $sce.trustAsHtml()), without luck.

The question

Is there any way that I can write dynamically the inputs / html to add to document - and process some Javascript logic - and to which I can attach dynamically some AngularJS properties (like ngModel so its values get data-binded with the object)?

The inputs would be inside an ngRepeat directive, so I have access to the objects iterated and I can pass them as variables into a function.

Thank you!

2 Answers 2

1

I think what you are looking for is the $compile service

Angular Documentation for $compile

$compile(element.contents())(scope);

Example in plunkr

Sign up to request clarification or add additional context in comments.

2 Comments

I think it's what I needed! I've tested it and it seems to work. The only thing I'm worried about is performance. The fact that it's watching explicitly - specified by me - so many properties won't slow down performance? Thank you for your answer and time!
In fact, after a while testing, it gets laggy whenever I try to type anything into any of the inputs... I think it's a performance issue regarding the $watch code. If you have any confirmation (or not) about the performance issue, I'd appreciate you to share it! Thank you again!
1

That's a good start. That might be a good idea to go for a directive. Also, i think there are so form generators that handle this type of work: http://schemaform.io/

var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
    $scope.fields = window.fields;
    $scope.fieldInit = function(field){
      //console.log('things and stuff: ' + JSON.stringify(field));
     }
});

window.fields = [
    {
        "name": "field 1",
        "type": "text",
        "scope": "restricted",
        "icon": "location-arrow",
        "order": 1,
        "id": 1,
        "possible_values": [
            {
                "id": 1,
                "field_id": 1,
                "name": "Demarcación 1"
            },
            {
                "id": 2,
                "field_id": 1,
                "name": "Demarcación 2"
            },
            {
                "id": 3,
                "field_id": 1,
                "name": "Demarcación 3"
            }
        ],
        "values": [
            {
                "id": 3,
                "value": "Demarcación 3"
            }
        ]
    },
    {
        "name": "field 2",
        "type": "multiple",
        "scope": "restricted",
        "icon": "location-arrow",
        "order": 1,
        "id": 2,
        "possible": [
            {
                "id": 1,
                "field_id": 1,
                "name": "Demarcación 1"
            },
            {
                "id": 2,
                "field_id": 1,
                "name": "Demarcación 2"
            },
            {
                "id": 3,
                "field_id": 1,
                "name": "Demarcación 3"
            }
        ],
        "values": [
            {
                "id": 3,
                "value": "Demarcación 3"
            }
        ]
    }
 
]
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
 

<div ng-app="myApp" ng-controller="myCtrl">
  <div ng-repeat="field in fields" ng-init="fieldInit(field)">
  {{field.name}}
    <input ng-model="field.model" ng-if="field.type != 'multiple'" type="{{field.type}}"/>
    <select ng-model="field.model" ng-if="field.type == 'multiple'" 
    ng-options="val.name for val in field.possible" />
  <div>
</div>

2 Comments

Thank you! I had thought of a directive, too, but I preferred to give it a try from a more scalable way! Thanks for your answer and time!
Hope you'll be able to handle all your rules by going like that. Unfortunatly this might looks ugly at some point. :( That's why a directive would be great. Good luck.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.