├── .bowerrc
├── publish.js
├── .gitignore
├── views
├── submit-form.client.view.html
└── directiveViews
│ ├── field
│ ├── hidden.html
│ ├── password.html
│ ├── natural.html
│ ├── statement.html
│ ├── rating.html
│ ├── date.html
│ ├── dropdown.html
│ ├── radio.html
│ ├── file.html
│ ├── textarea.html
│ ├── legal.html
│ ├── yes_no.html
│ └── textfield.html
│ └── form
│ └── submit-form.client.view.html
├── services
├── current-form.client.service.js
├── auth.client.service.js
├── forms.client.service.js
├── time-counter.client.service.js
└── form-fields.client.service.js
├── index.js
├── controllers
└── submit-form.client.controller.js
├── directives
├── on-finish-render.client.directive.js
├── field-icon.client.directive.js
├── render-form.client.directive.js
├── on-enter-key.client.directive.js
├── field.client.directive.js
└── submit-form.client.directive.js
├── LICENSE
├── config
├── i18n
│ ├── german.js
│ ├── italian.js
│ ├── french.js
│ ├── spanish.js
│ └── english.js
└── forms.client.config.js
├── gruntfile.js
├── bower.json
├── demo
├── index.html
├── dist
│ └── form.css
└── app.js
├── package.json
├── dist
├── form.css
└── template.js
├── README.md
└── css
└── form.css
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "demo/lib",
3 | "analytics": false
4 | }
5 |
--------------------------------------------------------------------------------
/publish.js:
--------------------------------------------------------------------------------
1 | require('./dist/bundle.js');
2 | module.exports = 'angular-tellform';
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | demo/lib
2 | node_modules
3 | demo/node_modules
4 | demo/modules
5 | demo/bundle.js
6 | .idea/
7 |
--------------------------------------------------------------------------------
/views/submit-form.client.view.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
--------------------------------------------------------------------------------
/views/directiveViews/field/hidden.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/services/current-form.client.service.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | //Forms service used for communicating with the forms REST endpoints
4 | angular.module('angular-tellform').service('CurrentForm',
5 | function(){
6 |
7 | //Private variables
8 | var _form = {};
9 |
10 | //Public Methods
11 | this.getForm = function() {
12 | return _form;
13 | };
14 | this.setForm = function(form) {
15 | _form = form;
16 | };
17 | }
18 | );
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angular-tellform', [
4 | 'ui.utils',
5 | 'duScroll',
6 | 'ui.select',
7 | 'cgBusy',
8 | 'ngSanitize',
9 | 'vButton',
10 | 'ngResource',
11 | 'ui.router',
12 | 'ui.bootstrap',
13 | 'pascalprecht.translate',
14 | 'angular-input-stars',
15 | 'angular-tellform.templates'
16 | ]).constant('version', require('./package.json').version);
17 |
18 | //FIXME: App breaks when I remove this line and put modules in above statement
19 | //angular.module('angular-tellform', ['ngResource', 'angular-tellform.templates']);
20 |
21 | require('./dist/form.js');
22 |
23 |
--------------------------------------------------------------------------------
/services/auth.client.service.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angular-tellform').factory('Auth', function() {
4 | var service = {
5 | _currentUser: null,
6 | get currentUser(){
7 | return this._currentUser;
8 | },
9 | ensureHasCurrentUser: function() {
10 | return null;
11 | },
12 | isAuthenticated: function() {
13 | return false;
14 | },
15 | getUserState: function() {
16 | return '';
17 | },
18 | login: function() {
19 | },
20 | logout: function() {
21 | }
22 | };
23 | return service;
24 | });
25 |
--------------------------------------------------------------------------------
/views/directiveViews/field/password.html:
--------------------------------------------------------------------------------
1 |
2 |
{{field.title}} *(required)
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/services/forms.client.service.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | //Forms service used for communicating with the forms REST endpoints
4 | angular.module('angular-tellform').factory('Forms', ['$resource', 'FORM_URL',
5 | function($resource, FORM_URL) {
6 | return $resource(FORM_URL, {
7 | formId: '@_id'
8 | }, {
9 | 'query' : {
10 | method: 'GET',
11 | isArray: true
12 | },
13 | 'get' : {
14 | method: 'GET',
15 | transformResponse: function(data, header) {
16 | var form = angular.fromJson(data);
17 |
18 | form.visible_form_fields = _.filter(form.form_fields, function(field){
19 | return (field.deletePreserved === false);
20 | });
21 | return form;
22 | }
23 | },
24 | 'update': {
25 | method: 'PUT'
26 | },
27 | 'save': {
28 | method: 'POST'
29 | }
30 | });
31 | }
32 | ]);
--------------------------------------------------------------------------------
/controllers/submit-form.client.controller.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // SubmitForm controller
4 | angular.module('angular-tellform').controller('SubmitFormController', [
5 | '$scope', '$rootScope', '$state', '$translate', 'myForm', 'Auth',
6 | function($scope, $rootScope, $state, $translate, myForm, Auth) {
7 | $scope.authentication = Auth;
8 | $scope.myform = myForm;
9 |
10 | $translate.use(myForm.language);
11 |
12 | if(!$scope.myform.isLive){
13 | // Show navbar if form is not public AND user IS loggedin
14 | if($scope.authentication.isAuthenticated()){
15 | $scope.hideNav = $rootScope.hideNav = false;
16 | }
17 | // Redirect if form is not public user IS NOT loggedin
18 | else {
19 | $scope.hideNav = $rootScope.hideNav = true;
20 | $state.go('access_denied');
21 | }
22 | }else{
23 | $scope.hideNav = $rootScope.hideNav = true;
24 | }
25 | }
26 | ]);
27 |
--------------------------------------------------------------------------------
/views/directiveViews/field/natural.html:
--------------------------------------------------------------------------------
1 |
2 |
{{field.title}} *(required)
3 |
4 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/services/time-counter.client.service.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angular-tellform').service('TimeCounter', [
4 | function(){
5 | var _startTime, _endTime = null, that=this;
6 |
7 | this.timeSpent = 0;
8 |
9 | this.restartClock = function(){
10 | _startTime = Date.now();
11 | _endTime = null;
12 | // console.log('Clock Started');
13 | };
14 |
15 | this.getTimeElapsed = function(){
16 | if(_startTime) {
17 | return Math.abs(Date.now().valueOf() - _startTime.valueOf()) / 1000;
18 | }
19 | };
20 |
21 | this.stopClock = function(){
22 | if(_startTime && _endTime === null){
23 | _endTime = Date.now();
24 | this.timeSpent = Math.abs(_endTime.valueOf() - _startTime.valueOf())/1000;
25 | this._startTime = this._endTime = null;
26 |
27 | return this.timeSpent;
28 | }else{
29 | return new Error('Clock has not been started');
30 | }
31 | };
32 |
33 | this.clockStarted = function(){
34 | return !!this._startTime;
35 | };
36 |
37 | }
38 | ]);
--------------------------------------------------------------------------------
/directives/on-finish-render.client.directive.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angular-tellform').directive('onFinishRender', function ($rootScope, $timeout) {
4 | return {
5 | restrict: 'A',
6 | link: function (scope, element, attrs) {
7 |
8 | //Don't do anything if we don't have a ng-repeat on the current element
9 | if(!element.attr('ng-repeat') && !element.attr('data-ng-repeat')){
10 | return;
11 | }
12 |
13 | var broadcastMessage = attrs.onFinishRender || 'ngRepeat';
14 |
15 | if(scope.$first && !scope.$last) {
16 | scope.$evalAsync(function () {
17 | $rootScope.$broadcast(broadcastMessage+' Started');
18 | });
19 | }else if(scope.$last) {
20 | scope.$evalAsync(function () {
21 | // console.log(broadcastMessage+'Finished');
22 | $rootScope.$broadcast(broadcastMessage+' Finished');
23 | });
24 | }
25 | }
26 | };
27 | });
28 |
--------------------------------------------------------------------------------
/directives/field-icon.client.directive.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angular-tellform').directive('fieldIconDirective', function() {
4 | return {
5 | template: '',
6 | restrict: 'E',
7 | scope: {
8 | typeName: '@'
9 | },
10 | controller: function($scope){
11 | var iconTypeMap = {
12 | 'textfield': 'fa fa-pencil-square-o',
13 | 'dropdown': 'fa fa-th-list',
14 | 'date': 'fa fa-calendar',
15 | 'checkbox': 'fa fa-check-square-o',
16 | 'radio': 'fa fa-dot-circle-o',
17 | 'email': 'fa fa-envelope-o',
18 | 'textarea': 'fa fa-pencil-square',
19 | 'legal': 'fa fa-legal',
20 | 'file': 'fa fa-cloud-upload',
21 | 'rating': 'fa fa-star-half-o',
22 | 'link': 'fa fa-link',
23 | 'scale': 'fa fa-sliders',
24 | 'stripe': 'fa fa-credit-card',
25 | 'statement': 'fa fa-quote-left',
26 | 'yes_no': 'fa fa-toggle-on',
27 | 'number': 'fa fa-slack'
28 | };
29 | $scope.typeIcon = iconTypeMap[$scope.typeName];
30 | }
31 | };
32 | });
33 |
--------------------------------------------------------------------------------
/views/directiveViews/field/statement.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
{{field.title}}
8 |
9 | {{field.description}}
10 |
11 |
12 |
24 |
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 tellform
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/config/i18n/german.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angular-tellform').config(['$translateProvider', function ($translateProvider) {
4 |
5 | $translateProvider.translations('german', {
6 | FORM_SUCCESS: 'Ihre Angaben wurden gespeichert.',
7 | REVIEW: 'Unvollständig',
8 | BACK_TO_FORM: 'Zurück zum Formular',
9 | EDIT_FORM: 'Bearbeiten Sie diese TellForm',
10 | CREATE_FORM: 'Erstellen Sie eine TellForm',
11 | ADVANCEMENT: '{{done}} von {{total}} beantwortet',
12 | CONTINUE_FORM: 'Zum Formular',
13 | REQUIRED: 'verpflichtend',
14 | COMPLETING_NEEDED: 'Es fehlen/fehtl noch {{answers_not_completed}} Antwort(en)',
15 | OPTIONAL: 'fakultativ',
16 | ERROR_EMAIL_INVALID: 'Bitte gültige Mailadresse eingeben',
17 | ERROR_NOT_A_NUMBER: 'Bitte nur Zahlen eingeben',
18 | ERROR_URL_INVALID: 'Bitte eine gültige URL eingeben',
19 | OK: 'Okay',
20 | ENTER: 'Eingabetaste drücken',
21 | YES: 'Ja',
22 | NO: 'Nein',
23 | NEWLINE: 'Für eine neue Zeile SHIFT+ENTER drücken',
24 | CONTINUE: 'Weiter',
25 | LEGAL_ACCEPT: 'Ich akzeptiere',
26 | LEGAL_NO_ACCEPT: 'Ich akzeptiere nicht',
27 | DELETE: 'Entfernen',
28 | CANCEL: 'Canceln',
29 | SUBMIT: 'Speichern',
30 | UPLOAD_FILE: 'Datei versenden',
31 | Y: 'J',
32 | N: 'N'
33 | });
34 |
35 | }]);
36 |
--------------------------------------------------------------------------------
/config/i18n/italian.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angular-tellform').config(['$translateProvider', function ($translateProvider) {
4 |
5 | $translateProvider.translations('italian', {
6 | FORM_SUCCESS: 'Il formulario è stato inviato con successo!',
7 | REVIEW: 'Incompleto',
8 | BACK_TO_FORM: 'Ritorna al formulario',
9 | EDIT_FORM: 'Modifica questo Tellform',
10 | CREATE_FORM: 'Creare un TellForm',
11 | ADVANCEMENT: '{{done}} su {{total}} completate',
12 | CONTINUE_FORM: 'Vai al formulario',
13 | REQUIRED: 'obbligatorio',
14 | COMPLETING_NEEDED: '{{answers_not_completed}} risposta/e deve/ono essere completata/e',
15 | OPTIONAL: 'opzionale',
16 | ERROR_EMAIL_INVALID: 'Si prega di inserire un indirizzo email valido',
17 | ERROR_NOT_A_NUMBER: 'Si prega di inserire solo numeri',
18 | ERROR_URL_INVALID: 'Grazie per inserire un URL valido',
19 | OK: 'OK',
20 | ENTER: 'premere INVIO',
21 | YES: 'Sì',
22 | NO: 'No',
23 | NEWLINE: 'premere SHIFT+INVIO per creare una nuova linea',
24 | CONTINUE: 'Continua',
25 | LEGAL_ACCEPT: 'Accetto',
26 | LEGAL_NO_ACCEPT: 'Non accetto',
27 | DELETE: 'Cancella',
28 | CANCEL: 'Reset',
29 | SUBMIT: 'Registra',
30 | UPLOAD_FILE: 'Invia un file',
31 | Y: 'S',
32 | N: 'N'
33 | });
34 |
35 | }]);
36 |
--------------------------------------------------------------------------------
/config/i18n/french.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angular-tellform').config(['$translateProvider', function ($translateProvider) {
4 |
5 | $translateProvider.translations('french', {
6 | FORM_SUCCESS: 'Votre formulaire a été enregistré!',
7 | REVIEW: 'Incomplet',
8 | BACK_TO_FORM: 'Retourner au formulaire',
9 | EDIT_FORM: 'Éditer le Tellform',
10 | CREATE_FORM: 'Créer un TellForm',
11 | ADVANCEMENT: '{{done}} complétés sur {{total}}',
12 | CONTINUE_FORM: 'Aller au formulaire',
13 | REQUIRED: 'obligatoire',
14 | COMPLETING_NEEDED: '{{answers_not_completed}} réponse(s) doive(nt) être complétée(s)',
15 | OPTIONAL: 'facultatif',
16 | ERROR_EMAIL_INVALID: 'Merci de rentrer une adresse mail valide',
17 | ERROR_NOT_A_NUMBER: 'Merce de ne rentrer que des nombres',
18 | ERROR_URL_INVALID: 'Merci de rentrer une url valide',
19 | OK: 'OK',
20 | ENTER: 'presser ENTRÉE',
21 | YES: 'Oui',
22 | NO: 'Non',
23 | NEWLINE: 'presser SHIFT+ENTER pour créer une nouvelle ligne',
24 | CONTINUE: 'Continuer',
25 | LEGAL_ACCEPT: 'J’accepte',
26 | LEGAL_NO_ACCEPT: 'Je n’accepte pas',
27 | DELETE: 'Supprimer',
28 | CANCEL: 'Réinitialiser',
29 | SUBMIT: 'Enregistrer',
30 | UPLOAD_FILE: 'Envoyer un fichier',
31 | Y: 'O',
32 | N: 'N'
33 | });
34 |
35 | }]);
36 |
--------------------------------------------------------------------------------
/config/i18n/spanish.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angular-tellform').config(['$translateProvider', function ($translateProvider) {
4 |
5 | $translateProvider.translations('spanish', {
6 | FORM_SUCCESS: '¡El formulario ha sido enviado con éxito!',
7 | REVIEW: 'Revisar',
8 | BACK_TO_FORM: 'Regresar al formulario',
9 | EDIT_FORM: 'Crear un TellForm',
10 | CREATE_FORM: 'Editar este TellForm',
11 | ADVANCEMENT: '{{done}} de {{total}} contestadas',
12 | CONTINUE_FORM: 'Continuar al formulario',
13 | REQUIRED: 'Información requerida',
14 | COMPLETING_NEEDED: '{{answers_not_completed}} respuesta(s) necesita(n) ser completada(s)',
15 | OPTIONAL: 'Opcional',
16 | ERROR_EMAIL_INVALID: 'Favor de proporcionar un correo electrónico válido',
17 | ERROR_NOT_A_NUMBER: 'Por favor, introduzca sólo números válidos',
18 | ERROR_URL_INVALID: 'Favor de proporcionar un url válido',
19 | OK: 'OK',
20 | ENTER: 'pulse INTRO',
21 | YES: 'Si',
22 | NO: 'No',
23 | NEWLINE: 'presione SHIFT+INTRO para crear una nueva línea',
24 | CONTINUE: 'Continuar',
25 | LEGAL_ACCEPT: 'Acepto',
26 | LEGAL_NO_ACCEPT: 'No acepto',
27 | DELETE: 'Eliminar',
28 | CANCEL: 'Cancelar',
29 | SUBMIT: 'Registrar',
30 | UPLOAD_FILE: 'Cargar el archivo',
31 | Y: 'S',
32 | N: 'N'
33 | });
34 |
35 | }]);
36 |
--------------------------------------------------------------------------------
/config/i18n/english.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angular-tellform').config(['$translateProvider', function ($translateProvider) {
4 |
5 | $translateProvider.translations('english', {
6 | FORM_SUCCESS: 'Form entry successfully submitted!',
7 | REVIEW: 'Review',
8 | BACK_TO_FORM: 'Go back to Form',
9 | EDIT_FORM: 'Edit this TellForm',
10 | CREATE_FORM: 'Create this TellForm',
11 | ADVANCEMENT: '{{done}} out of {{total}} answered',
12 | CONTINUE_FORM: 'Continue to Form',
13 | REQUIRED: 'required',
14 | COMPLETING_NEEDED: '{{answers_not_completed}} answer(s) need completing',
15 | OPTIONAL: 'optional',
16 | ERROR_EMAIL_INVALID: 'Please enter a valid email address',
17 | ERROR_NOT_A_NUMBER: 'Please enter valid numbers only',
18 | ERROR_URL_INVALID: 'Please a valid url',
19 | OK: 'OK',
20 | ENTER: 'press ENTER',
21 | YES: 'Yes',
22 | NO: 'No',
23 | NEWLINE: 'press SHIFT+ENTER to create a newline',
24 | CONTINUE: 'Continue',
25 | LEGAL_ACCEPT: 'I accept',
26 | LEGAL_NO_ACCEPT: 'I don’t accept',
27 | DELETE: 'Delete',
28 | CANCEL: 'Cancel',
29 | SUBMIT: 'Submit',
30 | UPLOAD_FILE: 'Upload your File'
31 | });
32 |
33 | $translateProvider.preferredLanguage('english')
34 | .fallbackLanguage('english')
35 | .useSanitizeValueStrategy('escape');
36 |
37 | }]);
38 |
--------------------------------------------------------------------------------
/gruntfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function(grunt) {
4 | require('jit-grunt')(grunt);
5 |
6 | // Project Configuration
7 | grunt.initConfig({
8 | ngAnnotate: {
9 | production: {
10 | files: {
11 | 'dist/form.js': [
12 | 'config/**/*.js', 'controllers/**/*.js',
13 | 'directives/**/*.js', 'services/**/*.js',
14 | 'dist/template.js'
15 | ]
16 | }
17 | }
18 | },
19 | html2js: {
20 | options: {
21 | base: '',
22 | module: 'angular-tellform.templates',
23 | singleModule: true,
24 | rename: function (moduleName) {
25 | return 'modules/forms/base/' + moduleName;
26 | }
27 | },
28 | form: {
29 | src: ['views/**/*.html'],
30 | dest: 'dist/template.js'
31 | }
32 | },
33 | cssmin: {
34 | combine: {
35 | files: {
36 | 'dist/form.css': 'css/**/*.css'
37 | }
38 | }
39 | },
40 | browserify: {
41 | dist: {
42 | files: {
43 | 'dist/bundle.js': ['index.js', 'dist/template.js']
44 | }
45 | }
46 | }
47 | });
48 |
49 | // Making grunt default to force in order not to break the project.
50 | grunt.option('force', true);
51 |
52 | // Default task(s).
53 | grunt.registerTask('default', ['html2js:form', 'ngAnnotate', 'cssmin', 'browserify:dist']);
54 | };
55 |
--------------------------------------------------------------------------------
/views/directiveViews/field/rating.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 | {{index+1}}
7 |
8 |
9 | {{field.title}}
10 | {{ 'OPTIONAL' | translate }}
11 |
12 |
13 | {{field.description}}
14 |
15 |
16 |
17 |
18 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/views/directiveViews/field/date.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 | {{index+1}}
7 |
8 |
9 | {{field.title}}
10 | {{ 'OPTIONAL' | translate }}
11 |
12 |
13 | {{field.description}}
14 |
15 |
16 |
33 |
34 |
--------------------------------------------------------------------------------
/directives/render-form.client.directive.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angular-tellform').directive('angularTellform',
4 | ['$rootScope', '$state', 'Auth', function ($rootScope, $state, Auth) {
5 | return {
6 | templateUrl: 'modules/forms/base/views/submit-form.client.view.html',
7 | restrict: 'E',
8 | scope: {
9 | myform:'='
10 | },
11 | controller: function($document, $window, $scope){
12 | console.log('angular-tellform directive');
13 | $scope.authentication = Auth;
14 | $scope.myform.visible_form_fields = _.filter($scope.myform.form_fields, function(field){
15 | return (field.deletePreserved === false);
16 | });
17 |
18 | if(!$scope.myform.isLive){
19 | // Show navbar if form is not public AND user IS loggedin
20 | if($scope.authentication.isAuthenticated()){
21 | $scope.hideNav = $rootScope.hideNav = false;
22 | }
23 | // Redirect if form is not public user IS NOT loggedin
24 | else {
25 | $scope.hideNav = $rootScope.hideNav = true;
26 | $state.go('access_denied');
27 | }
28 | }else{
29 | $scope.hideNav = $rootScope.hideNav = true;
30 | }
31 |
32 | }
33 | };
34 | }]);
35 |
--------------------------------------------------------------------------------
/services/form-fields.client.service.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | //TODO: DAVID: URGENT: Make this a $resource that fetches valid field types from server
4 | angular.module('angular-tellform').service('FormFields', function() {
5 | this.types = [
6 | {
7 | name : 'textfield',
8 | value : 'Short Text'
9 | },
10 | {
11 | name : 'email',
12 | value : 'Email'
13 | },
14 | {
15 | name : 'radio',
16 | value : 'Multiple Choice'
17 | },
18 | {
19 | name : 'dropdown',
20 | value : 'Dropdown'
21 | },
22 | {
23 | name : 'date',
24 | value : 'Date'
25 | },
26 | {
27 | name : 'textarea',
28 | value : 'Paragraph Text'
29 | },
30 | {
31 | name : 'yes_no',
32 | value : 'Yes/No'
33 | },
34 | {
35 | name : 'legal',
36 | value : 'Legal'
37 | },
38 | // {
39 | // name : 'sig',
40 | // value : 'Signature'
41 | // },
42 | // {
43 | // name : 'file',
44 | // value : 'File Upload'
45 | // },
46 | {
47 | name : 'rating',
48 | value : 'Rating'
49 | },
50 | {
51 | name : 'link',
52 | value : 'Link'
53 | },
54 | {
55 | name : 'number',
56 | value : 'Numbers'
57 | },
58 | // {
59 | // name : 'scale',
60 | // value : 'Opinion Scale'
61 | // },
62 | // {
63 | // name : 'stripe',
64 | // value : 'Payment'
65 | // },
66 | {
67 | name : 'statement',
68 | value : 'Statement'
69 | }
70 | ];
71 | });
--------------------------------------------------------------------------------
/views/directiveViews/field/dropdown.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 | {{index+1}}
7 |
8 |
9 | {{field.title}}
10 | {{ 'OPTIONAL' | translate }}
11 |
12 |
13 | {{field.description}}
14 |
15 |
16 |
17 |
27 |
28 |
29 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/views/directiveViews/field/radio.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 | {{index+1}}
9 |
10 |
11 | {{field.title}}
12 | {{ 'OPTIONAL' | translate }}
13 |
14 |
15 | {{field.description}}
16 |
17 |
18 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/config/forms.client.config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Configuring the Forms drop-down menus
4 | angular.module('angular-tellform')
5 | .filter('formValidity', function(){
6 | return function(formObj){
7 | if(formObj && formObj.form_fields && formObj.visible_form_fields){
8 |
9 | //get keys
10 | var formKeys = Object.keys(formObj);
11 |
12 | //we only care about things that don't start with $
13 | var fieldKeys = formKeys.filter(function(key){
14 | return key[0] !== '$';
15 | });
16 |
17 | var fields = formObj.form_fields;
18 |
19 | var valid_count = fields.filter(function(field){
20 | if(typeof field === 'object' && field.fieldType !== 'statement' && field.fieldType !== 'rating'){
21 | return !!(field.fieldValue);
22 | }
23 |
24 | }).length;
25 | return valid_count - (formObj.form_fields.length - formObj.visible_form_fields.length);
26 | }
27 | return 0;
28 | };
29 | }).factory('$state', [function() {
30 | return {
31 | go: function() {}
32 | };
33 | }]).constant('FORM_URL', '/form/:formId')
34 | .value('supportedFields', [
35 | 'textfield',
36 | 'textarea',
37 | 'date',
38 | 'dropdown',
39 | 'hidden',
40 | 'password',
41 | 'radio',
42 | 'legal',
43 | 'statement',
44 | 'rating',
45 | 'yes_no',
46 | 'number',
47 | 'natural'
48 | ]).value('SendVisitorData', {
49 | send: function(){}
50 | }).factory('Auth', [
51 | function() {
52 | var service = {
53 | _currentUser: null,
54 | get currentUser(){
55 | return this._currentUser;
56 | },
57 | ensureHasCurrentUser: function() {
58 | return null;
59 | },
60 | isAuthenticated: function() {
61 | return false;
62 | },
63 | getUserState: function() {
64 | return '';
65 | },
66 | login: function() {
67 | },
68 | logout: function() {
69 | }
70 | };
71 | return service;
72 | }
73 | ]);
74 |
--------------------------------------------------------------------------------
/views/directiveViews/field/file.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{index+1}}
7 |
8 |
9 | {{field.title}}
10 | {{ 'OPTIONAL' | translate }}
11 |
12 |
13 |
40 |
41 |
--------------------------------------------------------------------------------
/views/directiveViews/field/textarea.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{index+1}}
6 |
7 |
8 | {{field.title}}
9 | {{ 'OPTIONAL' | translate }}
10 |
11 |
{{ 'NEWLINE' | translate }}
12 |
13 | {{field.description}}
14 |
15 |
16 |
17 | Press SHIFT+ENTER to add a newline
18 |
30 |
31 |
32 |
33 |
34 |
36 |
43 |
44 |
45 | {{ 'ENTER' | translate }}
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-tellform",
3 | "description": "Frontend UI for Tellform",
4 | "version": "1.0.0",
5 | "main": [
6 | "dist/bundle.js",
7 | "dist/form.css"
8 | ],
9 | "authors": [
10 | "David Baldwynn (http://baldwynn.me)",
11 | "Samuel Laulhau (https://lalop.co)"
12 | ],
13 | "license": "MIT",
14 | "keywords": [
15 | "forms",
16 | "tellform",
17 | "formui",
18 | "ui"
19 | ],
20 | "moduleType": [
21 | "amd",
22 | "globals"
23 | ],
24 | "homepage": "https://github.com/tellform/angular-tellform",
25 | "ignore": [
26 | ".*",
27 | "node_modules",
28 | "bower_components",
29 | "demo",
30 | "test"
31 | ],
32 | "dependencies": {
33 | "angular-bootstrap": "^1.3.3",
34 | "angular-busy": "^4.1.3",
35 | "angular-animate": "^1.5.6",
36 | "angular-input-stars": "*",
37 | "angular-resource": "^1.5.6",
38 | "angular-sanitize": "^1.5.6",
39 | "angular-scroll": "^1.0.0",
40 | "angular-strap": "^2.3.9",
41 | "angular-ui-date": "^1.0.1",
42 | "angular-ui-event": "*",
43 | "angular-ui-indeterminate": "*",
44 | "angular-ui-mask": "*",
45 | "angular-ui-scroll": "*",
46 | "angular-ui-scrollpoint": "*",
47 | "angular-ui-select": "^0.18.0",
48 | "angular-ui-utils": "~3.0.0",
49 | "angular": "^1.5.6",
50 | "bootstrap": "~3",
51 | "components-font-awesome": "~4.6.1",
52 | "font-awesome": "^4.6.3",
53 | "file-saver.js": "~1.20150507.2",
54 | "jquery": "~3.0.0",
55 | "lodash": ">=1.3.0",
56 | "ng-file-upload": "^12.0.4",
57 | "restangular": "~1.5.2",
58 | "v-button": "^1.1.1",
59 | "ui-select": "angular-ui-select#^0.16.1",
60 | "angular-ui-router": "^0.3.1",
61 | "angular-translate": "^2.11.0",
62 | "js-yaml": "^3.6.1"
63 | },
64 | "resolutions": {
65 | "angular-animate": "^1.5.6",
66 | "jquery": "~2",
67 | "font-awesome": "^4.6.3",
68 | "angular": "^1.5.6"
69 | },
70 | "private": false
71 | }
72 |
--------------------------------------------------------------------------------
/directives/on-enter-key.client.directive.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | //TODO: DAVID: Need to refactor this
4 | angular.module('angular-tellform').directive('onEnterKey', ['$rootScope', function($rootScope){
5 | return {
6 | restrict: 'A',
7 | link: function($scope, $element, $attrs) {
8 | $element.bind('keydown keypress', function(event) {
9 |
10 | var keyCode = event.which || event.keyCode;
11 |
12 | var onEnterKeyDisabled = false;
13 | if($attrs.onEnterKeyDisabled !== null) onEnterKeyDisabled = $attrs.onEnterKeyDisabled;
14 |
15 | if(keyCode === 13 && !event.shiftKey && !onEnterKeyDisabled) {
16 | event.preventDefault();
17 | $rootScope.$apply(function() {
18 | $rootScope.$eval($attrs.onEnterKey);
19 | });
20 | }
21 | });
22 | }
23 | };
24 | }]).directive('onTabKey', ['$rootScope', function($rootScope){
25 | return {
26 | restrict: 'A',
27 | link: function($scope, $element, $attrs) {
28 | $element.bind('keydown keypress', function(event) {
29 |
30 | var keyCode = event.which || event.keyCode;
31 |
32 | if(keyCode === 9 && !event.shiftKey) {
33 |
34 | event.preventDefault();
35 | $rootScope.$apply(function() {
36 | $rootScope.$eval($attrs.onTabKey);
37 | });
38 | }
39 | });
40 | }
41 | };
42 | }]).directive('onEnterOrTabKey', ['$rootScope', function($rootScope){
43 | return {
44 | restrict: 'A',
45 | link: function($scope, $element, $attrs) {
46 | $element.bind('keydown keypress', function(event) {
47 |
48 | var keyCode = event.which || event.keyCode;
49 |
50 | if((keyCode === 13 || keyCode === 9) && !event.shiftKey) {
51 | event.preventDefault();
52 | $rootScope.$apply(function() {
53 | $rootScope.$eval($attrs.onEnterOrTabKey);
54 | });
55 | }
56 | });
57 | }
58 | };
59 | }]).directive('onTabAndShiftKey', ['$rootScope', function($rootScope){
60 | return {
61 | restrict: 'A',
62 | link: function($scope, $element, $attrs) {
63 | $element.bind('keydown keypress', function(event) {
64 |
65 | var keyCode = event.which || event.keyCode;
66 |
67 | if(keyCode === 9 && event.shiftKey) {
68 | event.preventDefault();
69 | $rootScope.$apply(function() {
70 | $rootScope.$eval($attrs.onTabAndShiftKey);
71 | });
72 | }
73 | });
74 | }
75 | };
76 | }]);
77 |
--------------------------------------------------------------------------------
/views/directiveViews/field/legal.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 | {{index+1}}
8 |
9 |
10 | {{field.title}}
11 | {{ 'OPTIONAL' | translate }}
12 |
13 |
14 |
{{field.description}}
15 |
16 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/views/directiveViews/field/yes_no.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 | {{index+1}}
9 |
10 |
11 | {{field.title}}
12 |
13 | {{ 'OPTIONAL' | translate }}
14 |
15 |
16 |
17 | {{field.description}}
18 |
19 |
20 |
21 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/views/directiveViews/field/textfield.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 | {{index+1}}
7 |
8 |
9 |
10 | {{field.title}}
11 |
12 |
13 | ({{ 'OPTIONAL' | translate }})
14 |
15 |
16 |
17 |
18 | {{field.description}}
19 |
20 |
21 |
22 |
38 |
39 |
40 |
41 |
42 | Error:
43 | {{ 'ERROR_EMAIL_INVALID' | translate }}
44 | {{ 'ERROR_NOT_A_NUMBER' | translate }}
45 | {{ 'ERROR_URL_INVALID' | translate }}
46 |
47 |
48 |
49 |
50 |
52 |
59 |
60 |
61 | {{ 'ENTER' | translate }}
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/directives/field.client.directive.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // coffeescript's for in loop
4 | var __indexOf = [].indexOf || function(item) {
5 | for (var i = 0, l = this.length; i < l; i++) {
6 | if (i in this && this[i] === item) return i;
7 | }
8 | return -1;
9 | };
10 |
11 | angular.module('angular-tellform').directive('fieldDirective', ['$http', '$compile', '$rootScope', '$templateCache', 'supportedFields',
12 | function($http, $compile, $rootScope, $templateCache, supportedFields) {
13 |
14 | var getTemplateUrl = function(fieldType) {
15 | var type = fieldType;
16 |
17 | var templateUrl = 'modules/forms/base/views/directiveViews/field/';
18 |
19 | if (__indexOf.call(supportedFields, type) >= 0) {
20 | templateUrl = templateUrl+type+'.html';
21 | }
22 | return $templateCache.get(templateUrl);
23 | };
24 |
25 | return {
26 | template: '{{field.title}}
',
27 | restrict: 'E',
28 | scope: {
29 | field: '=',
30 | required: '&',
31 | design: '=',
32 | index: '='
33 | },
34 | link: function(scope, element) {
35 |
36 | $rootScope.chooseDefaultOption = scope.chooseDefaultOption = function(type) {
37 | if(type === 'yes_no'){
38 | scope.field.fieldValue = 'true';
39 | }else if(type === 'rating'){
40 | scope.field.fieldValue = 0;
41 | }else if(scope.field.fieldType === 'radio'){
42 | console.log(scope.field);
43 | scope.field.fieldValue = scope.field.fieldOptions[0].option_value;
44 | console.log(scope.field.fieldValue);
45 | }else if(type === 'legal'){
46 | scope.field.fieldValue = 'true';
47 | $rootScope.nextField();
48 | }
49 | };
50 |
51 | scope.setActiveField = $rootScope.setActiveField;
52 |
53 | //Set format only if field is a date
54 | if(scope.field.fieldType === 'date'){
55 | scope.dateOptions = {
56 | changeYear: true,
57 | changeMonth: true,
58 | altFormat: 'mm/dd/yyyy',
59 | yearRange: '1900:-0',
60 | defaultDate: 0
61 | };
62 | }
63 |
64 | var fieldType = scope.field.fieldType;
65 |
66 | if(scope.field.fieldType === 'number' || scope.field.fieldType === 'textfield' || scope.field.fieldType === 'email' || scope.field.fieldType === 'link'){
67 | switch(scope.field.fieldType){
68 | case 'textfield':
69 | scope.field.input_type = 'text';
70 | break;
71 | case 'email':
72 | scope.field.input_type = 'email';
73 | scope.field.placeholder = 'joesmith@example.com';
74 | break;
75 | case 'number':
76 | scope.field.input_type = 'text';
77 | scope.field.validateRegex = /^-?\d+$/;
78 | break;
79 | default:
80 | scope.field.input_type = 'url';
81 | scope.field.placeholder = 'http://example.com';
82 | break;
83 | }
84 | fieldType = 'textfield';
85 | }
86 | var template = getTemplateUrl(fieldType);
87 | element.html(template);
88 | $compile(element.contents())(scope);
89 | }
90 | };
91 | }]);
92 |
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | angular-tellform Demo
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-tellform",
3 | "description": "Frontend UI for Tellform",
4 | "version": "1.0.2",
5 | "homepage": "https://github.com/tellform/angular-tellform",
6 | "authors": [
7 | "David Baldwynn (http://baldwynn.me)",
8 | "Samuel Laulhau (https://samuellaulhau.fr)"
9 | ],
10 | "license": "MIT",
11 | "repository": {
12 | "type": "git",
13 | "url": "https://github.com/tellform/angular-tellform.git"
14 | },
15 | "main": "publish.js",
16 | "engines": {
17 | "node": "~5.0.0",
18 | "npm": "~2.11.2"
19 | },
20 | "keywords": [
21 | "tellform",
22 | "forms",
23 | "formly",
24 | "angularjs",
25 | "angular forms",
26 | "typeform"
27 | ],
28 | "scripts": {},
29 | "dependencies": {
30 | "angular": "^1.5.7",
31 | "angular-animate": "^1.5.7",
32 | "angular-bootstrap": "^0.12.2",
33 | "angular-busy": "^4.1.3",
34 | "angular-input-stars": "^1.5.5",
35 | "angular-resource": "^1.5.7",
36 | "angular-sanitize": "^1.5.7",
37 | "angular-scroll": "^1.0.0",
38 | "angular-strap": "^2.3.9",
39 | "angular-translate": "^2.11.0",
40 | "angular-ui-date": "^1.1.1",
41 | "angular-ui-router": "^0.3.1",
42 | "angular-ui-utils": "^0.1.1",
43 | "jquery": "^2.2.3",
44 | "jquery-ui": "^1.10.5",
45 | "lodash": "~4.11.1",
46 | "ng-file-upload": "^10.0.4",
47 | "ui-select": "~0.16.1",
48 | "v-button": "git+https://git@github.com/whitef0x0/v-button.git"
49 | },
50 | "devDependencies": {
51 | "grunt-browserify": "^5.0.0",
52 | "http-server": "^0.9.0",
53 | "grunt-cli": "~0.1.13",
54 | "grunt-contrib-cssmin": "~0.14.0",
55 | "grunt-contrib-uglify": "~0.11.0",
56 | "grunt-html2js": "~0.3.5",
57 | "grunt-ng-annotate": "~1.0.1",
58 | "jit-grunt": "^0.10.0"
59 | },
60 | "browser": {
61 | "jquery": "./node_modules/jquery/dist/jquery.js",
62 | "jquery-ui-sortable": "./node_modules/jquery-ui/jquery-ui.js",
63 | "angular": "./node_modules/angular/angular.js",
64 | "ng-file-upload": "./node_modules/ng-file-upload/dist/ng-file-upload-all.js",
65 | "angular-animate": "./node_modules/angular-animate/angular-animate.min.js",
66 | "angular-bootstrap": "./node_modules/angular-bootstrap/ui-bootstrap.min.js",
67 | "angular-busy": "./node_modules/angular-busy/dist/angular-busy.min.js",
68 | "angular-input-stars": "./node_modules/angular-input-stars/angular-input-stars.js",
69 | "angular-resource": "./node_modules/angular-resource/angular-resource.min.js",
70 | "angular-sanitize": "./node_modules/angular-sanitize/angular-sanitize.min.js",
71 | "angular-scroll": "./node_modules/angular-scroll/angular-scroll.min.js",
72 | "angular-strap": "./node_modules/angular-strap/dist/angular-strap.min.js",
73 | "angular-ui-date": "./node_modules/angular-ui-date/src/date.js",
74 | "angular-ui-router": "./node_modules/angular-ui-router/release/angular-ui-router.min.js",
75 | "angular-ui-utils": "./node_modules/angular-ui-utils/publish.js"
76 | },
77 | "browserify-shim": {
78 | "jquery": {
79 | "exports": "jQuery"
80 | },
81 | "jquery-ui": {
82 | "depends": "jquery",
83 | "exports": null
84 | },
85 | "angular": {
86 | "exports": "angular",
87 | "depends": "jQuery"
88 | },
89 | "ng-file-upload": {
90 | "exports": "angular.module('ngFileUpload').name"
91 | },
92 | "angular-animate": {
93 | "exports": "angular.module('ngAnimate').name"
94 | },
95 | "angular-bootstrap": {
96 | "exports": "angular.module('ui.bootstrap').name"
97 | },
98 | "angular-busy": {
99 | "exports": "angular.module('cgBusy').name"
100 | },
101 | "angular-input-stars": {
102 | "exports": "angular.module('angular-input-stars').name"
103 | },
104 | "angular-resource": {
105 | "exports": "angular.module('ngResource').name"
106 | },
107 | "angular-sanitize": {
108 | "exports": "angular.module('ngSanitize').name"
109 | },
110 | "angular-scroll": {
111 | "exports": "angular.module('duScroll').name"
112 | },
113 | "angular-strap": {
114 | "exports": "angular.module('mgcrea.ngStrap').name"
115 | },
116 | "angular-ui-date": {
117 | "depends": [
118 | "angular",
119 | "jquery-ui"
120 | ],
121 | "exports": "null"
122 | },
123 | "angular-ui-router": {
124 | "depends": [
125 | "angular"
126 | ],
127 | "exports": null
128 | }
129 | },
130 | "browserify": {
131 | "transform": [
132 | "browserify-shim"
133 | ]
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/views/directiveViews/form/submit-form.client.view.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
42 |
43 |
44 |
148 |
149 |
150 |
166 |
--------------------------------------------------------------------------------
/demo/dist/form.css:
--------------------------------------------------------------------------------
1 | .container.admin-form,section.content>section>section.container{margin-top:70px}.admin-form .panel-heading a:hover,.current-fields .tool-panel>.panel-default .panel-heading a:hover{text-decoration:none}.panel-default.startPage{border-style:dashed;border-color:#a9a9a9;border-width:3px}.busy-updating-wrapper{text-align:center;font-size:20px;position:fixed;bottom:0;right:55px;z-index:1}.busy-submitting-wrapper{position:fixed;top:50%;left:0;right:0;bottom:0}.form-item,.letter,div.form-fields{position:relative}.dropzone h4.panel-title{height:17px;overflow:hidden}.public-form input,.public-form textarea{background-color:rgba(0,0,0,0);border:2px dashed #ddd!important}.public-form input:focus,.public-form textarea:focus{border:2px dashed #ddd!important;outline:0}.public-form input.no-border,.public-form textarea.no-border{border:none!important}section.content p.breakwords{word-break:break-all}.btn{border:1px solid #c6c6c6}.btn[type=submit]{font-size:1.5em;padding:.35em 1.2em}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5;font-size:18px;font-weight:400}.input-block{display:block;width:100%}.modal-footer input[type=text]{min-height:34px;padding:7px 8px;font-size:13px;color:#333;vertical-align:middle;background-color:#fff;background-repeat:no-repeat;background-position:right 8px center;border:1px solid #ccc;border-radius:3px;box-shadow:inset 0 1px 2px rgba(0,0,0,.075)}.modal-footer input[type=text]:focus{outline:0}.modal-body>.modal-body-alert{color:#796620;background-color:#f8eec7;border-color:#f2e09a;margin:-16px -15px 15px;padding:10px 15px;border-style:solid;border-width:1px 0}div.form-fields{padding-top:35vh}.letter{display:-moz-inline-stack;display:inline-block;vertical-align:top;zoom:1;width:16px;padding:0;height:17px;font-size:12px;line-height:19px;border:1px solid #000;border:1px solid rgba(0,0,0,.2);margin-right:7px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;text-align:center;font-weight:700}div.form-submitted>.field.row{padding-bottom:2%;margin-top:35vh}div.form-submitted>.field.row>div{font-size:1.7em}form .accordion-edit{width:inherit}.ui-datepicker.ui-widget{z-index:99!important}form .row.field{padding:1em 0 0;width:inherit}form .row.field>.field-title{margin-top:.5em;font-size:1.2em;padding-bottom:1.8em;width:inherit}form .row.field>.field-input{font-size:1.4em;color:#777}form.submission-form .row.field.statement>.field-title{font-size:1.7em}form.submission-form .row.field.statement>.field-input{font-size:1em;color:#ddd}form.submission-form .select.radio>.field-input input,form.submission-form .select>.field-input input{width:20%}form.submission-form .field.row.radio .btn.activeBtn{background-color:#000!important;background-color:rgba(0,0,0,.7)!important;color:#fff}form.submission-form .field.row.radio .btn{margin-right:1.2em}form.submission-form .select>.field-input .btn{text-align:left;margin-bottom:.7em}form.submission-form .select>.field-input .btn>span{font-size:1.1em}form .field-input>textarea{padding:.45em .9em;width:100%;line-height:160%}form .field-input>input.hasDatepicker{padding:.45em .9em;width:50%;line-height:160%}form .field-input>input.text-field-input{padding:.45em .9em;width:100%;line-height:160%}form .required-error{color:#ddd;font-size:.8em}form .row.field.dropdown>.field-input input{height:34px;border-width:0 0 2px;border-radius:5px}form .row.field.dropdown>.field-input input:focus{border:none}form .row.field.dropdown>.field-input .ui-select-match{border:0 solid grey;border-width:0 0 2px;border-radius:5px}form .dropdown>.field-input .ui-select-choices-row-inner{border-radius:3px;margin:5px;padding:10px;background-color:rgba(0,0,0,.05)}form .dropdown>.field-input .ui-select-choices-row-inner.active,form .dropdown>.field-input .ui-select-choices-row-inner.active:focus{background-color:rgba(0,0,0,.1)}.config-form{max-width:100%}.config-form>.row{padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}div.config-form .row.field{padding-top:1.5em}div.config-form>.row>.container:nth-of-type(odd){border-right:1px #ddd solid}div.config-form.design>.row>.container:nth-of-type(odd){border-right:none}div.config-form .row>.field-input{padding-left:.1em}div.config-form .row>.field-input label{padding-left:1.3em;display:block}.admin-form>.page-header{padding-bottom:0;margin-bottom:40px}.admin-form>.page-header h1{margin-bottom:0;margin-top:0}.admin-form>.page-header>.col-xs-3{padding-top:1.4em}.admin-form .form-controls .row{padding:5px}.admin-form .page-header{border:none}.admin-form .tab-content{padding-top:3em}.admin-form .panel-heading{background-color:#f1f1f1}.admin-form .panel-heading:hover{background-color:#fff;cursor:pointer}.current-fields .panel-body .row.description textarea,.current-fields .panel-body .row.question input[type=text]{width:100%}.current-fields .panel-body .row.options input[type=text]{width:80%}.current-fields .tool-panel>.panel-default:hover{border-color:#9d9d9d;cursor:pointer}.current-fields .tool-panel>.panel-default .panel-heading{background-color:#fff;color:#9d9d9d!important}.current-fields .tool-panel>.panel-default .panel-heading:hover{background-color:#eee;color:#000!important;cursor:pointer}.current-fields .tool-panel>.panel-default .panel-heading a{color:inherit}.submissions-table .table-outer.row{margin:1.5em 0 2em!important}.submissions-table .table-outer .col-xs-12{padding-left:0!important;border:1px solid #ddd;overflow-x:scroll;border-radius:3px}.submissions-table .table>thead>tr>th{min-width:8em}.submissions-table .table>tbody>tr.selected{background-color:#efefef}.admin-form .add-field{background-color:#ddd;padding:0 2%;border-radius:3px}.admin-form .add-field .col-xs-6{padding:.25em .4em}.admin-form .add-field .col-xs-6 .panel-heading{border-width:1px;border-style:solid;border-color:#bbb;border-radius:4px}.admin-form .oscar-field-select{margin:10px 0}.view-form-btn.span{padding-right:.6em}.status-light.status-light-off{color:#BE0000}.status-light.status-light-on{color:#3C0}section.public-form{padding:0 10%}section.public-form .form-submitted{height:100vh}section.public-form .btn{border:1px solid}.form-item{text-align:center;border-bottom:6px inset #ccc;background-color:#eee;width:180px;height:215px;margin-bottom:45px}.form-item.create-new input[type=text]{width:inherit;color:#000;border:none}.form-item.create-new{background-color:#838383;color:#fff}.form-item.create-new.new-form{background-color:#ff8383;z-index:11}.form-item.create-new.new-form:hover{background-color:#ff6464}.form-item.new-form input[type=text]{margin-top:.2em;width:inherit;color:#000;border:none;padding:.3em .6em}.form-item.new-form .custom-select{margin-top:.2em}.form-item.new-form .custom-select select{background-color:#fff}.form-item.new-form .details-row{margin-top:1em}.form-item.new-form .details-row.submit{margin-top:1.7em}.form-item.new-form .details-row.submit .btn{font-size:.95em}.form-item.new-form .title-row{margin-top:1em;top:0}.overlay{position:fixed;top:0;left:0;height:100%;width:100%;background-color:#000;background-color:rgba(0,0,0,.5);z-index:10}.overlay.submitform{background-color:#fff;background-color:rgba(256,256,256,.8)}.activeField,.activeField input{background-color:transparent}.field-directive{z-index:9;padding:10% 10% 10% 0;border:25px solid transparent;position:relative}.activeField{z-index:11;position:relative}.activeField.field-directive{display:inline-block;border-radius:7px;width:100%;border:25px solid transparent}.form-item.create-new:hover,.form-item:hover{border-bottom:8px inset #ccc;background-color:#d9d9d9}.form-item.create-new:hover{background-color:#515151}.form-item>.row.footer{position:absolute;bottom:0;left:30%}.form-item .title-row{position:relative;top:15px;padding-top:3em;padding-bottom:3.65em}.form-item .title-row h4{font-size:1.3em}.form-item.create-new .title-row{padding:0}.form-item.create-new .title-row h4{font-size:7em}.form-item .details-row{margin-top:3.2em}.form-item .details-row small{font-size:.6em}.form-item.create-new .details-row small{font-size:.95em}
--------------------------------------------------------------------------------
/dist/form.css:
--------------------------------------------------------------------------------
1 | .container.admin-form,section.content>section>section.container{margin-top:70px}.admin-form .panel-heading a:hover,.current-fields .tool-panel>.panel-default .panel-heading a:hover{text-decoration:none}.panel-default.startPage{border-style:dashed;border-color:#a9a9a9;border-width:3px}.busy-updating-wrapper{text-align:center;font-size:20px;position:fixed;bottom:0;right:55px;z-index:1}.busy-submitting-wrapper{position:fixed;top:50%;left:0;right:0;bottom:0}.dropzone h4.panel-title{height:17px;overflow:hidden}.public-form input,.public-form textarea{background-color:#000;border:2px dashed #ddd!important}.public-form input:focus,.public-form textarea:focus{border:2px dashed #ddd!important;outline:0}.public-form input.ng-valid,.public-form textarea.ng-valid{border-color:#20FF20!important;border-style:solid!important;border-width:3px!important}.public-form input.ng-invalid.ng-dirty,.public-form textarea.ng-invalid.ng-dirty{border-color:#FA787E!important;border-style:solid!important;border-width:3px!important}section.content p.breakwords{word-break:break-all}.btn{border:1px solid #c6c6c6}.btn[type=submit]{font-size:1.5em;padding:.35em 1.2em}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5;font-size:18px;font-weight:400}.input-block{display:block;width:100%}.modal-footer input[type=text]{min-height:34px;padding:7px 8px;font-size:13px;color:#333;vertical-align:middle;background-color:#fff;background-repeat:no-repeat;background-position:right 8px center;border:1px solid #ccc;border-radius:3px;box-shadow:inset 0 1px 2px rgba(0,0,0,.075)}.modal-footer input[type=text]:focus{outline:0}.modal-body>.modal-body-alert{color:#796620;background-color:#f8eec7;border-color:#f2e09a;margin:-16px -15px 15px;padding:10px 15px;border-style:solid;border-width:1px 0}div.form-fields{position:relative;padding-top:35vh}.letter{position:relative;display:-moz-inline-stack;display:inline-block;vertical-align:top;zoom:1;width:16px;padding:0;height:17px;font-size:12px;line-height:19px;border:1px solid #000;border:1px solid rgba(0,0,0,.2);margin-right:7px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;text-align:center;font-weight:700}div.form-submitted>.field.row{padding-bottom:2%;margin-top:35vh}div.form-submitted>.field.row>div{font-size:1.7em}form .accordion-edit{width:inherit}.ui-datepicker.ui-widget{z-index:99!important}form .row.field .field-number{margin-right:.5em}form .row.field{padding:1em 0 0;width:inherit}form .row.field>.field-title{margin-top:.5em;font-size:1.2em;padding-bottom:1.8em;width:inherit}form .row.field>.field-input{font-size:1.4em;color:#777}form.submission-form .row.field.statement>.field-title{font-size:1.7em}form.submission-form .row.field.statement>.field-input{font-size:1em;color:#ddd}form.submission-form .select.radio>.field-input input,form.submission-form .select>.field-input input{width:20%}form.submission-form .field.row.radio .btn.activeBtn{background-color:#000!important;background-color:rgba(0,0,0,.7)!important;color:#fff}form.submission-form .field.row.radio .btn{margin-right:1.2em}form.submission-form .select>.field-input .btn{text-align:left;margin-bottom:.7em}form.submission-form .select>.field-input .btn>span{font-size:1.1em}form .field-input>textarea{padding:.45em .9em;width:100%;line-height:160%}form .field-input>input.hasDatepicker{padding:.45em .9em;width:50%;line-height:160%}form .field-input>input.text-field-input{padding:.45em .9em;width:100%;line-height:160%}form .required-error{color:#ddd;font-size:.8em}form .row.field.dropdown>.field-input input{height:34px;border-width:0 0 2px;border-radius:5px}form .row.field.dropdown>.field-input input:focus{border:none}form .dropdown>.field-input .ui-select-choices-row-inner{border-radius:3px;margin:5px;padding:10px;background-color:#000;background-color:rgba(0,0,0,.05)}form .dropdown>.field-input .ui-select-choices-row-inner.active,form .dropdown>.field-input .ui-select-choices-row-inner.active:focus{background-color:#000;background-color:rgba(0,0,0,.1)}.config-form{max-width:100%}.config-form>.row{padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}div.config-form .row.field{padding-top:1.5em}div.config-form>.row>.container:nth-of-type(odd){border-right:1px #ddd solid}div.config-form.design>.row>.container:nth-of-type(odd){border-right:none}div.config-form .row>.field-input{padding-left:.1em}div.config-form .row>.field-input label{padding-left:1.3em;display:block}.admin-form>.page-header{padding-bottom:0;margin-bottom:40px}.admin-form>.page-header h1{margin-bottom:0;margin-top:0}.admin-form>.page-header>.col-xs-3{padding-top:1.4em}.admin-form .form-controls .row{padding:5px}.admin-form .page-header{border:none}.admin-form .tab-content{padding-top:3em}.admin-form .panel-heading{background-color:#f1f1f1;position:relative!important}.admin-form .panel-heading:hover{background-color:#fff;cursor:pointer}.current-fields .panel-body .row.description textarea,.current-fields .panel-body .row.question input[type=text]{width:100%}.current-fields .panel-body .row.options input[type=text]{width:80%}.ui-select-choices.ui-select-dropdown{top:2.5em!important}.ui-select-toggle{box-shadow:none!important;border:none!important}.current-fields .tool-panel>.panel-default:hover{border-color:#9d9d9d;cursor:pointer}.current-fields .tool-panel>.panel-default .panel-heading{background-color:#fff;color:#9d9d9d!important}.current-fields .tool-panel>.panel-default .panel-heading:hover{background-color:#eee;color:#000!important;cursor:pointer}.current-fields .tool-panel>.panel-default .panel-heading a{color:inherit}.submissions-table .table-outer.row{margin:1.5em 0 2em!important}.submissions-table .table-outer .col-xs-12{padding-left:0!important;border:1px solid #ddd;overflow-x:scroll;border-radius:3px}.submissions-table .table>thead>tr>th{min-width:8em}.submissions-table .table>tbody>tr.selected{background-color:#efefef}.admin-form .add-field{background-color:#ddd;padding:0 2%;border-radius:3px}.admin-form .add-field .col-xs-6{padding:.25em .4em}.admin-form .add-field .col-xs-6 .panel-heading{border-width:1px;border-style:solid;border-color:#bbb;border-radius:4px}.admin-form .oscar-field-select{margin:10px 0}.view-form-btn.span{padding-right:.6em}.status-light.status-light-off{color:#BE0000}.status-light.status-light-on{color:#3C0}section.public-form{padding:0 10%}section.public-form .form-submitted{height:100vh}section.public-form .btn{border:1px solid}.form-item{text-align:center;border-bottom:6px inset #ccc;background-color:#eee;width:180px;position:relative;height:215px;margin-bottom:45px}.form-item.create-new input[type=text]{width:inherit;color:#000;border:none}.form-item.create-new{background-color:#838383;color:#fff}.form-item.create-new.new-form{background-color:#ff8383;z-index:11}.form-item.create-new.new-form:hover{background-color:#ff6464}.form-item.new-form input[type=text]{margin-top:.2em;width:inherit;color:#000;border:none;padding:.3em .6em}.form-item.new-form .custom-select{margin-top:.2em}.form-item.new-form .custom-select select{background-color:#fff}.form-item.new-form .details-row{margin-top:1em}.form-item.new-form .details-row.submit{margin-top:1.7em}.form-item.new-form .details-row.submit .btn{font-size:.95em}.form-item.new-form .title-row{margin-top:1em;top:0}.overlay{position:fixed;top:0;left:0;height:100%;width:100%;background-color:#000;background-color:rgba(0,0,0,.5);z-index:10}.overlay.submitform{background-color:#fff;background-color:rgba(256,256,256,.8)}.activeField,.activeField input{background-color:transparent}.field-directive{z-index:9;padding:10% 10% 10% 0;border:25px solid transparent;position:relative}.activeField{z-index:11;position:relative}.activeField.field-directive{display:inline-block;border-radius:7px;width:100%;border:25px solid transparent}.form-item.create-new:hover,.form-item:hover{border-bottom:8px inset #ccc;background-color:#d9d9d9}.form-item.create-new:hover{background-color:#515151}.form-item>.row.footer{position:absolute;bottom:0;left:30%}.form-item .title-row{position:relative;top:15px;padding-top:3em;padding-bottom:3.65em}.form-item .title-row h4{font-size:1.3em}.form-item.create-new .title-row{padding:0}.form-item.create-new .title-row h4{font-size:7em}.form-item .details-row{margin-top:3.2em}.form-item .details-row small{font-size:.6em}.form-item.create-new .details-row small{font-size:.95em}
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Angular Tellform
2 |
3 | This module gives you the standalone front-end of tellform. It handles form rendering and form ui. For you to use this module you must have an API endpoint, such as [FormKeep](https://formkeep.com) or [Formlets](https://formlets.org).
4 |
5 | ```
6 |
9 | ```
10 |
11 | ## Installation
12 |
13 | via bower
14 |
15 | ```bower install angular-tellform```
16 |
17 | via npm
18 |
19 | ```npm install angular-tellform```
20 |
21 | ## Quick Example
22 |
23 | This serves as a quick guide to setting up and using angular-tellform in a small angular project. If you are looking for API documentation, please refer to the next section instead.
24 |
25 | ### Step 1. Add as a dependency
26 | First add *angular-tellform* as a dependency to your angular module/app.
27 |
28 | _app.js_
29 | ```
30 | 'use strict';
31 |
32 | angular.module('myModule', ['angular-tellform']);
33 | ```
34 |
35 | ### Step 2. Set the form data
36 | Set $scope.form in your controller to the JSON object of your form.
37 |
38 | *app.js*
39 | ```
40 | ...
41 |
42 | angular.module('myModule').controller('MyFormCtrl', function MyFormCtrl($scope) {
43 |
44 | $scope.form = {
45 | "title": "Job Application Example",
46 | "design": {
47 | "colors": {
48 | "buttonTextColor": "#5C780A",
49 | "buttonColor": "#C5F044",
50 | "answerColor": "#333",
51 | "questionColor": "#6D8524",
52 | "backgroundColor": "#E4F8A8"
53 | }
54 | },
55 | "hideFooter": false,
56 | "startPage": {
57 | "buttons": [],
58 | "introButtonText": "Apply Now",
59 | "introTitle": "We're looking for a great Growth Hacker",
60 | "showStart": true
61 | },
62 | "form_fields": [{
63 | "lastModified": "2016-04-22T23:02:46.017Z",
64 | "title": "How would you rate your experience and knowledge of running split tests?",
65 | "fieldType": "rating",
66 | "fieldValue": 1,
67 | "_id": "571940102aa1f3ff5e205b5d",
68 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
69 | "deletePreserved": false,
70 | "disabled": false,
71 | "required": true,
72 | "ratingOptions": {
73 | "shape": "thumbs-up",
74 | "steps": 5
75 | },
76 | "description": ""
77 | }, {
78 | "lastModified": "2016-04-22T23:02:46.017Z",
79 | "title": "And how would you rate your creativity and ability to find innovative solutions?",
80 | "fieldType": "rating",
81 | "fieldValue": 1,
82 | "_id": "571940222aa1f3ff5e205b5e",
83 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
84 | "deletePreserved": false,
85 | "disabled": false,
86 | "required": true,
87 | "ratingOptions": {
88 | "shape": "thumbs-up",
89 | "steps": 5
90 | },
91 | "description": ""
92 | }],
93 | "language": "english"
94 | };
95 |
96 | $scope.endPoint="https://myurl.com/endpoint";
97 |
98 | });
99 | ```
100 |
101 | ### Step 3. Modifying the view
102 | Then add the angular-tellform directive to your controller's html view
103 |
104 | *view.html*
105 | ```
106 | ...
107 |
108 |
111 |
112 | ...
113 | ```
114 |
115 | After this you will have a form displayed inside your **section** element. Since the directive is bounded to $scope.form, if you want to update the form all you need to do is change $scope.form to a new value.
116 |
117 | ## Form JSON Spec
118 |
119 | A typical JSON object for form data will look like this:
120 | ```
121 | {
122 | "title": "Job Application Example",
123 | "design": {
124 | "colors": {
125 | "buttonTextColor": "#5C780A",
126 | "buttonColor": "#C5F044",
127 | "answerColor": "#333",
128 | "questionColor": "#6D8524",
129 | "backgroundColor": "#E4F8A8"
130 | }
131 | },
132 | "hideFooter": false,
133 | "startPage": {
134 | "buttons": [],
135 | "introButtonText": "Apply Now",
136 | "introTitle": "We're looking for a great Growth Hacker",
137 | "showStart": true
138 | },
139 | "form_fields": [{
140 | "lastModified": "2016-04-22T23:02:46.017Z",
141 | "title": "How would you rate your experience and knowledge of running split tests?",
142 | "fieldType": "rating",
143 | "fieldValue": 1,
144 | "_id": "571940102aa1f3ff5e205b5d",
145 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
146 | "deletePreserved": false,
147 | "disabled": false,
148 | "required": true,
149 | "ratingOptions": {
150 | "shape": "thumbs-up",
151 | "steps": 5
152 | },
153 | "description": ""
154 | }, {
155 | "lastModified": "2016-04-22T23:02:46.017Z",
156 | "title": "And how would you rate your creativity and ability to find innovative solutions?",
157 | "fieldType": "rating",
158 | "fieldValue": 1,
159 | "_id": "571940222aa1f3ff5e205b5e",
160 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
161 | "deletePreserved": false,
162 | "disabled": false,
163 | "required": true,
164 | "ratingOptions": {
165 | "shape": "thumbs-up",
166 | "steps": 5
167 | },
168 | "description": ""
169 | }],
170 | "language": "english"
171 | ```
172 |
173 | ### title
174 |
175 | **Required**
176 |
177 | Type: `String`
178 |
179 | The title of the form
180 |
181 | * Must be unique.
182 | * Consecutive dashes or dots not allowed.
183 |
184 |
185 | ### design
186 |
187 | **Required**
188 |
189 | Type: `Object`
190 |
191 | The object containing the CSS styles and colors for the form
192 |
193 | #### design.colors.buttonTextColor
194 |
195 | **Required**
196 |
197 | Type: `String`
198 |
199 | The hex color of the button text
200 |
201 | #### design.colors.buttonColor
202 |
203 | **Required**
204 |
205 | Type: `String`
206 |
207 | The hex color of the button background
208 |
209 | #### colors.answerColor
210 |
211 | **Required**
212 |
213 | Type: `String`
214 |
215 | The hex color of the answer (input field) text.
216 |
217 | #### design.colors.questionColor
218 |
219 | **Required**
220 |
221 | Type: `String`
222 |
223 | The hex color of the question text.
224 |
225 | #### design.colors.backgroundColor
226 |
227 | **Required**
228 |
229 | Type: `String`
230 |
231 | The hex color of the form background.
232 |
233 | ### hideFooter
234 | *Recommended*
235 |
236 | Type: `Boolean`
237 |
238 | If it is true, form footer will be hidden and vice-versa if it is false
239 |
240 | ### startPage
241 | **Required**
242 |
243 | Type: `Object`
244 |
245 | Stores form's startPage data
246 |
247 | ```
248 | "startPage": {
249 | "buttons": [], //Array of Buttons
250 | "introButtonText": "Apply Now", //Continue button text
251 | "introTitle": "We're looking for a great Growth Hacker", //Intro title
252 | "showStart": true //Hides Start Page if false
253 | }
254 | ```
255 |
256 | ### form_fields
257 |
258 | **Required**
259 |
260 | Type: `Array` of `Object`
261 |
262 | The array of form fields that your form will display.
263 |
264 | ### language
265 |
266 | *Reccomended*
267 |
268 | Type: `String`
269 |
270 | Specifies the language that your form will be rendered in
271 |
272 | * Must be either `english`, `spanish`, `french`, `german` or `italian`
273 | * Defaults to `english` if specified
274 |
275 | ## Development
276 |
277 | First clone the repository and run `bower install`.
278 |
279 | When you want to test your code, run
280 | ```
281 | grunt
282 | bower install
283 | ```
284 | and then open the demo/index.html file for an example form.
285 |
286 | ## Contributing
287 |
288 | When submitting a PR, please make sure to delete your /dist directory.
289 |
290 | ## License
291 |
292 | Uses MIT License. See LICENSE.md for full license terms.
293 |
--------------------------------------------------------------------------------
/directives/submit-form.client.directive.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angular-tellform').directive('submitFormDirective', ['$http', 'TimeCounter', '$filter', '$rootScope', 'Auth', 'SendVisitorData',
4 | function ($http, TimeCounter, $filter, $rootScope, Auth, SendVisitorData) {
5 | return {
6 | templateUrl: 'modules/forms/base/views/directiveViews/form/submit-form.client.view.html',
7 | restrict: 'E',
8 | scope: {
9 | myform:'=',
10 | formEndPoint: '='
11 | },
12 | controller: function($document, $window, $scope){
13 | $scope.authentication = $rootScope.authentication;
14 | $scope.noscroll = false;
15 | $scope.forms = {};
16 |
17 | var form_fields_count = $scope.myform.visible_form_fields.filter(function(field){
18 | if(field.fieldType === 'statement' || field.fieldType === 'rating'){
19 | return false;
20 | }
21 | return true;
22 | }).length;
23 |
24 | var nb_valid = $filter('formValidity')($scope.myform);
25 | $scope.translateAdvancementData = {
26 | done: nb_valid,
27 | total: form_fields_count,
28 | answers_not_completed: form_fields_count - nb_valid
29 | };
30 |
31 | $scope.reloadForm = function(){
32 | //Reset Form
33 | $scope.myform.submitted = false;
34 | $scope.myform.form_fields = _.chain($scope.myform.visible_form_fields).map(function(field){
35 | field.fieldValue = '';
36 | return field;
37 | }).value();
38 |
39 | $scope.loading = false;
40 | $scope.error = '';
41 |
42 | $scope.selected = {
43 | _id: '',
44 | index: 0
45 | };
46 | $scope.setActiveField($scope.myform.visible_form_fields[0]._id, 0, false);
47 |
48 | //console.log($scope.selected);
49 | //Reset Timer
50 | TimeCounter.restartClock();
51 | };
52 |
53 | //Fire event when window is scrolled
54 | $window.onscroll = function(){
55 | $scope.scrollPos = document.body.scrollTop || document.documentElement.scrollTop || 0;
56 | var elemBox = document.getElementsByClassName('activeField')[0].getBoundingClientRect();
57 | $scope.fieldTop = elemBox.top;
58 | $scope.fieldBottom = elemBox.bottom;
59 |
60 | //console.log($scope.forms.myForm);
61 | var field_id;
62 | var field_index;
63 |
64 | if(!$scope.noscroll){
65 | //Focus on submit button
66 | if( $scope.selected.index === $scope.myform.visible_form_fields.length-1 && $scope.fieldBottom < 200){
67 | field_index = $scope.selected.index+1;
68 | field_id = 'submit_field';
69 | $scope.setActiveField(field_id, field_index, false);
70 | }
71 | //Focus on field above submit button
72 | else if($scope.selected.index === $scope.myform.visible_form_fields.length){
73 | if($scope.fieldTop > 200){
74 | field_index = $scope.selected.index-1;
75 | field_id = $scope.myform.visible_form_fields[field_index]._id;
76 | $scope.setActiveField(field_id, field_index, false);
77 | }
78 | }else if( $scope.fieldBottom < 0){
79 | field_index = $scope.selected.index+1;
80 | field_id = $scope.myform.visible_form_fields[field_index]._id;
81 | $scope.setActiveField(field_id, field_index, false);
82 | }else if ( $scope.selected.index !== 0 && $scope.fieldTop > 0) {
83 | field_index = $scope.selected.index-1;
84 | field_id = $scope.myform.visible_form_fields[field_index]._id;
85 | $scope.setActiveField(field_id, field_index, false);
86 | }
87 | //console.log('$scope.selected.index: '+$scope.selected.index);
88 | //console.log('scroll pos: '+$scope.scrollPos+' fieldTop: '+$scope.fieldTop+' fieldBottom: '+$scope.fieldBottom);
89 | $scope.$apply();
90 | }
91 | };
92 |
93 | /*
94 | ** Field Controls
95 | */
96 | var getActiveField = function(){
97 | if($scope.selected === null){
98 | console.error('current active field is null');
99 | throw new Error('current active field is null');
100 | }
101 |
102 | if($scope.selected._id === 'submit_field') {
103 | return $scope.myform.form_fields.length - 1;
104 | } else {
105 | return $scope.selected.index;
106 | }
107 | };
108 |
109 | $scope.setActiveField = $rootScope.setActiveField = function(field_id, field_index, animateScroll) {
110 | if($scope.selected === null || $scope.selected._id === field_id){
111 | //console.log('not scrolling');
112 | //console.log($scope.selected);
113 | return;
114 | }
115 | //console.log('field_id: '+field_id);
116 | //console.log('field_index: '+field_index);
117 | //console.log($scope.selected);
118 |
119 | $scope.selected._id = field_id;
120 | $scope.selected.index = field_index;
121 |
122 | var nb_valid = $filter('formValidity')($scope.myform);
123 | $scope.translateAdvancementData = {
124 | done: nb_valid,
125 | total: form_fields_count,
126 | answers_not_completed: form_fields_count - nb_valid
127 | };
128 |
129 | if(animateScroll){
130 | $scope.noscroll=true;
131 | setTimeout(function() {
132 | $document.scrollToElement(angular.element('.activeField'), -10, 200).then(function() {
133 | $scope.noscroll = false;
134 | setTimeout(function() {
135 | if (document.querySelectorAll('.activeField .focusOn').length) {
136 | //Handle default case
137 | document.querySelectorAll('.activeField .focusOn')[0].focus();
138 | } else if(document.querySelectorAll('.activeField input').length) {
139 | //Handle case for rating input
140 | document.querySelectorAll('.activeField input')[0].focus();
141 | } else {
142 | //Handle case for dropdown input
143 | document.querySelectorAll('.activeField .selectize-input')[0].focus();
144 | }
145 | });
146 | });
147 | });
148 | }else {
149 | setTimeout(function() {
150 | if (document.querySelectorAll('.activeField .focusOn')[0]) {
151 | //FIXME: DAVID: Figure out how to set focus without scroll movement in HTML Dom
152 | document.querySelectorAll('.activeField .focusOn')[0].focus();
153 | } else {
154 | document.querySelectorAll('.activeField input')[0].focus();
155 | }
156 | });
157 | }
158 |
159 | SendVisitorData.send($scope.myform, getActiveField(), TimeCounter.getTimeElapsed());
160 | };
161 |
162 | $rootScope.nextField = $scope.nextField = function(){
163 | //console.log('nextfield');
164 | //console.log($scope.selected.index);
165 | //console.log($scope.myform.visible_form_fields.length-1);
166 | var selected_index, selected_id;
167 | if($scope.selected.index < $scope.myform.visible_form_fields.length-1){
168 | selected_index = $scope.selected.index+1;
169 | selected_id = $scope.myform.visible_form_fields[selected_index]._id;
170 | $rootScope.setActiveField(selected_id, selected_index, true);
171 | } else if($scope.selected.index === $scope.myform.visible_form_fields.length-1) {
172 | //console.log('Second last element');
173 | selected_index = $scope.selected.index+1;
174 | selected_id = 'submit_field';
175 | $rootScope.setActiveField(selected_id, selected_index, true);
176 | }
177 | };
178 |
179 | $rootScope.prevField = $scope.prevField = function(){
180 | if($scope.selected.index > 0){
181 | var selected_index = $scope.selected.index - 1;
182 | var selected_id = $scope.myform.visible_form_fields[selected_index]._id;
183 | $scope.setActiveField(selected_id, selected_index, true);
184 | }
185 | };
186 |
187 | /*
188 | ** Form Display Functions
189 | */
190 | $scope.exitStartPage = function(){
191 | $scope.myform.startPage.showStart = false;
192 | if($scope.myform.visible_form_fields.length > 0){
193 | $scope.selected._id = $scope.myform.visible_form_fields[0]._id;
194 | }
195 | };
196 |
197 | $rootScope.goToInvalid = $scope.goToInvalid = function() {
198 | document.querySelectorAll('.ng-invalid.focusOn')[0].focus();
199 | };
200 |
201 | $rootScope.submitForm = $scope.submitForm = function() {
202 |
203 | var _timeElapsed = TimeCounter.stopClock();
204 | $scope.loading = true;
205 |
206 | var form = _.cloneDeep($scope.myform);
207 |
208 | form.timeElapsed = _timeElapsed;
209 |
210 | form.percentageComplete = $filter('formValidity')($scope.myform) / $scope.myform.visible_form_fields.length * 100;
211 | delete form.visible_form_fields;
212 |
213 | for(var i=0; i < $scope.myform.form_fields.length; i++){
214 | if($scope.myform.form_fields[i].fieldType === 'dropdown' && !$scope.myform.form_fields[i].deletePreserved){
215 | $scope.myform.form_fields[i].fieldValue = $scope.myform.form_fields[i].fieldValue.option_value;
216 | }
217 | }
218 |
219 | setTimeout(function () {
220 | $scope.submitPromise = $http.post($scope.formEndPoint, form)
221 | .success(function (data, status, headers) {
222 | console.log($scope.myform.form_fields[0]);
223 | $scope.myform.submitted = true;
224 | $scope.loading = false;
225 | SendVisitorData.send($scope.myform, getActiveField(), _timeElapsed);
226 | })
227 | .error(function (error) {
228 | $scope.loading = false;
229 | console.error(error);
230 | $scope.error = error.message;
231 | });
232 | }, 500);
233 | };
234 |
235 | //Reload our form
236 | $scope.reloadForm();
237 | }
238 | };
239 | }
240 | ]);
241 |
--------------------------------------------------------------------------------
/css/form.css:
--------------------------------------------------------------------------------
1 | .panel-default.startPage {
2 | border-style: dashed;
3 | border-color: #a9a9a9;
4 | border-width:3px;
5 | }
6 |
7 | .busy-updating-wrapper {
8 | text-align: center;
9 | font-size: 20px;
10 | position: fixed;
11 | bottom: 0;
12 | right: 55px;
13 | z-index: 1;
14 | }
15 |
16 | .busy-submitting-wrapper {
17 | position: fixed;
18 | top: 50%;
19 | left: 0;
20 | right: 0;
21 | bottom: 0;
22 | }
23 |
24 | .dropzone h4.panel-title {
25 | height: 17px;
26 | overflow: hidden;
27 | }
28 |
29 | .container.admin-form {
30 | margin-top: 70px;
31 | }
32 |
33 | .public-form input, .public-form textarea {
34 | background-color: rgba(0,0,0,0);
35 | background-color: #000000;
36 | border: 2px dashed #ddd!important;
37 | }
38 |
39 | .public-form input:focus, .public-form textarea:focus {
40 | border: 2px dashed #ddd!important;
41 | outline: none;
42 | }
43 |
44 | /*.public-form input.no-border.ng-invalid, .public-form textarea.no-border {
45 | border-color: none;
46 | }*/
47 | .public-form input.ng-valid, .public-form textarea.ng-valid {
48 | border-color: #20FF20!important;
49 | border-style: solid!important;
50 | border-width: 3px!important;
51 | }
52 |
53 | .public-form input.ng-invalid.ng-dirty, .public-form textarea.ng-invalid.ng-dirty {
54 | border-color: #FA787E!important;
55 | border-style: solid!important;
56 | border-width: 3px!important;
57 | }
58 |
59 | section.content p.breakwords {
60 | word-break: break-all;
61 | }
62 |
63 | .btn {
64 | border: 1px solid #c6c6c6;
65 | }
66 |
67 | .btn[type='submit'] {
68 | font-size: 1.5em;
69 | padding: 0.35em 1.2em 0.35em 1.2em;
70 | }
71 |
72 | section.content > section > section.container {
73 | margin-top: 70px;
74 | }
75 |
76 | /*
77 | ** Modal CSS Styles
78 | */
79 | .modal-header {
80 | padding: 15px;
81 | border-bottom: 1px solid #e5e5e5;
82 | font-size: 18px;
83 | font-weight: normal;
84 | }
85 | .input-block {
86 | display: block;
87 | width: 100%;
88 | }
89 | .modal-footer input[type='text'] {
90 | min-height: 34px;
91 | padding: 7px 8px;
92 | font-size: 13px;
93 | color: #333;
94 | vertical-align: middle;
95 | background-color: #fff;
96 | background-repeat: no-repeat;
97 | background-position: right 8px center;
98 | border: 1px solid #ccc;
99 | border-radius: 3px;
100 | box-shadow: inset 0 1px 2px rgba(0,0,0,0.075);
101 | }
102 | .modal-footer input[type='text']:focus {
103 | outline: 0;
104 | }
105 | .modal-body > .modal-body-alert {
106 | color: #796620;
107 | background-color: #f8eec7;
108 | border-color: #f2e09a;
109 | margin: -16px -15px 15px;
110 | padding: 10px 15px;
111 | border-style: solid;
112 | border-width: 1px 0;
113 | }
114 |
115 | div.form-fields {
116 | position: relative;
117 | padding-top: 35vh;
118 | }
119 | .letter {
120 | position: relative;
121 | display: -moz-inline-stack;
122 | display: inline-block;
123 | vertical-align: top;
124 | zoom: 1;
125 | width: 16px;
126 | padding: 0;
127 | height: 17px;
128 | font-size: 12px;
129 | line-height: 19px;
130 | border: 1px solid #000;
131 | border: 1px solid rgba(0,0,0,.2);
132 | margin-right: 7px;
133 | -webkit-border-radius: 3px;
134 | -moz-border-radius: 3px;
135 | border-radius: 3px;
136 | text-align: center;
137 | font-weight: 700;
138 | }
139 |
140 | div.form-submitted > .field.row {
141 | padding-bottom: 2%;
142 | margin-top: 35vh;
143 | }
144 | div.form-submitted > .field.row > div {
145 | font-size: 1.7em;
146 | }
147 |
148 | /* Styles for accordion */
149 | form .accordion-edit {
150 | width: inherit;
151 | }
152 |
153 | /*Styles for ui-datepicker*/
154 | .ui-datepicker.ui-widget {
155 | z-index: 99!important;
156 | }
157 |
158 | form .row.field .field-number {
159 | margin-right: 0.5em;
160 | }
161 |
162 | /* Styles for form submission view (/forms/:formID) */
163 | form .row.field {
164 | padding: 1em 0 0 0;
165 | width: inherit;
166 | }
167 | form .row.field > .field-title {
168 | margin-top:0.5em;
169 | font-size:1.2em;
170 | padding-bottom: 1.8em;
171 | width: inherit;
172 | }
173 | form .row.field > .field-input {
174 | font-size: 1.4em;
175 | color: #777;
176 | }
177 | form.submission-form .row.field.statement > .field-title {
178 | font-size:1.7em;
179 | }
180 | form.submission-form .row.field.statement > .field-input {
181 | font-size:1em;
182 | color:#ddd;
183 | }
184 |
185 | form.submission-form .select.radio > .field-input input, form.submission-form .select > .field-input input {
186 | width:20%;
187 | }
188 |
189 | form.submission-form .field.row.radio .btn.activeBtn {
190 | background-color: rgb(0,0,0)!important;
191 | background-color: rgba(0,0,0,0.7)!important;
192 | color: white;
193 | }
194 | form.submission-form .field.row.radio .btn {
195 | margin-right:1.2em;
196 | }
197 |
198 | form.submission-form .select > .field-input .btn {
199 | text-align: left;
200 | margin-bottom:0.7em;
201 | }
202 | form.submission-form .select > .field-input .btn > span {
203 | font-size: 1.10em;
204 | }
205 |
206 | /*form.submission-form .field-input > input:focus {
207 | font-size:1em;
208 | }*/
209 |
210 | form .field-input > textarea{
211 | padding: 0.45em 0.9em;
212 | width: 100%;
213 | line-height: 160%;
214 | }
215 |
216 | form .field-input > input.hasDatepicker{
217 | padding: 0.45em 0.9em;
218 | width: 50%;
219 | line-height: 160%;
220 | }
221 | form .field-input > input.text-field-input{
222 | padding: 0.45em 0.9em;
223 | width: 100%;
224 | line-height: 160%;
225 | }
226 | form .required-error{
227 | color: #ddd;
228 | font-size:0.8em;
229 | }
230 |
231 | form .row.field.dropdown > .field-input input {
232 | height: 34px;
233 | border-width: 0 0 2px 0;
234 | border-radius: 5px;
235 | }
236 |
237 | form .row.field.dropdown > .field-input input:focus {
238 | border: none;
239 | }
240 |
241 | form .dropdown > .field-input .ui-select-choices-row-inner {
242 | border-radius: 3px;
243 | margin: 5px;
244 | padding: 10px;
245 | background-color: #000000;
246 | background-color: rgba(0,0,0,0.05);
247 | }
248 |
249 | form .dropdown > .field-input .ui-select-choices-row-inner.active, form .dropdown > .field-input .ui-select-choices-row-inner.active:focus {
250 | background-color: #000000;
251 | background-color: rgba(0,0,0,0.1);
252 | }
253 | .config-form {
254 | max-width: 100%;
255 | }
256 |
257 | .config-form > .row {
258 | padding: 19px;
259 | margin-bottom: 20px;
260 | background-color: #f5f5f5;
261 | border: 1px solid #e3e3e3;
262 | border-radius: 4px;
263 | -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
264 | -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
265 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
266 | }
267 |
268 | div.config-form .row.field {
269 | padding-top:1.5em;
270 | }
271 |
272 | div.config-form > .row > .container:nth-of-type(odd){
273 | border-right: 1px #ddd solid;
274 | }
275 | div.config-form.design > .row > .container:nth-of-type(odd){
276 | border-right: none;
277 | }
278 |
279 | div.config-form .row > .field-input {
280 | padding-left:0.1em;
281 | }
282 | div.config-form .row > .field-input label {
283 | padding-left:1.3em;
284 | display: block;
285 | }
286 |
287 |
288 | /* Styles for form admin view (/forms/:formID/admin) */
289 | .admin-form > .page-header {
290 | padding-bottom: 0;
291 | margin-bottom: 40px;
292 | }
293 | .admin-form > .page-header h1 {
294 | margin-bottom: 0;
295 | margin-top: 0;
296 | }
297 | .admin-form > .page-header > .col-xs-3 {
298 | padding-top: 1.4em;
299 | }
300 | .admin-form .form-controls .row {
301 | padding: 5px;
302 | }
303 | .admin-form .page-header {
304 | border: none;
305 | }
306 |
307 | /*Styles for admin view tabs */
308 | .admin-form .tab-content {
309 | padding-top: 3em;
310 | }
311 |
312 | .admin-form .panel-heading {
313 | background-color: #f1f1f1;
314 | position: relative!important;
315 | }
316 | .admin-form .panel-heading:hover {
317 | background-color: #fff;
318 | cursor: pointer;
319 | }
320 | .admin-form .panel-heading a:hover {
321 | text-decoration: none;
322 | }
323 |
324 | .current-fields .panel-body .row.question input[type='text'], .current-fields .panel-body .row.description textarea{
325 | width: 100%;
326 | }
327 | .current-fields .panel-body .row.options input[type='text'] {
328 | width: 80%;
329 | }
330 |
331 | /*Override Select2 UI*/
332 | .ui-select-choices.ui-select-dropdown {
333 | top:2.5em!important;
334 | }
335 | .ui-select-toggle {
336 | box-shadow:none!important;
337 | border:none!important;
338 | }
339 |
340 | .current-fields .tool-panel > .panel-default:hover {
341 | border-color: #9d9d9d;
342 | cursor: pointer;
343 | }
344 |
345 | .current-fields .tool-panel > .panel-default .panel-heading {
346 | background-color: #fff;
347 | color: #9d9d9d!important;
348 | }
349 | .current-fields .tool-panel > .panel-default .panel-heading:hover {
350 | background-color: #eee;
351 | color: #000!important;
352 | cursor: pointer;
353 | }
354 | .current-fields .tool-panel > .panel-default .panel-heading a {
355 | color: inherit;
356 | }
357 | .current-fields .tool-panel > .panel-default .panel-heading a:hover{
358 | text-decoration: none;
359 | }
360 |
361 | /*Styles for submission table*/
362 | .submissions-table .table-outer.row {
363 | margin: 1.5em 0 2em 0!important;
364 | }
365 | .submissions-table .table-outer .col-xs-12 {
366 | padding-left: 0!important;
367 | border:1px solid #ddd;
368 | overflow-x: scroll;
369 | border-radius:3px;
370 | }
371 | .submissions-table .table > thead > tr > th {
372 | min-width:8em;
373 | }
374 | .submissions-table .table > tbody > tr.selected {
375 | background-color:#efefef;
376 | }
377 |
378 |
379 | /*Styles for add fields tab*/
380 | .admin-form .add-field {
381 | background-color: #ddd;
382 | padding: 0 2% 0 2%;
383 | border-radius: 3px;
384 | }
385 | .admin-form .add-field .col-xs-6 {
386 | padding: 0.25em 0.4em;
387 | }
388 | .admin-form .add-field .col-xs-6 .panel-heading {
389 | border-width: 1px;
390 | border-style: solid;
391 | border-color: #bbb;
392 | border-radius: 4px;
393 | }
394 |
395 | .admin-form .oscar-field-select {
396 | margin: 10px 0 10px;
397 | }
398 |
399 | .view-form-btn.span {
400 | padding-right:0.6em;
401 | }
402 | .status-light.status-light-off {
403 | color: #BE0000;
404 | }
405 | .status-light.status-light-on {
406 | color: #33CC00;
407 | }
408 |
409 | /* Styles for form list view (/forms) */
410 | section.public-form {
411 | padding: 0 10% 0 10%;
412 | }
413 | section.public-form .form-submitted {
414 | height: 100vh;
415 | }
416 |
417 | section.public-form .btn {
418 | border: 1px solid;
419 | }
420 |
421 | .form-item {
422 | text-align: center;
423 | border-bottom: 6px inset #ccc;
424 | background-color: #eee;
425 | width: 180px;
426 | /*width:100%;*/
427 | position: relative;
428 | height: 215px;
429 | /*padding-bottom: 25%;*/
430 | margin-bottom: 45px;
431 | }
432 | .form-item.create-new input[type='text']{
433 | width: inherit;
434 | color:black;
435 | border:none;
436 | }
437 |
438 | .form-item.create-new {
439 | background-color: rgb(131,131,131);
440 | color: white;
441 | }
442 |
443 | /*CREATE-NEW FORM MODAL*/
444 | .form-item.create-new.new-form {
445 | background-color: rgb(300,131,131);
446 | z-index: 11;
447 | }
448 | .form-item.create-new.new-form:hover {
449 | background-color: rgb(300,100,100);
450 | }
451 | .form-item.new-form input[type='text'] {
452 | margin-top:0.2em;
453 | width: inherit;
454 | color:black;
455 | border:none;
456 | padding: 0.3em 0.6em 0.3em 0.6em;
457 | }
458 | .form-item.new-form .custom-select {
459 | margin-top: 0.2em
460 | }
461 | .form-item.new-form .custom-select select {
462 | background-color: white;
463 | }
464 |
465 |
466 | .form-item.new-form .details-row {
467 | margin-top: 1em;
468 | }
469 | .form-item.new-form .details-row.submit {
470 | margin-top: 1.7em;
471 | }
472 | .form-item.new-form .details-row.submit .btn {
473 | font-size: 0.95em;
474 | }
475 |
476 | .form-item.new-form .title-row {
477 | margin-top: 1em;
478 | top:0;
479 | }
480 |
481 | /*Modal overlay (for lightbox effect)*/
482 | .overlay {
483 | position: fixed;
484 | top: 0;
485 | left: 0;
486 | height: 100%;
487 | width: 100%;
488 | background-color: rgb(0,0,0);
489 | background-color: rgba(0,0,0,0.5);
490 | z-index: 10;
491 | }
492 | .overlay.submitform {
493 | background-color: rgb(256,256,256);
494 | background-color: rgba(256,256,256,0.8);
495 | }
496 | .field-directive {
497 | z-index: 9;
498 | padding: 10% 10% 10% 0;
499 | border: 25px transparent solid;
500 | position: relative;
501 | }
502 | .activeField {
503 | z-index: 11;
504 | position: relative;
505 | background-color: transparent;
506 | }
507 | .activeField.field-directive {
508 | display: inline-block;
509 | border-radius: 7px;
510 | width: 100%;
511 | border: 25px transparent solid;
512 | }
513 | .activeField input {
514 | background-color: transparent;
515 | }
516 |
517 | .form-item:hover, .form-item.create-new:hover {
518 | border-bottom: 8px inset #ccc;
519 | background-color: #d9d9d9;
520 | }
521 |
522 | .form-item.create-new:hover {
523 | background-color: rgb(81,81,81);
524 | }
525 |
526 | .form-item > .row.footer {
527 | position: absolute;
528 | bottom: 0;
529 | left: 30%;
530 | }
531 |
532 | .form-item .title-row{
533 | position: relative;
534 | top: 15px;
535 | padding-top:3em;
536 | padding-bottom:3.65em;
537 | }
538 | .form-item .title-row h4 {
539 | font-size: 1.3em;
540 | }
541 |
542 | .form-item.create-new .title-row{
543 | padding: 0;
544 | }
545 | .form-item.create-new .title-row h4 {
546 | font-size: 7em;
547 | }
548 |
549 | .form-item .details-row{
550 | margin-top: 3.2em;
551 | }
552 | .form-item .details-row small {
553 | font-size: 0.6em;
554 | }
555 | .form-item.create-new .details-row small {
556 | font-size: 0.95em;
557 | }
558 |
--------------------------------------------------------------------------------
/demo/app.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('myModule', ['angular-tellform']);
4 | angular.module('myModule').controller('MyFormCtrl', function MyFormCtrl($scope) {
5 |
6 | $scope.myform = {
7 | "title": "Job Application Example",
8 | "_id": "57193ffa2aa1f3ff5e205b5c",
9 | "design": {
10 | "colors": {
11 | "buttonTextColor": "#5C780A",
12 | "buttonColor": "#C5F044",
13 | "answerColor": "#333",
14 | "questionColor": "#6D8524",
15 | "backgroundColor": "#E4F8A8"
16 | }
17 | },
18 | "hideFooter": false,
19 | "startPage": {
20 | "buttons": [],
21 | "introButtonText": "Apply Now",
22 | "introTitle": "We're looking for a great Growth Hacker",
23 | "showStart": true
24 | },
25 | "form_fields": [{
26 | "lastModified": "2016-04-22T23:02:46.017Z",
27 | "title": "How would you rate your experience and knowledge of running split tests?",
28 | "fieldType": "rating",
29 | "fieldValue": 1,
30 | "_id": "571940102aa1f3ff5e205b5d",
31 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
32 | "deletePreserved": false,
33 | "disabled": false,
34 | "required": true,
35 | "ratingOptions": {
36 | "shape": "thumbs-up",
37 | "steps": 5
38 | },
39 | "description": ""
40 | }, {
41 | "lastModified": "2016-04-22T23:02:46.017Z",
42 | "title": "And how would you rate your creativity and ability to find innovative solutions?",
43 | "fieldType": "rating",
44 | "fieldValue": 1,
45 | "_id": "571940222aa1f3ff5e205b5e",
46 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
47 | "deletePreserved": false,
48 | "disabled": false,
49 | "required": true,
50 | "ratingOptions": {
51 | "shape": "thumbs-up",
52 | "steps": 5
53 | },
54 | "description": ""
55 | }, {
56 | "_id": "57193ffa2aa1f3ff5e205b5c",
57 | "fieldValue": "no",
58 | "fieldType": "textfield",
59 | "title": "Can we get the link to your LinkedIn profile?",
60 | "lastModified": "2016-04-22T19:48:42.690Z",
61 | "created": "2016-04-21T21:02:50.583Z",
62 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
63 | "deletePreserved": true,
64 | "disabled": false,
65 | "required": false,
66 | "fieldOptions": [],
67 | "description": ""
68 | }, {
69 | "_id": "57193ffa2aa1f3ff5e205b5c",
70 | "fieldValue": "no",
71 | "fieldType": "textfield",
72 | "title": "Can we get the link to your LinkedIn profile?",
73 | "lastModified": "2016-04-22T19:48:42.690Z",
74 | "created": "2016-04-21T21:02:50.583Z",
75 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
76 | "deletePreserved": true,
77 | "disabled": false,
78 | "required": false,
79 | "fieldOptions": [],
80 | "description": ""
81 | }, {
82 | "_id": "57193ffa2aa1f3ff5e205b5c",
83 | "fieldValue": "no",
84 | "fieldType": "textfield",
85 | "title": "Can we get the link to your LinkedIn profile?",
86 | "lastModified": "2016-04-22T19:48:42.690Z",
87 | "created": "2016-04-21T21:02:50.583Z",
88 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
89 | "deletePreserved": true,
90 | "disabled": false,
91 | "required": false,
92 | "fieldOptions": [],
93 | "description": ""
94 | }, {
95 | "_id": "57193ffa2aa1f3ff5e205b5c",
96 | "fieldValue": "no",
97 | "fieldType": "textfield",
98 | "title": "Can we get the link to your LinkedIn profile?",
99 | "lastModified": "2016-04-22T19:48:42.690Z",
100 | "created": "2016-04-21T21:02:50.583Z",
101 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
102 | "deletePreserved": true,
103 | "disabled": false,
104 | "required": false,
105 | "fieldOptions": [],
106 | "description": ""
107 | }, {
108 | "_id": "57193ffa2aa1f3ff5e205b5c",
109 | "fieldValue": "no",
110 | "fieldType": "textfield",
111 | "title": "Can we get the link to your LinkedIn profile?",
112 | "lastModified": "2016-04-22T19:48:42.690Z",
113 | "created": "2016-04-21T21:02:50.583Z",
114 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
115 | "deletePreserved": true,
116 | "disabled": false,
117 | "required": false,
118 | "fieldOptions": [],
119 | "description": ""
120 | }, {
121 | "lastModified": "2016-04-22T23:02:46.025Z",
122 | "title": "Now, please read the following statement: \"Finding the \"Aha!\" moment on the customer journey is the first and most important job of a growth hacker\" What do you think of it?",
123 | "fieldType": "radio",
124 | "fieldValue": "",
125 | "_id": "571940472aa1f3ff5e205b60",
126 | "created": "2016-04-21T21:04:07.678Z",
127 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
128 | "deletePreserved": false,
129 | "disabled": false,
130 | "required": false,
131 | "fieldOptions": [{
132 | "option_id": 60612,
133 | "option_title": "Option 0",
134 | "option_value": "1 (disagree)",
135 | "_id": "571940632aa1f3ff5e205b61"
136 | }, {
137 | "option_id": 46890,
138 | "option_title": "Option 60612",
139 | "option_value": "2",
140 | "_id": "571940642aa1f3ff5e205b62"
141 | }, {
142 | "option_id": 14519,
143 | "option_title": "Option 46890",
144 | "option_value": "3",
145 | "_id": "5719406c2aa1f3ff5e205b63"
146 | }, {
147 | "option_id": 13374,
148 | "option_title": "Option 14519",
149 | "option_value": "4",
150 | "_id": "5719406f2aa1f3ff5e205b64"
151 | }, {
152 | "option_id": 88666,
153 | "option_title": "Option 13374",
154 | "option_value": "5",
155 | "_id": "571940722aa1f3ff5e205b65"
156 | }, {
157 | "option_id": 74204,
158 | "option_title": "Option 88666",
159 | "option_value": "6 (agree)",
160 | "_id": "571940822aa1f3ff5e205b66"
161 | }],
162 | "description": ""
163 | }, {
164 | "lastModified": "2016-04-22T23:02:46.019Z",
165 | "title": "In this cross-functional role, you’ll be optimizing our users' journey across all stages of our marketing funnel.",
166 | "fieldType": "statement",
167 | "fieldValue": "",
168 | "_id": "57193f562aa1f3ff5e205b58",
169 | "created": "2016-04-21T21:00:06.998Z",
170 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
171 | "deletePreserved": false,
172 | "disabled": false,
173 | "required": true,
174 | "fieldOptions": [],
175 | "description": ""
176 | }, {
177 | "lastModified": "2016-04-22T23:02:46.021Z",
178 | "title": "What about your ability to get things done quickly?",
179 | "fieldType": "rating",
180 | "fieldValue": 1,
181 | "_id": "571940332aa1f3ff5e205b5f",
182 | "created": "2016-04-21T21:03:12.644Z",
183 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
184 | "deletePreserved": false,
185 | "disabled": false,
186 | "required": true,
187 | "ratingOptions": {
188 | "shape": "Star",
189 | "steps": 5
190 | },
191 | "description": ""
192 | }, {
193 | "lastModified": "2016-04-22T23:02:46.021Z",
194 | "title": "Can you tell us more about your choice?",
195 | "fieldType": "textarea",
196 | "fieldValue": "",
197 | "_id": "571940932aa1f3ff5e205b67",
198 | "created": "2016-04-21T21:05:23.928Z",
199 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
200 | "deletePreserved": false,
201 | "disabled": false,
202 | "required": false,
203 | "fieldOptions": [],
204 | "description": ""
205 | }, {
206 | "lastModified": "2016-04-22T23:02:46.023Z",
207 | "title": "What growth hack have you done that you're most proud of?",
208 | "fieldType": "textarea",
209 | "fieldValue": "",
210 | "_id": "571940b12aa1f3ff5e205b68",
211 | "created": "2016-04-21T21:05:23.928Z",
212 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
213 | "deletePreserved": false,
214 | "disabled": false,
215 | "required": false,
216 | "fieldOptions": [],
217 | "description": ""
218 | }, {
219 | "lastModified": "2016-04-22T23:02:46.023Z",
220 | "title": "Now, some quick reasoning test questions...",
221 | "fieldType": "statement",
222 | "fieldValue": "",
223 | "_id": "571940c22aa1f3ff5e205b69",
224 | "created": "2016-04-21T21:06:10.235Z",
225 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
226 | "deletePreserved": false,
227 | "disabled": false,
228 | "required": true,
229 | "fieldOptions": [],
230 | "description": ""
231 | }, {
232 | "lastModified": "2016-04-22T23:02:46.025Z",
233 | "title": "Two students took an exam. One of them achieved 9 marks more than the other and his marks were 56% of the sum of both of their marks. What marks did they obtain?",
234 | "fieldType": "radio",
235 | "fieldValue": "",
236 | "_id": "571940ea2aa1f3ff5e205b6a",
237 | "created": "2016-04-21T21:06:50.729Z",
238 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
239 | "deletePreserved": false,
240 | "disabled": false,
241 | "required": true,
242 | "fieldOptions": [{
243 | "option_id": 45860,
244 | "option_title": "Option 0",
245 | "option_value": "42 and 33",
246 | "_id": "571941022aa1f3ff5e205b6b"
247 | }, {
248 | "option_id": 84531,
249 | "option_title": "Option 45860",
250 | "option_value": "41 and 32",
251 | "_id": "571941032aa1f3ff5e205b6c"
252 | }, {
253 | "option_id": 88832,
254 | "option_title": "Option 84531",
255 | "option_value": "39 and 30",
256 | "_id": "5719410d2aa1f3ff5e205b6d"
257 | }, {
258 | "option_id": 39666,
259 | "option_title": "Option 88832",
260 | "option_value": "43 and 34",
261 | "_id": "571941172aa1f3ff5e205b6e"
262 | }],
263 | "description": ""
264 | }, {
265 | "lastModified": "2016-04-22T23:02:46.026Z",
266 | "title": "Agnes, Pedro, Robert, Xavi, Santi and David are sitting in a row. Santi and David are in the centre. Agnes and Pedro are at the ends. Robert is sitting to the left of Agnes. Who is to the right of Pedro?",
267 | "fieldType": "radio",
268 | "fieldValue": "",
269 | "_id": "5719412c2aa1f3ff5e205b6f",
270 | "created": "2016-04-21T21:06:50.729Z",
271 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
272 | "deletePreserved": false,
273 | "disabled": false,
274 | "required": true,
275 | "fieldOptions": [{
276 | "option_id": 45860,
277 | "option_title": "Option 0",
278 | "option_value": "Agnes",
279 | "_id": "571941022aa1f3ff5e205b6b"
280 | }, {
281 | "option_id": 84531,
282 | "option_title": "Option 45860",
283 | "option_value": "Santi",
284 | "_id": "571941032aa1f3ff5e205b6c"
285 | }, {
286 | "option_id": 88832,
287 | "option_title": "Option 84531",
288 | "option_value": "Xavi",
289 | "_id": "5719410d2aa1f3ff5e205b6d"
290 | }, {
291 | "option_id": 39666,
292 | "option_title": "Option 88832",
293 | "option_value": "David",
294 | "_id": "571941172aa1f3ff5e205b6e"
295 | }],
296 | "description": ""
297 | }, {
298 | "lastModified": "2016-04-22T23:02:46.024Z",
299 | "title": "What makes you want to work at Cloud Metrics?",
300 | "fieldType": "textarea",
301 | "fieldValue": "",
302 | "_id": "571941572aa1f3ff5e205b70",
303 | "created": "2016-04-21T21:08:39.654Z",
304 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
305 | "deletePreserved": false,
306 | "disabled": false,
307 | "required": true,
308 | "fieldOptions": [],
309 | "description": ""
310 | }, {
311 | "lastModified": "2016-04-22T23:02:46.025Z",
312 | "title": "Finally, what annual salary ($) are you looking for?",
313 | "fieldType": "textfield",
314 | "fieldValue": "",
315 | "_id": "571941672aa1f3ff5e205b71",
316 | "created": "2016-04-21T21:08:55.492Z",
317 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
318 | "deletePreserved": false,
319 | "disabled": false,
320 | "required": false,
321 | "fieldOptions": [],
322 | "description": ""
323 | }, {
324 | "lastModified": "2016-04-22T23:02:46.025Z",
325 | "title": "Email2",
326 | "fieldType": "email",
327 | "fieldValue": "",
328 | "_id": "571a80045b53e2c651f28804",
329 | "created": "2016-04-22T19:48:20.733Z",
330 | "validFieldTypes": ["textfield", "date", "email", "link", "legal", "url", "textarea", "statement", "welcome", "thankyou", "file", "dropdown", "scale", "rating", "radio", "checkbox", "hidden", "yes_no", "natural", "number"],
331 | "deletePreserved": false,
332 | "disabled": false,
333 | "required": true,
334 | "fieldOptions": [],
335 | "description": ""
336 | }],
337 | "language": "english"
338 | };
339 |
340 | $scope.endPoint = "https://admin.tellform.com/forms/"+$scope.myform._id;
341 |
342 | });
--------------------------------------------------------------------------------
/dist/template.js:
--------------------------------------------------------------------------------
1 | angular.module('angular-tellform.templates', []).run(['$templateCache', function($templateCache) {
2 | $templateCache.put("modules/forms/base/views/directiveViews/field/date.html",
3 | "\n" +
5 | "
\n" +
6 | "
\n" +
7 | " \n" +
8 | " {{index+1}}\n" +
9 | " \n" +
10 | " \n" +
11 | " {{field.title}}\n" +
12 | " {{ 'OPTIONAL' | translate }}\n" +
13 | "
\n" +
14 | "
\n" +
15 | " {{field.description}}\n" +
16 | "
\n" +
17 | "
\n" +
18 | "
\n" +
19 | "
\n" +
20 | " \n" +
33 | "
\n" +
34 | "
\n" +
35 | "
\n" +
36 | "");
37 | $templateCache.put("modules/forms/base/views/directiveViews/field/dropdown.html",
38 | " 0\">\n" +
40 | "
\n" +
41 | "
\n" +
42 | " \n" +
43 | " {{index+1}}\n" +
44 | " \n" +
45 | " \n" +
46 | " {{field.title}}\n" +
47 | " {{ 'OPTIONAL' | translate }}\n" +
48 | "
\n" +
49 | "
\n" +
50 | " {{field.description}}\n" +
51 | "
\n" +
52 | "
\n" +
53 | "
\n" +
54 | " \n" +
64 | " \n" +
65 | " \n" +
66 | " \n" +
68 | " \n" +
69 | " \n" +
70 | " \n" +
71 | "
\n" +
72 | "
\n" +
73 | "
\n" +
74 | "");
75 | $templateCache.put("modules/forms/base/views/directiveViews/field/file.html",
76 | "\n" +
77 | "\n" +
78 | "
\n" +
79 | "
\n" +
80 | " \n" +
81 | " {{index+1}}\n" +
82 | " \n" +
83 | " \n" +
84 | " {{field.title}}\n" +
85 | " {{ 'OPTIONAL' | translate }}\n" +
86 | "
\n" +
87 | " \n" +
88 | "
\n" +
89 | "
\n" +
114 | "
\n" +
115 | "
\n" +
116 | "");
117 | $templateCache.put("modules/forms/base/views/directiveViews/field/hidden.html",
118 | "\n" +
119 | "");
120 | $templateCache.put("modules/forms/base/views/directiveViews/field/legal.html",
121 | "\n" +
124 | "
\n" +
125 | "
\n" +
126 | " \n" +
127 | " {{index+1}}\n" +
128 | " \n" +
129 | " \n" +
130 | " {{field.title}}\n" +
131 | " {{ 'OPTIONAL' | translate }}\n" +
132 | "
\n" +
133 | "
\n" +
134 | "
{{field.description}}
\n" +
135 | "
\n" +
136 | "
\n" +
137 | "
\n" +
172 | "
\n" +
173 | "
\n" +
174 | "
\n" +
175 | "");
176 | $templateCache.put("modules/forms/base/views/directiveViews/field/natural.html",
177 | "\n" +
178 | "
{{field.title}} *(required)
\n" +
179 | "
\n" +
180 | " \n" +
187 | "
\n" +
188 | "
\n" +
189 | "
\n" +
190 | " \n" +
191 | "
\n" +
192 | "
\n" +
193 | "");
194 | $templateCache.put("modules/forms/base/views/directiveViews/field/password.html",
195 | "\n" +
196 | "
{{field.title}} *(required)
\n" +
197 | "
\n" +
198 | " \n" +
199 | "
\n" +
200 | "
\n" +
201 | "");
202 | $templateCache.put("modules/forms/base/views/directiveViews/field/radio.html",
203 | " 0\">\n" +
207 | "
\n" +
208 | "
\n" +
209 | " \n" +
210 | " {{index+1}}\n" +
211 | " \n" +
212 | " \n" +
213 | " {{field.title}}\n" +
214 | " {{ 'OPTIONAL' | translate }}\n" +
215 | "
\n" +
216 | "
\n" +
217 | " {{field.description}}\n" +
218 | "
\n" +
219 | "
\n" +
220 | "
\n" +
221 | "\n" +
222 | "
\n" +
223 | "
\n" +
240 | "
\n" +
241 | "
\n" +
242 | "
\n" +
243 | "
\n" +
244 | "");
245 | $templateCache.put("modules/forms/base/views/directiveViews/field/rating.html",
246 | "\n" +
248 | "
\n" +
249 | "
\n" +
250 | " \n" +
251 | " {{index+1}}\n" +
252 | " \n" +
253 | " \n" +
254 | " {{field.title}}\n" +
255 | " {{ 'OPTIONAL' | translate }}\n" +
256 | "
\n" +
257 | "
\n" +
258 | " {{field.description}}\n" +
259 | "
\n" +
260 | "
\n" +
261 | "
\n" +
262 | "\n" +
263 | " \n" +
277 | " \n" +
278 | "
\n" +
279 | "
\n" +
280 | "");
281 | $templateCache.put("modules/forms/base/views/directiveViews/field/statement.html",
282 | "\n" +
286 | "
\n" +
287 | "
\n" +
288 | "
{{field.title}}
\n" +
289 | "
\n" +
290 | " {{field.description}}\n" +
291 | "
\n" +
292 | "
\n" +
293 | "
\n" +
294 | "
{{field.description}}
\n" +
295 | "
\n" +
296 | "
\n" +
297 | " \n" +
303 | "
\n" +
304 | "
\n" +
305 | "
\n" +
306 | "");
307 | $templateCache.put("modules/forms/base/views/directiveViews/field/textarea.html",
308 | "\n" +
309 | "
\n" +
310 | "
\n" +
311 | " \n" +
312 | " {{index+1}}\n" +
313 | " \n" +
314 | " \n" +
315 | " {{field.title}}\n" +
316 | " {{ 'OPTIONAL' | translate }}\n" +
317 | "
\n" +
318 | "
{{ 'NEWLINE' | translate }}\n" +
319 | "
\n" +
320 | " {{field.description}}\n" +
321 | "
\n" +
322 | "
\n" +
323 | "
\n" +
324 | " Press SHIFT+ENTER to add a newline\n" +
325 | " \n" +
337 | "
\n" +
338 | "
\n" +
339 | "\n" +
340 | "\n" +
341 | "
\n" +
343 | "
\n" +
350 | "
\n" +
351 | " \n" +
352 | " {{ 'ENTER' | translate }}\n" +
353 | " \n" +
354 | "
\n" +
355 | "
\n" +
356 | "
\n" +
357 | "");
358 | $templateCache.put("modules/forms/base/views/directiveViews/field/textfield.html",
359 | "\n" +
361 | "
\n" +
362 | "
\n" +
363 | " \n" +
364 | " {{index+1}}\n" +
365 | " \n" +
366 | " \n" +
367 | "\n" +
368 | " {{field.title}}\n" +
369 | "\n" +
370 | " \n" +
371 | " ({{ 'OPTIONAL' | translate }})\n" +
372 | " \n" +
373 | "
\n" +
374 | "\n" +
375 | "
\n" +
376 | " {{field.description}}\n" +
377 | "
\n" +
378 | "
\n" +
379 | "
\n" +
380 | " \n" +
396 | "
\n" +
397 | "
\n" +
398 | "
\n" +
399 | " \n" +
400 | " Error:\n" +
401 | " {{ 'ERROR_EMAIL_INVALID' | translate }} \n" +
402 | " {{ 'ERROR_NOT_A_NUMBER' | translate }} \n" +
403 | " {{ 'ERROR_URL_INVALID' | translate }} \n" +
404 | "
\n" +
405 | "
\n" +
406 | "
\n" +
407 | "\n" +
408 | "
\n" +
410 | "
\n" +
417 | "
\n" +
418 | " \n" +
419 | " {{ 'ENTER' | translate }}\n" +
420 | " \n" +
421 | "
\n" +
422 | "
\n" +
423 | "
\n" +
424 | "");
425 | $templateCache.put("modules/forms/base/views/directiveViews/field/yes_no.html",
426 | "\n" +
430 | "
\n" +
431 | "
\n" +
432 | " \n" +
433 | " {{index+1}}\n" +
434 | " \n" +
435 | " \n" +
436 | " {{field.title}}\n" +
437 | " \n" +
438 | " {{ 'OPTIONAL' | translate }}\n" +
439 | " \n" +
440 | "
\n" +
441 | "
\n" +
442 | " {{field.description}}\n" +
443 | "
\n" +
444 | "
\n" +
445 | "\n" +
446 | "
\n" +
447 | "
\n" +
448 | "
\n" +
465 | "
\n" +
466 | "\n" +
467 | "
\n" +
468 | "
\n" +
485 | "
\n" +
486 | "
\n" +
487 | "
\n" +
488 | "
\n" +
489 | "");
490 | $templateCache.put("modules/forms/base/views/directiveViews/form/submit-form.client.view.html",
491 | "\n" +
492 | "\n" +
493 | "\n" +
494 | "\n" +
495 | "\n" +
498 | "
\n" +
499 | "
\n" +
500 | "
\n" +
501 | "{{myform.startPage.introTitle}}\n" +
502 | "
\n" +
503 | "\n" +
504 | "
\n" +
505 | "
\n" +
506 | "{{myform.startPage.introParagraph}}\n" +
507 | "
\n" +
508 | "
\n" +
509 | "
\n" +
510 | "\n" +
511 | "
\n" +
512 | "\n" +
518 | "
\n" +
519 | "
\n" +
531 | "
\n" +
532 | "\n" +
533 | "\n" +
534 | "\n" +
638 | "\n" +
639 | "\n" +
640 | "\n" +
656 | "");
657 | $templateCache.put("modules/forms/base/views/submit-form.client.view.html",
658 | "\n" +
661 | "\n" +
662 | "");
663 | }]);
664 |
--------------------------------------------------------------------------------