added variable support in editor

This commit is contained in:
David Baldwynn 2017-10-31 16:05:50 -07:00
parent aa8efe8508
commit 5a6b957495
12 changed files with 137 additions and 135 deletions

View File

@ -10,7 +10,8 @@ var mongoose = require('mongoose'),
config = require('../../config/config'),
diff = require('deep-diff'),
_ = require('lodash'),
nodemailer = require('nodemailer');
nodemailer = require('nodemailer'),
emailNotifications = require('../libs/send-email-notifications');
var smtpTransport = nodemailer.createTransport(config.mailer.options);
@ -73,22 +74,25 @@ exports.createSubmission = function(req, res) {
});
}
if (req.body.emailNotifications && req.body.emailNotifications.enabled && req.body.emailNotifications.recipients) {
var mailOptions = {
from: config.mailer.from,
cc: req.body.emailNotifications.recipients,
subject: 'TellForm ' + submission.title + 'Submitted',
body: 'Your form ' + submission.title + 'was submitted.'
}
var form = req.body.form;
smtpTransport.sendMail(mailOptions, function(err) {
if (!err) {
return res.status(200).send('Form submission successfully saved');
}
return res.status(400).send({
message: 'Failure sending submission email'
});
if (form.selfNotifications && form.selfNotifications.enabled && form.selfNotifications.recipients) {
var formFieldDict = {};
form.form_fields.forEach(function(field){
formFieldDict[field._id] = field.fieldValue;
});
form.selfNotifications.from = formFieldDict[form.selfNotifications.fromField].fieldValue;
emailNotifications.send(form.selfNotifications, formFieldDict, smtpTransport, function(err){
if (!err) {
return res.status(200).send('Form submission successfully saved');
}
return res.status(400).send({
message: 'Failure sending submission email'
});
});
} else {
res.status(200).send('Form submission successfully saved');
}

View File

@ -0,0 +1,26 @@
module.exports = {
send: function(emailSettings, emailTemplateVars, smtpTransport, cb){
var parsedTemplate = parseTemplate(emailSettings.htmlTemplate, emailTemplateVars);
var parsedSubject = parseTemplate(emailSettings.body, emailTemplateVars);
var mailOptions = {
from: emailSettings.from,
cc: emailSettings.recipients,
subject: parsedSubject,
html: parsedTemplate
}
smtpTransport.sendMail(mailOptions, cb);
},
parseTemplate: function(emailTemplate, emailAttrs){
var resolvedTemplate = emailTemplate;
Object.keys(emailAttrs).forEach(function (key) {
resolvedTemplate = replaceTemplateVal(key, emailAttrs[key], resolvedTemplate);
});
return resolvedTemplate;
},
replaceTemplateVal: function(key, val, template){
return template.replace( new RegExp('${' + key + '}', 'g'), value )
}
}

View File

@ -150,7 +150,16 @@ var FormSchema = new Schema({
buttons:[ButtonSchema]
},
emailNotifications: {
selfNotifications: {
fromField: {
type: Schema.Types.ObjectId,
},
subject: {
type: String
},
htmlTemplate: {
type: String
},
enabled: {
type: Boolean,
default: false

View File

@ -35,6 +35,9 @@ block content
//Socket.io Client Dependency
script(src='https://cdn.socket.io/socket.io-1.4.5.js')
//TinyMCE
script(src='https://cdnjs.cloudflare.com/ajax/libs/tinymce/4.7.1/tinymce.min.js')
//Bower JS dependencies
each bowerJSFile in bowerJSFiles
script(type='text/javascript', src=bowerJSFile)
@ -42,8 +45,6 @@ block content
script(type='text/javascript', src='https://cdnjs.cloudflare.com/ajax/libs/angular-strap/2.3.8/angular-strap.min.js')
script(src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-animate.js")
//Application JavaScript Files
each jsFile in jsFiles
script(type='text/javascript', src=jsFile)

View File

@ -25,7 +25,6 @@
"angular-permission": "~1.1.1",
"file-saver.js": "~1.20150507.2",
"angular-bootstrap-colorpicker": "~3.0.19",
"angular-ui-router-tabs": "~1.7.0",
"angular-scroll": "^1.0.0",
"angular-sanitize": "1.4.14",
"v-button": "^1.1.1",
@ -42,7 +41,8 @@
"mobile-detect": "^1.3.3",
"socket.io-client": "^1.7.2",
"css-toggle-switch": "^4.0.2",
"angular-strap": "^2.3.12"
"angular-strap": "^2.3.12",
"textAngular": "^1.5.16"
},
"resolutions": {
"angular-bootstrap": "^0.14.0",

View File

@ -4,7 +4,7 @@
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'];
var applicationModuleVendorDependencies = ['duScroll', 'ui.select', 'ngSanitize', 'vButton', 'ngResource', 'TellForm.templates', 'ui.router', 'ui.bootstrap', 'ui.utils', 'pascalprecht.translate'];
// Add a new vertical module
var registerModule = function(moduleName, dependencies) {

View File

@ -22,6 +22,9 @@ angular.module('forms').config(['$translateProvider', function ($translateProvid
SELF_NOTIFICATIONS_TAB: 'Self notifications',
RESPONDENT_NOTIFICATIONS_TAB: 'Respondent notifications',
//Self Notifications Tab
ADD_VARIABLE_BUTTON: 'Add variable',
//List Forms View
CREATE_A_NEW_FORM: 'Create a new form',
CREATE_FORM: 'Create form',

View File

@ -0,0 +1,14 @@
.tag {
background-color: #999;
border-radius: 3px 3px 3px 3px;
border: 0;
color: #FFFFFF;
font-style: inherit;
font-size: 11px;
padding: 4px 5px;
margin: 0 2px 2px 2px;
font-family: inherit;
white-space: nowrap;
vertical-align: middle;
cursor: pointer !important;
}

View File

@ -9,10 +9,11 @@ angular.module('forms').directive('configureFormDirective', ['$rootScope', '$fil
myform:'='
},
controller: function($scope){
$rootScope.myform = $scope.myform;
$scope.languages = $rootScope.languages;
$scope.resetForm = $rootScope.resetForm;
$scope.update = $rootScope.update;
$scope.configureTabs = [
{
heading: $filter('translate')('GENERAL_TAB'),

View File

@ -1,39 +1,50 @@
<!-- Settings -->
<div class="row">
<div class="col-sm-offset-2 col-sm-4">
<div class="col-sm-offset-2">
<div class="row field">
<div class="field-title col-sm-12">
<h5>{{ 'FORM_NAME' | translate }}</h5>
<h5>{{ 'SEND_NOTIFICATION_TO' | translate }}</h5>
</div>
<div class="col-sm-12">
<input class="form-control"
type="text"
ng-model="myform.title"
value="{{myform.title}}"
style="width: 100%;"
ng-minlength="4"
ng-pattern="/^[a-zA-Z0-9 \-.]*$/">
type="text"
ng-model="myform.emailNotifications.recipients"
value="{{myform.emailNotifications.recipients}}"
placeholder="email@domain.com,email2@domain2.com,etc">
</div>
</div>
<div class="row field">
<div class="field-title col-sm-12">
<h5>{{ 'FORM_STATUS' | translate }}</h5>
<h5>{{ 'REPLY_TO' | translate }}</h5>
</div>
<div class="field-input col-sm-12">
<div class="col-xs-12 field-input">
<ui-select ng-model="myform.selfNotifications.fromField"
theme="selectize"
search-enabled="true"
search-by="title"
set-search-to-answer="true"
ng-required="true">
<ui-select-match placeholder="{{ 'OPTION_PLACEHOLDER' | translate }}">
</ui-select-match>
<ui-select-choices repeat="field in myform.form_fields | filter: $select.search"
ng-class="{'active': field._id === myform.selfNotifications.fromField }">
<span ng-bind-html="field.title | highlight: $select.search"></span>
</ui-select-choices>
</ui-select>
</div>
</div>
<label style="display: inline-block;">
<input type="radio" data-ng-value="true" ng-model="myform.isLive" ng-required="true" style="background-color:#33CC00;"/>
&nbsp;<span>{{ 'PUBLIC' | translate }}</span>
</label>
<div class="row field">
<div class="field-title col-sm-12">
<h5>{{ 'EMAIL_SUBJECT' | translate }}</h5>
</div>
<label style="display: inline-block;">
<input type="radio" data-ng-value="false" ng-model="myform.isLive" ng-required="true" />
&nbsp;<span>{{ 'PRIVATE' | translate }}</span>
</label>
<div class="col-sm-12">
<text-angular ng-model="htmlVariable" ta-toolbar="[['bold','italics', 'test']]"></text-angular>
<div ng-bind="htmlVariable"></div>
</div>
</div>
@ -57,22 +68,6 @@
</div>
</div>
<div class="row field" ng-if="myform.emailNotifications.enabled">
<div class="field-title col-sm-12">
<h5>{{ 'EMAIL_NOTIFICATION_RECIPIENTS' | translate }}</h5>
</div>
<div class="col-sm-12">
<input class="form-control"
type="text"
ng-model="myform.emailNotifications.recipients"
value="{{myform.emailNotifications.recipients}}"
style="width: 100%;"
placeholder="email@domain.com,email2@domain2.com,etc">
</div>
</div>
<div class="row field">
<div class="col-sm-12 field-title">{{ 'LANGUAGE' | translate }}</div>
<div class="col-sm-12 field-input">
@ -87,79 +82,4 @@
</div>
</div>
</div>
<div class="col-sm-4">
<div class="row field">
<div class="field-title col-sm-12">
<h5>{{ 'GA_TRACKING_CODE' | translate }}</h5>
</div>
<div class="col-sm-12">
<input class="form-control"
type="text"
ng-model="myform.analytics.gaCode"
value="{{myform.analytics.gaCode}}"
style="width: 100%;"
ng-minlength="4"
placeholder="UA-XXXXX-Y"
ng-pattern="/\bUA-\d{4,10}-\d{1,4}\b/">
</div>
</div>
<div class="row field">
<div class="field-title col-sm-12">
<h5>{{ 'DISPLAY_FOOTER' | translate }}</h5>
</div>
<div class="field-input col-sm-12">
<label style="display: inline-block;">
<input type="radio" data-ng-value="false" ng-model="myform.hideFooter" ng-required="true" />
&nbsp;<span>{{ 'YES' | translate }}</span>
</label>
<label style="display: inline-block;">
<input type="radio" data-ng-value="true" ng-model="myform.hideFooter" ng-required="true" />
&nbsp;<span>{{ 'NO' | translate }}</span>
</label>
</div>
</div>
<div class="row field">
<div class="field-title col-sm-12">
<h5>{{ 'DISPLAY_START_PAGE' | translate }}</h5>
</div>
<div class="field-input col-sm-12">
<label style="display: inline-block;">
<input type="radio" data-ng-value="true" ng-model="myform.startPage.showStart" ng-required="true" style="background-color:#33CC00;"/>
&nbsp;<span>{{ 'YES' | translate }}</span>
</label>
<label style="display: inline-block;">
<input type="radio" data-ng-value="false" ng-model="myform.startPage.showStart" ng-required="true" />
&nbsp;<span>{{ 'NO' | translate }}</span>
</label>
</div>
</div>
<div class="row field">
<div class="field-title col-sm-12">
<h5>{{ 'DISPLAY_END_PAGE' | translate }}</h5>
</div>
<div class="field-input col-sm-12">
<label style="display: inline-block;">
<input type="radio" data-ng-value="true" ng-model="myform.endPage.showEnd" ng-required="true" style="background-color:#33CC00;"/>
&nbsp;<span>{{ 'YES' | translate }}</span>
</label>
<label style="display: inline-block;">
<input type="radio" data-ng-value="false" ng-model="myform.endPage.showEnd" ng-required="true" />
&nbsp;<span>{{ 'NO' | translate }}</span>
</label>
</div>
</div>
</div>
</div>

View File

@ -46,4 +46,28 @@ angular.module('forms').run(['Menus',
directive.replace = true;
return $delegate;
});
}]);
}]).config(['$provide', function ($provide){
$provide.decorator('taOptions', ['$delegate', 'taRegisterTool', '$translate', '$window', function(taOptions, taRegisterTool, $translate, $window) {
taRegisterTool('test', {
display: '<div class="dropdown" uib-dropdown is-open="isopen">\
<div class="dropdown-toggle" ng-disabled="isDisabled()" uib-dropdown-toggle>\
<span>{{ "ADD_A_VARIABLE" | translate }}</span>\
<b class="caret"></b>\
</div>\
<ul class="dropdown-menu">\
<li ng-repeat="field in $root.myform.form_fields" ng-click="onClickField(field._id, field.title)">\
{{field.title}}\
</li>\
</ul>\
</div>',
onClickField: function(field_id, field_name){
this.$editor().wrapSelection('insertHTML', '<var class="fieldVariable tag" contenteditable="false" id="' + field_id + '">' + field_name + '</var>', true);
},
action: function(){
}
});
taOptions.toolbar[1].push('test');
return taOptions;
}]);
}]);

View File

@ -2,6 +2,6 @@
// 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'
'ngFileUpload', 'ui.date', 'ui.sortable',
'angular-input-stars', 'users', 'ngclipboard', 'textAngular'
]);//, 'colorpicker.module' @TODO reactivate this module