Angular: Form Builder

Made a simple form-builder demo for my work. Has sorting, almost every type of input, and works pretty well. Could use a few more options for help text and drag-n-drop sorting.

by gavinfoley

HTML

<script src="http://code.angularjs.org/angular-0.10.5.js" ng:autobind></script>
<div ng:controller="FormBuilderCtrl">
    
<div id="jv-formbuilder">
    <h2>Form Builder</h2>
    <form ng:submit="saveField()">
        <div class="input">
            <label for="newField-name">Field Name:</label>
            <input type="text" id="newField-name" ng:model="newField.name" ng:required>
        </div>
        <div class="input">
            <label for="newField-required">Required:</label>
            <input type="checkbox" id="newField-required" ng:model="newField.required">
        </div>
        <div class="input">
            <label for="newField-order">Order Weight:</label>
            <input type="number" id="newField-order" ng:model="newField.order" value="0" ng:required placeholder="0">
        </div>
        <div class="input">
            <label for="newField-type">Field Type:</label>
            <select id="newField-type" ng:model="newField.type" ng:required>
                <option value="text" selected>Text</option>
                <option value="radio">Radio Buttons</option>
                <option value="select">Drop Menu (Select)</option>
                <option value="multiple">Multi-Select</option>
                <option value="checkbox">Toggle (Checkbox)</option>
                <option value="checkboxes">Checkboxes</option>
                <option value="textarea">Paragraph(s)</option>
                <option value="number">Number</option>
                <option value="url">Url</option>
                <option value="phone">Phone</option>
                <option value="email">Email</option>
                <option value="header">Heading</option>
            </select>
        </div>
        <ng:switch on="typeSwitch(newField.type)">
            <div ng:switch-default class="input">
                <label for="newField-placeholder">Instructions:</label>
                <input type="text" id="newField-placeholder" ng:model="newField.placeholder">
   ...

CSS

h2 {
    font-size: 140%;
    margin: 10px 0;
    font-weight: bold;
}
.input {
    margin: 10px;
}
.edit {
    font-weight: bold;
    color: green;
}
.delete {
    font-weight: bold;
    color: red;
}
label {
    width: 50%;
    text-align: right;
    display: inline-block;
}
input, select {

}
.radio fieldset label, .checkboxes fieldset label {
    display: block;
    text-align: left;
}
.radio fieldset label input, .checkboxes fieldset label input {
    margin-right: 5px;
}
h3 {
    border-top: 2px solid #ccc;
    margin-top: 20px;
    padding-top: 5px;
}
.required label:after {
    color: #e32;
    content: '*';
    display:inline;
}
.order {
    color: #ccc;
}
fieldset {
    border: 1px solid #eee;
    margin: 10px;
    padding: 0 10px;
}
fieldset legend {
    margin: 10px;
}
fieldset label {
    width: auto;
}
fieldset div {
    margin: 10px 0;
}
strong {
    font-weight: bold; 
}

JavaScript

function FormBuilderCtrl(){
    var scope = this;
    scope.newField = {};
    scope.fields = [{
        type: 'text',
        name: 'Name',
        placeholder: 'John Doe',
        order: 10
    }];
    scope.editing = false;
    scope.tokenize = function(slug1, slug2) {
        var result = slug1;
        result = result.replace(/[^-a-zA-Z0-9,&\s]+/ig, '');
        result = result.replace(/-/gi, "_");
        result = result.replace(/\s/gi, "-");
        if (slug2) {
            result += '-' + scope.token(slug2);
        }
        return result;
    };
    scope.saveField = function() {
        if (scope.newField.type == 'checkboxes') {
            scope.newField.value = {};
        }
        if (scope.editing !== false) {
            scope.fields[scope.editing] = scope.newField;
            scope.editing = false;
        } else {
            scope.fields.push(scope.newField);
        }
        scope.newField = { order: 0 };
    };
    scope.editField = function(field) {
        scope.editing = scope.fields.indexOf(field);
        scope.newField = field;
    };
    scope.splice = function(field, fields) {
        fields.splice(fields.indexOf(field), 1);
    };
    scope.addOption = function() {
        if (scope.newField.options === undefined) {
            scope.newField.options = [];
        }
        scope.newField.options.push({ order: 0 });
    };
    scope.typeSwitch = function(type) {
        if (angular.Array.indexOf(['checkboxes','select','radio'], type) === -1)
            return type;
        return 'multiple';
    }
}