Skip to content

Instantly share code, notes, and snippets.

/gist:f1e91f78efe1b3278434 Secret
Created Dec 24, 2014

Embed
What would you like to do?
<!doctype html>
<html ng-app="app">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Form Builder</title>
<meta name="description" content="">
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.3.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script>
<script type="text/javascript" src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0-rc1/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui/0.4.0/angular-ui.min.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.0.js"></script>
<link rel="stylesheet" href="css/ngDialog.css">
<link rel="stylesheet" href="css/ngDialog-theme-default.css">
<link rel="stylesheet" href="css/ngDialog-theme-plain.css">
<script src="js/xeditable.js"></script>
<script src="js/ngDialog.js"></script>
<link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0-rc1/css/bootstrap.min.css">
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
<link href="css/xeditable.css" rel="stylesheet">
<script>
// App module //
var app = angular.module("app", ["xeditable", "ui", "ngDialog"]);
// Elements for this form //
// @TODO AJAX load with existing elements
app.factory('formElements', function($http) {
return [
{id: 1, elementType: 'textfield', name: 'name'},
{id: 2, elementType: 'select', name: 'select'},
{id: 3, elementType: 'checkbox', name: 'checkbox'},
{id: 3, elementType: 'radio', name: 'radio'}
];
/* return $http.post('/saveFormelement');*/ // @TODO dynamically pass the formID in the url
});
// Modal configuration //
app.config(['ngDialogProvider', function (ngDialogProvider) {
ngDialogProvider.setDefaults({
className: 'ngdialog-theme-default',
plain: false,
showClose: true,
closeByDocument: true,
closeByEscape: true,
appendTo: false,
preCloseCallback: function () {
console.log('default pre-close callback');
}
});
}]);
// Angular Controllers //
// Modal controller //
app.controller('ModalCtrl', function ($scope, $rootScope, ngDialog, formElements, $http) {
$scope.formElements = formElements;
$rootScope.theme = 'ngdialog-theme-default';
$scope.elementTypeLookup = function(formElementName) {
console.log('fired element type lookup');
// @TODO determine elementType from form name
// @TODO AJAX query server for lookup table
// RETURN elementType
}
$scope.openConfirm = function () {
ngDialog.openConfirm({
template: 'modalDialogId',
className: 'ngdialog-theme-default'
}).then(function (value) {
// AJAX //
// $http.post('/saveFormelement', value);
$scope.inserted = {
// @TODO find largest form index then add 1 to it
id: $scope.formElements.length+1,
name: value,
elementType: value // $scope.elementTypeLookup(value)
};
$scope.formElements.push($scope.inserted);
console.log('Modal promise resolved. Value: ', value);
}, function (reason) {
console.log('Modal promise rejected. Reason: ', reason);
});
};
});
// Inline row edit controller //
app.controller('EditableRowCtrl', function($scope, $filter, $http, formElements) {
$scope.formElements = formElements;
// @TODO AJAX request to save elements
$scope.saveAllFormElements = function() {
//return $http.post('/saveFormelement', data);
}
$scope.saveFormelement = function(data, id) {
//$scope.formElement not updated yet
angular.extend(data, {id: id});
console.log(formElements);
//return $http.post('/saveFormelement', data);
};
// remove formElement
$scope.removeFormelement = function(index) {
$scope.formElements.splice(index, 1);
};
// add formElement // add element
$scope.addElement = function() {
$scope.inserted = {
id: $scope.formElements.length+1,
name: '',
status: null,
//group: null
};
$scope.formElements.push($scope.inserted);
// @TODO write function to add new element to bottom of page
};
});
// Directive //
/*
'use strict';
app.directive('fieldDirective', function ($http, $compile) {
var getTemplateUrl = function(field) {
var type = field.field_type;
var templateUrl = '';
switch(type) {
case 'textfield':
templateUrl = './views/directive-templates/field/textfield.html';
break;
case 'email':
templateUrl = './views/directive-templates/field/email.html';
break;
case 'textarea':
templateUrl = './views/directive-templates/field/textarea.html';
break;
case 'checkbox':
templateUrl = './views/directive-templates/field/checkbox.html';
break;
case 'date':
templateUrl = './views/directive-templates/field/date.html';
break;
case 'dropdown':
templateUrl = './views/directive-templates/field/dropdown.html';
break;
case 'hidden':
templateUrl = './views/directive-templates/field/hidden.html';
break;
case 'password':
templateUrl = './views/directive-templates/field/password.html';
break;
case 'radio':
templateUrl = './views/directive-templates/field/radio.html';
break;
}
return templateUrl;
}
var linker = function(scope, element) {
// GET template content from path
var templateUrl = getTemplateUrl(scope.field);
$http.get(templateUrl).success(function(data) {
element.html(data);
$compile(element.contents())(scope);
});
}
return {
template: '<div>{{field}}</div>',
restrict: 'E',
scope: {
field:'='
},
link: linker
};
});
*/
app.directive("formbuilder", function($http, $compile) {
var getTemplateUrl = function(elementType) {
//var type = field.elementType;
var templateUrl = '';
switch(elementType) {
case 'textfield':
templateUrl = './views/directive-templates/field/textfield.html';
break;
case 'email':
templateUrl = './views/directive-templates/field/email.html';
break;
case 'textarea':
templateUrl = './views/directive-templates/field/textarea.html';
break;
case 'checkbox':
templateUrl = './views/directive-templates/field/checkbox.html';
break;
case 'date':
templateUrl = './views/directive-templates/field/date.html';
break;
case 'dropdown':
templateUrl = './views/directive-templates/field/dropdown.html';
break;
case 'hidden':
templateUrl = './views/directive-templates/field/hidden.html';
break;
case 'password':
templateUrl = './views/directive-templates/field/password.html';
break;
case 'radio':
templateUrl = './views/directive-templates/field/radio.html';
break;
}
return templateUrl;
}
var linker = function(scope, element) {
// GET template content from path
console.log(scope.elementType);
var templateUrl = getTemplateUrl(scope.elementType);
$http.get(templateUrl).success(function(data) {
//element.html(data);
//var node = $compile(element.contents())(scope);
// element.append(node);
});
}
return {
// template: '<div>{{formElement}}</div>',
restrict: "E",
scope: {
elementType: "="
},
link: linker
}
});
</script>
<!-- Modal template -->
<script type="text/ng-template" id="modalDialogId">
// @TODO Generate dynamically from elements table
<div class="ngdialog-message">
<h3>Select form element</h3>
<button type="button" ng-click="confirm('name')">Name</a>
<button type="button" ng-click="confirm('radio')">Radio</a>
<button type="button" ng-click="confirm('checkbox')">Checkbox</a>
<button type="button" ng-click="confirm('select')">Select</a>
<button type="button" ng-click="confirm('textarea')">Textarea</a>
</div>
</script>
<script type="text/ng-template" id="withInlineController">
<div class="ngdialog-message">
<h3>Select form element</h3>
<button type="button" onClick="selectElement('name')">Name</a>
<button type="button" ng-click="addElement()">Radio</a>
<button type="button" ng-click="pushNewElement()">Checkbox</a>
<button type="button" ng-click="selectElement(select)">Select</a>
<button type="button" ng-click="selectElement(textarea)">Textarea</a>
</div>
<div class="ngdialog-buttons">
<button type="button" class="ngdialog-button ngdialog-button-primary" ng-click="closeThisDialog()">Close</button>
</div>
</script>
</head>
<body>
<h1>Form builder</h1>
<div ng-controller="EditableRowCtrl">
<table class="table table-bordered table-hover table-condensed">
<thead>
<tr style="font-weight: bold">
<th style="width:35%">Form element</th>
<!--td style="width:20%">Status</td-->
<!--td style="width:20%">Group</td-->
<th style="width:25%">Edit</th>
</tr>
</thead>
<tbody ui:sortable="" ng:model="formElements">
<tr ng-repeat="formElement in formElements" style="cursor: move;">
<td>
<!-- editable formElementname (text with validation) -->
<span editable-text="formElement.name" e-name="name" e-form="rowform" e-required>
{{ formElement.name || 'empty' }}
</span>
<div class="elementDetails" ng-show="rowform.$visible" >
<span editable-text="formElement.description" e-name="description" e-form="rowform">
{{formElement.description}}
</span>
<span ng-switch="formElement.elementType">
<div ng-switch-when="text">
<span editable-text="formElement.placeholder" e-name="placeholder" e-form="rowform">
{{formElement.placeholder}}
</span>
</div>
<!-- @TODO place correct element tags -->
<div ng-switch-when="select">
<span editable-textarea="formElement.elementOptions" value="" e-name="elementOptions" e-form="rowform">
Option 1
Option 2
Option 3
</span>
</div>
<div ng-switch-when="radio">
<span editable-textarea="formElement.elementOptions" value="" e-name="elementOptions" e-form="rowform">
Option 1
Option 2
Option 3
</span>
</div>
<div ng-switch-when="checkbox">
<span editable-textarea="formElement.elementOptions" value="" e-name="elementOptions" e-form="rowform">
Option 1
Option 2
Option 3
</span>
</div>
</span>
<span editable-checkbox="formElement.requiredField" e-name="requiredField" e-form="rowform">
{{formElement.requiredField}}
</span>
</div>
</td>
<td style="white-space: nowrap">
<!-- form -->
<form editable-form name="rowform" onbeforesave="saveFormelement($data, formElement.id)" ng-show="rowform.$visible" class="form-buttons form-inline" shown="inserted == formElement">
<button type="submit" ng-disabled="rowform.$waiting" class="btn btn-primary">
save
</button>
<button type="button" ng-disabled="rowform.$waiting" ng-click="rowform.$cancel()" class="btn btn-default">
cancel
</button>
</form>
<div class="buttons" ng-show="!rowform.$visible">
<button ng-if="!formElement.expanded" class="btn btn-primary" ng-click="rowform.$show()">edit</button>
<button class="btn btn-danger" ng-click="removeFormelement($index)">del</button>
</div>
</td>
</tr>
</tbody>
</table>
<div ng-controller="ModalCtrl">
<button class="btn btn-default" ng-click="openConfirm()">Add element</button>
</div>
<br />
<br />
<br />
<!-- ********************** Display Form ********************** -->
{{formElements}}
<br />
<br />
<br />
<formbuilder element-type="textfield"></formbuilder>
<!-- ********************** Display Form ********************** -->
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.