'use strict';
// Init the application configuration module for AngularJS application
var ApplicationConfiguration = (function() {
// Init module configuration options
var applicationModuleName = 'TellForm';
var applicationModuleVendorDependencies = ['duScroll', 'ui.select', 'ngSanitize', 'vButton', 'ngResource', 'TellForm.templates', 'ui.router', 'ui.bootstrap', 'ui.utils', 'pascalprecht.translate', 'view-form'];
// Add a new vertical module
var registerModule = function(moduleName, dependencies) {
// Create angular module
angular.module(moduleName, dependencies || []);
// Add the module to the AngularJS configuration file
angular.module(applicationModuleName).requires.push(moduleName);
};
return {
applicationModuleName: applicationModuleName,
applicationModuleVendorDependencies: applicationModuleVendorDependencies,
registerModule: registerModule
};
})();
'use strict';
//Start by defining the main module and adding the module dependencies
angular.module(ApplicationConfiguration.applicationModuleName, ApplicationConfiguration.applicationModuleVendorDependencies);
// Setting HTML5 Location Mode
angular.module(ApplicationConfiguration.applicationModuleName).config(['$locationProvider',
function($locationProvider) {
$locationProvider.hashPrefix('!');
}
]);
//Permission Constants
angular.module(ApplicationConfiguration.applicationModuleName).constant('APP_PERMISSIONS', {
viewAdminSettings: 'viewAdminSettings',
editAdminSettings: 'editAdminSettings',
editForm: 'editForm',
viewPrivateForm: 'viewPrivateForm'
});
//User Role constants
angular.module(ApplicationConfiguration.applicationModuleName).constant('USER_ROLES', {
admin: 'admin',
normal: 'user',
superuser: 'superuser'
});
//form url
angular.module(ApplicationConfiguration.applicationModuleName).constant('FORM_URL', '/forms/:formId');
//Then define the init function for starting up the application
angular.element(document).ready(function() {
//Fixing facebook bug with redirect
if (window.location.hash === '#_=_') window.location.hash = '#!';
//Then init the app
angular.bootstrap(document, [ApplicationConfiguration.applicationModuleName]);
});
angular.module('TellForm.templates', []).run(['$templateCache', function ($templateCache) {
"use strict";
$templateCache.put("modules/core/views/header.client.view.html",
"");
$templateCache.put("modules/forms/admin/views/admin-form.client.view.html",
"");
$templateCache.put("modules/forms/admin/views/list-forms.client.view.html",
"
{{ 'CREATE_A_NEW_FORM' | translate }}
{{ form.numberOfResponses }} {{ 'RESPONSES' | translate }}
{{ 'FORM_PAUSED' | translate }}
");
$templateCache.put("modules/forms/admin/views/adminTabs/analyze.html",
"");
$templateCache.put("modules/forms/admin/views/adminTabs/configure.html",
"");
$templateCache.put("modules/forms/admin/views/adminTabs/create.html",
"");
$templateCache.put("modules/forms/admin/views/directiveViews/form/configure-form.client.view.html",
"
");
$templateCache.put("modules/forms/admin/views/directiveViews/form/edit-form.client.view.html",
"");
$templateCache.put("modules/forms/admin/views/directiveViews/form/edit-submissions-form.client.view.html",
"{{ 'TOTAL_VIEWS' | translate }}
{{ 'RESPONSES' | translate }}
{{ 'COMPLETION_RATE' | translate }}
{{ 'AVERAGE_TIME_TO_COMPLETE' | translate }}
{{myform.analytics.visitors.length}}
{{myform.analytics.submissions}}
{{myform.analytics.conversionRate | number:0}}%
{{ AverageTimeElapsed | secondsToDateTime | date:'mm:ss'}}
{{ 'DESKTOP_AND_LAPTOP' | translate }}
{{ 'TABLETS' | translate }}
{{ 'PHONES' | translate }}
{{ 'OTHER' | translate }}
{{ 'UNIQUE_VISITS' | translate }}
{{DeviceStatistics.desktop.visits}}
{{ 'UNIQUE_VISITS' | translate }}
{{DeviceStatistics.tablet.visits}}
{{ 'UNIQUE_VISITS' | translate }}
{{DeviceStatistics.tablet.visits}}
{{ 'UNIQUE_VISITS' | translate }}
{{DeviceStatistics.other.visits}}
{{ 'RESPONSES' | translate }}
{{DeviceStatistics.desktop.responses}}
{{ 'RESPONSES' | translate }}
{{DeviceStatistics.tablet.responses}}
{{ 'RESPONSES' | translate }}
{{DeviceStatistics.phone.responses}}
{{ 'RESPONSES' | translate }}
{{DeviceStatistics.other.responses}}
{{ 'COMPLETION_RATE' | translate }}
{{DeviceStatistics.desktop.completion}}%
{{ 'COMPLETION_RATE' | translate }}
{{DeviceStatistics.tablet.completion}}%
{{ 'COMPLETION_RATE' | translate }}
{{DeviceStatistics.phone.completion}}%
{{ 'COMPLETION_RATE' | translate }}
{{DeviceStatistics.other.completion}}%
{{ 'AVERAGE_TIME_TO_COMPLETE' | translate }}
{{DeviceStatistics.desktop.average_time | secondsToDateTime | date:'mm:ss'}}
{{ 'AVERAGE_TIME_TO_COMPLETE' | translate }}
{{DeviceStatistics.tablet.average_time | secondsToDateTime | date:'mm:ss'}}
{{ 'AVERAGE_TIME_TO_COMPLETE' | translate }}
{{DeviceStatistics.phone.average_time | secondsToDateTime | date:'mm:ss'}}
{{ 'AVERAGE_TIME_TO_COMPLETE' | translate }}
{{DeviceStatistics.other.average_time | secondsToDateTime | date:'mm:ss'}}
{{ 'FIELD_TITLE' | translate }}
{{ 'FIELD_VIEWS' | translate }}
{{ 'FIELD_RESPONSES' | translate }}
{{ 'FIELD_DROPOFF' | translate }}
{{fieldStats.field.title}}
{{fieldStats.totalViews}}
{{fieldStats.responses}}
{{fieldStats.continueRate}}%
");
$templateCache.put("modules/users/views/authentication/access-denied.client.view.html",
"{{ 'ACCESS_DENIED_TEXT' | translate }}
");
$templateCache.put("modules/users/views/authentication/signin.client.view.html",
"");
$templateCache.put("modules/users/views/authentication/signup-success.client.view.html",
"{{ 'SUCCESS_HEADER' | translate }}
{{ 'SUCCESS_TEXT' | translate }}
{{ 'NOT_ACTIVATED_YET' | translate }}
{{ 'BEFORE_YOU_CONTINUE' | translate }} team@tellform.com
");
$templateCache.put("modules/users/views/authentication/signup.client.view.html",
"");
$templateCache.put("modules/users/views/password/forgot-password.client.view.html",
"");
$templateCache.put("modules/users/views/password/reset-password-invalid.client.view.html",
"{{ 'PASSWORD_RESET_INVALID' | translate }}
");
$templateCache.put("modules/users/views/password/reset-password-success.client.view.html",
"{{ 'PASSWORD_RESET_SUCCESS' | translate }}
");
$templateCache.put("modules/users/views/password/reset-password.client.view.html",
"{{ 'RESET_PASSWORD' | translate }}
");
$templateCache.put("modules/users/views/settings/change-password.client.view.html",
"{{ 'CHANGE_PASSWORD' | translate }}
");
$templateCache.put("modules/users/views/settings/edit-profile.client.view.html",
"{{ 'EDIT_PROFILE' | translate }}
");
$templateCache.put("modules/users/views/settings/social-accounts.client.view.html",
"{{ 'CONNECTED_SOCIAL_ACCOUNTS' | translate }}:
{{ 'CONNECT_OTHER_SOCIAL_ACCOUNTS' | translate }}
");
$templateCache.put("modules/users/views/verify/resend-verify-email.client.view.html",
"{{ 'VERIFICATION_EMAIL_SENT' | translate }}
{{ 'VERIFICATION_EMAIL_SENT_TO' | translate }} {{username}}.
{{ 'NOT_ACTIVATED_YET' | translate }}
{{ 'CHECK_YOUR_EMAIL' | translate }} polydaic@gmail.com
");
$templateCache.put("modules/users/views/verify/verify-account.client.view.html",
"{{ 'VERIFY_SUCCESS' | translate }}
{{ 'VERIFY_ERROR' | translate }}
");
$templateCache.put("form_modules/forms/base/views/directiveViews/entryPage/startPage.html",
"{{pageData.introTitle}}
{{pageData.introParagraph}}
");
$templateCache.put("form_modules/forms/base/views/directiveViews/field/date.html",
"{{index+1}} {{field.title}} {{ 'OPTIONAL' | translate }}
{{field.description}}
");
$templateCache.put("form_modules/forms/base/views/directiveViews/field/dropdown.html",
" 0\">
{{index+1}} {{field.title}} {{ 'OPTIONAL' | translate }}
{{field.description}}
");
$templateCache.put("form_modules/forms/base/views/directiveViews/field/hidden.html",
"");
$templateCache.put("form_modules/forms/base/views/directiveViews/field/legal.html",
"{{index+1}} {{field.title}} {{ 'OPTIONAL' | translate }}
{{field.description}}
");
$templateCache.put("form_modules/forms/base/views/directiveViews/field/radio.html",
" 0\">
{{index+1}} {{field.title}} {{ 'OPTIONAL' | translate }}
{{field.description}}
");
$templateCache.put("form_modules/forms/base/views/directiveViews/field/rating.html",
"{{index+1}} {{field.title}} {{ 'OPTIONAL' | translate }}
{{field.description}}
");
$templateCache.put("form_modules/forms/base/views/directiveViews/field/statement.html",
"
{{field.title}}
{{field.description}}
{{field.description}}
");
$templateCache.put("form_modules/forms/base/views/directiveViews/field/textarea.html",
"{{index+1}} {{field.title}} {{ 'OPTIONAL' | translate }}
{{ 'NEWLINE' | translate }}{{field.description}}
{{ 'ADD_NEW_LINE_INSTR' | translate }}
{{ 'ENTER' | translate }}
");
$templateCache.put("form_modules/forms/base/views/directiveViews/field/textfield.html",
"{{index+1}} {{field.title}} ({{ 'OPTIONAL' | translate }})
{{field.description}}
{{ 'ERROR' | translate }}: {{ 'ERROR_EMAIL_INVALID' | translate }} {{ 'ERROR_NOT_A_NUMBER' | translate }} {{ 'ERROR_URL_INVALID' | translate }}
{{ 'ENTER' | translate }}
");
$templateCache.put("form_modules/forms/base/views/directiveViews/field/yes_no.html",
"{{index+1}} {{field.title}} {{ 'OPTIONAL' | translate }}
{{field.description}}
");
$templateCache.put("form_modules/forms/base/views/directiveViews/form/submit-form.client.view.html",
"");
$templateCache.put("form_modules/forms/base/views/form-not-found.client.view.html",
"");
$templateCache.put("form_modules/forms/base/views/form-unauthorized.client.view.html",
"");
$templateCache.put("form_modules/forms/base/views/submit-form.client.view.html",
"");
}]);
'use strict';
// Use Application configuration module to register a new module
ApplicationConfiguration.registerModule('core', ['users']);
'use strict';
// Use Application configuration module to register a new module
ApplicationConfiguration.registerModule('forms', [
'ngFileUpload', 'ui.router.tabs', 'ui.date', 'ui.sortable',
'angular-input-stars', 'users', 'ngclipboard'
]);//, 'colorpicker.module' @TODO reactivate this module
'use strict';
// Use Application configuration module to register a new module
ApplicationConfiguration.registerModule('users');
'use strict';
// Setting up route
angular.module('core').config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider, Authorization) {
// Redirect to home view when route not found
$urlRouterProvider.otherwise('/forms');
}
]);
angular.module(ApplicationConfiguration.applicationModuleName).run(['$rootScope', 'Auth', '$state', '$stateParams',
function($rootScope, Auth, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
// add previous state property
$rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState) {
$state.previous = fromState;
var statesToIgnore = ['home', 'signin', 'resendVerifyEmail', 'verify', 'signup', 'signup-success', 'forgot', 'reset-invalid', 'reset', 'reset-success'];
//Redirect to listForms if user is authenticated
if(statesToIgnore.indexOf(toState.name) > 0){
if(Auth.isAuthenticated()){
event.preventDefault(); // stop current execution
$state.go('listForms'); // go to listForms page
}
}
//Redirect to 'signup' route if user is not authenticated
else if(toState.name !== 'access_denied' && !Auth.isAuthenticated() && toState.name !== 'submitForm'){
event.preventDefault(); // stop current execution
$state.go('listForms'); // go to listForms page
}
});
}
]);
//Page access/authorization logic
angular.module(ApplicationConfiguration.applicationModuleName).run(['$rootScope', 'Auth', 'User', 'Authorizer', '$state', '$stateParams',
function($rootScope, Auth, User, Authorizer, $state, $stateParams) {
$rootScope.$on('$stateChangeStart', function(event, next) {
var authenticator, permissions, user;
permissions = next && next.data && next.data.permissions ? next.data.permissions : null;
Auth.ensureHasCurrentUser(User);
user = Auth.currentUser;
if(user){
authenticator = new Authorizer(user);
if( (permissions !== null) ){
if( !authenticator.canAccess(permissions) ){
event.preventDefault();
$state.go('access_denied');
}
}
}
});
}]);
'use strict';
angular.module('core').controller('HeaderController', ['$rootScope', '$scope', 'Menus', '$state', 'Auth', 'User', '$window', '$translate',
function ($rootScope, $scope, Menus, $state, Auth, User, $window, $translate) {
$rootScope.signupDisabled = $window.signupDisabled;
$scope.user = $rootScope.user = Auth.ensureHasCurrentUser(User);
$scope.authentication = $rootScope.authentication = Auth;
$rootScope.languages = $scope.languages = ['en', 'fr', 'es', 'it', 'de'];
//Set global app language
$rootScope.language = $scope.user.language;
$translate.use($scope.user.language);
$scope.isCollapsed = false;
$rootScope.hideNav = false;
$scope.menu = Menus.getMenu('topbar');
$scope.signout = function() {
var promise = User.logout();
promise.then(function() {
Auth.logout();
Auth.ensureHasCurrentUser(User);
$scope.user = $rootScope.user = null;
$state.go('listForms');
//Refresh view
$state.reload();
},
function(reason) {
console.error('Logout Failed: ' + reason);
});
};
$scope.toggleCollapsibleMenu = function() {
$scope.isCollapsed = !$scope.isCollapsed;
};
// Collapsing the menu after navigation
$scope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
$scope.isCollapsed = false;
$rootScope.hideNav = false;
if ( angular.isDefined( toState.data ) ) {
if ( angular.isDefined( toState.data.hideNav ) ) {
$rootScope.hideNav = toState.data.hideNav;
}
}
});
}
]);
'use strict';
//Menu service used for managing menus
angular.module('core').service('Menus', [
function() {
// Define a set of default roles
this.defaultRoles = ['*'];
// Define the menus object
this.menus = {};
// A private function for rendering decision
var shouldRender = function(user) {
if (user) {
if (~this.roles.indexOf('*')) {
return true;
}
for (var userRoleIndex in user.roles) {
for (var roleIndex in this.roles) {
if (this.roles[roleIndex] === user.roles[userRoleIndex]) {
return true;
}
}
}
return false;
}
return this.isPublic;
};
// Validate menu existance
this.validateMenuExistance = function(menuId) {
if (menuId && menuId.length) {
if (this.menus[menuId]) {
return true;
} else {
throw new Error('Menu does not exists');
}
} else {
throw new Error('MenuId was not provided');
}
};
// Get the menu object by menu id
this.getMenu = function(menuId) {
// Validate that the menu exists
this.validateMenuExistance(menuId);
// Return the menu object
return this.menus[menuId];
};
// Add new menu object by menu id
this.addMenu = function(menuId, isPublic, roles) {
// Create the new menu
this.menus[menuId] = {
isPublic: isPublic || false,
roles: roles || this.defaultRoles,
items: [],
shouldRender: shouldRender
};
// Return the menu object
return this.menus[menuId];
};
// Remove existing menu object by menu id
this.removeMenu = function(menuId) {
// Validate that the menu exists
this.validateMenuExistance(menuId);
// Return the menu object
delete this.menus[menuId];
};
// Add menu item object
this.addMenuItem = function(menuId, menuItemTitle, menuItemURL, menuItemType, menuItemUIRoute, isPublic, roles, position) {
// Validate that the menu exists
this.validateMenuExistance(menuId);
// Push new menu item
this.menus[menuId].items.push({
title: menuItemTitle,
link: menuItemURL,
menuItemType: menuItemType || 'item',
menuItemClass: menuItemType,
uiRoute: menuItemUIRoute || ('/' + menuItemURL),
isPublic: ((isPublic === null || typeof isPublic === 'undefined') ? this.menus[menuId].isPublic : isPublic),
roles: ((roles === null || typeof roles === 'undefined') ? this.menus[menuId].roles : roles),
position: position || 0,
items: [],
shouldRender: shouldRender
});
// Return the menu object
return this.menus[menuId];
};
// Add submenu item object
this.addSubMenuItem = function(menuId, rootMenuItemURL, menuItemTitle, menuItemURL, menuItemUIRoute, isPublic, roles, position) {
// Validate that the menu exists
this.validateMenuExistance(menuId);
// Search for menu item
for (var itemIndex in this.menus[menuId].items) {
if (this.menus[menuId].items[itemIndex].link === rootMenuItemURL) {
// Push new submenu item
this.menus[menuId].items[itemIndex].items.push({
title: menuItemTitle,
link: menuItemURL,
uiRoute: menuItemUIRoute || ('/' + menuItemURL),
isPublic: ((isPublic === null || typeof isPublic === 'undefined') ? this.menus[menuId].items[itemIndex].isPublic : isPublic),
roles: ((roles === null || typeof roles === 'undefined') ? this.menus[menuId].items[itemIndex].roles : roles),
position: position || 0,
shouldRender: shouldRender
});
}
}
// Return the menu object
return this.menus[menuId];
};
// Remove existing menu object by menu id
this.removeMenuItem = function(menuId, menuItemURL) {
// Validate that the menu exists
this.validateMenuExistance(menuId);
// Search for menu item to remove
for (var itemIndex in this.menus[menuId].items) {
if (this.menus[menuId].items[itemIndex].link === menuItemURL) {
this.menus[menuId].items.splice(itemIndex, 1);
}
}
// Return the menu object
return this.menus[menuId];
};
// Remove existing menu object by menu id
this.removeSubMenuItem = function(menuId, submenuItemURL) {
// Validate that the menu exists
this.validateMenuExistance(menuId);
// Search for menu item to remove
for (var itemIndex in this.menus[menuId].items) {
for (var subitemIndex in this.menus[menuId].items[itemIndex].items) {
if (this.menus[menuId].items[itemIndex].items[subitemIndex].link === submenuItemURL) {
this.menus[menuId].items[itemIndex].items.splice(subitemIndex, 1);
}
}
}
// Return the menu object
return this.menus[menuId];
};
//Adding the topbar menu
this.addMenu('topbar', false, ['*']);
//Adding the bottombar menu for the Form-Footer view
this.addMenu('bottombar', false, ['*']);
}
]);
'use strict';
angular.module('core').factory('subdomain', ['$location', function ($location) {
var host = $location.host();
if (host.indexOf('.') < 0) {
return null;
}
return host.split('.')[0];
}]);
'use strict';
// Configuring the Forms drop-down menus
angular.module('forms').run(['Menus',
function(Menus) {
// Set top bar menu items
Menus.addMenuItem('topbar', 'My Forms', 'forms', '', '/forms', false);
}
]).filter('secondsToDateTime', [function() {
return function(seconds) {
return new Date(1970, 0, 1).setSeconds(seconds);
};
}]).filter('formValidity', [function(){
return function(formObj){
if(formObj && formObj.form_fields && formObj.visible_form_fields){
//get keys
var formKeys = Object.keys(formObj);
//we only care about things that don't start with $
var fieldKeys = formKeys.filter(function(key){
return key[0] !== '$';
});
var fields = formObj.form_fields;
var valid_count = fields.filter(function(field){
if(typeof field === 'object' && field.fieldType !== 'statement' && field.fieldType !== 'rating'){
return !!(field.fieldValue);
} else if(field.fieldType === 'rating'){
return true;
}
}).length;
return valid_count - (formObj.form_fields.length - formObj.visible_form_fields.length);
}
return 0;
};
}]).filter('trustSrc', ['$sce', function($sce){
return function(formUrl){
return $sce.trustAsResourceUrl(formUrl);
};
}]).config(['$provide', function ($provide){
$provide.decorator('accordionDirective', ["$delegate", function($delegate) {
var directive = $delegate[0];
directive.replace = true;
return $delegate;
}]);
}]);
'use strict';
// Setting up route
angular.module('forms').config(['$stateProvider',
function($stateProvider) {
// Forms state routing
$stateProvider.
state('listForms', {
url: '/forms',
templateUrl: 'modules/forms/admin/views/list-forms.client.view.html',
resolve: {
Forms: 'GetForms',
myForms: ["GetForms", "$q", function (GetForms, $q) {
var deferred = $q.defer();
GetForms.query(function(forms){
deferred.resolve(forms);
});
return deferred.promise;
}]
},
controller: 'ListFormsController',
controllerAs: 'ctrl'
}).state('submitForm', {
url: '/forms/:formId',
templateUrl: '/static/form_modules/forms/base/views/submit-form.client.view.html',
data: {
hideNav: true
},
resolve: {
Forms: 'GetForms',
myForm: ["GetForms", "$stateParams", "$q", function (GetForms, $stateParams, $q) {
var deferred = $q.defer();
GetForms.get({formId: $stateParams.formId}, function(resolvedForm){
deferred.resolve(resolvedForm);
});
return deferred.promise;
}]
},
controller: 'SubmitFormController',
controllerAs: 'ctrl'
}).state('viewForm', {
url: '/forms/:formId/admin',
templateUrl: 'modules/forms/admin/views/admin-form.client.view.html',
data: {
permissions: [ 'editForm' ]
},
resolve: {
GetForms: 'GetForms',
myForm: ["GetForms", "$stateParams", "$q", function (GetForms, $stateParams, $q) {
var deferred = $q.defer();
GetForms.get({formId: $stateParams.formId}, function(resolvedForm){
deferred.resolve(resolvedForm);
});
return deferred.promise;
}]
},
controller: 'AdminFormController'
}).state('viewForm.configure', {
url: '/configure',
templateUrl: 'modules/forms/admin/views/adminTabs/configure.html'
}).state('viewForm.design', {
url: '/design',
templateUrl: 'modules/forms/admin/views/adminTabs/design.html'
}).state('viewForm.analyze', {
url: '/analyze',
templateUrl: 'modules/forms/admin/views/adminTabs/analyze.html'
}).state('viewForm.create', {
url: '/create',
templateUrl: 'modules/forms/admin/views/adminTabs/create.html'
});
}
]);
'use strict';
//Forms service used for communicating with the forms REST endpoints
angular.module('forms').factory('GetForms', ['$resource', 'FORM_URL',
function($resource, FORM_URL) {
return $resource(FORM_URL, {
formId: '@_id'
}, {
'query' : {
method: 'GET',
isArray: true
},
'get' : {
method: 'GET',
transformResponse: function(data, header) {
var form = angular.fromJson(data);
form.visible_form_fields = _.filter(form.form_fields, function(field){
return (field.deletePreserved === false);
});
return form;
}
},
'update': {
method: 'PUT'
},
'save': {
method: 'POST'
}
});
}
]);
'use strict';
// Config HTTP Error Handling
angular.module('users').config(['$httpProvider',
function($httpProvider) {
$httpProvider.interceptors.push(["$q", "$location", function($q, $location) {
return {
responseError: function(response) {
if( $location.path() !== '/users/me' && response.config){
if(response.config.url !== '/users/me'){
if (response.status === 401) {
// save the current location so that login can redirect back
$location.nextAfterLogin = $location.path();
$location.path('/signin');
}else if(response.status === 403){
$location.path('/access_denied');
}
}
}
return $q.reject(response);
}
};
}]);
}]);
'use strict';
// Setting up route
angular.module('users').config(['$stateProvider',
function($stateProvider) {
var checkLoggedin = function($q, $timeout, $state, User, Auth) {
var deferred = $q.defer();
if (Auth.currentUser && Auth.currentUser.email) {
$timeout(deferred.resolve);
}
else {
Auth.currentUser = User.getCurrent(
function() {
Auth.login();
$timeout(deferred.resolve());
},
function() {
Auth.logout();
$timeout(deferred.reject());
$state.go('signin', {reload: true});
});
}
return deferred.promise;
};
checkLoggedin.$inject = ["$q", "$timeout", "$state", "User", "Auth"];
var checkSignupDisabled = function($window, $timeout, $q) {
var deferred = $q.defer();
if($window.signupDisabled) {
$timeout(deferred.reject());
} else {
$timeout(deferred.resolve());
}
return deferred.promise;
};
checkSignupDisabled.$inject = ["$window", "$timeout", "$q"];
// Users state routing
$stateProvider.
state('profile', {
resolve: {
loggedin: checkLoggedin
},
url: '/settings/profile',
templateUrl: 'modules/users/views/settings/edit-profile.client.view.html'
}).
state('password', {
resolve: {
loggedin: checkLoggedin
},
url: '/settings/password',
templateUrl: 'modules/users/views/settings/change-password.client.view.html'
}).
state('accounts', {
resolve: {
loggedin: checkLoggedin
},
url: '/settings/accounts',
templateUrl: 'modules/users/views/settings/social-accounts.client.view.html'
}).
state('signup', {
resolve: {
isDisabled: checkSignupDisabled
},
url: '/signup',
templateUrl: 'modules/users/views/authentication/signup.client.view.html'
}).
state('signup-success', {
resolve: {
isDisabled: checkSignupDisabled
},
url: '/signup-success',
templateUrl: 'modules/users/views/authentication/signup-success.client.view.html'
}).
state('signin', {
url: '/signin',
templateUrl: 'modules/users/views/authentication/signin.client.view.html'
}).
state('access_denied', {
url: '/access_denied',
templateUrl: 'modules/users/views/authentication/access-denied.client.view.html'
}).
state('verify', {
resolve: {
isDisabled: checkSignupDisabled
},
url: '/verify/:token',
templateUrl: 'modules/users/views/verify/verify-account.client.view.html'
}).
state('resendVerifyEmail', {
resolve: {
isDisabled: checkSignupDisabled
},
url: '/verify',
templateUrl: 'modules/users/views/verify/resend-verify-email.client.view.html'
}).
state('forgot', {
url: '/password/forgot',
templateUrl: 'modules/users/views/password/forgot-password.client.view.html'
}).
state('reset-invalid', {
url: '/password/reset/invalid',
templateUrl: 'modules/users/views/password/reset-password-invalid.client.view.html'
}).
state('reset-success', {
url: '/password/reset/success',
templateUrl: 'modules/users/views/password/reset-password-success.client.view.html'
}).
state('reset', {
url: '/password/reset/:token',
templateUrl: 'modules/users/views/password/reset-password.client.view.html'
});
}
]);
'use strict';
angular.module('users').controller('AuthenticationController', ['$scope', '$location', '$state', '$rootScope', 'User', 'Auth', '$translate', '$window',
function($scope, $location, $state, $rootScope, User, Auth, $translate, $window) {
$scope = $rootScope;
$scope.credentials = {};
$scope.error = '';
$scope.forms = {};
$scope.signin = function() {
if(!$scope.forms.signinForm.$invalid){
User.login($scope.credentials).then(
function(response) {
Auth.login(response);
$scope.user = $rootScope.user = Auth.ensureHasCurrentUser(User);
if($state.previous.name !== 'home' && $state.previous.name !== 'verify' && $state.previous.name !== '') {
$state.go($state.previous.name);
} else {
$state.go('listForms');
}
},
function(error) {
$rootScope.user = Auth.ensureHasCurrentUser(User);
$scope.user = $rootScope.user;
$scope.error = error;
console.error('loginError: '+error);
}
);
}
};
$scope.signup = function() {
if($scope.credentials === 'admin'){
$scope.error = 'Username cannot be \'admin\'. Please pick another username.';
return;
}
if(!$scope.forms.signupForm.$invalid){
User.signup($scope.credentials).then(
function(response) {
$state.go('signup-success');
},
function(error) {
console.error(error);
if(error) {
$scope.error = error;
console.error(error);
} else {
console.error('No response received');
}
}
);
}
};
}
]);
'use strict';
angular.module('users').controller('PasswordController', ['$scope', '$stateParams', '$state', 'User', '$translate', '$window',
function($scope, $stateParams, $state, User, $translate, $window) {
$translate.use($window.locale);
$scope.error = '';
$scope.forms = {};
// Submit forgotten password account id
$scope.askForPasswordReset = function() {
User.askForPasswordReset($scope.credentials).then(
function(response){
$scope.success = response.message;
$scope.error = null;
$scope.credentials = null;
},
function(error){
$scope.error = error;
$scope.success = null;
$scope.credentials = null;
}
);
};
// Change user password
$scope.resetUserPassword = function() {
if(!$scope.forms.resetPasswordForm.$invalid){
$scope.success = $scope.error = null;
User.resetPassword($scope.passwordDetails, $stateParams.token).then(
function(response){
// If successful show success message and clear form
$scope.success = response.message;
$scope.error = null;
$scope.passwordDetails = null;
// And redirect to the index page
$state.go('reset-success');
},
function(error){
$scope.error = error.message || error;
$scope.success = null;
$scope.passwordDetails = null;
}
);
}
};
}
]);
'use strict';
angular.module('users').controller('SettingsController', ['$scope', '$rootScope', '$http', '$state', 'Users', 'Auth',
function($scope, $rootScope, $http, $state, Users, Auth) {
$scope.user = Auth.currentUser;
// Check if there are additional accounts
$scope.hasConnectedAdditionalSocialAccounts = function(provider) {
for (var i in $scope.user.additionalProvidersData) {
return true;
}
return false;
};
$scope.cancel = function(){
$scope.user = Auth.currentUser;
};
// Check if provider is already in use with current user
$scope.isConnectedSocialAccount = function(provider) {
return $scope.user.provider === provider || ($scope.user.additionalProvidersData && $scope.user.additionalProvidersData[provider]);
};
// Remove a user social account
$scope.removeUserSocialAccount = function(provider) {
$scope.success = $scope.error = null;
$http.delete('/users/accounts', {
params: {
provider: provider
}
}).success(function(response) {
// If successful show success message and clear form
$scope.success = true;
$scope.error = null;
$scope.user = response;
}).error(function(response) {
$scope.success = null;
$scope.error = response.message;
});
};
// Update a user profile
$scope.updateUserProfile = function(isValid) {
if (isValid) {
$scope.success = $scope.error = null;
var user = new Users($scope.user);
user.$update(function(response) {
$scope.success = true;
$scope.error = null;
$scope.user = response;
}, function(response) {
$scope.success = null;
$scope.error = response.data.message;
});
} else {
$scope.submitted = true;
}
};
// Change user password
$scope.changeUserPassword = function() {
$scope.success = $scope.error = null;
$http.post('/users/password', $scope.passwordDetails).success(function(response) {
// If successful show success message and clear form
$scope.success = true;
$scope.error = null;
$scope.passwordDetails = null;
}).error(function(response) {
$scope.success = null;
$scope.error = response.message;
});
};
}
]);
'use strict';
angular.module('users').controller('VerifyController', ['$scope', '$state', '$rootScope', 'User', 'Auth', '$stateParams', '$translate', '$window',
function($scope, $state, $rootScope, User, Auth, $stateParams, $translate, $window) {
$translate.use($window.locale);
$scope.isResetSent = false;
$scope.credentials = {};
$scope.error = '';
// Submit forgotten password account id
$scope.resendVerifyEmail = function() {
User.resendVerifyEmail($scope.credentials.email).then(
function(response){
$scope.success = response.message;
$scope.error = null;
$scope.credentials = null;
$scope.isResetSent = true;
},
function(error){
$scope.error = error;
$scope.success = null;
$scope.credentials.email = null;
$scope.isResetSent = false;
}
);
};
//Validate Verification Token
$scope.validateVerifyToken = function() {
if($stateParams.token){
console.log($stateParams.token);
User.validateVerifyToken($stateParams.token).then(
function(response){
$scope.success = response.message;
$scope.error = null;
$scope.isResetSent = true;
$scope.credentials.email = null;
},
function(error){
$scope.isResetSent = false;
$scope.success = null;
$scope.error = error;
$scope.credentials.email = null;
}
);
}
};
}
]);
'use strict';
angular.module('users').factory('Auth', ['$window',
function($window) {
var userState = {
isLoggedIn: false
};
var service = {
_currentUser: null,
get currentUser(){
return this._currentUser;
},
// Note: we can't make the User a dependency of Auth
// because that would create a circular dependency
// Auth <- $http <- $resource <- LoopBackResource <- User <- Auth
ensureHasCurrentUser: function(User) {
if (service._currentUser && service._currentUser.username) {
return service._currentUser;
} else if ($window.user){
service._currentUser = $window.user;
return service._currentUser;
} else{
User.getCurrent().then(function(user) {
// success
service._currentUser = user;
userState.isLoggedIn = true;
$window.user = service._currentUser;
return service._currentUser;
},
function(response) {
userState.isLoggedIn = false;
service._currentUser = null;
$window.user = null;
return null;
});
}
},
isAuthenticated: function() {
return !!service._currentUser;
},
getUserState: function() {
return userState;
},
login: function(new_user) {
userState.isLoggedIn = true;
service._currentUser = new_user;
},
logout: function() {
$window.user = null;
userState.isLoggedIn = false;
service._currentUser = null;
}
};
return service;
}
]);
'use strict';
angular.module('users').service('Authorizer', ["APP_PERMISSIONS", "USER_ROLES", function(APP_PERMISSIONS, USER_ROLES) {
return function(user) {
return {
canAccess: function(permissions) {
var i, len, permission;
if (!angular.isArray(permissions)) {
permissions = [permissions];
}
for (i = 0, len = permissions.length; i < len; i++) {
permission = permissions[i];
if (APP_PERMISSIONS[permission] === null) {
throw 'Bad permission value';
}
if (user && user.roles) {
switch (permission) {
case APP_PERMISSIONS.viewAdminSettings:
case APP_PERMISSIONS.editAdminSettings:
return user.roles.indexOf(USER_ROLES.admin) > -1;
case APP_PERMISSIONS.viewPrivateForm:
case APP_PERMISSIONS.editForm:
return user.roles.indexOf(USER_ROLES.admin) > -1 || user.roles.indexOf(USER_ROLES.normal) > -1;
}
} else {
return false;
}
}
return false;
}
};
};
}]);
'use strict';
angular.module('users').factory('User', ['$window', '$q', '$timeout', '$http', '$state',
function($window, $q, $timeout, $http, $state) {
var userService = {
getCurrent: function() {
var deferred = $q.defer();
$http.get('/users/me')
.success(function(response) {
deferred.resolve(response);
})
.error(function() {
deferred.reject('User\'s session has expired');
});
return deferred.promise;
},
login: function(credentials) {
var deferred = $q.defer();
$http.post('/auth/signin', credentials).then(function(response) {
deferred.resolve(response.data);
}, function(error) {
deferred.reject(error.data.message || error.data);
});
return deferred.promise;
},
logout: function() {
var deferred = $q.defer();
$http.get('/auth/signout').then(function(response) {
deferred.resolve(null);
}, function(error) {
deferred.reject(error.data.message || error.data);
});
return deferred.promise;
},
signup: function(credentials) {
var deferred = $q.defer();
$http.post('/auth/signup', credentials).then(function(response) {
// If successful we assign the response to the global user model
deferred.resolve(response.data);
}, function(error) {
deferred.reject(error.data.message || error.data);
});
return deferred.promise;
},
resendVerifyEmail: function(_email) {
var deferred = $q.defer();
$http.post('/auth/verify', {email: _email}).then(function(response) {
deferred.resolve(response.data);
}, function(error) {
deferred.reject(error.data.message || error.data);
});
return deferred.promise;
},
validateVerifyToken: function(token) {
//DAVID: TODO: The valid length of a token should somehow be linked to server config values
//DAVID: TODO: SEMI-URGENT: Should we even be doing this?
var validTokenRe = /^([A-Za-z0-9]{48})$/g;
if( !validTokenRe.test(token) ) throw new Error('Error token: '+token+' is not a valid verification token');
var deferred = $q.defer();
$http.get('/auth/verify/'+token).then(function(response) {
deferred.resolve(response.data);
}, function(error) {
deferred.reject(error.data);
});
return deferred.promise;
},
resetPassword: function(passwordDetails, token) {
var deferred = $q.defer();
$http.post('/auth/reset/'+token, passwordDetails).then(function(response) {
deferred.resolve(response);
}, function(error) {
deferred.reject(error.data.message || error.data);
});
return deferred.promise;
},
// Submit forgotten password account id
askForPasswordReset: function(credentials) {
var deferred = $q.defer();
$http.post('/auth/forgot', credentials).then(function(response) {
// Show user success message and clear form
deferred.resolve(response.data);
}, function(error) {
// Show user error message
deferred.reject(error.data.message || error.data);
});
return deferred.promise;
}
};
return userService;
}
]);
'use strict';
// Users service used for communicating with the users REST endpoint
angular.module('users').factory('Users', ['$resource',
function($resource) {
return $resource('users', {}, {
update: {
method: 'PUT'
}
});
}
]);
'use strict';
angular.module('core').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('en', {
MENU: 'MENU',
SIGNUP_TAB: 'Sign Up',
SIGNIN_TAB: 'Sign In',
SIGNOUT_TAB: 'Signout',
EDIT_PROFILE: 'Edit Profile',
MY_SETTINGS: 'My Settings',
CHANGE_PASSWORD: 'Change Password',
TOGGLE_NAVIGATION: 'Toggle navigation'
});
$translateProvider.preferredLanguage('en')
.fallbackLanguage('en')
.useSanitizeValueStrategy('escape');
}]);
'use strict';
angular.module('core').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('fr', {
MENU: 'MENU',
SIGNUP_TAB: 'Créer un Compte',
SIGNIN_TAB: 'Connexion',
SIGNOUT_TAB: 'Créer un compte',
EDIT_PROFILE: 'Modifier Mon Profil',
MY_SETTINGS: 'Mes Paramètres',
CHANGE_PASSWORD: 'Changer mon Mot de Pass',
TOGGLE_NAVIGATION: 'Basculer la navigation',
});
}]);
'use strict';
angular.module('core').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('de', {
MENU: 'MENÜ',
SIGNUP_TAB: 'Anmelden',
SIGNIN_TAB: 'Anmeldung',
SIGNOUT_TAB: 'Abmelden',
EDIT_PROFILE: 'Profil bearbeiten',
MY_SETTINGS: 'Meine Einstellungen',
CHANGE_PASSWORD: 'Passwort ändern',
TOGGLE_NAVIGATION: 'Navigation umschalten'
});
}]);
'use strict';
angular.module('core').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('it', {
MENU: 'MENÜ',
SIGNUP_TAB: 'Vi Phrasal',
SIGNIN_TAB: 'Accedi',
SIGNOUT_TAB: 'Esci',
EDIT_PROFILE: 'Modifica Profilo',
MY_SETTINGS: 'Mie Impostazioni',
CHANGE_PASSWORD: 'Cambia la password',
TOGGLE_NAVIGATION: 'Attiva la navigazione'
});
}]);
'use strict';
angular.module('core').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('es', {
MENU: 'MENU',
SIGNUP_TAB: 'Registrarse',
SIGNIN_TAB: 'Entrar',
SIGNOUT_TAB: 'Salir',
EDIT_PROFILE: 'Editar Perfil',
MY_SETTINGS: 'Mis configuraciones',
CHANGE_PASSWORD: 'Cambiar contraseña',
TOGGLE_NAVIGATION: 'Navegación de palanca'
});
}]);
'use strict';
// Forms controller
angular.module('forms').controller('AdminFormController', ['$rootScope', '$window', '$scope', '$stateParams', '$state', 'Forms', 'CurrentForm', '$http', '$uibModal', 'myForm', '$filter', '$translate',
function($rootScope, $window, $scope, $stateParams, $state, Forms, CurrentForm, $http, $uibModal, myForm, $filter, $translate) {
//Set active tab to Create
$scope.activePill = 0;
$scope.copied = false;
$scope.onCopySuccess = function (e) {
$scope.copied = true;
};
$scope = $rootScope;
$scope.animationsEnabled = true;
$scope.myform = myForm;
$rootScope.saveInProgress = false;
$scope.oldForm = _.cloneDeep($scope.myform);
CurrentForm.setForm($scope.myform);
$scope.formURL = '/#!/forms/' + $scope.myform._id;
if ($scope.myform.isLive) {
if ($window.subdomainsDisabled === true) {
$scope.actualFormURL = window.location.protocol + '//' + window.location.host + '/view' + $scope.formURL;
} else {
if (window.location.host.split('.').length < 3) {
$scope.actualFormURL = window.location.protocol + '//' + $scope.myform.admin.username + '.' + window.location.host + $scope.formURL;
} else {
$scope.actualFormURL = window.location.protocol + '//' + $scope.myform.admin.username + '.' + window.location.host.split('.').slice(1, 3).join('.') + $scope.formURL;
}
}
} else {
$scope.actualFormURL = window.location.protocol + '//' + window.location.host + $scope.formURL;
}
var refreshFrame = $scope.refreshFrame = function(){
if(document.getElementById('iframe')) {
document.getElementById('iframe').contentWindow.location.reload();
}
};
$scope.tabData = [
{
heading: $filter('translate')('CONFIGURE_TAB'),
templateName: 'configure'
}
];
$scope.designTabActive = false
$scope.deactivateDesignTab = function(){
$scope.designTabActive = false
}
$scope.activateDesignTab = function(){
$scope.designTabActive = true
}
$scope.setForm = function(form){
$scope.myform = form;
};
$rootScope.resetForm = function(){
$scope.myform = Forms.get({
formId: $stateParams.formId
});
};
/*
** DeleteModal Functions
*/
$scope.openDeleteModal = function(){
$scope.deleteModal = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'formDeleteModal.html',
controller: 'AdminFormController',
resolve: {
myForm: function(){
return $scope.myform;
}
}
});
$scope.deleteModal.result.then(function (selectedItem) {
$scope.selected = selectedItem;
});
};
$scope.cancelDeleteModal = function(){
if($scope.deleteModal){
$scope.deleteModal.dismiss('cancel');
}
};
// Remove existing Form
$scope.removeCurrentForm = function() {
if($scope.deleteModal && $scope.deleteModal.opened){
$scope.deleteModal.close();
var form_id = $scope.myform._id;
if(!form_id) throw new Error('Error - removeCurrentForm(): $scope.myform._id does not exist');
$http.delete('/forms/'+form_id)
.then(function(response){
$state.go('listForms', {}, {reload: true})
}, function(error){
console.error(error);
});
}
};
$scope.updateDesign = function(updateImmediately, data, shouldDiff, refreshAfterUpdate){
$scope.update(updateImmediately, data, shouldDiff, refreshAfterUpdate, function(){
refreshFrame();
});
}
// Update existing Form
$scope.update = $rootScope.update = function(updateImmediately, data, shouldDiff, refreshAfterUpdate, cb){
var continueUpdate = true;
if(!updateImmediately){
continueUpdate = !$rootScope.saveInProgress;
}
//Update form **if we are not in the middle of an update** or if **shouldUpdateNow flag is set**
if(continueUpdate) {
var err = null;
if (!updateImmediately) {
$rootScope.saveInProgress = true;
}
if (shouldDiff) {
//Do this so we can create duplicate fields
var checkForValidId = new RegExp('^[0-9a-fA-F]{24}$');
for(var i=0; i < $scope.myform.form_fields.length; i++){
var field = $scope.myform.form_fields[i];
if(!checkForValidId.exec(field._id+'')){
delete $scope.myform.form_fields[i]._id;
delete $scope.myform.form_fields[i].id;
}
}
var data = DeepDiff.diff($scope.oldForm, $scope.myform);
$scope.updatePromise = $http.put('/forms/' + $scope.myform._id, {changes: data})
.then(function (response) {
if (refreshAfterUpdate) {
$rootScope.myform = $scope.myform = response.data;
$scope.oldForm = _.cloneDeep($scope.myform);
}
}).catch(function (response) {
err = response.data;
console.error(err);
}).finally(function () {
if (!updateImmediately) {
$rootScope.saveInProgress = false;
}
if ((typeof cb) === 'function') {
return cb(err);
}
});
} else {
var dataToSend = data;
if(dataToSend.analytics && dataToSend.analytics.visitors){
delete dataToSend.analytics.visitors;
}
if(dataToSend.submissions){
delete dataToSend.submissions;
}
if(dataToSend.visible_form_fields){
delete dataToSend.visible_form_fields;
}
if(dataToSend.analytics){
delete dataToSend.analytics.visitors;
delete dataToSend.analytics.fields;
delete dataToSend.analytics.submissions;
delete dataToSend.analytics.views;
delete dataToSend.analytics.conversionRate;
}
delete dataToSend.created;
delete dataToSend.lastModified;
delete dataToSend.__v;
$scope.updatePromise = $http.put('/forms/' + $scope.myform._id, {form: dataToSend})
.then(function (response) {
if (refreshAfterUpdate) {
$rootScope.myform = $scope.myform = response.data;
}
}).catch(function (response) {
err = response.data;
console.error(err);
}).finally(function () {
if (!updateImmediately) {
$rootScope.saveInProgress = false;
}
if ((typeof cb) === 'function') {
return cb(err);
}
});
}
}
};
}
]);
'use strict';
// Forms controller
angular.module('forms').controller('ListFormsController', ['$rootScope', '$scope', '$stateParams', '$state', 'GetForms', 'CurrentForm', '$http', '$uibModal', 'myForms',
function($rootScope, $scope, $stateParams, $state, GetForms, CurrentForm, $http, $uibModal, myForms) {
$scope = $rootScope;
$scope.forms = {};
$scope.showCreateModal = false;
$scope.myforms = myForms
$rootScope.languageRegExp = {
regExp: /[@!#$%^&*()\-+={}\[\]|\\/'";:`.,~№?<>]+/i,
test: function(val) {
return !this.regExp.test(val);
}
};
/*
** DeleteModal Functions
*/
$scope.openDeleteModal = function(index){
$scope.deleteModal = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'deleteModalListForms.html',
controller: ["$uibModalInstance", "items", "$scope", function($uibModalInstance, items, $scope) {
$scope.content = items;
$scope.cancel = $scope.cancelDeleteModal;
$scope.deleteForm = function() {
$scope.$parent.removeForm(items.formIndex);
};
}],
resolve: {
items: function() {
return {
currFormTitle: $scope.myforms[index].title,
formIndex: index
};
}
}
});
};
$scope.cancelDeleteModal = function(){
if($scope.deleteModal){
$scope.deleteModal.dismiss('cancel');
}
};
//Modal functions
$scope.openCreateModal = function(){
if(!$scope.showCreateModal){
$scope.showCreateModal = true;
}
};
$scope.closeCreateModal = function(){
if($scope.showCreateModal){
$scope.showCreateModal = false;
}
};
$scope.setForm = function (form) {
$scope.myform = form;
};
$scope.goToWithId = function(route, id) {
$state.go(route, {'formId': id}, {reload: true});
};
$scope.duplicateForm = function(form_index){
var form = _.cloneDeep($scope.myforms[form_index]);
delete form._id;
$http.post('/forms', {form: form})
.success(function(data, status, headers){
$scope.myforms.splice(form_index+1, 0, data);
}).error(function(errorResponse){
console.error(errorResponse);
if(errorResponse === null){
$scope.error = errorResponse.data.message;
}
});
};
// Create new Form
$scope.createNewForm = function(){
var form = {};
form.title = $scope.forms.createForm.title.$modelValue;
form.language = $scope.forms.createForm.language.$modelValue;
if($scope.forms.createForm.$valid && $scope.forms.createForm.$dirty){
$http.post('/forms', {form: form})
.success(function(data, status, headers){
// Redirect after save
$scope.goToWithId('viewForm.create', data._id+'');
}).error(function(errorResponse){
console.error(errorResponse);
$scope.error = errorResponse.data.message;
});
}
};
$scope.removeForm = function(form_index) {
if(form_index >= $scope.myforms.length || form_index < 0){
throw new Error('Error: form_index in removeForm() must be between 0 and '+$scope.myforms.length-1);
}
$http.delete('/forms/'+$scope.myforms[form_index]._id)
.success(function(data, status, headers){
$scope.myforms.splice(form_index, 1);
$scope.cancelDeleteModal();
}).error(function(error){
console.error(error);
});
};
}
]);
'use strict';
angular.module('forms').directive('configureFormDirective', ['$rootScope', '$http', 'Upload', 'CurrentForm',
function ($rootScope, $http, Upload, CurrentForm) {
return {
templateUrl: 'modules/forms/admin/views/directiveViews/form/configure-form.client.view.html',
restrict: 'E',
scope: {
myform:'=',
user:'=',
pdfFields:'@',
formFields:'@'
},
controller: ["$scope", function($scope){
$scope.log = '';
$scope.languages = $rootScope.languages;
$scope.resetForm = $rootScope.resetForm;
$scope.update = $rootScope.update;
}]
};
}
]);
'use strict';
angular.module('forms').directive('editFormDirective', ['$rootScope', 'FormFields', '$uibModal',
function ($rootScope, FormFields, $uibModal) {
return {
templateUrl: 'modules/forms/admin/views/directiveViews/form/edit-form.client.view.html',
restrict: 'E',
transclude: true,
scope: {
myform:'='
},
controller: ["$scope", function($scope){
/*
** Initialize scope with variables
*/
var newField;
//Setup UI-Sortable
$scope.sortableOptions = {
appendTo: '.dropzone',
//helper: 'clone',
forceHelperSize: true,
forcePlaceholderSize: true,
update: function(e, ui) {
$scope.update(false, $scope.myform, true, false, function(err){
});
},
};
/*
** EditModal Functions
*/
$scope.openEditModal = function(curr_field, isEdit, field_index){
$scope.editFieldModal = $uibModal.open({
animation: true,
templateUrl: 'editFieldModal.html',
windowClass: 'edit-modal-window',
controller: ["$uibModalInstance", "$scope", function($uibModalInstance, $scope) {
$scope.field = curr_field;
$scope.showLogicJump = false;
$scope.isEdit = isEdit;
// decides whether field options block will be shown (true for dropdown and radio fields)
$scope.showAddOptions = function (field){
if($scope.field.fieldType === 'dropdown' || $scope.field.fieldType === 'checkbox' || $scope.field.fieldType === 'radio'){
return true;
} else {
return false;
}
};
$scope.validShapes = [
'Heart',
'Star',
'thumbs-up',
'thumbs-down',
'Circle',
'Square',
'Check Circle',
'Smile Outlined',
'Hourglass',
'bell',
'Paper Plane',
'Comment',
'Trash'
];
// add new option to the field
$scope.addOption = function(){
if($scope.field.fieldType === 'checkbox' || $scope.field.fieldType === 'dropdown' || $scope.field.fieldType === 'radio'){
if(!$scope.field.fieldOptions){
$scope.field.fieldOptions = [];
}
var lastOptionID = $scope.field.fieldOptions.length+1;
// new option's id
var newOption = {
'option_id' : Math.floor(100000*Math.random()),
'option_title' : 'Option '+lastOptionID,
'option_value' : 'Option ' +lastOptionID
};
// put new option into fieldOptions array
$scope.field.fieldOptions.push(newOption);
}
};
// delete particular option
$scope.deleteOption = function (option){
if($scope.field.fieldType === 'checkbox' || $scope.field.fieldType === 'dropdown' || $scope.field.fieldType === 'radio'){
for(var i = 0; i < $scope.field.fieldOptions.length; i++){
if($scope.field.fieldOptions[i].option_id === option.option_id){
$scope.field.fieldOptions.splice(i, 1);
break;
}
}
}
};
//Populate Name to Font-awesomeName Conversion Map
$scope.select2FA = {
'Heart': 'Heart',
'Star': 'Star',
'thumbs-up': 'Thumbs Up',
'thumbs-down':'Thumbs Down',
'Circle': 'Circle',
'Square':'Square',
'Check Circle': 'Checkmark',
'Smile Outlined': 'Smile',
'Hourglass': 'Hourglass',
'bell': 'Bell',
'Paper Plane': 'Paper Plane',
'Comment': 'Chat Bubble',
'Trash': 'Trash Can'
};
// decides whether field options block will be shown (true for dropdown and radio fields)
$scope.showRatingOptions = function (){
if($scope.field.fieldType === 'rating'){
return true;
} else {
return false;
}
};
$scope.saveField = function(){
if($scope.isEdit){
$scope.myform.form_fields[field_index] = $scope.field;
} else {
$scope.myform.form_fields.push(curr_field);
}
$scope.$parent.update(false, $scope.$parent.myform, true, true, function(){
$uibModalInstance.close();
});
};
$scope.cancel = function(){
$uibModalInstance.close();
};
}]
});
};
/*
** EditStartPageModal Functions
*/
$scope.openEditStartPageModal = function(){
$scope.editStartPageModal = $uibModal.open({
animation: true,
templateUrl: 'editStartPageModal.html',
windowClass: 'edit-modal-window',
controller: ["$uibModalInstance", "$scope", function($uibModalInstance, $scope) {
/*
** startPage Button Methods
*/
$scope.showButtons = false;
$scope.lastButtonID = 0;
// add new Button to the startPage
$scope.addButton = function(){
var newButton = {};
newButton.bgColor = '#ddd';
newButton.color = '#ffffff';
newButton.text = 'Button';
newButton._id = Math.floor(100000*Math.random());
$scope.myform.startPage.buttons.push(newButton);
};
// delete particular Button from startPage
$scope.deleteButton = function(button){
var currID;
for(var i = 0; i < $scope.myform.startPage.buttons.length; i++){
currID = $scope.myform.startPage.buttons[i]._id;
if(currID === button._id){
$scope.myform.startPage.buttons.splice(i, 1);
break;
}
}
};
$scope.saveStartPage = function(){
$scope.$parent.update(false, $scope.$parent.myform, true, true, function(){
$uibModalInstance.close();
});
};
$scope.cancel = function(){
$uibModalInstance.close();
};
}]
});
};
/*
** EditEndPageModal Functions
*/
$scope.openEditEndPageModal = function(){
$scope.editEndPageModal = $uibModal.open({
animation: true,
templateUrl: 'editEndPageModal.html',
windowClass: 'edit-modal-window',
controller: ["$uibModalInstance", "$scope", function($uibModalInstance, $scope) {
/*
** startPage Button Methods
*/
$scope.showButtons = false;
$scope.lastButtonID = 0;
// add new Button to the startPage
$scope.addButton = function(){
var newButton = {};
newButton.bgColor = '#ddd';
newButton.color = '#ffffff';
newButton.text = 'Button';
newButton._id = Math.floor(100000*Math.random());
$scope.myform.endPage.buttons.push(newButton);
};
// delete particular Button from startPage
$scope.deleteButton = function(button){
var currID;
for(var i = 0; i < $scope.myform.endPage.buttons.length; i++){
currID = $scope.myform.endPage.buttons[i]._id;
if(currID === button._id){
$scope.myform.endPage.buttons.splice(i, 1);
break;
}
}
};
$scope.saveEndPage = function(){
$scope.$parent.update(false, $scope.$parent.myform, true, true, function(){
$uibModalInstance.close();
});
};
$scope.cancel = function(){
$uibModalInstance.close();
};
}]
});
};
//Populate local scope with rootScope methods/variables
$scope.update = $rootScope.update;
/*
** FormFields (ui-sortable) drag-and-drop configuration
*/
$scope.dropzone = {
handle: '.handle',
containment: '.dropzoneContainer',
cursor: 'grabbing'
};
/*
** Field CRUD Methods
*/
// Add a new field
$scope.addNewField = function(fieldType){
// increment lastAddedID counter
$scope.addField.lastAddedID++;
var fieldTitle = fieldType;
for(var i = 0; i < $scope.addField.types.length; i++){
if($scope.addField.types[i].name === fieldType){
$scope.addField.types[i].lastAddedID++;
fieldTitle = $scope.addField.types[i].value+$scope.addField.types[i].lastAddedID;
break;
}
}
newField = {
title: fieldTitle,
fieldType: fieldType,
fieldValue: '',
required: true,
disabled: false,
deletePreserved: false,
logicJump: {}
};
if(fieldType === 'rating'){
newField.ratingOptions = {
steps: 5,
shape: 'Heart'
};
newField.fieldValue = 0;
}
if($scope.showAddOptions(newField)){
newField.fieldOptions = [];
newField.fieldOptions.push({
'option_id' : Math.floor(100000*Math.random()), //Generate pseudo-random option id
'option_title' : 'Option 0',
'option_value' : 'Option 0'
});
}
$scope.openEditModal(newField, false, $scope.myform.form_fields.length);
};
// decides whether field options block will be shown (true for dropdown and radio fields)
$scope.showAddOptions = function (field){
if(field.fieldType === 'dropdown' || field.fieldType === 'checkbox' || field.fieldType === 'radio'){
return true;
} else {
return false;
}
};
// decides whether field options block will be shown (true for dropdown and radio fields)
$scope.showRatingOptions = function (field){
if(field.fieldType === 'rating'){
return true;
} else {
return false;
}
};
// Delete particular field on button click
$scope.deleteField = function (field_index) {
$scope.myform.form_fields.splice(field_index, 1);
$scope.update(false, $scope.myform, false, true, null);
};
$scope.duplicateField = function(field_index){
var currField = angular.copy($scope.myform.form_fields[field_index]);
currField._id = 'cloned'+_.uniqueId();
currField.title += ' copy';
//Insert field at selected index
$scope.myform.form_fields.push(currField);
$scope.update(false, $scope.myform, false, true, null);
};
//Populate AddField with all available form field types
$scope.addField = {};
$scope.addField.types = FormFields.types;
$scope.addField.types.forEach(function(type){
type.lastAddedID = 1;
return type;
});
}]
};
}
]);
'use strict';
angular.module('forms').directive('editSubmissionsFormDirective', ['$rootScope', '$http', 'Forms', '$stateParams', '$interval',
function ($rootScope, $http, Forms, $stateParams, $interval) {
return {
templateUrl: 'modules/forms/admin/views/directiveViews/form/edit-submissions-form.client.view.html',
restrict: 'E',
scope: {
user:'=',
myform: '='
},
controller: ["$scope", function($scope){
$scope.table = {
masterChecker: false,
rows: []
};
var initController = function(){
$http({
method: 'GET',
url: '/forms/'+$scope.myform._id+'/submissions'
}).then(function successCallback(response) {
var defaultFormFields = _.cloneDeep($scope.myform.form_fields);
var submissions = response.data || [];
//Iterate through form's submissions
for(var i = 0; i < submissions.length; i++){
for(var x = 0; x < submissions[i].form_fields.length; x++){
if(submissions[i].form_fields[x].fieldType === 'dropdown'){
submissions[i].form_fields[x].fieldValue = submissions[i].form_fields[x].fieldValue.option_value;
}
//var oldValue = submissions[i].form_fields[x].fieldValue || '';
//submissions[i].form_fields[x] = _.merge(defaultFormFields, submissions[i].form_fields);
//submissions[i].form_fields[x].fieldValue = oldValue;
}
submissions[i].selected = false;
}
$scope.table.rows = submissions;
});
};
initController();
/*
** Analytics Functions
*/
$scope.AverageTimeElapsed = (function(){
var totalTime = 0;
var numSubmissions = $scope.table.rows.length;
for(var i=0; i<$scope.table.rows.length; i++){
totalTime += $scope.table.rows[i].timeElapsed;
}
if(numSubmissions === 0) {
return 0;
}
return (totalTime/numSubmissions).toFixed(0);
})();
$scope.DeviceStatistics = (function(){
var newStatItem = function(){
return {
visits: 0,
responses: 0,
completion: 0,
average_time: 0,
total_time: 0
};
};
var stats = {
desktop: newStatItem(),
tablet: newStatItem(),
phone: newStatItem(),
other: newStatItem()
};
if($scope.myform.analytics && $scope.myform.analytics.visitors) {
var visitors = $scope.myform.analytics.visitors;
for (var i = 0; i < visitors.length; i++) {
var visitor = visitors[i];
var deviceType = visitor.deviceType;
stats[deviceType].visits++;
if (visitor.isSubmitted) {
stats[deviceType].total_time = stats[deviceType].total_time + visitor.timeElapsed;
stats[deviceType].responses++;
}
if(stats[deviceType].visits) {
stats[deviceType].completion = 100*(stats[deviceType].responses / stats[deviceType].visits).toFixed(2);
}
if(stats[deviceType].responses){
stats[deviceType].average_time = (stats[deviceType].total_time / stats[deviceType].responses).toFixed(0);
}
}
}
return stats;
})();
var updateFields = $interval(initController, 1000000);
$scope.$on('$destroy', function() {
if (updateFields) {
$interval.cancel($scope.updateFields);
}
});
/*
** Table Functions
*/
$scope.isAtLeastOneChecked = function(){
for(var i=0; i<$scope.table.rows.length; i++){
if($scope.table.rows[i].selected) return true;
}
return false;
};
$scope.toggleAllCheckers = function(){
for(var i=0; i<$scope.table.rows.length; i++){
$scope.table.rows[i].selected = $scope.table.masterChecker;
}
};
$scope.toggleObjSelection = function($event) {
$event.stopPropagation();
};
$scope.rowClicked = function(row_index) {
$scope.table.rows[row_index].selected = !$scope.table.rows[row_index].selected;
};
/*
* Form Submission Methods
*/
//Delete selected submissions of Form
$scope.deleteSelectedSubmissions = function(){
var delete_ids = _.chain($scope.table.rows).filter(function(row){
return !!row.selected;
}).pluck('_id').value();
$http({ url: '/forms/'+$scope.myform._id+'/submissions',
method: 'DELETE',
data: {deleted_submissions: delete_ids},
headers: {'Content-Type': 'application/json;charset=utf-8'}
}).success(function(data, status){
//Remove deleted ids from table
var tmpArray = [];
for(var i=0; i<$scope.table.rows.length; i++){
if(!$scope.table.rows[i].selected){
tmpArray.push($scope.table.rows[i]);
}
}
$scope.table.rows = tmpArray;
})
.error(function(err){
console.error(err);
});
};
//Export selected submissions of Form
$scope.exportSubmissions = function(type){
angular.element('#table-submission-data').tableExport({type: type, escape:false, ignoreColumn: [0]});
};
}]
};
}
]);
'use strict';
//TODO: DAVID: URGENT: Make this a $resource that fetches valid field types from server
angular.module('forms').service('FormFields', [ '$rootScope', '$translate', '$window',
function($rootScope, $translate, $window) {
$translate.use($window.user.language);
console.log($translate.instant('SHORT_TEXT'));
this.types = [
{
name : 'textfield',
value : $translate.instant('SHORT_TEXT'),
},
{
name : 'email',
value : $translate.instant('EMAIL'),
},
{
name : 'radio',
value : $translate.instant('MULTIPLE_CHOICE'),
},
{
name : 'dropdown',
value : $translate.instant('DROPDOWN'),
},
{
name : 'date',
value : $translate.instant('DATE'),
},
{
name : 'textarea',
value : $translate.instant('PARAGRAPH'),
},
{
name : 'yes_no',
value : $translate.instant('YES_NO'),
},
{
name : 'legal',
value : $translate.instant('LEGAL'),
},
// {
// name : 'sig',
// value : $translate.instant('SIGNATURE'),
// },
// {
// name : 'file',
// value : $translate.instant('FILE_UPLOAD'),
// },
{
name : 'rating',
value : $translate.instant('RATING'),
},
{
name : 'link',
value : $translate.instant('LINK'),
},
{
name : 'number',
value : $translate.instant('NUMBERS'),
},
// {
// name : 'scale',
// value : $translate.instant('OPINION SCALE'),
// },
// {
// name : 'stripe',
// value : $translate.instant('PAYMENT'),
// },
{
name : 'statement',
value : $translate.instant('STATEMENT')
}
];
}
]);
'use strict';
//Submissions service used for communicating with the forms REST endpoints
angular.module('forms').factory('Submissions', ['$resource',
function($resource) {
return $resource('forms/:formID/submissions/:submissionId', {
submissionId: '@_id',
formId: '@_id'
}, {
'query' : {
method: 'GET',
isArray: true,
},
'update': {
method: 'PUT'
},
'save': {
method: 'POST'
}
});
}
]);
'use strict';
angular.module('users').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('en', {
ACCESS_DENIED_TEXT: 'You need to be logged in to access this page',
USERNAME_OR_EMAIL_LABEL: 'Username or Email',
USERNAME_LABEL: 'Username',
PASSWORD_LABEL: 'Password',
CURRENT_PASSWORD_LABEL: 'Current Password',
NEW_PASSWORD_LABEL: 'New Password',
VERIFY_PASSWORD_LABEL: 'Verify Password',
UPDATE_PASSWORD_LABEL: 'Update Password',
FIRST_NAME_LABEL: 'First Name',
LAST_NAME_LABEL: 'Last Name',
LANGUAGE_LABEL: 'Language',
EMAIL_LABEL: 'Email',
SIGNUP_ACCOUNT_LINK: 'Don\'t have an account? Sign up here',
SIGN_IN_ACCOUNT_LINK: 'Already have an account? Sign in here',
SIGNUP_HEADER_TEXT: 'Sign up',
SIGNIN_HEADER_TEXT: 'Sign in',
SIGNUP_ERROR_TEXT: 'Couldn\'t complete registration due to errors',
ENTER_ACCOUNT_EMAIL: 'Enter your account email.',
RESEND_VERIFICATION_EMAIL: 'Resend Verification Email',
SAVE_CHANGES: 'Save Changes',
CANCEL_BTN: 'Cancel',
EDIT_PROFILE: 'Edit your profile',
UPDATE_PROFILE_BTN: 'Update Profile',
PROFILE_SAVE_SUCCESS: 'Profile saved successfully',
PROFILE_SAVE_ERROR: 'Could\'t Save Your Profile.',
CONNECTED_SOCIAL_ACCOUNTS: 'Connected social accounts',
CONNECT_OTHER_SOCIAL_ACCOUNTS: 'Connect other social accounts',
FORGOT_PASSWORD_LINK: 'Forgot your password?',
REVERIFY_ACCOUNT_LINK: 'Resend your verification email',
SIGNIN_BTN: 'Sign in',
SIGNUP_BTN: 'Sign up',
SAVE_PASSWORD_BTN: 'Save Password',
SUCCESS_HEADER: 'Signup Successful',
SUCCESS_TEXT: 'You’ve successfully registered an account at TellForm.',
VERIFICATION_EMAIL_SENT: 'Verification Email has been Sent',
VERIFICATION_EMAIL_SENT_TO: 'A verification email has been sent to',
NOT_ACTIVATED_YET: 'But your account is not activated yet',
BEFORE_YOU_CONTINUE: 'Before you continue, make sure to check your email for our verification. If you don’t receive it within 24h drop us a line at ',
CHECK_YOUR_EMAIL: 'Check your email and click on the activation link to activate your account. If you have any questions drop us a line at',
CONTINUE: 'Continue',
PASSWORD_RESTORE_HEADER: 'Restore your password',
ENTER_YOUR_EMAIL: 'Enter your account email.',
SUBMIT_BTN: 'Submit',
ASK_FOR_NEW_PASSWORD: 'Ask for new password reset',
PASSWORD_RESET_INVALID: 'Password reset link is invalid',
PASSWORD_RESET_SUCCESS: 'Password successfully reset',
PASSWORD_CHANGE_SUCCESS: 'Password successfully changed',
RESET_PASSWORD: 'Reset your password',
CHANGE_PASSWORD: 'Change your password',
CONTINUE_TO_LOGIN: 'Continue to login page',
VERIFY_SUCCESS: 'Account successfully activated',
VERIFY_ERROR: 'Verification link is invalid or has expired',
ERROR: 'Error'
});
$translateProvider.preferredLanguage('en')
.fallbackLanguage('en')
.useSanitizeValueStrategy('escape');
}]);
'use strict';
angular.module('users').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('fr', {
ACCESS_DENIED_TEXT: 'Vouz n’êtes pas autorisé à accéder à cette page.',
USERNAME_LABEL: 'Nom d’utilisateur',
PASSWORD_LABEL: 'Mot de Passe',
CURRENT_PASSWORD_LABEL: 'Mot de passe actuel',
NEW_PASSWORD_LABEL: 'Nouveau Mot de Passe',
VERIFY_PASSWORD_LABEL: 'Vérifier le mot de passe',
UPDATE_PASSWORD_LABEL: 'Mettre à jour le mot de passe',
FIRST_NAME_LABEL: 'Prénom',
LAST_NAME_LABEL: 'Nom',
LANGUAGE_LABEL: 'Langue',
EMAIL_LABEL: 'Email',
UPDATE_PROFILE_BTN: 'Modifier le Profil',
PROFILE_SAVE_SUCCESS: 'Profil enregistré avec succès',
PROFILE_SAVE_ERROR: 'Erreur: impossible d’enregistrer votre Profile.',
FORGOT_PASSWORD_LINK: 'Mot de passe oublié ?',
REVERIFY_ACCOUNT_LINK: 'Re-envoyez un email de vérification',
SIGNIN_BTN: 'Connexion',
SIGNUP_BTN: 'Créer un compte',
SAVE_PASSWORD_BTN: 'Enregistrer votre nouveau Mot de Passe',
SUCCESS_HEADER: 'Votre Compte a été enregistré !',
SUCCESS_TEXT: 'Votre compte Tellform a été crée avec succès.',
VERIFICATION_EMAIL_SENT: 'Un email de verification a été envoyer à',
NOT_ACTIVATED_YET: 'Mais votre compte n\'est pas activé',
BEFORE_YOU_CONTINUE: 'Avant de continuer, vous devez valider votre adresse mail. Merci de vérifier votre boite mail. Si vous ne l’avez pas reçu dans les prochaines 24h, contactez-nous a ',
CHECK_YOUR_EMAIL: 'Vérifiez vos emails, et cliquez sur le lien de validation pour activer votre compte. Si vous avez une question contactez-nous à',
PASSWORD_RESTORE_HEADER: 'Mot de passe perdu',
ENTER_YOUR_EMAIL: 'Entrer votre email',
SUBMIT_BTN: 'Enregistrer',
ASK_FOR_NEW_PASSWORD: 'Demander un nouveau mot de pass ',
PASSWORD_RESET_INVALID: 'Ce lien de réinitialisation de mot de passe a déjà expiré',
PASSWORD_RESET_SUCCESS: 'Mot de passe réinitialisé avec succès',
PASSWORD_CHANGE_SUCCESS: 'Mot de passe enregistré avec succès',
CONTINUE_TO_LOGIN: 'Allez à la page de connexion',
VERIFY_SUCCESS: 'Votre compte est activé !',
VERIFY_ERROR: 'Le lien de vérification est invalide ou à expiré',
ERROR: 'Erreur'
});
}]);
'use strict';
angular.module('users').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('de', {
ACCESS_DENIED_TEXT: 'Sie müssen eingeloggt sein, um auf diese Seite zugreifen zu können',
USERNAME_OR_EMAIL_LABEL: 'Benutzername oder E-Mail',
USERNAME_LABEL: 'Benutzername',
PASSWORD_LABEL: 'Passwort',
CURRENT_PASSWORD_LABEL: 'Aktuelles Passwort',
NEW_PASSWORD_LABEL: 'Neues Passwort',
VERIFY_PASSWORD_LABEL: 'Passwort bestätigen',
UPDATE_PASSWORD_LABEL: 'Passwort aktualisieren',
FIRST_NAME_LABEL: 'Vorname',
LAST_NAME_LABEL: 'Nachname',
LANGUAGE_LABEL: 'Sprache',
EMAIL_LABEL: 'Email',
SIGNUP_ACCOUNT_LINK: 'Haben Sie kein Konto? Hier registrieren',
SIGN_IN_ACCOUNT_LINK: 'Haben Sie bereits ein Konto? Hier anmelden',
SIGNUP_HEADER_TEXT: 'Registrieren',
SIGNIN_HEADER_TEXT: 'Anmelden',
SIGNUP_ERROR_TEXT: 'Konnte die Registrierung aufgrund von Fehlern nicht abschließen',
ENTER_ACCOUNT_EMAIL: 'Geben Sie Ihre Konto-E-Mail ein.',
RESEND_VERIFICATION_EMAIL: 'Bestätigungs-E-Mail erneut senden',
SAVE_CHANGES: 'Änderungen speichern',
CANCEL_BTN: 'Abbrechen',
EDIT_PROFILE: 'Bearbeiten Sie Ihr Profil',
UPDATE_PROFILE_BTN: 'Profil aktualisieren',
PROFILE_SAVE_SUCCESS: 'Profil wurde erfolgreich gespeichert',
PROFILE_SAVE_ERROR: 'Könnte Ihr Profil nicht speichern.',
CONNECTED_SOCIAL_ACCOUNTS: 'Verbundene Sozialkonten',
CONNECT_OTHER_SOCIAL_ACCOUNTS: 'Andere soziale Konten verbinden',
FORGOT_PASSWORD_LINK: 'Passwort vergessen?',
REVERIFY_ACCOUNT_LINK: 'Bestätige deine Bestätigungs-E-Mail erneut',
SIGNIN_BTN: "Anmelden",
SIGNUP_BTN: 'Registrieren',
SAVE_PASSWORD_BTN: 'Passwort speichern',
SUCCESS_HEADER: 'Anmeldung erfolgreich',
SUCCESS_TEXT: 'Sie haben ein Konto erfolgreich bei TellForm registriert.',
VERIFICATION_EMAIL_SENT: 'Bestätigungs-E-Mail wurde gesendet',
VERIFICATION_EMAIL_SENT_TO: 'Es wurde eine Bestätigungs-E-Mail gesendet.',
NOT_ACTIVATED_YET: 'Dein Account ist noch nicht aktiviert',
BEFORE_YOU_CONTINUE: 'Bevor Sie fortfahren, überprüfen Sie bitte Ihre E-Mail-Adresse auf Überprüfung. Wenn Sie nicht innerhalb von 24 Stunden erhalten Sie uns eine Zeile bei ',
CHECK_YOUR_EMAIL: 'Überprüfe deine E-Mail und klicke auf den Aktivierungslink, um deinen Account zu aktivieren. Wenn Sie irgendwelche Fragen haben, lassen Sie uns eine Zeile bei ',
WEITER: 'Weiter',
PASSWORD_RESTORE_HEADER: 'Wiederherstellen Ihres Passworts',
ENTER_YOUR_EMAIL: 'Geben Sie Ihre E-Mail-Adresse ein.',
SUBMIT_BTN: 'Senden',
ASK_FOR_NEW_PASSWORD: 'Neues Passwort zurücksetzen',
PASSWORD_RESET_INVALID: 'Dieser Link zum Zurücksetzen des Passworts ist bereits abgelaufen',
PASSWORD_RESET_SUCCESS: 'Passport erfolgreich zurückgesetzt',
PASSWORD_CHANGE_SUCCESS: 'Pass wurde erfolgreich geändert',
RESET_PASSWORD: 'Passwort zurücksetzen',
CHANGE_PASSWORD: 'Ändern Sie Ihr Passwort',
CONTINUE_TO_LOGIN: 'Weiter zur Anmeldeseite',
VERIFY_SUCCESS: 'Konto erfolgreich aktiviert',
VERIFY_ERROR: 'Überprüfungslink ist ungültig oder abgelaufen',
ERROR: 'Fehler'
});
}]);
'use strict';
angular.module('users').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('it', {
ACCESS_DENIED_TEXT: 'Devi aver effettuato l\'accesso per accedere a questa pagina',
USERNAME_OR_EMAIL_LABEL: 'Nome utente o posta elettronica',
USERNAME_LABEL: 'Nome utente',
PASSWORD_LABEL: 'Password',
CURRENT_PASSWORD_LABEL: 'Current Password',
NEW_PASSWORD_LABEL: 'Nuova password',
VERIFY_PASSWORD_LABEL: 'Verifica password',
UPDATE_PASSWORD_LABEL: 'Aggiorna password',
FIRST_NAME_LABEL: 'Nome',
LAST_NAME_LABEL: 'Cognome',
LANGUAGE_LABEL: 'Lingua',
EMAIL_LABEL: 'Email',
SIGNUP_ACCOUNT_LINK: 'Non hai un account? Iscriviti qui ',
SIGN_IN_ACCOUNT_LINK: 'Hai già un account? Accedi qui ',
SIGNUP_HEADER_TEXT: 'Iscriviti',
SIGNIN_HEADER_TEXT: 'Accedi',
SIGNUP_ERROR_TEXT: 'Impossibile completare la registrazione a causa di errori',
ENTER_ACCOUNT_EMAIL: "Inserisci l'email del tuo account.",
RESEND_VERIFICATION_EMAIL: 'Ripeti l\'email di verifica',
SAVE_CHANGES: 'Salva modifiche',
CANCEL_BTN: 'Annulla',
EDIT_PROFILE: 'Modifica il tuo profilo',
UPDATE_PROFILE_BTN: 'Aggiorna profilo',
PROFILE_SAVE_SUCCESS: 'Profilo salvato con successo',
PROFILE_SAVE_ERROR: 'Impossibile salvare il tuo profilo.',
CONNECTED_SOCIAL_ACCOUNTS: 'Conti sociali connessi',
CONNECT_OTHER_SOCIAL_ACCOUNTS: 'Connetti altri account sociali',
FORGOT_PASSWORD_LINK: 'Hai dimenticato la password?',
REVERIFY_ACCOUNT_LINK: 'Ripeti la tua email di verifica',
SIGNIN_BTN: 'Accedi',
SIGNUP_BTN: 'Iscriviti',
SAVE_PASSWORD_BTN: 'Salva password',
SUCCESS_HEADER: 'Registra il successo',
SUCCESS_TEXT: 'Hai registrato un account con TellForm.',
VERIFICATION_EMAIL_SENT: 'L\'email di verifica è stata inviata',
VERIFICATION_EMAIL_SENT_TO: 'E\' stata inviata un\'email di verifica a ',
NOT_ACTIVATED_YET: 'Ma il tuo account non è ancora attivato',
BEFORE_YOU_CONTINUE: 'Prima di continuare, assicurati di controllare la tua email per la nostra verifica. Se non lo ricevi entro 24 ore ci cali una linea a ',
CHECK_YOUR_EMAIL: 'Controlla la tua email e fai clic sul link di attivazione per attivare il tuo account. Se hai domande, fai una linea a ',
CONTINUA: 'Continua',
PASSWORD_RESTORE_HEADER: 'Ripristina password',
ENTER_YOUR_EMAIL: 'Inserisci l\'email del tuo account',
SUBMIT_BTN: 'Invia',
ASK_FOR_NEW_PASSWORD: 'Richiedi nuova password reimpostata',
PASSWORD_RESET_INVALID: 'Questo collegamento per la reimpostazione della password è già scaduto',
PASSWORD_RESET_SUCCESS: 'Passaporto resettato con successo',
PASSWORD_CHANGE_SUCCESS: 'Passaporto modificato con successo',
RESET_PASSWORD: 'Ripristina la tua password',
CHANGE_PASSWORD: 'Modifica password',
CONTINUE_TO_LOGIN: 'Continua alla pagina di login',
VERIFY_SUCCESS: 'Account attivato correttamente',
VERIFY_ERROR: 'Il collegamento di verifica non è valido o è scaduto',
ERROR: 'Errore'
});
}]);
'use strict';
angular.module('users').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('es', {
ACCESS_DENIED_TEXT: 'Tenés que estar logueado para acceder a esta página',
USERNAME_OR_EMAIL_LABEL: 'Usuario o Email',
USERNAME_LABEL: 'Usuario',
PASSWORD_LABEL: 'Contraseña',
CURRENT_PASSWORD_LABEL: 'Contraseña actual',
NEW_PASSWORD_LABEL: 'Nueva contraseña',
VERIFY_PASSWORD_LABEL: 'Verificar contraseña',
UPDATE_PASSWORD_LABEL: 'Actualizar contraseña',
FIRST_NAME_LABEL: 'Nombre',
LAST_NAME_LABEL: 'Apellido',
LANGUAGE_LABEL: 'Idioma',
EMAIL_LABEL: 'Email',
SIGNUP_ACCOUNT_LINK: '¿No tenés cuenta? Resgistrate acá',
SIGN_IN_ACCOUNT_LINK: '¿Ya tenés cuenta? Entra acá',
SIGNUP_HEADER_TEXT: 'Registrar',
SIGNIN_HEADER_TEXT: 'Entrar',
SIGNUP_ERROR_TEXT: 'No se pudo terminar la registración por errores',
ENTER_ACCOUNT_EMAIL: 'Ingresá tu correo electrónico.',
RESEND_VERIFICATION_EMAIL: 'Reenviar email de verificación',
SAVE_CHANGES: 'Grabar cambios',
CANCEL_BTN: 'Cancelar',
EDIT_PROFILE: 'Editar perfil',
UPDATE_PROFILE_BTN: 'Actualizar perfil',
PROFILE_SAVE_SUCCESS: 'Perfil actualizado satisfactoriamente',
PROFILE_SAVE_ERROR: 'No se pudo grabar el perfil.',
CONNECTED_SOCIAL_ACCOUNTS: 'Redes sociales conectadas',
CONNECT_OTHER_SOCIAL_ACCOUNTS: 'Conectar otras redes sociales',
FORGOT_PASSWORD_LINK: '¿Olvidaste la contraseña?',
REVERIFY_ACCOUNT_LINK: 'Reenviar email de verificación',
SIGNIN_BTN: 'Entrar',
SIGNUP_BTN: 'Registrarse',
SAVE_PASSWORD_BTN: 'Grabar contraseña',
SUCCESS_HEADER: 'Ingresaste exitosamente',
SUCCESS_TEXT: 'Registraste exitosamente una cuenta en TellForm.',
VERIFICATION_EMAIL_SENT: 'El email de verificación fue enviado exitosamente',
VERIFICATION_EMAIL_SENT_TO: 'Un email de verificación fue enviado a',
NOT_ACTIVATED_YET: 'Tu cuenta aún no está activa',
BEFORE_YOU_CONTINUE: 'Antes de continuar asegurate de leer el email de verificación que te enviamos. Si no lo recibís en 24hs escribinos a ',
CHECK_YOUR_EMAIL: 'Leé el email y hacé click en el link de activación para activar la cuenta. Si tenés alguna pregunta escribinos a ',
CONTINUE: 'Continuar',
PASSWORD_RESTORE_HEADER: 'Restaurar la contraseña',
ENTER_YOUR_EMAIL: 'Ingresá el email de tu cuenta.',
SUBMIT_BTN: 'Enviar',
ASK_FOR_NEW_PASSWORD: 'Pedir reseteo de contraseña',
PASSWORD_RESET_INVALID: 'Este enlace de restablecimiento de contraseña ya ha caducado',
PASSWORD_RESET_SUCCESS: 'Contraseña exitosamente reseteada',
PASSWORD_CHANGE_SUCCESS: 'Contraseña exitosamente cambiada',
RESET_PASSWORD: 'Resetear contraseña',
CHANGE_PASSWORD: 'Cambiar contraseña',
CONTINUE_TO_LOGIN: 'Ir a la página de ingreso',
VERIFY_SUCCESS: 'Cuenta activada exitosamente',
VERIFY_ERROR: 'El link de verificación es inválido o inexistente',
ERROR: 'Error'
});
}]);
'use strict';
angular.module('forms').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('en', {
//Configure Form Tab View
ADVANCED_SETTINGS: 'Advanced Settings',
FORM_NAME: 'Form Name',
FORM_STATUS: 'Form Status',
PUBLIC: 'Public',
PRIVATE: 'Private',
GA_TRACKING_CODE: 'Google Analytics Tracking Code',
DISPLAY_FOOTER: 'Display Form Footer?',
SAVE_CHANGES: 'Save Changes',
CANCEL: 'Cancel',
DISPLAY_START_PAGE: 'Display Start Page?',
DISPLAY_END_PAGE: 'Display Custom End Page?',
//List Forms View
CREATE_A_NEW_FORM: 'Create a new form',
CREATE_FORM: 'Create form',
CREATED_ON: 'Created on',
MY_FORMS: 'My forms',
NAME: 'Name',
LANGUAGE: 'Language',
FORM_PAUSED: 'Form paused',
//Edit Field Modal
EDIT_FIELD: 'Edit this Field',
SAVE_FIELD: 'Save',
ON: 'ON',
OFF: 'OFF',
REQUIRED_FIELD: 'Required',
LOGIC_JUMP: 'Logic Jump',
SHOW_BUTTONS: 'Additional Buttons',
SAVE_START_PAGE: 'Save',
//Admin Form View
ARE_YOU_SURE: 'Are you ABSOLUTELY sure?',
READ_WARNING: 'Unexpected bad things will happen if you don’t read this!',
DELETE_WARNING1: 'This action CANNOT be undone. This will permanently delete the "',
DELETE_WARNING2: '" form and remove all associated form submissions.',
DELETE_CONFIRM: 'Please type in the name of the form to confirm.',
I_UNDERSTAND: 'I understand the consequences, delete this form.',
DELETE_FORM_SM: 'Delete',
DELETE_FORM_MD: 'Delete Form',
DELETE: 'Delete',
FORM: 'Form',
VIEW: 'View',
LIVE: 'Live',
PREVIEW: 'Preview',
COPY: 'Copy',
COPY_AND_PASTE: 'Copy and Paste this to add your TellForm to your website',
CHANGE_WIDTH_AND_HEIGHT: 'Change the width and height values to suit you best',
POWERED_BY: 'Powered by',
TELLFORM_URL: 'Your TellForm is permanently at this URL',
//Edit Form View
DISABLED: 'Disabled',
YES: 'YES',
NO: 'NO',
ADD_LOGIC_JUMP: 'Add Logic Jump',
ADD_FIELD_LG: 'Click to Add New Field',
ADD_FIELD_MD: 'Add New Field',
ADD_FIELD_SM: 'Add Field',
EDIT_START_PAGE: 'Edit Start Page',
EDIT_END_PAGE: 'Edit End Page',
WELCOME_SCREEN: 'Start Page',
END_SCREEN: 'End Page',
INTRO_TITLE: 'Title',
INTRO_PARAGRAPH: 'Paragraph',
INTRO_BTN: 'Start Button',
TITLE: 'Title',
PARAGRAPH: 'Paragraph',
BTN_TEXT: 'Go Back Button',
BUTTONS: 'Buttons',
BUTTON_TEXT: 'Text',
BUTTON_LINK: 'Link',
ADD_BUTTON: 'Add Button',
PREVIEW_FIELD: 'Preview Question',
QUESTION_TITLE: 'Title',
QUESTION_DESCRIPTION: 'Description',
OPTIONS: 'Options',
ADD_OPTION: 'Add Option',
NUM_OF_STEPS: 'Number of Steps',
CLICK_FIELDS_FOOTER: 'Click on fields to add them here',
SHAPE: 'Shape',
IF_THIS_FIELD: 'If this field',
IS_EQUAL_TO: 'is equal to',
IS_NOT_EQUAL_TO: 'is not equal to',
IS_GREATER_THAN: 'is greater than',
IS_GREATER_OR_EQUAL_THAN: 'is greater or equal than',
IS_SMALLER_THAN: 'is smaller than',
IS_SMALLER_OR_EQUAL_THAN: 'is smaller or equal than',
CONTAINS: 'contains',
DOES_NOT_CONTAINS: 'does not contain',
ENDS_WITH: 'ends with',
DOES_NOT_END_WITH: 'does not end with',
STARTS_WITH: 'starts with',
DOES_NOT_START_WITH: 'does not start with',
THEN_JUMP_TO: 'then jump to',
//Edit Submissions View
TOTAL_VIEWS: 'total unique visits',
RESPONSES: 'responses',
COMPLETION_RATE: 'completion rate',
AVERAGE_TIME_TO_COMPLETE: 'avg. completion time',
DESKTOP_AND_LAPTOP: 'Desktops',
TABLETS: 'Tablets',
PHONES: 'Phones',
OTHER: 'Other',
UNIQUE_VISITS: 'Unique Visits',
FIELD_TITLE: 'Field Title',
FIELD_VIEWS: 'Field Views',
FIELD_DROPOFF: 'Field Completion',
FIELD_RESPONSES: 'Field Responses',
DELETE_SELECTED: 'Delete Selected',
EXPORT_TO_EXCEL: 'Export to Excel',
EXPORT_TO_CSV: 'Export to CSV',
EXPORT_TO_JSON: 'Export to JSON',
PERCENTAGE_COMPLETE: 'Percentage Complete',
TIME_ELAPSED: 'Time Elapsed',
DEVICE: 'Device',
LOCATION: 'Location',
IP_ADDRESS: 'IP Address',
DATE_SUBMITTED: 'Date Submitted',
//Design View
BACKGROUND_COLOR: 'Background Color',
DESIGN_HEADER: 'Change how your Form Looks',
QUESTION_TEXT_COLOR: 'Question Text Color',
ANSWER_TEXT_COLOR: 'Answer Text Color',
BTN_BACKGROUND_COLOR: 'Button Background Color',
BTN_TEXT_COLOR: 'Button Text Color',
//Share View
EMBED_YOUR_FORM: 'Embed your form',
SHARE_YOUR_FORM: 'Share your form',
//Admin Tabs
CREATE_TAB: 'Create',
DESIGN_TAB: 'Design',
CONFIGURE_TAB: 'Configure',
ANALYZE_TAB: 'Analyze',
SHARE_TAB: 'Share',
//Field Types
SHORT_TEXT: 'Short Text',
EMAIL: 'Email',
MULTIPLE_CHOICE: 'Multiple Choice',
DROPDOWN: 'Dropdown',
DATE: 'Date',
PARAGRAPH_T: 'Paragraph',
YES_NO: 'Yes/No',
LEGAL: 'Legal',
RATING: 'Rating',
NUMBERS: 'Numbers',
SIGNATURE: 'Signature',
FILE_UPLOAD: 'File upload',
OPTION_SCALE: 'Option Scale',
PAYMENT: 'Payment',
STATEMENT: 'Statement',
LINK: 'Link',
//Form Preview
FORM_SUCCESS: 'Form entry successfully submitted!',
REVIEW: 'Review',
BACK_TO_FORM: 'Go back to Form',
EDIT_FORM: 'Edit this TellForm',
ADVANCEMENT: '{{done}} out of {{total}} answered',
CONTINUE_FORM: 'Continue to Form',
REQUIRED: 'required',
COMPLETING_NEEDED: '{{answers_not_completed}} answer(s) need completing',
OPTIONAL: 'optional',
ERROR_EMAIL_INVALID: 'Please enter a valid email address',
ERROR_NOT_A_NUMBER: 'Please enter valid numbers only',
ERROR_URL_INVALID: 'Please a valid url',
OK: 'OK',
ENTER: 'press ENTER',
NEWLINE: 'press SHIFT+ENTER to create a newline',
CONTINUE: 'Continue',
LEGAL_ACCEPT: 'I accept',
LEGAL_NO_ACCEPT: 'I don’t accept',
SUBMIT: 'Submit',
UPLOAD_FILE: 'Upload your File'
});
}]);
'use strict';
angular.module('forms').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('fr', {
// Configurer la vue de l'onglet Formulaire
ADVANCED_SETTINGS: 'Paramètres avancés',
FORM_NAME: "Nom du formulaire",
FORM_STATUS: 'Statut du formulaire',
PUBLIC: 'Public',
PRIVATE: "Privé",
GA_TRACKING_CODE: "Code de suivi Google Analytics",
DISPLAY_FOOTER: "Afficher le pied de formulaire?",
SAVE_CHANGES: 'Enregistrer les modifications',
CANCEL: 'Annuler',
DISPLAY_START_PAGE: "Afficher la page de démarrage?",
DISPLAY_END_PAGE: "Afficher la page de fin personnalisée?",
// Afficher les formulaires
CREATE_A_NEW_FORM: "Créer un nouveau formulaire",
CREATE_FORM: "Créer un formulaire",
CREATED_ON: 'Créé le',
MY_FORMS: 'Mes formes',
NAME: "Nom",
LANGUE: 'Langue',
FORM_PAUSED: 'Formulaire en pause',
// Modifier le modal de champ
EDIT_FIELD: "Modifier ce champ",
SAVE_FIELD: 'Enregistrer',
ON: 'ON',
OFF: "OFF",
REQUIRED_FIELD: "Obligatoire",
LOGIC_JUMP: 'Saut logique',
SHOW_BUTTONS: 'Boutons supplémentaires',
SAVE_START_PAGE: "Enregistrer",
// Affichage du formulaire d'administration
ARE_YOU_SURE: 'Es-tu ABSOLUMENT sûr?',
READ_WARNING: "De mauvaises choses inattendues se produiront si vous ne lisez pas ceci!",
DELETE_WARNING1: 'Cette action NE PEUT PAS être annulée. Cela supprimera définitivement le "',
DELETE_WARNING2: '" forme et supprime toutes les soumissions de formulaire associées. ',
DELETE_CONFIRM: "Veuillez taper le nom du formulaire pour confirmer.",
I_UNDERSTAND: 'Je comprends les conséquences, efface ce formulaire.',
DELETE_FORM_SM: 'Supprimer',
DELETE_FORM_MD: "Supprimer le formulaire",
DELETE: "Supprimer",
FORM: 'Formulaire',
VIEW: "Afficher",
LIVE: "Live",
PREVIEW: 'Aperçu',
COPY: "Copier",
COPY_AND_PASTE: "Copiez et collez ceci pour ajouter votre TellForm à votre site Web",
CHANGE_WIDTH_AND_HEIGHT: "Changez les valeurs de largeur et de hauteur pour mieux vous convenir",
POWERED_BY: "Alimenté par",
TELLFORM_URL: "Votre TellForm est en permanence sur cette URL",
// Modifier la vue de formulaire
DISABLED: "Désactivé",
OUI: 'OUI',
NO: 'NON',
ADD_LOGIC_JUMP: 'Ajouter un saut de logique',
ADD_FIELD_LG: "Cliquez pour ajouter un nouveau champ",
ADD_FIELD_MD: "Ajouter un nouveau champ",
ADD_FIELD_SM: "Ajouter un champ",
EDIT_START_PAGE: "Modifier la page de démarrage",
EDIT_END_PAGE: "Modifier la page de fin",
WELCOME_SCREEN: 'Page de démarrage',
END_SCREEN: 'Fin de page',
INTRO_TITLE: "Titre",
INTRO_PARAGRAPH: 'Paragraphe',
INTRO_BTN: 'Bouton de démarrage',
TITLE: "Titre",
PARAGRAPHE: 'Paragraphe',
BTN_TEXT: "Bouton Retour",
BOUTONS: 'Boutons',
BUTTON_TEXT: "Texte",
BUTTON_LINK: "Lien",
ADD_BUTTON: 'Ajouter un bouton',
PREVIEW_FIELD: 'Question d\'aperçu',
QUESTION_TITLE: "Titre",
QUESTION_DESCRIPTION: 'Description',
OPTIONS: 'Options',
ADD_OPTION: 'Ajouter une option',
NUM_OF_STEPS: "Nombre d'étapes",
CLICK_FIELDS_FOOTER: 'Cliquez sur les champs pour les ajouter ici',
SHAPE: 'Forme',
IF_THIS_FIELD: "Si ce champ",
IS_EQUAL_TO: 'est égal à',
IS_NOT_EQUAL_TO: 'n\'est pas égal à',
IS_GREATER_THAN: 'est supérieur à',
IS_GREATER_OR_EQUAL_THAN: 'est supérieur ou égal à',
IS_SMALLER_THAN: 'est plus petit que',
IS_SMALLER_OR_EQUAL_THAN: 'est plus petit ou égal à',
CONTAINS: 'contient',
DOES_NOT_CONTAINS: 'ne contient pas',
ENDS_WITH: "se termine par",
DOES_NOT_END_WITH: "ne finit pas avec",
STARTS_WITH: 'commence par',
DOES_NOT_START_WITH: "ne commence pas par",
THEN_JUMP_TO: 'alors saute à',
// Modifier la vue des soumissions
TOTAL_VIEWS: 'total des visites uniques',
RESPONSES: "réponses",
COMPLETION_RATE: "taux d'achèvement",
AVERAGE_TIME_TO_COMPLETE: 'moy. le temps d\'achèvement',
DESKTOP_AND_LAPTOP: 'Desktops',
TABLETS: 'Tablettes',
PHONES: 'Téléphones',
OTHER: 'Autre',
UNIQUE_VISITS: 'Visites uniques',
FIELD_TITLE: 'Titre du champ',
FIELD_VIEWS: 'Vues de champ',
FIELD_DROPOFF: "Achèvement du champ",
FIELD_RESPONSES: 'Réponses sur le terrain',
DELETE_SELECTED: 'Supprimer la sélection',
EXPORT_TO_EXCEL: 'Exporter vers Excel',
EXPORT_TO_CSV: 'Export vers CSV',
EXPORT_TO_JSON: "Exporter vers JSON",
PERCENTAGE_COMPLETE: 'Pourcentage terminé',
TIME_ELAPSED: 'Temps écoulé',
DEVICE: "Dispositif",
LOCATION: "Emplacement",
IP_ADDRESS: 'Adresse IP',
DATE_SUBMITTED: 'Date de soumission',
// Vue de conception
BACKGROUND_COLOR: "Couleur d'arrière-plan",
DESIGN_HEADER: "Changez l'apparence de votre formulaire",
QUESTION_TEXT_COLOR: "Couleur du texte de la question",
ANSWER_TEXT_COLOR: "Couleur du texte de la réponse",
BTN_BACKGROUND_COLOR: "Couleur d'arrière-plan du bouton",
BTN_TEXT_COLOR: "Couleur du texte du bouton",
// Vue de partage
EMBED_YOUR_FORM: "Intégrez votre formulaire",
SHARE_YOUR_FORM: "Partager votre formulaire",
// Onglets d'administration
CREATE_TAB: "Créer",
DESIGN_TAB: 'Design',
CONFIGURE_TAB: 'Configurer',
ANALYZE_TAB: "Analyser",
SHARE_TAB: "Partager",
// Types de champs
SHORT_TEXT: "Texte court",
EMAIL: "E-mail",
MULTIPLE_CHOICE: 'Choix multiple',
DROPDOWN: 'Menu Déroulant',
DATE: 'Date',
PARAGRAPH_T: "Paragraphe",
OUI_NON: 'Oui / Non',
LEGAL: 'Légal',
RATING: "Évaluation",
NUMBERS: "Chiffres",
SIGNATURE: 'Signature',
FILE_UPLOAD: 'Téléchargement de fichier',
OPTION_SCALE: 'Option Scale',
PAYMENT: 'Paiement',
STATEMENT: 'Déclaration',
LINK: "Lien",
// Aperçu du formulaire
FORM_SUCCESS: 'Entrée de formulaire soumise avec succès!',
REVIEW: 'Réviser',
BACK_TO_FORM: "Revenir au formulaire",
EDIT_FORM: "Modifier ce TellForm",
ADVANCEMENT: '{{done}} sur {{total}} a répondu',
CONTINUE_FORM: "Continuer à se former",
REQUIRED: 'requis',
COMPLETING_NEEDED: '{{answers_not_completed}} réponse (s) doivent être complétées',
OPTIONAL: 'optionnel',
ERROR_EMAIL_INVALID: "Veuillez entrer une adresse email valide",
ERROR_NOT_A_NUMBER: "Veuillez entrer uniquement des numéros valides",
ERROR_URL_INVALID: "S'il vous plaît une adresse valide",
OK: 'OK',
ENTER: 'appuyez sur ENTRER',
NEWLINE: 'appuyez sur MAJ + ENTRÉE pour créer une nouvelle ligne',
CONTINUE: "Continuer",
LEGAL_ACCEPT: 'J\'accepte',
LEGAL_NO_ACCEPT: "Je n'accepte pas",
SUBMIT: "Soumettre",
UPLOAD_FILE: "Télécharger votre fichier"
});
}]);
'use strict';
angular.module('forms').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('de', {
// Konfigurieren der Formularregisterkarte
ADVANCED_SETTINGS: 'Erweiterte Einstellungen',
FORM_NAME: 'Formularname',
FORM_STATUS: 'Formularstatus',
PUBLIC: 'Öffentlich',
PRIVATE: 'Privat',
GA_TRACKING_CODE: 'Google Analytics Tracking-Code',
DISPLAY_FOOTER: 'Formularfußzeile anzeigen?',
SAVE_CHANGES: 'Änderungen speichern',
CANCEL: 'Abbrechen',
DISPLAY_START_PAGE: 'Startseite anzeigen?',
DISPLAY_END_PAGE: 'Benutzerdefinierte Endseite anzeigen?',
// Listenformularansicht
CREATE_A_NEW_FORM: 'Erstelle ein neues Formular',
CREATE_FORM: 'Formular erstellen',
CREATED_ON: 'Erstellt am',
MY_FORMS: 'Meine Formulare',
NAME: 'Name',
SPRACHE: 'Sprache',
FORM_PAUSED: 'Formular pausiert',
// Feld Modal bearbeiten
EDIT_FIELD: 'Dieses Feld bearbeiten',
SAVE_FIELD: 'Speichern',
ON: 'ON',
AUS: 'AUS',
REQUIRED_FIELD: 'Erforderlich',
LOGIC_JUMP: 'Logischer Sprung',
SHOW_BUTTONS: 'Zusätzliche Schaltflächen',
SAVE_START_PAGE: 'Speichern',
// Admin-Formularansicht
ARE_YOU_SURE: "Bist du ABSOLUT sicher?",
READ_WARNING: 'Unerwartete schlimme Dinge werden passieren, wenn Sie das nicht lesen!',
DELETE_WARNING1: 'Diese Aktion kann NICHT rückgängig gemacht werden. Dies wird dauerhaft die "',
DELETE_WARNING2: '"Formular und entferne alle verknüpften Formulareinreichungen.',
DELETE_CONFIRM: 'Bitte geben Sie den Namen des zu bestätigenden Formulars ein.',
I_UNDERSTAND: "Ich verstehe die Konsequenzen, lösche dieses Formular.",
DELETE_FORM_SM: 'Löschen',
DELETE_FORM_MD: 'Formular löschen',
DELETE: 'Löschen',
FORM: 'Formular',
VIEW: 'Ansicht',
LIVE: 'Leben',
PREVIEW: 'Vorschau',
COPY: 'Kopieren',
COPY_AND_PASTE: 'Kopieren und einfügen, um Ihre TellForm auf Ihrer Website hinzuzufügen',
CHANGE_WIDTH_AND_HEIGHT: 'Ändern Sie die Werte für Breite und Höhe, um Ihnen am besten zu entsprechen',
POWERED_BY: 'Unterstützt von',
TELLFORM_URL: "Ihr TellForm ist dauerhaft unter dieser URL",
// Formularansicht bearbeiten
DISABLED: 'Deaktiviert',
JA: 'JA',
NO: 'NEIN',
ADD_LOGIC_JUMP: 'Logic Jump hinzufügen',
ADD_FIELD_LG: 'Klicken Sie auf Neues Feld hinzufügen',
ADD_FIELD_MD: 'Neues Feld hinzufügen',
ADD_FIELD_SM: 'Feld hinzufügen',
EDIT_START_PAGE: 'Startseite bearbeiten',
EDIT_END_PAGE: 'Endseite bearbeiten',
WELCOME_SCREEN: 'Startseite',
END_SCREEN: 'Ende Seite',
INTRO_TITLE: 'Titel',
INTRO_PARAGRAPH: "Absatz",
INTRO_BTN: 'Start Knopf',
TITLE: "Titel",
PARAGRAPH: "Absatz",
BTN_TEXT: 'Zurück Button',
TASTEN: 'Knöpfe',
BUTTON_TEXT: 'Text',
BUTTON_LINK: 'Link',
ADD_BUTTON: 'Schaltfläche hinzufügen',
PREVIEW_FIELD: 'Vorschaufrage',
QUESTION_TITLE: 'Titel',
QUESTION_DESCRIPTION: 'Beschreibung',
OPTIONS: 'Optionen',
ADD_OPTION: 'Option hinzufügen',
NUM_OF_STEPS: 'Anzahl der Schritte',
CLICK_FIELDS_FOOTER: 'Klicken Sie auf Felder, um sie hier hinzuzufügen',
FORM: 'Formular',
IF_THIS_FIELD: 'Wenn dieses Feld',
IS_EQUAL_TO: 'ist gleich',
IS_NOT_EQUAL_TO: 'ist nicht gleich',
IS_GREATER_THAN: 'ist größer als',
IS_GREATER_OR_EQUAL_THAN: 'ist größer oder gleich',
IS_SMALLER_THAN: 'ist kleiner als',
IS_SMALLER_OR_EQUAL_THAN: 'ist kleiner oder gleich',
CONTAINS: 'enthält',
DOES_NOT_CONTAINS: 'enthält nicht',
ENDS_WITH: 'endet mit',
DOES_NOT_END_WITH: 'endet nicht mit',
STARTS_WITH: 'beginnt mit',
DOES_NOT_START_WITH: 'beginnt nicht mit',
THEN_JUMP_TO: 'Springe dann zu',
// Bearbeiten der Einreichungsansicht
TOTAL_VIEWS: 'Gesamtzahl eindeutiger Besuche',
RESPONSES: 'Antworten',
COMPLETION_RATE: 'Abschlussrate',
AVERAGE_TIME_TO_COMPLETE: 'avg. Fertigstellungszeit',
DESKTOP_AND_LAPTOP: 'Desktops',
TABLETS: "Tabletten",
PHONES: 'Telefone',
OTHER: 'Andere',
UNIQUE_VISITS: 'Eindeutige Besuche',
FIELD_TITLE: 'Feldtitel',
FIELD_VIEWS: 'Feld Ansichten',
FIELD_DROPOFF: 'Feldabschluss',
FIELD_RESPONSES: 'Feldantworten',
DELETE_SELECTED: 'Ausgewählte löschen',
EXPORT_TO_EXCEL: 'Export nach Excel',
EXPORT_TO_CSV: 'In CSV exportieren',
EXPORT_TO_JSON: 'Export nach JSON',
PERCENTAGE_COMPLETE: 'Prozent abgeschlossen',
TIME_ELAPSED: 'Zeit verstrichen',
DEVICE: 'Gerät',
LOCATION: 'Ort',
IP_ADDRESS: 'IP-Adresse',
DATE_SUBMITTED: 'Eingereichtes Datum',
// Entwurfsansicht
BACKGROUND_COLOR: 'Hintergrundfarbe',
DESIGN_HEADER: 'Ändern Sie, wie Ihr Formular aussieht',
QUESTION_TEXT_COLOR: 'Fragetextfarbe',
ANSWER_TEXT_COLOR: 'Textfarbe beantworten',
BTN_BACKGROUND_COLOR: 'Schaltfläche Hintergrundfarbe',
BTN_TEXT_COLOR: 'Schaltfläche Textfarbe',
// Freigabeansicht
EMBED_YOUR_FORM: 'Einbetten Ihres Formulars',
SHARE_YOUR_FORM: 'Teilen Sie Ihr Formular',
// Admin-Registerkarten
CREATE_TAB: 'Erstellen',
DESIGN_TAB: 'Entwurf',
CONFIGURE_TAB: 'Konfigurieren',
ANALYZE_TAB: 'Analysieren',
SHARE_TAB: 'Freigeben',
// Feldtypen
SHORT_TEXT: 'Kurztext',
EMAIL: 'Email',
MULTIPLE_CHOICE: 'Mehrfachauswahl',
DROPDOWN: 'Dropdown-Liste',
DATE: 'Datum',
PARAGRAPH_T: "Absatz",
YES_NO: 'Ja / Nein',
LEGAL: "Rechtliche",
RATING: 'Bewertung',
NUMBERS: 'Zahlen',
SIGNATURE: "Unterschrift",
FILE_UPLOAD: 'Datei-Upload',
OPTION_SCALE: 'Optionsskala',
ZAHLUNG: "Zahlung",
STATEMENT: 'Anweisung',
LINK: 'Link',
// Formularvorschau
FORM_SUCCESS: 'Formulareintrag erfolgreich gesendet!',
REVIEW: 'Überprüfung',
BACK_TO_FORM: 'Gehe zurück zu Formular',
EDIT_FORM: 'Bearbeiten Sie diese TellForm',
ADVANCEMENT: '{{done}} von {{total}} wurde beantwortet',
CONTINUE_FORM: 'Weiter zum Formular',
REQUIRED: 'erforderlich',
COMPLETING_NEEDED: '{{answers_not_completed}} Antwort (en) müssen ausgefüllt werden',
OPTIONAL: 'optional',
ERROR_EMAIL_INVALID: 'Geben Sie eine gültige E-Mail-Adresse ein',
ERROR_NOT_A_NUMBER: 'Bitte nur gültige Nummern eingeben',
ERROR_URL_INVALID: 'Bitte eine gültige URL',
OK: 'OK',
ENTER: 'ENTER drücken',
NEWLINE: 'Drücken Sie UMSCHALT + EINGABETASTE, um eine neue Zeile zu erstellen',
CONTINUE: 'Weiter',
LEGAL_ACCEPT: "Ich akzeptiere",
LEGAL_NO_ACCEPT: "Ich akzeptiere nicht",
SUBMIT: 'Senden',
UPLOAD_FILE: 'Hochladen Ihrer Datei'
});
}]);
'use strict';
angular.module('forms').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('it', {
// Configura la visualizzazione scheda modulo
ADVANCED_SETTINGS: 'Impostazioni avanzate',
FORM_NAME: 'Nome modulo',
FORM_STATUS: 'Stato modulo',
PUBLIC: 'pubblico',
PRIVATE: 'Privato',
GA_TRACKING_CODE: 'Codice di monitoraggio di Google Analytics',
DISPLAY_FOOTER: 'Visualizza piè di pagina?',
SAVE_CHANGES: 'Salva modifiche',
CANCEL: 'Annulla',
DISPLAY_START_PAGE: 'Visualizza pagina iniziale?',
DISPLAY_END_PAGE: 'Mostra pagina finale personalizzata?',
// Visualizzazione dei moduli di elenco
CREATE_A_NEW_FORM: 'Crea un nuovo modulo',
CREATE_FORM: 'Crea modulo',
CREATED_ON: 'Creato su',
MY_FORMS: 'Le mie forme',
NAME: 'Nome',
LINGUA: 'Lingua',
FORM_PAUSED: 'Forme in pausa',
// Modifica campo modale
EDIT_FIELD: 'Modifica questo campo',
SAVE_FIELD: 'Salva',
ON: 'ON',
OFF: 'OFF',
REQUIRED_FIELD: 'Obbligatorio',
LOGIC_JUMP: 'Jump Logic',
SHOW_BUTTONS: 'Pulsanti aggiuntivi',
SAVE_START_PAGE: 'Salva',
// Visualizzazione modulo di amministrazione
ARE_YOU_SURE: 'Sei ASSOLUTAMENTE sicuro?',
READ_WARNING: 'Le cose cattive impreviste avverranno se non lo leggi!',
DELETE_WARNING1: 'Questa azione NON può essere annullata. Ciò eliminerà in modo permanente il "',
DELETE_WARNING2: '" forma e rimuovi tutti i moduli di modulo associati. ',
DELETE_CONFIRM: 'Inserisci il nome del modulo per confermare',
I_UNDERSTAND: "Capisco le conseguenze, elimina questa forma",
DELETE_FORM_SM: 'Elimina',
DELETE_FORM_MD: 'Elimina modulo',
DELETE: 'Elimina',
FORM: 'Forma',
VIEW: 'Visualizza',
LIVE: 'Live',
PREVIEW: 'Anteprima',
COPY: 'Copia',
COPY_AND_PASTE: 'Copia e incolla questo per aggiungere il tuo TellForm al tuo sito web',
CHANGE_WIDTH_AND_HEIGHT: 'Modifica i valori di larghezza e di altezza per adattarti al meglio',
POWERED_BY: 'Offerto da',
TELLFORM_URL: 'Il tuo TellForm è permanente in questo URL',
// Modifica vista modulo
DISABLED: 'disabilitato',
YES: 'SI',
NO: 'NO',
ADD_LOGIC_JUMP: 'Aggiungi logico salto',
ADD_FIELD_LG: 'Clicca per aggiungere nuovo campo',
ADD_FIELD_MD: 'Aggiungi nuovo campo',
ADD_FIELD_SM: 'Aggiungi campo',
EDIT_START_PAGE: 'Modifica pagina iniziale',
EDIT_END_PAGE: 'Modifica pagina finale',
WELCOME_SCREEN: 'Pagina iniziale',
END_SCREEN: 'Fine pagina',
INTRO_TITLE: 'Titolo',
INTRO_PARAGRAPH: 'Paragrafo',
INTRO_BTN: 'Pulsante Start',
TITLE: 'Titolo',
PARAGRAFO: 'Paragrafo',
BTN_TEXT: 'Tornare indietro',
TASTI: 'Pulsanti',
BUTTON_TEXT: 'Testo',
BUTTON_LINK: 'Link',
ADD_BUTTON: 'Aggiungi pulsante',
PREVIEW_FIELD: 'Anteprima domanda',
QUESTION_TITLE: 'Titolo',
QUESTION_DESCRIPTION: 'Descrizione',
OPTIONS: 'Opzioni',
ADD_OPTION: 'Aggiungi opzione',
NUM_OF_STEPS: 'Numero di passi',
CLICK_FIELDS_FOOTER: 'Clicca sui campi per aggiungerli qui',
FORMA: 'Forma',
IF_THIS_FIELD: 'Se questo campo',
IS_EQUAL_TO: 'è uguale a',
IS_NOT_EQUAL_TO: 'non è uguale a',
IS_GREATER_THAN: 'è maggiore di',
IS_GREATER_OR_EQUAL_THAN: 'è maggiore o uguale a',
IS_SMALLER_THAN: 'è inferiore a',
IS_SMALLER_OR_EQUAL_THAN: 'è più piccolo o uguale a quello',
CONTAINS: 'contiene',
DOES_NOT_CONTAINS: 'non contiene',
ENDS_WITH: 'finisce con',
DOES_NOT_END_WITH: 'non finisce con',
STARTS_WITH: 'inizia con',
DOES_NOT_START_WITH: 'non inizia con',
THEN_JUMP_TO: 'poi salta a',
// Modifica visualizzazione presentazioni
TOTAL_VIEWS: 'visite totali totali',
RESPONSES: 'risposte',
COMPLETION_RATE: 'tasso di completamento',
AVERAGE_TIME_TO_COMPLETE: 'avg. tempo di completamento',
DESKTOP_AND_LAPTOP: 'Desktop',
TABLETS: 'compresse',
PHONES: 'Telefoni',
OTHER: 'Altro',
UNIQUE_VISITS: 'Visite Uniche',
FIELD_TITLE: 'Titolo del campo',
FIELD_VIEWS: 'Viste sul campo',
FIELD_DROPOFF: 'Completamento del campo',
FIELD_RESPONSES: 'Risposte sul campo',
DELETE_SELECTED: 'Elimina selezionata',
EXPORT_TO_EXCEL: 'Esporta in Excel',
EXPORT_TO_CSV: 'Esporta in CSV',
EXPORT_TO_JSON: 'Esporta in JSON',
PERCENTAGE_COMPLETE: 'Percentuale completa',
TIME_ELAPSED: 'Tempo trascorso',
DEVICE: 'Dispositivo',
LOCATION: 'Posizione',
IP_ADDRESS: 'Indirizzo IP',
DATE_SUBMITTED: 'Data trasmessa',
// Vista di progettazione
BACKGROUND_COLOR: 'Colore di sfondo',
DESIGN_HEADER: 'Modifica il tuo aspetto forma',
QUESTION_TEXT_COLOR: 'Colore del testo di domanda',
ANSWER_TEXT_COLOR: 'Rispondere al colore del testo',
BTN_BACKGROUND_COLOR: 'Colore di sfondo del pulsante',
BTN_TEXT_COLOR: 'Colore del testo pulsante',
// Vista condivisione
EMBED_YOUR_FORM: 'Inserisci il tuo modulo',
SHARE_YOUR_FORM: 'Condividi il tuo modulo',
// Schede amministratore
CREATE_TAB: 'Crea',
DESIGN_TAB: 'Design',
CONFIGURE_TAB: 'Configura',
ANALYZE_TAB: 'Analizza',
SHARE_TAB: 'Condividi',
// Tipi di campo
SHORT_TEXT: 'Testo corto',
EMAIL: 'E-mail',
MULTIPLE_CHOICE: 'Scelta multipla',
DROPDOWN: 'Dropdown',
DATE: 'Data',
PARAGRAPH_T: 'Paragrafo',
YES_NO: 'Sì / no',
LEGAL: 'Legale',
RATING: 'Valutazione',
NUMBERS: 'Numeri',
SIGNATURE: 'Firma',
FILE_UPLOAD: 'Caricamento file',
OPTION_SCALE: 'Scala opzione',
PAGAMENTO: 'Pagamento',
STATEMENT: 'Dichiarazione',
LINK: 'Link',
// Anteprima del modulo
FORM_SUCCESS: 'Inserimento modulo con successo presentato!',
REVIEW: 'Recensione',
BACK_TO_FORM: 'Torna alla scheda',
EDIT_FORM: 'Modifica questo TellForm',
ADVANCEMENT: '{{done}} su {{total}} ha risposto',
CONTINUE_FORM: "Continua a formare",
REQUIRED: 'richiesta',
COMPLETING_NEEDED: '{{answers_not_completed}} answer (s) need completing',
OPTIONAL: 'facoltativo',
ERROR_EMAIL_INVALID: 'Inserisci un indirizzo e-mail valido',
ERROR_NOT_A_NUMBER: 'Inserisci solo numeri validi',
ERROR_URL_INVALID: 'Per favore un url valido',
OK: 'OK',
ENTER: 'premere INVIO',
NEWLINE: 'premere SHIFT + INVIO per creare una nuova riga',
CONTINUE: 'Continua',
LEGAL_ACCEPT: 'accetto',
LEGAL_NO_ACCEPT: 'Non accetto',
SUBMIT: 'Invia',
UPLOAD_FILE: 'Carica il tuo file'
});
}]);
'use strict';
angular.module('forms').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('es', {
//Configure Form Tab View
ADVANCED_SETTINGS: 'Configuraciones avanzadas',
FORM_NAME: 'Nombre del formulario',
FORM_STATUS: 'Estado del formulario',
PUBLIC: 'Público',
PRIVATE: 'Privado',
GA_TRACKING_CODE: 'Código de Google Analytics',
DISPLAY_FOOTER: '¿Mostrar pie de página?',
SAVE_CHANGES: 'Grabar',
CANCEL: 'Cancelar',
DISPLAY_START_PAGE: '¿Mostrar página de inicio?',
DISPLAY_END_PAGE: '¿Mostrar paǵina de fin?',
//List Forms View
CREATE_A_NEW_FORM: 'Crear formulario',
CREATE_FORM: 'Crear formulario',
CREATED_ON: 'Creado en',
MY_FORMS: 'Mis formularios',
NAME: 'Nombre',
LANGUAGE: 'Idioma',
FORM_PAUSED: 'Formulario pausado',
//Edit Field Modal
EDIT_FIELD: 'Editar este campo',
SAVE_FIELD: 'Grabar',
ON: 'EN',
OFF: 'APAGADO',
REQUIRED_FIELD: 'Requerido',
LOGIC_JUMP: 'Salto lógico',
SHOW_BUTTONS: 'Botones adicionales',
SAVE_START_PAGE: 'Grabar',
//Admin Form View
ARE_YOU_SURE: '¿Estás absolutamente seguro?',
READ_WARNING: '¡Algo malo ocurrirá si no lees esto!',
DELETE_WARNING1: 'Esta acción no tiene vuelta atrás. Esto borrará permanentemente el "',
DELETE_WARNING2: '" formulario y todos los datos asociados.',
DELETE_CONFIRM: 'Por favor escribí el nombre del formulario para confirmar.',
I_UNDERSTAND: 'Entiendo las consecuencias y quiero borrarlo.',
DELETE_FORM_SM: 'Borrar',
DELETE_FORM_MD: 'Borrar formulario',
DELETE: 'Borrar',
FORM: 'Formulario',
VIEW: 'Vista',
LIVE: 'Online',
PREVIEW: 'Vista previa',
COPY: 'Copiar',
COPY_AND_PASTE: 'Copiar y pegar esto para agregar su TellForm a su sitio web',
CHANGE_WIDTH_AND_HEIGHT: 'Cambie los valores de ancho y altura para adaptar el formulario a sus necesidades',
POWERED_BY: 'Con la tecnlogía de',
TELLFORM_URL: 'Tu TellForm está en esta URL permanente',
//Edit Form View
DISABLED: 'Deshabilitado',
YES: 'SI',
NO: 'NO',
ADD_LOGIC_JUMP: 'Agregar salto lógico',
ADD_FIELD_LG: 'Click para agregar campo',
ADD_FIELD_MD: 'Agregar nuevo campo',
ADD_FIELD_SM: 'Agregar campo',
EDIT_START_PAGE: 'Editar paǵina de inicio',
EDIT_END_PAGE: 'Editar página de finalización',
WELCOME_SCREEN: 'Comienzo',
END_SCREEN: 'Fin',
INTRO_TITLE: 'Título',
INTRO_PARAGRAPH: 'Parágrafo',
INTRO_BTN: 'Botón de comienzo',
TITLE: 'Título',
PARAGRAPH: 'Paragrafo',
BTN_TEXT: 'Botón para volver atrás',
BUTTONS: 'Botones',
BUTTON_TEXT: 'Texto',
BUTTON_LINK: 'Link',
ADD_BUTTON: 'Agregar Botón',
PREVIEW_FIELD: 'Vista previa Pregunta',
QUESTION_TITLE: 'Título',
QUESTION_DESCRIPTION: 'Descripción',
OPTIONS: 'Opciones',
ADD_OPTION: 'Agregar Opciones',
NUM_OF_STEPS: 'Cantidad de pasos',
CLICK_FIELDS_FOOTER: 'Click en los campos para agregar',
SHAPE: 'Forma',
IF_THIS_FIELD: 'Si este campo',
IS_EQUAL_TO: 'es igual a',
IS_NOT_EQUAL_TO: 'no es igual a',
IS_GREATER_THAN: 'es mayor que',
IS_GREATER_OR_EQUAL_THAN: 'es mayor o igual que',
IS_SMALLER_THAN: 'es menor que',
IS_SMALLER_OR_EQUAL_THAN: 'is menor o igual que',
CONTAINS: 'contiene',
DOES_NOT_CONTAINS: 'no contiene',
ENDS_WITH: 'termina con',
DOES_NOT_END_WITH: 'no termina con',
STARTS_WITH: 'comienza con',
DOES_NOT_START_WITH: 'no comienza con',
THEN_JUMP_TO: 'luego salta a',
//Edit Submissions View
TOTAL_VIEWS: 'Total de visitas únicas',
RESPONSES: 'respuestas',
COMPLETION_RATE: 'Taza de terminación',
AVERAGE_TIME_TO_COMPLETE: 'Promedio de tiempo de rellenado',
DESKTOP_AND_LAPTOP: 'Computadora',
TABLETS: 'Tablets',
PHONES: 'Móviles',
OTHER: 'Otros',
UNIQUE_VISITS: 'Visitas únicas',
FIELD_TITLE: 'Título de campo',
FIELD_VIEWS: 'Vistas de campo',
FIELD_DROPOFF: 'Finalización de campo',
FIELD_RESPONSES: 'Respuestas de campo',
DELETE_SELECTED: 'Borrar selección',
EXPORT_TO_EXCEL: 'Exportar a Excel',
EXPORT_TO_CSV: 'Exportar a CSV',
EXPORT_TO_JSON: 'Exportar a JSON',
PERCENTAGE_COMPLETE: 'Porcentaje de completitud',
TIME_ELAPSED: 'Tiempo usado',
DEVICE: 'Dispositivo',
LOCATION: 'Lugar',
IP_ADDRESS: 'Dirección IP',
DATE_SUBMITTED: 'Fecha de envío',
//Design View
BACKGROUND_COLOR: 'Color de fondo',
DESIGN_HEADER: 'Cambiar diseño de formulario',
QUESTION_TEXT_COLOR: 'Color de la pregunta',
ANSWER_TEXT_COLOR: 'Color de la respuesta',
BTN_BACKGROUND_COLOR: 'Color de fondo del botón',
BTN_TEXT_COLOR: 'Color del texto del botón',
//Share View
EMBED_YOUR_FORM: 'Pone tu formulario',
SHARE_YOUR_FORM: 'Compartí tu formulario',
//Admin Tabs
CREATE_TAB: 'Crear',
DESIGN_TAB: 'Diseño',
CONFIGURE_TAB: 'Configuración',
ANALYZE_TAB: 'Análisis',
SHARE_TAB: 'Compartir',
//Field Types
SHORT_TEXT: 'Texto corto',
EMAIL: 'Email',
MULTIPLE_CHOICE: 'Opciones múltiples',
DROPDOWN: 'Desplegable',
DATE: 'Fecha',
PARAGRAPH_T: 'Párrafo',
YES_NO: 'Si/No',
LEGAL: 'Legal',
RATING: 'Puntaje',
NUMBERS: 'Números',
SIGNATURE: 'Firma',
FILE_UPLOAD: 'Subir archivo',
OPTION_SCALE: 'Escala',
PAYMENT: 'Pago',
STATEMENT: 'Declaración',
LINK: 'Enlace',
FORM_SUCCESS: '¡El formulario ha sido enviado con éxito!',
REVIEW: 'Revisar',
BACK_TO_FORM: 'Regresar al formulario',
ADVANCEMENT: '{{done}} de {{total}} contestadas',
CONTINUE_FORM: 'Continuar al formulario',
REQUIRED: 'Información requerida',
COMPLETING_NEEDED: '{{answers_not_completed}} respuesta(s) necesita(n) ser completada(s)',
OPTIONAL: 'Opcional',
ERROR_EMAIL_INVALID: 'Favor de proporcionar un correo electrónico válido',
ERROR_NOT_A_NUMBER: 'Por favor, introduzca sólo números válidos',
ERROR_URL_INVALID: 'Favor de proporcionar un url válido',
OK: 'OK',
ENTER: 'pulse INTRO',
NEWLINE: 'presione SHIFT+INTRO para crear una nueva línea',
CONTINUE: 'Continuar',
LEGAL_ACCEPT: 'Yo acepto',
LEGAL_NO_ACCEPT: 'Yo no acepto',
SUBMIT: 'Registrar',
UPLOAD_FILE: 'Cargar el archivo',
Y: 'S',
N: 'N'
});
}]);
'use strict';
// Use Application configuration module to register a new module
ApplicationConfiguration.registerModule('view-form', [
'ngFileUpload', 'ui.date', 'angular-input-stars'
]);
(function () {
'use strict';
// Create the SendVisitorData service
angular
.module('view-form')
.factory('SendVisitorData', SendVisitorData);
SendVisitorData.$inject = ['Socket', '$state'];
function SendVisitorData(Socket, $state) {
// Create a controller method for sending visitor data
function send(form, lastActiveIndex, timeElapsed) {
var lang = window.navigator.userLanguage || window.navigator.language;
lang = lang.slice(0,2);
var userAgentString = navigator.userAgent;
var md = new MobileDetect(userAgentString);
var deviceType = 'other';
if (md.tablet()){
deviceType = 'tablet';
} else if (md.mobile()) {
deviceType = 'mobile';
} else if (!md.is('bot')) {
deviceType = 'desktop';
}
// Create a new message object
var visitorData = {
referrer: document.referrer,
isSubmitted: form.submitted,
formId: form._id,
lastActiveField: form.form_fields[lastActiveIndex]._id,
timeElapsed: timeElapsed,
language: lang,
deviceType: deviceType,
ipAddr: null,
geoLocation: null
};
Socket.emit('form-visitor-data', visitorData);
}
function init(){
// Make sure the Socket is connected
if (!Socket.socket) {
Socket.connect();
}
Socket.on('disconnect', function(){
Socket.connect();
});
}
var service = {
send: send
};
init();
return service;
}
}());
'use strict';
angular.module('view-form').directive('keyToOption', function(){
return {
restrict: 'A',
scope: {
field: '='
},
link: function($scope, $element, $attrs, $select) {
$element.bind('keydown keypress', function(event) {
var keyCode = event.which || event.keyCode;
var index = parseInt(String.fromCharCode(keyCode))-1;
if (index < $scope.field.fieldOptions.length) {
event.preventDefault();
$scope.$apply(function () {
$scope.field.fieldValue = $scope.field.fieldOptions[index].option_value;
});
}
});
}
};
});
'use strict';
angular.module('view-form').directive('keyToTruthy', ['$rootScope', function($rootScope){
return {
restrict: 'A',
scope: {
field: '=',
nextField: '&'
},
link: function($scope, $element, $attrs) {
$element.bind('keydown keypress', function(event) {
var keyCode = event.which || event.keyCode;
var truthyKeyCode = $attrs.keyCharTruthy.charCodeAt(0) - 32;
var falseyKeyCode = $attrs.keyCharFalsey.charCodeAt(0) - 32;
if(keyCode === truthyKeyCode ) {
event.preventDefault();
$scope.$apply(function() {
$scope.field.fieldValue = 'true';
if($attrs.onValidKey){
$scope.$root.$eval($attrs.onValidKey);
}
});
}else if(keyCode === falseyKeyCode){
event.preventDefault();
$scope.$apply(function() {
$scope.field.fieldValue = 'false';
if($attrs.onValidKey){
$scope.$root.$eval($attrs.onValidKey);
}
});
}
});
}
};
}]);
'use strict';
// Configuring the Forms drop-down menus
angular.module('view-form')
.filter('formValidity', function(){
return function(formObj){
if(formObj && formObj.form_fields && formObj.visible_form_fields){
//get keys
var formKeys = Object.keys(formObj);
//we only care about things that don't start with $
var fieldKeys = formKeys.filter(function(key){
return key[0] !== '$';
});
var fields = formObj.form_fields;
var valid_count = fields.filter(function(field){
if(typeof field === 'object' && field.fieldType !== 'rating' && field.fieldType !== 'statement'){
return !!(field.fieldValue);
} else if (field.fieldType === 'rating'){
return true;
}
}).length;
return valid_count - (formObj.form_fields.length - formObj.visible_form_fields.length);
}
return 0;
};
});
angular.module('view-form').value('supportedFields', [
'textfield',
'textarea',
'date',
'dropdown',
'hidden',
'password',
'radio',
'legal',
'statement',
'rating',
'yes_no',
'number',
'natural'
]);
angular.module('view-form').constant('VIEW_FORM_URL', '/forms/:formId/render');
'use strict';
angular.module('view-form').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('en', {
FORM_SUCCESS: 'Form entry successfully submitted!',
REVIEW: 'Review',
BACK_TO_FORM: 'Go back to Form',
EDIT_FORM: 'Edit this TellForm',
CREATE_FORM: 'Create this TellForm',
ADVANCEMENT: '{{done}} out of {{total}} answered',
CONTINUE_FORM: 'Continue to Form',
REQUIRED: 'required',
COMPLETING_NEEDED: '{{answers_not_completed}} answer(s) need completing',
OPTIONAL: 'optional',
ERROR_EMAIL_INVALID: 'Please enter a valid email address',
ERROR_NOT_A_NUMBER: 'Please enter valid numbers only',
ERROR_URL_INVALID: 'Please a valid url',
OK: 'OK',
ENTER: 'press ENTER',
YES: 'Yes',
NO: 'No',
NEWLINE: 'press SHIFT+ENTER to create a newline',
CONTINUE: 'Continue',
LEGAL_ACCEPT: 'I accept',
LEGAL_NO_ACCEPT: 'I don’t accept',
DELETE: 'Delete',
CANCEL: 'Cancel',
SUBMIT: 'Submit',
UPLOAD_FILE: 'Upload your File',
Y: 'Y',
N: 'N',
OPTION_PLACEHOLDER: 'Type or select an option',
ADD_NEW_LINE_INSTR: 'Press SHIFT+ENTER to add a newline',
ERROR: 'Error',
FORM_404_HEADER: '404 - Form Does Not Exist',
FORM_404_BODY: 'The form you are trying to access does not exist. Sorry about that!',
FORM_UNAUTHORIZED_HEADER: 'Not Authorized to Access Form',
FORM_UNAUTHORIZED_BODY1: 'The form you are trying to access is currently private and not accesible publically.',
FORM_UNAUTHORIZED_BODY2: 'If you are the owner of the form, you can set it to "Public" in the "Configuration" panel in the form admin.',
});
$translateProvider.preferredLanguage('en')
.fallbackLanguage('en')
.useSanitizeValueStrategy('escape');
}]);
'use strict';
angular.module('view-form').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('fr', {
FORM_SUCCESS: 'Votre formulaire a été enregistré!',
REVIEW: 'Incomplet',
BACK_TO_FORM: 'Retourner au formulaire',
EDIT_FORM: 'Éditer le Tellform',
CREATE_FORM: 'Créer un TellForm',
ADVANCEMENT: '{{done}} complétés sur {{total}}',
CONTINUE_FORM: 'Aller au formulaire',
REQUIRED: 'obligatoire',
COMPLETING_NEEDED: '{{answers_not_completed}} réponse(s) doive(nt) être complétée(s)',
OPTIONAL: 'facultatif',
ERROR_EMAIL_INVALID: 'Merci de rentrer une adresse mail valide',
ERROR_NOT_A_NUMBER: 'Merce de ne rentrer que des nombres',
ERROR_URL_INVALID: 'Merci de rentrer une url valide',
OK: 'OK',
ENTER: 'presser ENTRÉE',
YES: 'Oui',
NO: 'Non',
NEWLINE: 'presser SHIFT+ENTER pour créer une nouvelle ligne',
CONTINUE: 'Continuer',
LEGAL_ACCEPT: 'J’accepte',
LEGAL_NO_ACCEPT: 'Je n’accepte pas',
DELETE: 'Supprimer',
CANCEL: 'Réinitialiser',
SUBMIT: 'Enregistrer',
UPLOAD_FILE: 'Envoyer un fichier',
Y: 'O',
N: 'N',
OPTION_PLACEHOLDER: 'Tapez ou sélectionnez une option',
ADD_NEW_LINE_INSTR: 'Appuyez sur MAJ + ENTRÉE pour ajouter une nouvelle ligne',
ERROR: 'Erreur',
FORM_404_HEADER: '404 - Le formulaire n\'existe pas',
FORM_404_BODY: 'Le formulaire auquel vous essayez d\'accéder n\'existe pas. Désolé pour ça!',
FORM_UNAUTHORIZED_HEADER: 'Non autorisé à accéder au formulaire',
FORM_UNAUTHORIZED_BODY1: 'Le formulaire auquel vous essayez d\'accéder est actuellement privé et inaccessible publiquement.',
FORM_UNAUTHORIZED_BODY2: 'Si vous êtes le propriétaire du formulaire, vous pouvez le définir sur "Public" dans le panneau "Configuration" du formulaire admin.',
});
}]);
'use strict';
angular.module('view-form').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('de', {
FORM_SUCCESS: 'Ihre Angaben wurden gespeichert.',
REVIEW: 'Unvollständig',
BACK_TO_FORM: 'Zurück zum Formular',
EDIT_FORM: 'Bearbeiten Sie diese TellForm',
CREATE_FORM: 'Dieses TellForm erstellen',
ADVANCEMENT: '{{done}} von {{total}} beantwortet',
CONTINUE_FORM: 'Zum Formular',
REQUIRED: 'verpflichtend',
COMPLETING_NEEDED: 'Es fehlen/fehtl noch {{answers_not_completed}} Antwort(en)',
OPTIONAL: 'fakultativ',
ERROR_EMAIL_INVALID: 'Bitte gültige Mailadresse eingeben',
ERROR_NOT_A_NUMBER: 'Bitte nur Zahlen eingeben',
ERROR_URL_INVALID: 'Bitte eine gültige URL eingeben',
OK: 'Okay',
ENTER: 'Eingabetaste drücken',
YES: 'Ja',
NO: 'Nein',
NEWLINE: 'Für eine neue Zeile SHIFT+ENTER drücken',
CONTINUE: 'Weiter',
LEGAL_ACCEPT: 'I accept',
LEGAL_NO_ACCEPT: 'I don’t accept',
DELETE: 'Entfernen',
CANCEL: 'Canceln',
SUBMIT: 'Speichern',
UPLOAD_FILE: 'Datei versenden',
Y: 'J',
N: 'N',
OPTION_PLACEHOLDER: 'Geben oder wählen Sie eine Option aus',
ADD_NEW_LINE_INSTR: 'Drücken Sie UMSCHALT + EINGABETASTE, um eine neue Zeile hinzuzufügen',
ERROR: 'Fehler',
FORM_404_HEADER: '404 - Formular existiert nicht',
FORM_404_BODY: 'Das Formular, auf das Sie zugreifen möchten, existiert nicht. Das tut mir leid!',
FORM_UNAUTHORIZED_HEADER: 'Nicht zum Zugriffsformular berechtigt\' ',
FORM_UNAUTHORIZED_BODY1: 'Das Formular, auf das Sie zugreifen möchten, ist derzeit privat und nicht öffentlich zugänglich.',
FORM_UNAUTHORIZED_BODY2: 'Wenn Sie der Eigentümer des Formulars sind, können Sie es im Fenster "Konfiguration" im Formular admin auf "Öffentlich" setzen.',
});
}]);
'use strict';
angular.module('view-form').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('it', {
FORM_SUCCESS: 'Il formulario è stato inviato con successo!',
REVIEW: 'Incompleto',
BACK_TO_FORM: 'Ritorna al formulario',
EDIT_FORM: 'Modifica questo TellForm',
CREATE_FORM: 'Crea questo TellForm',
ADVANCEMENT: '{{done}} su {{total}} completate',
CONTINUE_FORM: 'Vai al formulario',
REQUIRED: 'obbligatorio',
COMPLETING_NEEDED: '{{answers_not_completed}} risposta/e deve/ono essere completata/e',
OPTIONAL: 'opzionale',
ERROR_EMAIL_INVALID: 'Si prega di inserire un indirizzo email valido',
ERROR_NOT_A_NUMBER: 'Si prega di inserire solo numeri',
ERROR_URL_INVALID: 'Grazie per inserire un URL valido',
OK: 'OK',
ENTER: 'premere INVIO',
YES: 'Sì',
NO: 'No',
NEWLINE: 'premere SHIFT+INVIO per creare una nuova linea',
CONTINUE: 'Continua',
LEGAL_ACCEPT: 'I accept',
LEGAL_NO_ACCEPT: 'I don’t accept',
DELETE: 'Cancella',
CANCEL: 'Reset',
SUBMIT: 'Registra',
UPLOAD_FILE: 'Invia un file',
Y: 'S',
N: 'N',
OPTION_PLACEHOLDER: 'Digitare o selezionare un\'opzione',
ADD_NEW_LINE_INSTR: 'Premere SHIFT + INVIO per aggiungere una nuova riga',
ERROR: 'Errore',
FORM_404_HEADER: '404 - Il modulo non esiste',
FORM_404_BODY: 'La forma che stai cercando di accedere non esiste. Ci dispiace!',
FORM_UNAUTHORIZED_HEADER: 'Non autorizzato per accedere al modulo',
FORM_UNAUTHORIZED_BODY1: 'Il modulo che si sta tentando di accedere è attualmente privato e non accessibile in pubblico.',
FORM_UNAUTHORIZED_BODY2: 'Se sei il proprietario del modulo, puoi impostarlo su "Pubblico" nel pannello "Configurazione" nell\'amministratore di moduli.',
});
}]);
'use strict';
angular.module('view-form').config(['$translateProvider', function ($translateProvider) {
$translateProvider.translations('es', {
FORM_SUCCESS: '¡El formulario ha sido enviado con éxito!',
REVIEW: 'Revisar',
BACK_TO_FORM: 'Regresar al formulario',
EDIT_FORM: 'Editar este TellForm',
CREATE_FORM: 'Crear este TellForm',
ADVANCEMENT: '{{done}} de {{total}} contestadas',
CONTINUE_FORM: 'Continuar al formulario',
REQUIRED: 'Información requerida',
COMPLETING_NEEDED: '{{answers_not_completed}} respuesta(s) necesita(n) ser completada(s)',
OPTIONAL: 'Opcional',
ERROR_EMAIL_INVALID: 'Favor de proporcionar un correo electrónico válido',
ERROR_NOT_A_NUMBER: 'Por favor, introduzca sólo números válidos',
ERROR_URL_INVALID: 'Favor de proporcionar un url válido',
OK: 'OK',
ENTER: 'pulse INTRO',
YES: 'Si',
NO: 'No',
NEWLINE: 'presione SHIFT+INTRO para crear una nueva línea',
CONTINUE: 'Continuar',
LEGAL_ACCEPT: 'Yo acepto',
LEGAL_NO_ACCEPT: 'Yo no acepto',
DELETE: 'Eliminar',
CANCEL: 'Cancelar',
SUBMIT: 'Registrar',
UPLOAD_FILE: 'Cargar el archivo',
Y: 'S',
N: 'N',
OPTION_PLACEHOLDER: 'Escriba o seleccione una opción',
ADD_NEW_LINE_INSTR: 'Presione MAYÚS + ENTRAR para agregar una nueva línea',
ERROR: 'Error',
FORM_404_HEADER: '404 - La forma no existe',
FORM_404_BODY: 'El formulario al que intenta acceder no existe. ¡Lo siento por eso!',
FORM_UNAUTHORIZED_HEADER: 'Non autorizzato per accedere al modulo',
FORM_UNAUTHORIZED_BODY1: 'Il modulo che si sta tentando di accedere è attualmente privato e non accessibile in pubblico.',
FORM_UNAUTHORIZED_BODY2: 'Se sei il proprietario del modulo, puoi impostarlo su "Pubblico" nel pannello "Configurazione" nell\'amministratore di moduli.',
});
}]);
'use strict';
// SubmitForm controller
angular.module('view-form').controller('SubmitFormController', [
'$scope', '$rootScope', '$state', '$translate', 'myForm',
function($scope, $rootScope, $state, $translate, myForm) {
$scope.myform = myForm;
$(".loader").fadeOut("slow");
document.body.style.background = myForm.design.colors.backgroundColor;
$translate.use(myForm.language);
}
]);
'use strict';
angular.module('view-form').directive('fieldIconDirective', function() {
return {
template: '',
restrict: 'E',
scope: {
typeName: '@'
},
controller: ["$scope", function($scope){
var iconTypeMap = {
'textfield': 'fa fa-pencil-square-o',
'dropdown': 'fa fa-th-list',
'date': 'fa fa-calendar',
'checkbox': 'fa fa-check-square-o',
'radio': 'fa fa-dot-circle-o',
'email': 'fa fa-envelope-o',
'textarea': 'fa fa-pencil-square',
'legal': 'fa fa-legal',
'file': 'fa fa-cloud-upload',
'rating': 'fa fa-star-half-o',
'link': 'fa fa-link',
'scale': 'fa fa-sliders',
'stripe': 'fa fa-credit-card',
'statement': 'fa fa-quote-left',
'yes_no': 'fa fa-toggle-on',
'number': 'fa fa-slack'
};
$scope.typeIcon = iconTypeMap[$scope.typeName];
}]
};
});
'use strict';
// coffeescript's for in loop
var __indexOf = [].indexOf || function(item) {
for (var i = 0, l = this.length; i < l; i++) {
if (i in this && this[i] === item) return i;
}
return -1;
};
angular.module('view-form').directive('fieldDirective', ['$http', '$compile', '$rootScope', '$templateCache', 'supportedFields',
function($http, $compile, $rootScope, $templateCache, supportedFields) {
var getTemplateHtml = function(fieldType) {
var type = fieldType;
var supported_fields = [
'textfield',
'textarea',
'date',
'dropdown',
'hidden',
'password',
'radio',
'legal',
'statement',
'rating',
'yes_no',
'number',
'natural'
];
var templateUrl = 'form_modules/forms/base/views/directiveViews/field/';
if (__indexOf.call(supportedFields, type) >= 0) {
templateUrl = templateUrl+type+'.html';
}
return $templateCache.get(templateUrl);
};
return {
template: '{{field.title}}
',
restrict: 'E',
scope: {
field: '=',
required: '&',
design: '=',
index: '=',
forms: '='
},
link: function(scope, element) {
$rootScope.chooseDefaultOption = scope.chooseDefaultOption = function(type) {
if(type === 'yes_no'){
scope.field.fieldValue = 'true';
}else if(type === 'rating'){
scope.field.fieldValue = 0;
}else if(scope.field.fieldType === 'radio'){
scope.field.fieldValue = scope.field.fieldOptions[0].option_value;
}else if(type === 'legal'){
scope.field.fieldValue = 'true';
$rootScope.nextField();
}
};
scope.nextField = $rootScope.nextField;
scope.setActiveField = $rootScope.setActiveField;
//Set format only if field is a date
if(scope.field.fieldType === 'date'){
scope.dateOptions = {
changeYear: true,
changeMonth: true,
altFormat: 'mm/dd/yyyy',
yearRange: '1900:-0',
defaultDate: 0
};
}
var fieldType = scope.field.fieldType;
if(scope.field.fieldType === 'number' || scope.field.fieldType === 'textfield' || scope.field.fieldType === 'email' || scope.field.fieldType === 'link'){
switch(scope.field.fieldType){
case 'textfield':
scope.input_type = 'text';
break;
case 'email':
scope.input_type = 'email';
scope.placeholder = 'joesmith@example.com';
break;
case 'number':
scope.input_type = 'text';
scope.validateRegex = /^-?\d+$/;
break;
default:
scope.input_type = 'url';
scope.placeholder = 'http://example.com';
break;
}
fieldType = 'textfield';
}
var template = getTemplateHtml(fieldType);
element.html(template).show();
var output = $compile(element.contents())(scope);
}
};
}]);
'use strict';
//TODO: DAVID: Need to refactor this
angular.module('view-form').directive('onEnterKey', ['$rootScope', function($rootScope){
return {
restrict: 'A',
link: function($scope, $element, $attrs) {
$element.bind('keydown keypress', function(event) {
var keyCode = event.which || event.keyCode;
var onEnterKeyDisabled = false;
if($attrs.onEnterKeyDisabled !== null) onEnterKeyDisabled = $attrs.onEnterKeyDisabled;
if(keyCode === 13 && !event.shiftKey && !onEnterKeyDisabled) {
event.preventDefault();
$rootScope.$apply(function() {
$rootScope.$eval($attrs.onEnterKey);
});
}
});
}
};
}]).directive('onTabKey', ['$rootScope', function($rootScope){
return {
restrict: 'A',
link: function($scope, $element, $attrs) {
$element.bind('keyup keypress', function(event) {
var keyCode = event.which || event.keyCode;
if(keyCode === 9 && !event.shiftKey) {
event.preventDefault();
$rootScope.$apply(function() {
$rootScope.$eval($attrs.onTabKey);
});
}
});
}
};
}]).directive('onEnterOrTabKey', ['$rootScope', function($rootScope){
return {
restrict: 'A',
link: function($scope, $element, $attrs) {
$element.bind('keydown keypress', function(event) {
var keyCode = event.which || event.keyCode;
if((keyCode === 13 || keyCode === 9) && !event.shiftKey) {
event.preventDefault();
$rootScope.$apply(function() {
$rootScope.$eval($attrs.onEnterOrTabKey);
});
}
});
}
};
}]).directive('onTabAndShiftKey', ['$rootScope', function($rootScope){
return {
restrict: 'A',
link: function($scope, $element, $attrs) {
$element.bind('keydown keypress', function(event) {
var keyCode = event.which || event.keyCode;
if(keyCode === 9 && event.shiftKey) {
console.log('onTabAndShiftKey');
event.preventDefault();
$rootScope.$apply(function() {
$rootScope.$eval($attrs.onTabAndShiftKey);
});
}
});
}
};
}]);
'use strict';
angular.module('view-form').directive('onFinishRender', ["$rootScope", "$timeout", function ($rootScope, $timeout) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
//Don't do anything if we don't have a ng-repeat on the current element
if(!element.attr('ng-repeat') && !element.attr('data-ng-repeat')){
return;
}
var broadcastMessage = attrs.onFinishRender || 'ngRepeat';
if(scope.$first && !scope.$last) {
scope.$evalAsync(function () {
$rootScope.$broadcast(broadcastMessage+' Started');
});
}else if(scope.$last) {
scope.$evalAsync(function () {
$rootScope.$broadcast(broadcastMessage+' Finished');
});
}
}
};
}]);
'use strict';
//FIXME: Should find an appropriate place for this
//Setting up jsep
jsep.addBinaryOp('contains', 10);
jsep.addBinaryOp('!contains', 10);
jsep.addBinaryOp('begins', 10);
jsep.addBinaryOp('!begins', 10);
jsep.addBinaryOp('ends', 10);
jsep.addBinaryOp('!ends', 10);
angular.module('view-form').directive('submitFormDirective', ['$http', 'TimeCounter', '$filter', '$rootScope', 'SendVisitorData', '$translate', '$timeout',
function ($http, TimeCounter, $filter, $rootScope, SendVisitorData, $translate, $timeout) {
return {
templateUrl: 'form_modules/forms/base/views/directiveViews/form/submit-form.client.view.html',
restrict: 'E',
scope: {
myform:'=',
ispreview: '='
},
controller: ["$document", "$window", "$scope", function($document, $window, $scope){
var NOSCROLL = false;
var FORM_ACTION_ID = 'submit_field';
$scope.forms = {};
//Don't start timer if we are looking at a design preview
if($scope.ispreview){
TimeCounter.restartClock();
}
var form_fields_count = $scope.myform.visible_form_fields.filter(function(field){
return field.fieldType !== 'statement';
}).length;
var nb_valid = $filter('formValidity')($scope.myform);
$scope.translateAdvancementData = {
done: nb_valid,
total: form_fields_count,
answers_not_completed: form_fields_count - nb_valid
};
$scope.reloadForm = function(){
//Reset Form
$scope.myform.submitted = false;
$scope.myform.form_fields = _.chain($scope.myform.visible_form_fields).map(function(field){
field.fieldValue = '';
return field;
}).value();
$scope.loading = false;
$scope.error = '';
$scope.selected = {
_id: '',
index: 0
};
$scope.setActiveField($scope.myform.visible_form_fields[0]._id, 0, false);
//Reset Timer
TimeCounter.restartClock();
};
/*
** Field Controls
*/
var evaluateLogicJump = function(field){
var logicJump = field.logicJump;
if(logicJump.enabled){
if (logicJump.expressionString && logicJump.valueB && field.fieldValue) {
var parse_tree = jsep(logicJump.expressionString);
var left, right;
if(parse_tree.left.name === 'field'){
left = field.fieldValue;
right = logicJump.valueB;
} else {
left = logicJump.valueB;
right = field.fieldValue;
}
if(field.fieldType === 'number' || field.fieldType === 'scale' || field.fieldType === 'rating'){
switch(parse_tree.operator) {
case '==':
return (parseInt(left) === parseInt(right));
case '!==':
return (parseInt(left) !== parseInt(right));
case '>':
return (parseInt(left) > parseInt(right));
case '>=':
return (parseInt(left) > parseInt(right));
case '<':
return (parseInt(left) < parseInt(right));
case '<=':
return (parseInt(left) <= parseInt(right));
default:
return false;
}
} else {
switch(parse_tree.operator) {
case '==':
return (left === right);
case '!==':
return (left !== right);
case 'contains':
return (left.indexOf(right) > -1);
case '!contains':
/* jshint -W018 */
return !(left.indexOf(right) > -1);
case 'begins':
return left.startsWith(right);
case '!begins':
return !left.startsWith(right);
case 'ends':
return left.endsWith(right);
case '!ends':
return left.endsWith(right);
default:
return false;
}
}
}
}
};
var getActiveField = function(){
if($scope.selected === null){
console.error('current active field is null');
throw new Error('current active field is null');
}
if($scope.selected._id === FORM_ACTION_ID) {
return $scope.myform.form_fields.length - 1;
}
return $scope.selected.index;
};
$scope.isActiveField = function(field){
if($scope.selected._id === field._id) {
return true
}
return false;
};
$scope.setActiveField = $rootScope.setActiveField = function(field_id, field_index, animateScroll) {
if($scope.selected === null || (!field_id && field_index === null) ) {
return;
}
if(!field_id){
field_id = $scope.myform.visible_form_fields[field_index]._id;
} else if(field_index === null){
field_index = $scope.myform.visible_form_fields.length
for(var i=0; i < $scope.myform.visible_form_fields.length; i++){
var currField = $scope.myform.visible_form_fields[i];
if(currField['_id'] == field_id){
field_index = i;
break;
}
}
}
if($scope.selected._id === field_id){
return;
}
$scope.selected._id = field_id;
$scope.selected.index = field_index;
var nb_valid = $filter('formValidity')($scope.myform);
$scope.translateAdvancementData = {
done: nb_valid,
total: form_fields_count,
answers_not_completed: form_fields_count - nb_valid
};
if(animateScroll){
NOSCROLL=true;
setTimeout(function() {
$document.scrollToElement(angular.element('.activeField'), -10, 200).then(function() {
NOSCROLL = false;
setTimeout(function() {
if (document.querySelectorAll('.activeField .focusOn').length) {
//Handle default case
document.querySelectorAll('.activeField .focusOn')[0].focus();
} else if(document.querySelectorAll('.activeField input').length) {
//Handle case for rating input
document.querySelectorAll('.activeField input')[0].focus();
} else {
//Handle case for dropdown input
document.querySelectorAll('.activeField .selectize-input')[0].focus();
}
});
});
});
}
};
$scope.$watch('selected.index', function(oldValue, newValue){
if(oldValue !== newValue && newValue < $scope.myform.form_fields.length){
//Only send analytics data if form has not been submitted
if(!$scope.myform.submitted){
console.log('SendVisitorData.send()');
SendVisitorData.send($scope.myform, newValue, TimeCounter.getTimeElapsed());
}
}
});
//Fire event when window is scrolled
$window.onscroll = function(){
if(!NOSCROLL){
var scrollTop = $(window).scrollTop();
var elemBox = document.getElementsByClassName('activeField')[0].getBoundingClientRect();
var fieldTop = elemBox.top;
var fieldBottom = elemBox.bottom;
var field_id, field_index;
var elemHeight = $('.activeField').height();
var submitSectionHeight = $('.form-actions').height();
var maxScrollTop = $(document).height() - $(window).height();
var fieldWrapperHeight = $('form_fields').height();
var selector = 'form > .field-directive:nth-of-type(' + String($scope.myform.visible_form_fields.length - 1)+ ')'
var fieldDirectiveHeight = $(selector).height()
var scrollPosition = maxScrollTop - submitSectionHeight - fieldDirectiveHeight*1.2;
var fractionToJump = 0.9;
//Focus on field above submit form button
if($scope.selected.index === $scope.myform.visible_form_fields.length){
if(scrollTop < scrollPosition){
field_index = $scope.selected.index-1;
$scope.setActiveField(null, field_index, false);
}
}
//Focus on submit form button
else if($scope.selected.index === $scope.myform.visible_form_fields.length-1 && scrollTop > scrollPosition){
field_index = $scope.selected.index+1;
$scope.setActiveField(FORM_ACTION_ID, field_index, false);
}
//If we scrolled bellow the current field, move to next field
else if(fieldBottom < elemHeight * fractionToJump && $scope.selected.index < $scope.myform.visible_form_fields.length-1 ){
field_index = $scope.selected.index+1;
$scope.setActiveField(null, field_index, false);
}
//If we scrolled above the current field, move to prev field
else if ( $scope.selected.index !== 0 && fieldTop > elemHeight * fractionToJump) {
field_index = $scope.selected.index-1;
$scope.setActiveField(null, field_index, false);
}
}
$scope.$apply();
};
$rootScope.nextField = $scope.nextField = function(){
if($scope.selected && $scope.selected.index > -1){
if($scope.selected._id !== FORM_ACTION_ID){
var currField = $scope.myform.visible_form_fields[$scope.selected.index];
//Jump to logicJump's destination if it is true
if(currField.logicJump && currField.logicJump.jumpTo && evaluateLogicJump(currField)){
$scope.setActiveField(currField.logicJump.jumpTo, null, true);
} else if($scope.selected.index < $scope.myform.visible_form_fields.length-1){
$scope.setActiveField(null, $scope.selected.index+1, true);
} else {
$scope.setActiveField(FORM_ACTION_ID, null, true);
}
} else {
//If we are at the submit actions page, go to the first field
$rootScope.setActiveField(null, 0, true);
}
} else {
//If selected is not defined go to the first field
$rootScope.setActiveField(null, 0, true);
}
};
$rootScope.prevField = $scope.prevField = function(){
console.log('prevField');
console.log($scope.selected);
var selected_index = $scope.selected.index - 1;
if($scope.selected.index > 0){
$scope.setActiveField(null, selected_index, true);
}
};
$rootScope.goToInvalid = $scope.goToInvalid = function() {
var field_id = $('.row.field-directive .ng-invalid.focusOn, .row.field-directive .ng-untouched.focusOn:not(.ng-valid)').first().parents('.row.field-directive').first().attr('data-id');
$scope.setActiveField(field_id, null, true);
};
/*
** Form Display Functions
*/
$scope.exitStartPage = function(){
$scope.myform.startPage.showStart = false;
if($scope.myform.visible_form_fields.length > 0){
$scope.selected._id = $scope.myform.visible_form_fields[0]._id;
}
};
var getDeviceData = function(){
var md = new MobileDetect(window.navigator.userAgent);
var deviceType = 'other';
if (md.tablet()){
deviceType = 'tablet';
} else if (md.mobile()) {
deviceType = 'mobile';
} else if (!md.is('bot')) {
deviceType = 'desktop';
}
return {
type: deviceType,
name: window.navigator.platform
};
};
var getIpAndGeo = function(){
//Get Ip Address and GeoLocation Data
$.ajaxSetup( { 'async': false } );
var geoData = $.getJSON('https://freegeoip.net/json/').responseJSON;
$.ajaxSetup( { 'async': true } );
if(!geoData || !geoData.ip){
geoData = {
ip: 'Adblocker'
};
}
return {
ipAddr: geoData.ip,
geoLocation: {
City: geoData.city,
Country: geoData.country_name
}
};
};
$rootScope.submitForm = $scope.submitForm = function() {
if($scope.forms.myForm.$invalid){
$scope.goToInvalid();
return;
}
var _timeElapsed = TimeCounter.stopClock();
$scope.loading = true;
var form = _.cloneDeep($scope.myform);
var deviceData = getDeviceData();
form.device = deviceData;
var geoData = getIpAndGeo();
form.ipAddr = geoData.ipAddr;
form.geoLocation = geoData.geoLocation;
form.timeElapsed = _timeElapsed;
form.percentageComplete = $filter('formValidity')($scope.myform) / $scope.myform.visible_form_fields.length * 100;
delete form.endPage
delete form.isLive
delete form.provider
delete form.startPage
delete form.visible_form_fields;
delete form.analytics;
delete form.design;
delete form.submissions;
delete form.submitted;
for(var i=0; i < $scope.myform.form_fields.length; i++){
if($scope.myform.form_fields[i].fieldType === 'dropdown' && !$scope.myform.form_fields[i].deletePreserved){
$scope.myform.form_fields[i].fieldValue = $scope.myform.form_fields[i].fieldValue.option_value;
}
//Get rid of unnessecary attributes for each form field
delete form.form_fields[i].submissionId;
delete form.form_fields[i].disabled;
delete form.form_fields[i].ratingOptions;
delete form.form_fields[i].fieldOptions;
delete form.form_fields[i].logicJump;
delete form.form_fields[i].description;
delete form.form_fields[i].validFieldTypes;
delete form.form_fields[i].fieldType;
}
setTimeout(function () {
$scope.submitPromise = $http.post('/forms/' + $scope.myform._id, form)
.success(function (data, status) {
$scope.myform.submitted = true;
$scope.loading = false;
SendVisitorData.send(form, getActiveField(), _timeElapsed);
})
.error(function (error) {
$scope.loading = false;
console.error(error);
$scope.error = error.message;
});
}, 500);
};
//Reload our form
$scope.reloadForm();
}]
};
}
]);
'use strict';
//Forms service used for communicating with the forms REST endpoints
angular.module('view-form').service('CurrentForm',
function(){
//Private variables
var _form = {};
//Public Methods
this.getForm = function() {
return _form;
};
this.setForm = function(form) {
_form = form;
};
}
);
'use strict';
//Forms service used for communicating with the forms REST endpoints
angular.module('view-form').factory('Forms', ['$resource', 'VIEW_FORM_URL',
function($resource, VIEW_FORM_URL) {
return $resource(VIEW_FORM_URL, {
formId: '@_id'
}, {
'get' : {
method: 'GET',
transformResponse: function(data, header) {
var form = angular.fromJson(data);
form.visible_form_fields = _.filter(form.form_fields, function(field){
return (field.deletePreserved === false);
});
return form;
}
},
'update': {
method: 'PUT'
},
'save': {
method: 'POST'
}
});
}
]);
(function () {
'use strict';
// Create the Socket.io wrapper service
function Socket($timeout, $window) {
var service = {
socket: null
};
// Connect to TellForm Socket.io server
function connect() {
var url = '';
if($window.socketUrl && $window.socketPort){
url = window.location.protocol + '//' + $window.socketUrl + ':' + $window.socketPort;
} else if ($window.socketUrl){
url = window.location.protocol + '//' + $window.socketUrl;
} else if ($window.socketPort){
url = window.location.protocol + '//' + window.location.hostname + ':' + $window.socketPort;
} else {
url = window.location.protocol + '//' + window.location.hostname;
}
service.socket = io(url, {'transports': ['websocket', 'polling']});
}
// Wrap the Socket.io 'emit' method
function emit(eventName, data) {
if (service.socket) {
service.socket.emit(eventName, data);
}
}
// Wrap the Socket.io 'on' method
function on(eventName, callback) {
if (service.socket) {
service.socket.on(eventName, function (data) {
$timeout(function () {
callback(data);
});
});
}
}
// Wrap the Socket.io 'removeListener' method
function removeListener(eventName) {
if (service.socket) {
service.socket.removeListener(eventName);
}
}
connect();
service = {
connect: connect,
emit: emit,
on: on,
removeListener: removeListener,
socket: null
};
return service;
}
angular
.module('view-form')
.factory('Socket', Socket);
Socket.$inject = ['$timeout', '$window'];
}());
'use strict';
angular.module('view-form').service('TimeCounter', [
function(){
var _startTime, _endTime = null;
this.timeSpent = 0;
this.restartClock = function(){
_startTime = Date.now();
_endTime = null;
};
this.getTimeElapsed = function(){
if(_startTime) {
return Math.abs(Date.now().valueOf() - _startTime.valueOf()) / 1000;
}
};
this.stopClock = function(){
if(_startTime && _endTime === null){
_endTime = Date.now();
this.timeSpent = Math.abs(_endTime.valueOf() - _startTime.valueOf())/1000;
this._startTime = this._endTime = null;
return this.timeSpent;
}
return new Error('Clock has not been started');
};
this.clockStarted = function(){
return !!this._startTime;
};
}
]);