"draggable form"
Bootstrap 3.0.0 Snippet by evarevirus

<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> <script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script> <script src="//code.jquery.com/jquery-1.11.1.min.js"></script> <!------ Include the above in your HEAD tag ----------> <!DOCTYPE html><html lang='en' class=''> <head><script src='//production-assets.codepen.io/assets/editor/live/console_runner-079c09a0e3b9ff743e39ee2d5637b9216b3545af0de366d4b9aad9dc87e26bfd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/events_runner-73716630c22bbc8cff4bd0f07b135f00a0bdc5d14629260c3ec49e5606f98fdd.js'></script><script src='//production-assets.codepen.io/assets/editor/live/css_live_reload_init-2c0dc5167d60a5af3ee189d570b1835129687ea2a61bee3513dee3a50c115a77.js'></script><meta charset='UTF-8'><meta name="robots" content="noindex"><link rel="shortcut icon" type="image/x-icon" href="//production-assets.codepen.io/assets/favicon/favicon-8ea04875e70c4b0bb41da869e81236e54394d63638a1ef12fa558a4a835f1164.ico" /><link rel="mask-icon" type="" href="//production-assets.codepen.io/assets/favicon/logo-pin-f2d2b6d2c61838f7e76325261b7195c27224080bc099486ddd6dccb469b8e8e6.svg" color="#111" /><link rel="canonical" href="https://codepen.io/thinhlam/pen/BowEPp?depth=everything&order=popularity&page=2&q=builder&show_forks=false" /> <link rel='stylesheet prefetch' href='https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css'> <style class="cp-pen-styles">body { padding-top: 20px; color: #75736f; overflow: hidden; } ::-webkit-scrollbar { display: none; } a { color: #75736f; } a:focus, a:hover, a:visited, a:active, a:link { text-decoration: none !important; color: #75736f; } ul.neo-nav { border: 2px solid #75736f; display: inline-block; -moz-padding-start: 0px; -webkit-padding-start: 0px; padding-start: 0px; border-radius: 5px; } ul.neo-nav li { display: inline-block; list-style: none; } ul.neo-nav li a { color: #75736f; padding: 10px 30px; font-weight: bold; display: block; } ul.neo-nav li.active a { color: white; } ul.neo-nav li:not(:first-child) { border-left: 2px solid #75736f; } ul.neo-nav li.active { background-color: #75736f; color: white; } ul.neo-nav li a:hover, ul.neo-nav li a:visited, ul.neo-nav li a:active, ul.neo-nav li a:link { text-decoration: none; } #main-content { background-color: whitesmoke; border-left: 1px solid #ddd; padding-top: 20px; padding-bottom: 20px; z-index: 1; overflow-y: scroll; } #sideBar { padding-top: 20px; padding-left: 0px; padding-right: 0px; z-index: 2; } .tab-container { border-bottom: 1px solid gray; padding-bottom: 20px; } #addFieldTab { padding-top: 20px; padding-left: 20px; } #fieldSettingTab { padding: 20px; } #stdFields {} #formBuilderContent { background-color: white; padding: 20px; } .dragElement-wrapper { width: 50%; display: inline-block; margin-bottom: 20px; } .dragElement-wrapper .drag-element { display: block; width: 90%; padding: 10px; border: 1px solid #ddd; border-radius: 5px; cursor: pointer; } .dragElement-wrapper .drag-element i { margin-right: 5px; } [draggable] { -moz-user-select: none; -khtml-user-select: none; -webkit-user-select: none; user-select: none; /* Required to make elements draggable in old WebKit */ -khtml-user-drag: element; -webkit-user-drag: element; } #chkBoxZone { margin-top: 15px; } .input-as-label { border: none; box-shadow: none; display: inline-block; max-width: 100%; margin-bottom: 5px; font-weight: 700; background-color: transparent; } .active-field { background-color: #f1fafc; } .form-group { padding: 10px; position: relative; } .form-group i.remove-ico { position: absolute; right: 5px; top: 5px; cursor: pointer; } .pale { opacity: 50%; } .sortable-formbuilder, .sortable-stdFields { padding-left: 0px; -moz-padding-start: 0px; -webkit-padding-start: 0px; -khtml-padding-start: 0px; -o-padding-start: 0px; padding-start: 0px; list-style: none; min-height: 40px; } .drop-to-add { height: 40px; } a[data-toggle="collapse"] i.fa-plus-square-o { display: none; } a[data-toggle="collapse"] i.fa-minus-square-o { display: inline-block; } a[data-toggle="collapse"].collapsed i.fa-plus-square-o { display: inline-block; } a[data-toggle="collapse"].collapsed i.fa-minus-square-o { display: none; } .orange-txt { color: orange; } #sidebar-tab-content{ overflow-y: scroll; }</style></head><body> <html lang="en" ng-app="DragDropApp"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js" type="text/javascript"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js" type="text/javascript"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.min.js" type="text/javascript"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular-animate.js" type="text/javascript"></script> <script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/374704/sortable.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" /> <title>Drag drop form builder</title> </head> <body ng-controller="DragDropCtrl"> <div class="container-fluid"> <div class="row"> <div class="col-md-3" id="sideBar"> <div class="tab-container text-center"> <ul class="neo-nav clearfix" role="tablist"> <li role="presentation" class="active"><a href="#addFieldTab" id="addFieldTab_lnk" aria-controls="home" role="tab" data-toggle="tab">Add a Field</a></li><!-- --><li role="presentation"><a href="#fieldSettingTab" id="fieldSettingTab_lnk" aria-controls="profile" role="tab" data-toggle="tab">Field Settings</a></li> </ul> </div> <div class="tab-content" id="sidebar-tab-content"> <div role="tabpanel" class="tab-pane active" id="addFieldTab"> <p> <a role="button" data-toggle="collapse" href="#stdFields"> <i class="fa fa-lg fa-plus-square-o"></i><i class="fa fa-lg fa-minus-square-o"></i> STANDARD FIELDS </a> </p> <div class="collapse in" id="stdFields"> <ul ng-model="dragElements" class="sortable-stdFields"> <li draggable="true" class="dragElement-wrapper" ng-repeat="ele in dragElements" element-draggable data-index="{{$index}}"> <div class="drag-element" ng-click="addElement(ele)" > <i class="fa fa-cogs"></i> {{ele.Name}} </div> </li> </ul> </div> </div> <div role="tabpanel" class="tab-pane" id="fieldSettingTab"> <div ng-repeat="set in current_field.Settings" ng-switch on="set.Type"> <div > <div class="form-group " ng-switch-when="text"> <label for="{{set.Name.replace(' ','_')}}">{{set.Name}}</label> <input ng-change="current_field.ChangeFieldSetting(set.Value, set.Name)" type="text" ng-model="set.Value" class="form-control" id="{{set.Name.replace(' ','_')}}" value="{{set.Value}}" placeholder="{{set.Name}}"> </div> <div class="form-group" ng-switch-when="string"> <label >{{set.Name}}</label> <br> <span >{{set.Value}}</span> </div> <div class="form-group" ng-switch-when="label"> <label class="pale">{{set.Name}}</label> </div> <div class="form-group " ng-switch-when="dropdown" > <label >{{set.Name}}</label> <select class="form-control" ng-model="set.Value" > <option ng-repeat="op in set.PossibleValue">{{op}}</option> </select> </div> <div class="form-group" ng-switch-when="radio"> <div ng-repeat="val in set.PossibleValue" class="radio"> <label> <input type="radio" name="optionsRadios" value="{{val.Checked}}" ng-checked="val.Checked"> {{val.Text}} </label> </div> </div> <div class="form-group" ng-switch-when="dropdown_increment"> <label class="control-label"> Choices </label> <div ng-repeat="val in set.PossibleValue" class="radio" class="form-control"> <i class="fa fa-sort fa-lg"> </i>   <i class="fa fa-circle-o fa-lg"> </i> <input type="text" value="val.Text" ng-model="val.Text"> </div> </div> <div ng-switch-when="checkBoxZone"> <a role="button" data-toggle="collapse" href="#chkBoxZone"> <i class="fa fa-lg fa-plus-square-o"></i><i class="fa fa-lg fa-minus-square-o"></i> {{set.Name}} </a> <div class="collapse in" id="chkBoxZone"> <div class="form-group" ng-repeat="op in set.Options"> <label class="checkbox-inline" > <input type="checkbox" value="{{op.Value}}" ng-model="op.Value"> {{op.Name}} </label> </div> </div> </div> <p ng-switch-default> Unknown </p> </div> </div> </div> </div> </div> <div class="col-md-9 text-center" id="main-content"> <ul class="neo-nav" role="tablist"> <li role="presentation" class="active"><a href="#addFieldTab" aria-controls="home" role="tab" data-toggle="tab">Form Builder</a></li><!-- --><li role="presentation"><a href="#" aria-controls="profile" role="tab" data-toggle="tab">Entity & Field Permission</a></li><!-- --><li role="presentation" class=""><a href="#" aria-controls="home" role="tab" data-toggle="tab">Detail Builder</a></li><!-- --><li role="presentation"><a href="#" aria-controls="profile" role="tab" data-toggle="tab">Workflows</a></li> </ul> <div class="tab-content"> <div role="tabpanel" class="tab-pane active text-left" id="formBuilderContent"> <p> <i class="fa fa-pencil fa-lg"></i> <span class="lead">Employee</span> </p> <div class="container-fluid" id="dropZone"> <ul class="row sortable-formbuilder" element-drop ui-sortable="formbuilderSortableOpts" ng-model="formFields" id="sortable-formbuilder-ul"> <li ng-repeat="field in formFields" element-drop data-index="{{$index}}" ng-switch on="field.Type" ng-class="field.GetFieldSetting('Column Span').Value == 1 ? 'col-md-6 sortable-field' : 'col-md-12 sortable-field' " ng-click="activeField(field)" data-index="{{$index}}"> <div class="form-group " ng-switch-when="text" ng-class="field.Active ? 'active-field' : '' " > <input type="text" class="input-as-label" ng-model="field.Name" value="{{field.Name + (field.GetFieldSetting('Required') ? '*': '')}}" ng-change="field.ChangeFieldSetting(field.Name,'Field Label')"/> <span ng-if="field.GetFieldSetting('Required').Value" class="orange-txt">*</span> <!--<label ng-if="!field.Active" for="{{field.Name.replace(' ','_') + field.id}}">{{field.Name}}<span ng-if="field.GetFieldSetting('Required')">*</span></label> --> <input type="text" class="form-control" id="{{field.Name.replace(' ','_') + field.id}}" value="{{field.Value}}" placeholder="{{field.Name}}"> <i class ="fa fa-lg fa-minus-square-o remove-ico" ng-click="removeElement($index)" ng-if="field.Active"></i> </div> <div class="form-group k" ng-switch-when="date" ng-class="field.Active ? 'active-field' : '' "> <input type="text" class="input-as-label" ng-model="field.Name" value="{{field.Name + (field.GetFieldSetting('Required').Value ? '*': '')}}" ng-change="field.ChangeFieldSetting(field.Name,'Field Label')"/> <span ng-if="field.GetFieldSetting('Required').Value" class="orange-txt">*</span> <div class="has-feedback"> <input type="text" class="form-control" placeholder="{{field.Name}}"> <span class="glyphicon glyphicon-calendar form-control-feedback custom-feedback" aria-hidden="true"></span> <span id="inputSuccess2Status" class="sr-only">(success)</span> </div> <i class ="fa fa-lg fa-minus-square-o remove-ico" ng-if="field.Active" ng-click="removeElement($index)"></i> </div> <div class="form-group " ng-switch-when="dropdown" ng-class="field.Active ? 'active-field' : '' "> <input type="text" class="input-as-label" ng-model="field.Name" value="{{field.Name + (field.GetFieldSetting('Required').Value ? '*': '')}}" ng-change="field.ChangeFieldSetting(field.Name,'Field Label')"/> <span ng-if="field.GetFieldSetting('Required').Value" class="orange-txt">*</span> <select class="form-control" > <option ng-repeat="val in field.GetFieldSetting('Choice').PossibleValue"> {{val.Text}} </option> </select> <i class ="fa fa-lg fa-minus-square-o remove-ico" ng-if="field.Active" ng-click="removeElement($index)"></i> </div> <div class="form-group " ng-switch-when="textarea" ng-class="field.Active ? 'active-field' : '' "> <input type="text" class="input-as-label" ng-model="field.Name" value="{{field.Name + (field.GetFieldSetting('Required').Value ? '*': '')}}" ng-change="field.ChangeFieldSetting(field.Name,'Field Label')"/> <span ng-if="field.GetFieldSetting('Required').Value" class="orange-txt">*</span> <textarea class="form-control" id="{{field.Name.replace(' ','_') + field.id}}" rows="4"></textarea> <i class ="fa fa-lg fa-minus-square-o remove-ico" ng-if="field.Active" ng-click="removeElement($index)"></i> </div> <div ng-switch-default> </div> </li> <li class="drop-to-add col-md-12" element-drop> </li> </ul> </div> </div> </div> </div> </div> </div> </body> </html> <script src='//production-assets.codepen.io/assets/common/stopExecutionOnTimeout-b2a7b3fe212eaa732349046d8416e00a9dec26eb7fd347590fbced3ab38af52e.js'></script> <script >/** * Created by thinhlam on 10/16/15. */ (function() { var guid = 1; var app = angular.module('DragDropApp', ['ui.sortable']); app.controller('DragDropCtrl', function($scope) { $scope.dragElements = [{ 'Name': "Single Text", 'Type': "text", 'Settings': [{ 'Name': 'Field Label', 'Value': 'Single Text', 'Type': 'text' }, { 'Name': 'Short Label', 'Value': 'Single Text', 'Type': 'text' }, { 'Name': 'Internal Name', 'Value': 'xSingle_Text', 'Type': 'text' }, { 'Name': 'Field Type', 'Value': 'Single Text', 'Type': 'string' }, { 'Name': 'Single Line Text Options', 'Value': '', 'Type': 'label' }, { 'Name': 'Max Input Length', 'Value': '50', 'Type': 'text' }, { 'Name': 'Url Template', 'Value': '', 'Type': 'text' }, { 'Name': 'Column Span', 'Value': '1', 'Type': 'dropdown', 'PossibleValue': ['1', '2'] }, { 'Name': 'General Options', 'Type': 'checkBoxZone', 'Options': [{ 'Name': 'Required', 'Value': false }, { 'Name': 'Show on list', 'Value': false }, { 'Name': 'Unique', 'Value': false }, { 'Name': 'Index', 'Value': false }] } ] }, { 'Name': "Date", 'Type': "date", 'Settings': [{ 'Name': 'Field Label', 'Value': 'Field Label', 'Type': 'text' }, { 'Name': 'Short Label', 'Value': 'Short Label', 'Type': 'text' }, { 'Name': 'Internal Name', 'Value': 'Internal Name', 'Type': 'text' }, { 'Name': 'Field Type', 'Value': 'Date', 'Type': 'string' }, { 'Name': 'Display Type', 'Value': '', 'Type': 'radio', 'PossibleValue': [ { 'Text' : 'DateTimeInstance', 'Checked' : true }, { 'Text' : 'DateTimeLocal', 'Checked' : false }, { 'Text' : 'DateLocal', 'Checked' : false }, { 'Text' : 'Time', 'Checked' : false }, ] }, { 'Name': 'Column Span', 'Value': '1', 'Type': 'dropdown', 'PossibleValue': ['1', '2'] }, { 'Name': 'General Options', 'Type': 'checkBoxZone', 'Options': [{ 'Name': 'Required', 'Value': false }, { 'Name': 'Show on list', 'Value': false }, { 'Name': 'Unique', 'Value': false }, { 'Name': 'Index', 'Value': false }] } ] }, { 'Name': "Singe Selection", "Type": "dropdown", 'Settings': [{ 'Name': 'Field Label', 'Value': 'Field Label', 'Type': 'text' }, { 'Name': 'Short Label', 'Value': '', 'Type': 'text' }, { 'Name': 'Internal Name', 'Value': 'Short Label', 'Type': 'text' }, { 'Name': 'Field Type', 'Value': 'Single Selection', 'Type': 'string' }, { 'Name': 'Display Type', 'Value': '', 'Type': 'radio', 'PossibleValue': [ { 'Text' : 'Dropdown', 'Checked' : true }, { 'Text' : 'Radio List', 'Checked' : false } ] }, { 'Name': 'Choice', 'Type': 'dropdown_increment', 'PossibleValue': [ { 'Text':'Choice 1', } , { 'Text': 'Choice 2' } ] }, { 'Name': 'Column Span', 'Value': '1', 'Type': 'dropdown', 'PossibleValue': ['1', '2'] }, { 'Name': 'General Options', 'Type': 'checkBoxZone', 'Options': [{ 'Name': 'Required', 'Value': false }, { 'Name': 'Show on list', 'Value': false }, { 'Name': 'Unique', 'Value': false }, { 'Name': 'Index', 'Value': false }] } ] }, { 'Name': "Pagaraph Text", "Type": "textarea", 'Settings': [{ 'Name': 'Field Label', 'Value': '', 'Type': 'text' }, { 'Name': 'Short Label', 'Value': '', 'Type': 'text' }, { 'Name': 'Internal Name', 'Value': '', 'Type': 'text' }, { 'Name': 'Field Type', 'Value': 'Paragraph Text', 'Type': 'string' }, { 'Name': 'Column Span', 'Value': '1', 'Type': 'dropdown', 'PossibleValue': ['1', '2'] }, { 'Name': 'General Options', 'Type': 'checkBoxZone', 'Options': [{ 'Name': 'Required', 'Value': false }, { 'Name': 'Enable Rich Text', 'Value': false }, { 'Name': 'Active', 'Value': true }, { 'Name': 'Hidden', 'Value': false }] } ] }]; $scope.formFields = []; $scope.current_field = {}; var createNewField = function() { return { 'id': ++guid, 'Name': '', 'Settings': [], 'Active': true, 'ChangeFieldSetting': function(Value, SettingName) { switch (SettingName) { case 'Field Label': case 'Short Label': case 'Internal Name': $scope.current_field.Name = Value; $scope.current_field.Settings[0].Value = $scope.current_field.Name; $scope.current_field.Settings[1].Value = $scope.current_field.Name; $scope.current_field.Settings[2].Value = 'x' + $scope.current_field.Name.replace(/\s/g, '_'); break; default: break; } }, 'GetFieldSetting': function(settingName) { var result = {}; var settings = this.Settings; $.each(settings, function(index, set) { if (set.Name == settingName) { result = set; return; } }); if (!Object.keys(result).length) { //Continue to search settings in the checkbox zone $.each(settings[settings.length - 1].Options, function(index, set) { if (set.Name == settingName) { result = set; return; } }); } return result; } }; } $scope.changeFieldName = function(Value) { $scope.current_field.Name = Value; $scope.current_field.Settings[0].Value = $scope.current_field.Name; $scope.current_field.Settings[1].Value = $scope.current_field.Name; $scope.current_field.Settings[2].Value = 'x' + $scope.current_field.Name.replace(/\s/g, '_'); } $scope.removeElement = function(idx){ if($scope.formFields[idx].Active) { $('#addFieldTab_lnk').tab('show'); $scope.current_field = {}; } $scope.formFields.splice(idx, 1); }; $scope.addElement = function(ele, idx) { $scope.current_field.Active = false; $scope.current_field = createNewField(); //Merge setting from template object angular.merge($scope.current_field, ele); if (typeof idx == 'undefined') { $scope.formFields.push($scope.current_field); } else { $scope.formFields.splice(idx, 0, $scope.current_field); $('#fieldSettingTab_lnk').tab('show'); } }; $scope.activeField = function(f) { $scope.current_field.Active = false; $scope.current_field = f; f.Active = true; $('#fieldSettingTab_lnk').tab('show'); }; $scope.formbuilderSortableOpts = { 'ui-floating': true, }; }); app.directive('elementDraggable', ['$document', function($document) { return { link: function(scope, element, attr) { element.on('dragstart', function(event) { event.originalEvent.dataTransfer.setData('templateIdx', $(element).data('index')); }); } }; }]); app.directive('elementDrop', ['$document', function($document) { return { link: function(scope, element, attr) { element.on('dragover', function(event) { event.preventDefault(); }); $('.drop').on('dragenter', function(event) { event.preventDefault(); }) element.on('drop', function(event) { event.stopPropagation(); var self = $(this); scope.$apply(function() { var idx = event.originalEvent.dataTransfer.getData('templateIdx'); var insertIdx = self.data('index') scope.addElement(scope.dragElements[idx], insertIdx); }); }); } }; }]); })(); $(function() { // Code here var dh = $(document).height(); $('#sidebar-tab-content').height(dh - 115); $('#main-content').height(dh - 10); }); //# sourceURL=pen.js </script> </body></html>

Related: See More


Questions / Comments: