UNPKG

vormjs

Version:

Write your forms in JSON and HTML, use the same API.

434 lines (364 loc) 9.77 kB
<!doctype html> <html> <head> <title>Dynamic forms</title> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script> <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular-animate.min.js"></script> --> <script src="../../node_modules/angular-animate/angular-animate.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script> <!-- vorm --> <script src="../../vorm.js"></script> <!-- end of vorm --> <script src="https://code.jquery.com/jquery-2.1.3.min.js"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/highlight.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/languages/javascript.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/styles/monokai_sublime.min.css"> <script id="app"> angular.module('app', [ 'vorm', 'ngAnimate' ]) .controller('FormController', [ '$scope', function ( $scope ) { var ctrl = this, fields; fields = [ { name: 'title', type: 'text', label: 'Post title', required: true, data: { placeholder: 'What would the title of the post be?' } }, { name: 'content', type: 'textarea', label: 'Content', required: true, data: { placeholder: 'What do you have to say?' } }, { name: 'category', type: 'select', label: 'Category', data: { options: getCategoryOptions() }, required: true }, { name: 'sub_category', type: 'select', label: 'Sub category', data: { options: [ '$values', function ( $values ) { var options = $values.category ? $values.category.children : []; return options; }] }, when: [ '$values', function ( $values ) { return ( $values.category && $values.category.children && $values.category.children.length > 0 ); }], required: true }, { name: 'schedule', type: 'checkbox', data: { checkboxLabel: 'Schedule this post for later' }, defaults: true }, { name: 'schedule_date', type: 'date', disabled: '!schedule', required: true, defaults: new Date() }, { name: 'generateDeeplinkId', type: 'checkbox', data: { checkboxLabel: 'Automatically generate a deeplink' }, defaults: true }, { name: 'deeplinkId', type: 'text', required: true, disabled: [ '$values', function ( $values ) { return !!$values.generateDeeplinkId; }] } ]; function getCategoryOptions ( ) { return [ { label: 'Programming', value: { id: 1, children: [ 'JavaScript', 'Ruby', 'Go', 'PHP' ].map(function ( lang ) { return { value: lang, label: lang }; }) } }, { label: 'Culture', value: { id: 2, children: [ 'Music', 'Movies', 'Books' ].map(function ( type ) { return { value: type, label: type }; }) } }, { label: 'Other', value: { id: 3, children: [ { value: 'Other', label: 'Other' } ] } } ]; } ctrl.getFields = function ( ) { return fields; }; ctrl.handleSubmit = function ( values ) { console.log('submitted with', values); }; function setDeeplinkId ( ) { var form = $scope.vormForm; if(form.getValue('title')) { form.setValue('deeplinkId', form.getValue('title').replace(/[^A-Za-z0-9]/g, '-').toLowerCase()); } } ctrl.handleChange = function ( name ) { console.log('change', arguments); var form = $scope.vormForm; switch(name) { case 'title': if(form.getValue('generateDeeplinkId')) { setDeeplinkId(); } break; case 'generateDeeplinkId': setDeeplinkId(); break; case 'schedule': form.setValue('schedule_date', new Date()); break; } }; }]) .config([ 'vormTemplateServiceProvider', function ( vormTemplateServiceProvider ) { vormTemplateServiceProvider.modifyModelTemplates(function ( el, type ) { if(type !== 'checkbox') { el.addClass('form-control'); } return el; }); vormTemplateServiceProvider.modifyControlTemplate(function ( el ) { el.find('vorm-display').addClass('flip'); el.find('vorm-edit').addClass('flip'); return el; }); }]); </script> <style> .vorm-field-label { padding: 4px 0; } .vorm-field-label:empty { display: none; } .vorm-field-required .vorm-field-label::after { content: " (*)"; } vorm-edit, vorm-display { display: flex; } .vorm-control-clear-button { margin-left: 5px; } .vorm-delegate-button { margin-top: 10px; } .vorm-field-empty vorm-display span::before { content: "-"; } [vorm-field=generateDeeplinkId], [vorm-field=schedule] { padding-top: 10px; } [vorm-field] { transition:0.5s ease-in opacity; } [vorm-field].ng-enter { opacity: 0; } [vorm-field].ng-enter-active { opacity: 1; } [vorm-field].ng-leave { opacity: 1; } [vorm-field].ng-leave-active { opacity: 0; } vorm-control { display: block; position: relative; margin-bottom: 10px; } vorm-display { padding: 6px 12px; border: 1px solid transparent; } vorm-edit, vorm-display { top: 0; right: 0; left: 0; } vorm-edit.ng-hide-add, vorm-display.ng-hide-add { -webkit-animation: 0.5s flipOutX ease; animation: 0.5s flipOutX ease; } /* when showing the thing */ vorm-edit.ng-hide-remove, vorm-display.ng-hide-remove { -webkit-animation: 0.5s flipInX ease; animation: 0.5s flipInX ease; position: absolute; } vorm-edit > label { display: flex; } input[type="checkbox"] { margin-right: 5px; } /* ANIMATIONS (FROM ANIMATE.CSS) */ /* flip in */ @-webkit-keyframes flipInX { 0% { -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 180deg); transform: perspective(400px) rotate3d(1, 0, 0, 180deg); -webkit-transition-timing-function: ease-in; transition-timing-function: ease-in; opacity: 0; } 100% { -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 0deg); transform: perspective(400px) rotate3d(1, 0, 0, 0deg); opacity: 1; } } @-webkit-keyframes flipOutX { 0% { -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 180deg); transform: perspective(400px) rotate3d(1, 0, 0, 180deg); -webkit-transition-timing-function: ease-in; transition-timing-function: ease-in; opacity: 1; } 100% { -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 0deg); transform: perspective(400px) rotate3d(1, 0, 0, 0deg); opacity: 0; } } @keyframes flipInX { 0% { -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 180deg); transform: perspective(400px) rotate3d(1, 0, 0, 180deg); -webkit-transition-timing-function: ease-in; transition-timing-function: ease-in; opacity: 0; } 100% { -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 0deg); transform: perspective(400px) rotate3d(1, 0, 0, 0deg); opacity: 1; } } @keyframes flipOutX { 0% { -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 180deg); transform: perspective(400px) rotate3d(1, 0, 0, 180deg); -webkit-transition-timing-function: ease-in; transition-timing-function: ease-in; opacity: 1; } 100% { -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 0deg); transform: perspective(400px) rotate3d(1, 0, 0, 0deg); opacity: 0; } } </style> </head> <body ng-app="app"> <div class="col-md-6" style="padding: 20px" form-template> <form vorm-form vorm-submit="ctrl.handleSubmit($values)" vorm-change="ctrl.handleChange($name)" ng-controller="FormController as ctrl" > <vorm-fieldset class="form-group" fields="ctrl.getFields()"> </vorm-fieldset> <button class="btn btn-primary" ng-disabled="!vormForm.isValid()" type"submit"> Submit </button> </form> <div style="color: #333; background-color: #f2f2f2; padding: 5px; margin-top: 20px">Open up your console to see some logging.</div> </div> <div class="col-md-6"> <pre style="tab-size: 4 !important;padding: 0px !important"><code form class="html"></code></pre> <pre style="tab-size: 4 !important;padding: 0px !important"><code js></code></pre> </div> <script> void function ( ) { var script = document.querySelector('script#app'), tpl = document.querySelector('[form-template]'), jsCode = document.querySelector('code[js]'), formCode = document.querySelector('code[form]'); jsCode.textContent = script.textContent; formCode.textContent = tpl.innerHTML; hljs.highlightBlock(jsCode); hljs.highlightBlock(formCode); }(); </script> </body> </html>