Faiz
Faiz

Reputation: 623

AngularJS: Generate a form dynamically in AngularJS

I am trying to generate a HTML form.

I have an object which contains an array of form elements like

{
    "formFields": [
        {
            "type": "select",
            "label": "Fabric",
            "name": "fabric",
            "options": [
                "Georgette",
                "Crepe",
                "Net",
                "Lace"
            ]
        },
        {
            "type": "text",
            "label": "Weight",
            "name": "weight",
            "options": []
        }
    ]
}

I want to generate a form which has fields in accordance with the above object i.e. it should generate a Select labelled Fabric with drop down options "Georgette","Crepe","Net","Lace" and an input element of type text with label Weight.

What is the best way to do this in AngularJS?

Upvotes: 0

Views: 113

Answers (2)

Shashank
Shashank

Reputation: 2060

You can refer to the sample here. Please find the code below:

HTML:

<div ng-app="app" ng-controller="test">
    <form name="myForm" ng-submit="validateForm(myForm.$valid)">
        <div ng-repeat="item in formData.formFields">
            <div ng-if="item.type == 'text'">
                <label>{{item.label}}: </label>
                <input type="{{item.type}}" name="{{item.name}}">
            </div>
            <div ng-if="item.type == 'select'">
                <label>{{item.label}}: </label>
                <select name="{{item.name}}">
                    <option ng-repeat="opt in item.options" value="{{opt}}">{{opt}}</option>
                </select>
            </div>
            <br>
        </div>
    </form>
</div>

JS:

var app = angular.module('app', []);

app.controller('test', function ($scope) {
    $scope.formData = {
        "formFields": [
            {
                "type": "select",
                "label": "Fabric",
                "name": "fabric",
                "options": [
                    "Georgette",
                    "Crepe",
                    "Net",
                    "Lace"
                ]
            },
            {
                "type": "text",
                "label": "Weight",
                "name": "weight",
                "options": []
            }
        ]
    };

$scope.validateForm = function(isValid){
 /*..*/
}
});

Upvotes: 0

Martijn Welker
Martijn Welker

Reputation: 5605

I would make a directive which accepts a form field object as input and $compiles a template based on the input.

Html:

<div my-input="settings"></div>

Js:

angular.module('myApp').directive('myInput', ['$compile', function($compile) {
    return {
        restrict: 'EA',
        require: 'ngModel',
        link: linkFn,
        scope: {
            config: '=myInput'
        }
    };

    function linkFn($scope, $element, $attrs, ngModelCtrl) {
        init();

        function init() {
            $scope.model = {};
            var template = getTemplate();

            template.attr('ng-model', 'model.value');

            $compile(template)($scope, function(clonedElem) {
                $element.html(clonedElem);
            });
        }

        function getTemplate() {
            switch($scope.config.type) {
                case 'text':
                    return '<input type="text"/>';
                case 'select':
                    return '<input type="select" ng-options="option in config.options">';
            }
        }
    }
}]);

This is from the top of my head so the code might be wrong but you get the idea.

Upvotes: 1

Related Questions