2 * Created by aditya on 6/12/14.
4 (function (angular
, $, _
) {
6 var partialUrl = function (relPath
) {
7 return CRM
.resourceUrls
['civicrm'] + '/partials/abtesting/' + relPath
;
10 var crmMailingAB
= angular
.module('crmMailingAB', ['ngRoute', 'ui.utils', 'ngSanitize']);
12 crmMailingAB
.run(function ($rootScope
, $templateCache
) {
13 $rootScope
.$on('$viewContentLoaded', function () {
14 $templateCache
.removeAll();
19 function ($routeProvider
) {
20 $routeProvider
.when('/mailing/abtesting', {
21 templateUrl
: partialUrl('list.html'),
22 controller
: 'ABListingCtrl',
24 mailingABList: function ($route
, crmApi
) {
25 return crmApi('MailingAB', 'get', {});
29 $routeProvider
.when('/mailing/abtesting/report/:id', {
30 templateUrl
: partialUrl('report.html'),
31 controller
: 'ReportCtrl',
33 selectedABTest: function ($route
, crmApi
) {
34 return crmApi('MailingAB', 'getsingle', {id
: $route
.current
.params
.id
});
38 $routeProvider
.when('/mailing/abtesting/:id', {
39 templateUrl
: partialUrl('main.html'),
40 controller
: 'crmABTestingTabsCtrl',
42 selectedABTest: function ($route
, crmApi
) {
43 if ($route
.current
.params
.id
!== 'new') {
45 return crmApi('MailingAB', 'getsingle', {id
: $route
.current
.params
.id
});
48 //created_id has been set to my id. Does not save without created_id. Needs to made generic based on the user
49 return { just_created
: "1"
58 //-----------------------------------------
59 // Add a new record by name.
60 // Ex: <crmAddName crm-options="['Alpha','Beta','Gamma']" crm-var="newItem" crm-on-add="callMyCreateFunction(newItem)" />
62 * This controler lists the existing ABtests
63 * used on /partials/abtesting/list.html
64 * @returns mailingABList - object that contains the existing AB mailings
65 * @returns testing_criteria - array that has the name of the different test types
67 crmMailingAB
.controller('ABListingCtrl', function ($scope
, crmApi
, mailingABList
) {
68 $scope
.mailingABList
= mailingABList
.values
;
69 $scope
.testing_criteria
= {
72 '3': "Two different emails"
76 crmMailingAB
.controller('ReportCtrl', function ($scope
, crmApi
, selectedABTest
, $location
) {
85 $scope
.graphload
= false;
86 if (selectedABTest
.winner_criteria_id
== 1) {
87 $scope
.winnercriteria
= "Open";
90 if (selectedABTest
.winner_criteria_id
== 2) {
91 $scope
.winnercriteria
= "Total Unique Clicks";
94 if (selectedABTest
.winner_criteria_id
== 3) {
95 $scope
.winnercriteria
= "Total Clicks on a particular link";
100 $scope
.copyatoc = function () {
101 var res
= crmApi('Mailing', 'get', {id
: selectedABTest
.mailing_id_a
});
102 res
.success(function (data
) {
103 for (var key
in data
.values
) {
104 var mail
= data
.values
[key
];
106 mail
.id
= selectedABTest
.mailing_id_c
;
107 crmApi('Mailing', 'create', mail
);
109 $location
.path('mailing/abtesting');
112 $scope
.sendc = function () {
113 var res
= crmApi('Mailing', 'get', {id
: selectedABTest
.mailing_id_b
});
114 res
.success(function (data
) {
115 for (var key
in data
.values
) {
116 var mail
= data
.values
[key
];
118 mail
.id
= selectedABTest
.mailing_id_c
;
119 crmApi('Mailing', 'create', mail
);
121 $location
.path('mailing/abtesting');
123 var result
= crmApi('Mailing', 'stats', {mailing_id
: selectedABTest
.mailing_id_a
});
125 result
.success(function (data
) {
127 $scope
.r
.push(data
.values
[selectedABTest
.mailing_id_a
]["Delivered"].toString());
128 $scope
.r
.push(data
.values
[selectedABTest
.mailing_id_a
]["Bounces"].toString());
129 $scope
.r
.push(data
.values
[selectedABTest
.mailing_id_a
]["Unsubscribers"].toString());
130 $scope
.r
.push(data
.values
[selectedABTest
.mailing_id_a
]["Opened"].toString());
131 $scope
.r
.push(data
.values
[selectedABTest
.mailing_id_a
]["Unique Clicks"].toString());
136 result
= crmApi('Mailing', 'stats', {mailing_id
: selectedABTest
.mailing_id_b
});
137 result
.success(function (data
) {
138 $scope
.d
.push(data
.values
[selectedABTest
.mailing_id_b
]["Delivered"].toString());
139 $scope
.d
.push(data
.values
[selectedABTest
.mailing_id_b
]["Bounces"].toString());
140 $scope
.d
.push(data
.values
[selectedABTest
.mailing_id_b
]["Unsubscribers"].toString());
141 $scope
.d
.push(data
.values
[selectedABTest
.mailing_id_b
]["Opened"].toString());
142 $scope
.d
.push(data
.values
[selectedABTest
.mailing_id_b
]["Unique Clicks"].toString());
145 $scope
.aastop
= false;
146 $scope
.asure = function () {
147 $scope
.aastop
= true;
149 $scope
.bbstop
= false;
150 $scope
.bsure = function () {
151 $scope
.bbstop
= true;
156 for (i
= 1; i
<= numdiv
; i
++) {
157 var result
= crmApi('MailingAB', 'graph_stats', {id
: selectedABTest
.id
, split_count
: numdiv
, split_count_select
: i
});
158 result
.success(function (data
) {
161 for (var key
in data
.values
.A
) {
164 var t
= data
.values
.A
[temp
].time
.split(" ");
167 var day
= t
[1].substr(0, t
[1].length
- 3);
169 var t1
= t
[4].split(":");
178 hour
= parseInt(hur
) + 12;
183 var t1
= t
[3].split(":");
192 hour
= parseInt(hur
) + 12;
236 var tp
= new Date(year
, month
, day
, hour
, min
, 0, 0);
237 $scope
.graph_data
[temp
- 1] = {
239 x
: data
.values
.A
[temp
].count
,
240 y
: data
.values
.B
[temp
].count
243 if (keep_cnt
== numdiv
) {
244 $scope
.graphload
= true;
246 var data
= $scope
.graph_data
;
248 // set up a colour variable
249 var color
= d3
.scale
.category10();
251 // map one colour each to x, y and z
252 // keys grabs the key value or heading of each key value pair in the json
254 color
.domain(d3
.keys(data
[0]).filter(function (key
) {
255 return key
!== "time";
258 // create a nested series for passing to the line generator
259 // it's best understood by console logging the data
260 var series
= color
.domain().map(function (name
) {
263 values
: data
.map(function (d
) {
272 // Set the dimensions of the canvas / graph
279 width
= 550 - margin
.left
- margin
.right
,
280 height
= 350 - margin
.top
- margin
.bottom
;
283 //var x = d3.time.scale().range([0, width]).domain([0,10]);
284 var x
= d3
.time
.scale().range([0, width
]);
285 var y
= d3
.scale
.linear().range([height
, 0]);
288 var xAxis
= d3
.svg
.axis().scale(x
)
289 .orient("bottom").ticks(10);
291 var yAxis
= d3
.svg
.axis().scale(y
)
292 .orient("left").ticks(5);
295 // Note you plot the time / score pair from each key you created ealier
296 var valueline
= d3
.svg
.line()
304 // Adds the svg canvas
305 var svg
= d3
.select("#linegraph")
307 .attr("width", width
+ margin
.left
+ margin
.right
)
308 .attr("height", height
+ margin
.top
+ margin
.bottom
)
310 .attr("transform", "translate(" + margin
.left
+ "," + margin
.top
+ ")");
312 // Scale the range of the data
313 x
.domain(d3
.extent(data
, function (d
) {
317 // note the nested nature of this you need to dig an additional level
319 d3
.min(series
, function (c
) {
320 return d3
.min(c
.values
, function (v
) {
324 d3
.max(series
, function (c
) {
325 return d3
.max(c
.values
, function (v
) {
330 svg
.append("text") // text label for the x axis
331 .attr("x", width
/ 2)
332 .attr("y", height
+ margin
.bottom
)
333 .style("text-anchor", "middle")
336 svg
.append("text") // text label for the x axis
337 .style("text-anchor", "middle")
338 .text($scope
.winnercriteria
).attr("transform",function (d
) {
340 }).attr("x", -height
/ 2)
343 // create a variable called series and bind the date
344 // for each series append a g element and class it as series for css styling
345 var series
= svg
.selectAll(".series")
348 .attr("class", "series");
350 // create the path for each series in the variable series i.e. x, y and z
351 // pass each object called x, y nad z to the lne generator
352 series
.append("path")
353 .attr("class", "line")
354 .attr("d", function (d
) {
355 // console.log(d); // to see how d3 iterates through series
356 return valueline(d
.values
);
358 .style("stroke", function (d
) {
359 return color(d
.name
);
363 svg
.append("g") // Add the X Axis
364 .attr("class", "x axis")
365 .attr("transform", "translate(0," + height
+ ")")
368 .attr("transform", function (d
) {
369 return "rotate(-30)";
373 svg
.append("g") // Add the Y Axis
374 .attr("class", "y axis")
379 console
.log($scope
.graph_data
);
382 crmMailingAB
.controller('crmABTestingTabsCtrl', function ($scope
, crmApi
, selectedABTest
, $sce
) {
383 $scope
.partialUrl
= partialUrl
;
386 $scope
.currentABTest
= selectedABTest
;
387 $scope
.groups
= CRM
.crmMailing
.groupNames
;
388 $scope
.mailList
= CRM
.crmMailing
.civiMails
;
389 $scope
.eMailing
= CRM
.crmMailing
.emailAdd
;
390 $scope
.tmpList
= CRM
.crmMailing
.mesTemplate
;
391 $scope
.mailingGrp
= CRM
.crmMailing
.mailGrp
;
392 $scope
.headerfooter
= CRM
.crmMailing
.headerfooterList
;
393 $scope
.sparestuff
= {};
394 $scope
.sparestuff
.emailadd
= "";
395 $scope
.sparestuff
.winnercriteria
= "";
396 $scope
.sparestuff
.isnew
= false;
397 $scope
.sparestuff
.allgroups
= "";
399 $scope
.preventsubmit
= false;
402 mltokens
= CRM
.crmMailing
.mailTokens
;
403 if ($scope
.currentABTest
.declare_winning_time
!= null) {
404 $scope
.ans
= $scope
.currentABTest
.declare_winning_time
.split(" ");
405 $scope
.currentABTest
.date
= $scope
.ans
[0];
406 $scope
.currentABTest
.time
= $scope
.ans
[1];
410 if ($scope
.currentABTest
.just_created
!= 1) {
411 $scope
.abId
= $scope
.currentABTest
.id
;
412 $scope
.sparestuff
.isnew
= false;
414 var abmailA
= crmApi('Mailing', 'getsingle', {id
: $scope
.currentABTest
.mailing_id_a
});
415 var abmailB
= crmApi('Mailing', 'getsingle', {id
: $scope
.currentABTest
.mailing_id_b
});
416 var abmailC
= crmApi('Mailing', 'getsingle', {id
: $scope
.currentABTest
.mailing_id_c
});
417 abmailA
.success(function (data
) {
418 if (data
.is_error
== 0) {
422 abmailB
.success(function (data
) {
423 if (data
.is_error
== 0) {
427 abmailC
.success(function (data
) {
428 if (data
.is_error
== 0) {
436 $scope
.sparestuff
.isnew
= true;
442 $scope
.sendtest
= false;
443 if (typeof $scope
.mailA
== 'undefined') {
446 if (typeof $scope
.mailB
== 'undefined') {
449 if (typeof $scope
.mailB
== 'undefined') {
455 { name
: 'Subject Lines', url
: partialUrl('subject_lines.html'), val
: 1},
456 { name
: 'From Name', url
: partialUrl('from_name.html'), val
: 2},
457 { name
: 'Two different Emails', url
: partialUrl('two_emails.html'), val
: 3}
460 if ($scope
.currentABTest
.just_created
!= 1) {
461 $scope
.sparestuff
.template
= $scope
.templates
[$scope
.currentABTest
.testing_criteria_id
- 1];
464 $scope
.sparestuff
.template
= $scope
.templates
[0];
468 $scope
.deliberatelyTrustDangerousSnippeta = function () {
469 return $sce
.trustAsHtml($scope
.sparestuff
.previewa
);
472 $scope
.deliberatelyTrustDangerousSnippetb = function () {
473 return $sce
.trustAsHtml($scope
.sparestuff
.previewb
);
477 $scope
.max_tab
= ($scope
.sparestuff
.isnew
== true) ? 0 : 4;
479 $scope
.campaign_clicked = function () {
480 if ($scope
.max_tab
>= 0) {
485 $scope
.compose_clicked = function () {
486 if ($scope
.max_tab
>= 1) {
490 $scope
.rec_clicked = function () {
491 if ($scope
.max_tab
>= 2) {
495 $scope
.preview_clicked = function () {
496 if ($scope
.max_tab
>= 3) {
501 $scope
.preview
= false;
502 $scope
.slide_value
= 0;
504 $scope
.setifyes = function (val
) {
505 $scope
.ifyes
= val
== 1;
508 /* $scope.reply = function () {
509 if ($scope.trackreplies == 0) {
510 $scope.trackreplies = 1;
513 $scope.trackreplies = 0;
514 $scope.mailA.forward_replies = 0;
515 $scope.mailA.auto_responder = 0;
519 $scope
.isAuto = function (au
) {
520 return au
.component_type
== "Reply";
523 $scope
.trackr = function (trackreplies
) {
524 return trackreplies
== "1";
527 $scope
.sendTestMailing = function () {
528 $scope
.sendtest
= true;
531 $scope
.isHeader = function (hf
) {
532 return hf
.component_type
== "Header";
534 //filter so we only get footers from mailing component
535 $scope
.isFooter = function (f
) {
536 return f
.component_type
== "Footer";
539 $scope
.send_date
= "01/01/2000";
542 $scope
.savea = function (dat
) {
544 var result
= crmApi('Mailing', 'create', dat
, true);
545 result
.success(function (data
) {
546 if (data
.is_error
== 0) {
547 $scope
.mailA
.id
= data
.id
;
548 $scope
.currentABTest
.mailing_id_a
= $scope
.mailA
.id
;
553 $scope
.append_mails = function () {
554 crmApi('MailingAB', 'create', {
556 mailing_id_a
: $scope
.mailA
.id
,
557 mailing_id_b
: $scope
.mailB
.id
,
558 mailing_id_c
: $scope
.mailC
.id
560 $scope
.currentABTest
.id
= $scope
.abId
;
563 $scope
.saveb = function (dat
) {
564 var result
= crmApi('Mailing', 'create', dat
, true);
565 result
.success(function (data
) {
566 if (data
.is_error
== 0) {
567 $scope
.mailB
.id
= data
.id
;
568 $scope
.currentABTest
.mailing_id_b
= $scope
.mailB
.id
;
569 //$scope.append_mails();
574 $scope
.savec = function (dat
) {
575 var result
= crmApi('Mailing', 'create', dat
, true);
577 result
.success(function (data
) {
578 if (data
.is_error
== 0) {
579 $scope
.mailC
.id
= data
.id
;
580 $scope
.currentABTest
.mailing_id_c
= $scope
.mailC
.id
;
581 $scope
.append_mails();
586 $scope
.sparestuff
.previewa
= "";
587 $scope
.pre = function () {
588 $scope
.preview
= true;
591 $scope
.init = function (par
) {
593 $scope
.sparestuff
.template
.url
= partialUrl('from_name.html');
597 $scope
.sparestuff
.template
.url
= partialUrl('subject_lines.html');
600 $scope
.sparestuff
.template
.url
= partialUrl('two_emails.html');
603 $scope
.whatnext
= par
.toString();
606 $scope
.tab_upd = function () {
607 $scope
.tab_val
= $scope
.tab_val
+ 1;
608 $scope
.max_tab
= Math
.max($scope
.tab_val
, $scope
.max_tab
);
611 $scope
.tab_upd_dec = function () {
612 $scope
.tab_val
= $scope
.tab_val
- 1;
615 $scope
.setdate = function (par
) {
616 $scope
.send_date
= par
;
621 $scope
.testmailid
= "";
622 $scope
.incGroup
= [];
623 $scope
.excGroup
= [];
624 $scope
.incGroupids
= [];
625 $scope
.excGroupids
= [];
627 $scope
.create_abtest = function () {
629 $scope
.currentABTest
.testing_criteria_id
= $scope
.sparestuff
.template
.val
;
631 if ($scope
.abId
== "") {
632 result
= crmApi('MailingAB', 'create', {name
: $scope
.currentABTest
.name
, testing_criteria_id
: $scope
.sparestuff
.template
.val
});
635 if (typeof $scope
.currentABTest
.mailing_id_a
== 'undefined') {
636 result
= crmApi('MailingAB', 'create', {name
: $scope
.currentABTest
.name
, id
: $scope
.abId
, testing_criteria_id
: $scope
.sparestuff
.template
.val
});
639 result
= crmApi('MailingAB', 'create', {name
: $scope
.currentABTest
.name
, id
: $scope
.abId
, testing_criteria_id
: $scope
.sparestuff
.template
.val
, mailing_id_a
: $scope
.currentABTest
.mailing_id_a
, mailing_id_b
: $scope
.currentABTest
.mailing_id_b
});
643 result
.success(function (data
) {
644 if (data
.is_error
== 0) {
645 $scope
.abId
= data
.id
;
649 $scope
.tokenfunc = function (elem
, e
, chng
) {
650 var msg
= document
.getElementById(elem
).value
;
651 var cursorlen
= document
.getElementById(elem
).selectionStart
;
652 var textlen
= msg
.length
;
653 document
.getElementById(elem
).value
= msg
.substring(0, cursorlen
) + e
.val
+ msg
.substring(cursorlen
, textlen
);
654 chng
= msg
.substring(0, cursorlen
) + e
.val
+ msg
.substring(cursorlen
, textlen
);
655 var cursorPos
= (cursorlen
+ e
.val
.length
);
656 document
.getElementById(elem
).selectionStart
= cursorPos
;
657 document
.getElementById(elem
).selectionEnd
= cursorPos
;
658 document
.getElementById(elem
).focus();
661 $scope
.sparestuff
.ingrps
= "";
662 $scope
.sparestuff
.excgrps
= "";
663 $scope
.a_b_update = function () {
664 $scope
.tp1
.include
= $scope
.incGroupids
;
665 $scope
.tp1
.exclude
= $scope
.excGroupids
;
666 console
.log($scope
.tp1
);
667 crmApi('MailingAB', 'recipients_update', {
668 id
: $scope
.currentABTest
.id
,
672 var resulta
= crmApi('Mailing', 'preview', {id
: $scope
.currentABTest
.mailing_id_a
});
674 resulta
.success(function (data
) {
675 if (data
.is_error
== 0) {
676 $scope
.sparestuff
.previewa
= data
.values
.html
;
680 resulta
= crmApi('Mailing', 'preview', {id
: $scope
.currentABTest
.mailing_id_b
});
682 resulta
.success(function (data
) {
683 if (data
.is_error
== 0) {
684 $scope
.sparestuff
.previewb
= data
.values
.html
;
688 $scope
.startabtest = function () {
689 if (typeof $scope
.sparestuff
.date
== 'undefined') {
690 $scope
.sparestuff
.date
= 'now';
692 crmApi('MailingAB', 'send_mail', {id
: $scope
.abId
,
693 scheduled_date
: $scope
.sparestuff
.date
, scheduled_date_time
: $scope
.currentABTest
.latertime
});
696 angular
.forEach($scope
.incGroup
, function (value
) {
697 $scope
.sparestuff
.ingrps
+= value
.toString() + ", ";
699 angular
.forEach($scope
.excGroup
, function (value
) {
700 $scope
.sparestuff
.excgrps
+= value
.toString() + ", ";
702 if ($scope
.sparestuff
.ingrps
.length
!= 0) {
703 $scope
.sparestuff
.ingrps
= $scope
.sparestuff
.ingrps
.substr(0, $scope
.sparestuff
.ingrps
.length
- 2);
705 if ($scope
.sparestuff
.excgrps
.length
!= 0) {
706 $scope
.sparestuff
.excgrps
= $scope
.sparestuff
.excgrps
.substr(0, $scope
.sparestuff
.excgrps
.length
- 2);
710 $scope
.update_abtest = function () {
711 $scope
.currentABTest
.declare_winning_time
= $scope
.currentABTest
.date
+ " " + $scope
.currentABTest
.time
;
712 crmApi('MailingAB', 'create', {
714 testing_criteria_id
: $scope
.sparestuff
.template
.val
,
715 mailing_id_a
: $scope
.currentABTest
.mailing_id_a
,
716 mailing_id_b
: $scope
.currentABTest
.mailing_id_b
,
717 mailing_id_c
: $scope
.currentABTest
.mailing_id_c
,
718 specific_url
: $scope
.currentABTest
.acturl
,
719 winner_criteria_id
: $scope
.currentABTest
.winner_criteria_id
,
720 group_percentage
: $scope
.currentABTest
.group_percentage
,
721 declare_winning_time
: $scope
.currentABTest
.declare_winning_time
724 $scope
.currentABTest
.latertime
= "";
725 $scope
.tmp = function (tst
, aorb
) {
727 $scope
.mailA
.msg_template_id
= tst
;
728 if ($scope
.mailA
.msg_template_id
== null) {
729 $scope
.mailA
.body_html
= "";
730 $scope
.mailA
.subject
= "";
733 for (var a
in $scope
.tmpList
) {
734 if ($scope
.tmpList
[a
].id
== $scope
.mailA
.msg_template_id
) {
735 $scope
.mailA
.body_html
= $scope
.tmpList
[a
].msg_html
;
736 if (typeof $scope
.mailA
.subject
== 'undefined' || $scope
.mailA
.subject
.length
== 0) {
737 $scope
.mailA
.subject
= $scope
.tmpList
[a
].msg_subject
;
745 $scope
.mailB
.msg_template_id
= tst
;
746 if ($scope
.mailB
.msg_template_id
== null) {
747 $scope
.mailB
.body_html
= "";
748 $scope
.mailB
.subject
= "";
751 for (var a
in $scope
.tmpList
) {
752 if ($scope
.tmpList
[a
].id
== $scope
.mailB
.msg_template_id
) {
753 $scope
.mailB
.body_html
= $scope
.tmpList
[a
].msg_html
;
754 if (typeof $scope
.mailB
.subject
== 'undefined' || $scope
.mailB
.subject
.length
== 0) {
755 $scope
.mailB
.subject
= $scope
.tmpList
[a
].msg_subject
;
763 $scope
.mailA
.msg_template_id
= tst
;
764 if ($scope
.mailA
.msg_template_id
== null) {
765 $scope
.mailA
.body_html
= "";
766 $scope
.mailA
.subject
= "";
769 for (var a
in $scope
.tmpList
) {
770 if ($scope
.tmpList
[a
].id
== $scope
.mailA
.msg_template_id
) {
771 $scope
.mailA
.body_html
= $scope
.tmpList
[a
].msg_html
;
772 if (typeof $scope
.mailA
.subject
== 'undefined' || $scope
.mailA
.subject
.length
== 0) {
773 $scope
.mailA
.subject
= $scope
.tmpList
[a
].msg_subject
;
779 $scope
.mailB
.msg_template_id
= tst
;
780 if ($scope
.mailB
.msg_template_id
== null) {
781 $scope
.mailB
.body_html
= "";
782 $scope
.mailB
.subject
= "";
786 for (var a
in $scope
.tmpList
) {
787 if ($scope
.tmpList
[a
].id
== $scope
.mailB
.msg_template_id
) {
788 $scope
.mailB
.body_html
= $scope
.tmpList
[a
].msg_html
;
789 if (typeof $scope
.mailB
.subject
== 'undefined' || $scope
.mailB
.subject
.length
== 0) {
790 $scope
.mailB
.subject
= $scope
.tmpList
[a
].msg_subject
;
800 /*$scope.tmp = function (tst){
801 $scope.currentMailing.msg_template_id=tst;
802 console.log($scope.currentMailing.msg_template_id+ "sasas");
803 if($scope.currentMailing.msg_template_id == null){
804 $scope.currentMailing.body_html="";
805 $scope.currentMailing.subject="";
808 for(var a in $scope.tmpList){
810 if($scope.tmpList[a].id==$scope.currentMailing.msg_template_id){
811 $scope.currentMailing.body_html=$scope.tmpList[a].msg_html;
812 console.log($scope.tmpList[a].msg_subject);
813 $scope.currentMailing.subject=$scope.tmpList[a].msg_subject;
814 console.log($scope.currentMailing.subject);
821 $scope
.$watch('preview', function () {
822 if ($scope
.preview
== true) {
823 $('#prevmail').dialog({
824 title
: 'Preview Mailing',
833 of: $(".crmABTestingAllTabs")
837 $scope
.preview
= false;
842 $("#prevmail").dialog('option', 'position', [300, 50]);
847 $scope
.call = function () {
849 crmApi('Mailing', 'send_test', {
850 mailing_id
: $scope
.currentABTest
.mailing_id_a
,
851 test_email
: $scope
.sparestuff
.emailadd
854 crmApi('Mailing', 'send_test', {
855 mailing_id
: $scope
.currentABTest
.mailing_id_b
,
856 test_email
: $scope
.sparestuff
.emailadd
860 $scope
.$watch('sendtest', function () {
861 if ($scope
.sendtest
== true) {
862 $('#sendtest').dialog({
863 title
: 'Send Test Mails',
870 'Send': function () {
872 $scope
.sendtest
= false;
873 $('#sendtest').dialog("close");
878 $scope
.sendtest
= false;
887 crmMailingAB
.directive('nexttab', function () {
889 // Restrict it to be an attribute in this case
892 // responsible for registering DOM listeners as well as updating the DOM
893 link: function (scope
, element
, attrs
) {
895 var tabselector
= $(".crmABTestingAllTabs");
896 tabselector
.tabs(scope
.$eval(attrs
.nexttab
));
898 // disable remaining tabs
899 if (scope
.sparestuff
.isnew
== true) {
900 tabselector
.tabs({disabled
: [1, 2, 3]});
903 $(element
).on("click", function () {
904 if (scope
.tab_val
== 0) {
906 scope
.create_abtest();
911 if (scope
.tab_val
== 2) {
912 scope
.update_abtest();
913 if (scope
.currentABTest
.winner_criteria_id
== 1) {
914 scope
.sparestuff
.winnercriteria
= "Open";
918 if (scope
.currentABTest
.winner_criteria_id
== 2) {
919 scope
.sparestuff
.winnercriteria
= " Total Unique Clicks";
923 if (scope
.currentABTest
.winner_criteria_id
== 3) {
924 scope
.sparestuff
.winnercriteria
= "Total Clicks on a particular link";
936 for (var i
= scope
.max_tab
+ 1; i
< 4; i
++) {
939 tabselector
.tabs("option", "disabled", myArray1
);
940 tabselector
.tabs("option", "active", scope
.tab_val
);
947 crmMailingAB
.directive('prevtab', function () {
949 // Restrict it to be an attribute in this case
952 // responsible for registering DOM listeners as well as updating the DOM
953 link: function (scope
, element
, attrs
) {
954 $(element
).on("click", function () {
955 var temp
= scope
.tab_val
- 1;
959 $(".crmABTestingAllTabs").tabs("option", "active", temp
);
967 crmMailingAB
.directive('chsgroup', function () {
970 link: function (scope
, element
, attrs
) {
971 function format(item
) {
973 // return `text` for optgroup
976 // return item template
977 var a
= item
.id
.split(" ");
978 if (a
[1] == "civicrm_group" && a
[2] == "include") {
979 return "<img src='../../sites/all/modules/civicrm/i/include.jpeg' height=12 width=12/>" + " " + "<img src='../../sites/all/modules/civicrm/i/group.png' height=12 width=12/>" + item
.text
;
981 if (a
[1] == "civicrm_group" && a
[2] == "exclude") {
982 return "<img src='../../sites/all/modules/civicrm/i/Error.gif' height=12 width=12/>" + " " + "<img src='../../sites/all/modules/civicrm/i/group.png' height=12 width=12/>" + item
.text
;
984 if (a
[1] == "civicrm_mailing" && a
[2] == "include") {
985 return "<img src='../../sites/all/modules/civicrm/i/include.jpeg' height=12 width=12/>" + " " + "<img src='../../sites/all/modules/civicrm/i/EnvelopeIn.gif' height=12 width=12/>" + item
.text
;
987 if (a
[1] == "civicrm_mailing" && a
[2] == "exclude") {
988 return "<img src='../../sites/all/modules/civicrm/i/Error.gif' height=12 width=12/>" + " " + "<img src='../../sites/all/modules/civicrm/i/EnvelopeIn.gif' height=12 width=12/>" + item
.text
;
995 placeholder
: "Select the groups you wish to include",
996 formatResult
: format
,
997 formatSelection
: format
,
998 escapeMarkup: function (m
) {
1001 }).select2("data", scope
.sparestuff
.allgroups
);
1004 $(element
).on('select2-selecting', function (e
) {
1005 var a
= e
.val
.split(" ");
1007 if (a
[2] == "include") {
1009 for (i
= 3; i
< l
; i
++) {
1013 scope
.incGroup
.push(str
);
1014 scope
.incGroupids
.push(a
[0]);
1020 for (i
= 3; i
< l
; i
++) {
1025 scope
.excGroup
.push(str
);
1026 scope
.excGroupids
.push(a
[0]);
1033 $(element
).on("select2-removed", function (e
) {
1034 if (e
.val
.split(" ")[2] == "exclude") {
1035 var excIndex
= scope
.excGroup
.indexOf(e
.val
.split(" ")[3]);
1036 scope
.excGroup
.splice(excIndex
, 1);
1037 scope
.excGroupids
.splice(excIndex
, 1);
1041 var incIndex
= scope
.incGroup
.indexOf(e
.val
.split(" ")[3]);
1042 scope
.incGroup
.splice(incIndex
, 1);
1043 scope
.incGroupids
.splice(incIndex
, 1);
1053 crmMailingAB
.directive('sliderbar', function () {
1056 link: function (scope
, element
, attrs
) {
1057 if (typeof scope
.currentABTest
.group_percentage
!= 'undefined') {
1058 $(element
).slider({value
: scope
.currentABTest
.group_percentage
});
1060 $(element
).slider({min
: 1});
1062 slide: function (event
, ui
) {
1063 scope
.currentABTest
.group_percentage
= ui
.value
;
1071 crmMailingAB
.directive('datepick', function () {
1074 link: function (scope
, element
, attrs
) {
1075 $(element
).datepicker({
1076 dateFormat
: "dd-mm-yy",
1077 onSelect: function (date
) {
1078 $(".ui-datepicker a").removeAttr("href");
1079 scope
.sparestuff
.date
= date
.toString();
1087 crmMailingAB
.directive('submitform', function () {
1091 link: function (scope
, element
, attrs
) {
1092 $(element
).on("click", function () {
1096 visibility
: scope
.mailA
.visibility
,
1098 subject
: scope
.mailA
.subject
,
1099 msg_template_id
: scope
.mailA
.msg_template_id
== null ? "" : scope
.mailA
.msg_template_id
,
1100 open_tracking
: scope
.mailA
.open_tracking
,
1101 url_tracking
: scope
.mailA
.url_tracking
,
1102 forward_replies
: scope
.mailA
.forward_replies
,
1103 auto_responder
: scope
.mailA
.auto_responder
,
1104 from_name
: scope
.mailA
.from_name
,
1105 from_email
: scope
.mailA
.from_email
,
1106 replyto_email
: scope
.mailA
.replyto_email
,
1107 unsubscribe_id
: scope
.mailA
.unsubscribe_id
,
1108 resubscribe_id
: scope
.mailA
.resubscribe_id
,
1109 body_html
: scope
.mailA
.body_html
,
1110 body_text
: scope
.mailA
.body_text
,
1111 scheduled_date
: scope
.mailA
.scheduled_date
,
1112 scheduled_id
: scope
.mailA
.scheduled_id
,
1113 campaign_id
: scope
.mailA
.campaign_id
== null ? "" : scope
.mailA
.campaign_id
,
1114 header_id
: scope
.mailA
.header_id
,
1115 footer_id
: scope
.mailA
.footer_id
,
1116 is_completed
: scope
.mailA
.is_completed
1119 if (scope
.whatnext
== "3") {
1120 scope
.mailB
.name
= scope
.mailA
.name
;
1121 scope
.mailB
.visibility
= scope
.mailA
.visibility
;
1122 scope
.mailB
.created_id
= scope
.mailA
.created_id
;
1123 scope
.mailB
.subject
= scope
.mailA
.subject
;
1124 scope
.mailB
.msg_template_id
= scope
.mailA
.msg_template_id
== null ? "" : scope
.mailA
.msg_template_id
;
1125 scope
.mailB
.open_tracking
= scope
.mailA
.open_tracking
;
1126 scope
.mailB
.url_tracking
= scope
.mailA
.url_tracking
;
1127 scope
.mailB
.forward_replies
= scope
.mailA
.forward_replies
;
1128 scope
.mailB
.auto_responder
= scope
.mailA
.auto_responder
;
1129 scope
.mailB
.from_name
= scope
.mailA
.from_name
;
1130 scope
.mailB
.replyto_email
= scope
.mailA
.replyto_email
;
1131 scope
.mailB
.unsubscribe_id
= scope
.mailA
.unsubscribe_id
;
1132 scope
.mailB
.resubscribe_id
= scope
.mailA
.resubscribe_id
;
1133 scope
.mailB
.body_html
= scope
.mailA
.body_html
;
1134 scope
.mailB
.body_text
= scope
.mailA
.body_text
;
1135 scope
.mailB
.scheduled_id
= scope
.mailA
.scheduled_id
;
1136 scope
.mailB
.campaign_id
= scope
.mailA
.campaign_id
== null ? "" : scope
.mailA
.campaign_id
;
1137 scope
.mailB
.header_id
= scope
.mailA
.header_id
;
1138 scope
.mailB
.footer_id
= scope
.mailA
.footer_id
;
1139 scope
.mailB
.is_completed
= scope
.mailA
.is_completed
;
1142 if (scope
.whatnext
== "2") {
1143 scope
.mailB
.fromEmail
= scope
.mailA
.fromEmail
;
1144 scope
.mailB
.name
= scope
.mailA
.name
;
1145 scope
.mailB
.visibility
= scope
.mailA
.visibility
;
1146 scope
.mailB
.created_id
= scope
.mailA
.created_id
;
1147 scope
.mailB
.msg_template_id
= scope
.mailA
.msg_template_id
== null ? "" : scope
.mailA
.msg_template_id
;
1148 scope
.mailB
.open_tracking
= scope
.mailA
.open_tracking
;
1149 scope
.mailB
.url_tracking
= scope
.mailA
.url_tracking
;
1150 scope
.mailB
.forward_replies
= scope
.mailA
.forward_replies
;
1151 scope
.mailB
.auto_responder
= scope
.mailA
.auto_responder
;
1152 scope
.mailB
.from_name
= scope
.mailA
.from_name
;
1153 scope
.mailB
.replyto_email
= scope
.mailA
.replyto_email
;
1154 scope
.mailB
.unsubscribe_id
= scope
.mailA
.unsubscribe_id
;
1155 scope
.mailB
.resubscribe_id
= scope
.mailA
.resubscribe_id
;
1156 scope
.mailB
.body_html
= scope
.mailA
.body_html
;
1157 scope
.mailB
.body_text
= scope
.mailA
.body_text
;
1158 scope
.mailB
.scheduled_id
= scope
.mailA
.scheduled_id
;
1159 scope
.mailB
.campaign_id
= scope
.mailA
.campaign_id
== null ? "" : scope
.mailA
.campaign_id
;
1160 scope
.mailB
.header_id
= scope
.mailA
.header_id
;
1161 scope
.mailB
.footer_id
= scope
.mailA
.footer_id
;
1162 scope
.mailB
.is_completed
= scope
.mailA
.is_completed
;
1168 visibility
: scope
.mailB
.visibility
,
1170 subject
: scope
.mailB
.subject
,
1171 msg_template_id
: scope
.mailB
.msg_template_id
== null ? "" : scope
.mailB
.msg_template_id
,
1172 open_tracking
: scope
.mailB
.open_tracking
,
1173 url_tracking
: scope
.mailB
.url_tracking
,
1174 forward_replies
: scope
.mailB
.forward_replies
,
1175 auto_responder
: scope
.mailB
.auto_responder
,
1176 from_name
: scope
.mailB
.from_name
,
1177 from_email
: scope
.mailB
.from_email
,
1178 replyto_email
: scope
.mailB
.replyto_email
,
1179 unsubscribe_id
: scope
.mailB
.unsubscribe_id
,
1180 resubscribe_id
: scope
.mailB
.resubscribe_id
,
1181 body_html
: scope
.mailB
.body_html
,
1182 body_text
: scope
.mailB
.body_text
,
1183 scheduled_id
: scope
.mailB
.scheduled_id
,
1184 campaign_id
: scope
.mailB
.campaign_id
== null ? "" : scope
.mailB
.campaign_id
,
1185 header_id
: scope
.mailB
.header_id
,
1186 footer_id
: scope
.mailB
.footer_id
,
1187 is_completed
: scope
.mailA
.is_completed
1193 visibility
: scope
.mailB
.visibility
,
1195 subject
: scope
.mailB
.subject
,
1196 msg_template_id
: scope
.mailB
.msg_template_id
== null ? "" : scope
.mailB
.msg_template_id
,
1197 open_tracking
: scope
.mailB
.open_tracking
,
1198 url_tracking
: scope
.mailB
.url_tracking
,
1199 forward_replies
: scope
.mailB
.forward_replies
,
1200 auto_responder
: scope
.mailB
.auto_responder
,
1201 from_name
: scope
.mailB
.from_name
,
1202 from_email
: scope
.mailB
.from_email
,
1203 replyto_email
: scope
.mailB
.replyto_email
,
1204 unsubscribe_id
: scope
.mailB
.unsubscribe_id
,
1205 resubscribe_id
: scope
.mailB
.resubscribe_id
,
1206 body_html
: scope
.mailB
.body_html
,
1207 body_text
: scope
.mailB
.body_text
,
1208 campaign_id
: scope
.mailB
.campaign_id
== null ? "" : scope
.mailB
.campaign_id
,
1209 header_id
: scope
.mailB
.header_id
,
1210 footer_id
: scope
.mailB
.footer_id
,
1211 is_completed
: scope
.mailA
.is_completed
,
1212 'api.mailing_job.create': 0
1219 crmMailingAB
.directive('chsdate', function () {
1222 link: function (scope
, element
, attrs
) {
1223 $(element
).datepicker({
1224 dateFormat
: "yy-mm-dd",
1225 onSelect: function (date
) {
1226 $(".ui-datepicker a").removeAttr("href");
1227 scope
.currentABTest
.date
= date
.toString();
1235 crmMailingAB
.directive('prevbutton', function () {
1239 template
: '<div class="crm-submit-buttons" >' +
1240 '<div class = "crm-button crm-button-type-upload crm-button_qf_Contact_upload_view" >' +
1241 '<input type="submit" value="Previous" id="campaignbutton _qf_Contact_upload_view-top" class="btn btn-primary" prevtab={{tab_val}}>' +
1246 crmMailingAB
.directive('groupselect', function () {
1249 link: function (scope
, element
, attrs
) {
1250 $(element
).select2({width
: "200px", data
: mltokens
, placeholder
: "Insert Token"});
1251 $(element
).on('select2-selecting', function (e
) {
1253 scope
.$evalAsync('_resetSelection()');
1254 var a
= $(element
).attr('id');
1255 if (a
== "htgroupcompose") {
1256 scope
.tokenfunc("body_html", e
, scope
.mailA
.body_html
);
1259 if (a
== "htgroupcomposetwob") {
1260 scope
.tokenfunc("twomailbbody_html", e
, scope
.mailB
.body_html
);
1263 if (a
== "htgroupcomposetwoa") {
1264 scope
.tokenfunc("twomailabody_html", e
, scope
.mailA
.body_html
);
1267 if (a
== "textgroupcompose") {
1268 scope
.tokenfunc("body_text", e
, scope
.mailA
.body_text
);
1271 if (a
== "textgroupcomposetwoa") {
1272 scope
.tokenfunc("twomailabody_text", e
, scope
.mailA
.body_text
);
1275 if (a
== "textgroupcomposetwob") {
1276 scope
.tokenfunc("twomailbbody_text", e
, scope
.mailB
.body_text
);
1279 if (a
== "subgroupsuba") {
1280 scope
.tokenfunc("suba", e
, scope
.mailA
.subject
);
1283 if (a
== "subgroupsubb") {
1284 scope
.tokenfunc("subb", e
, scope
.mailB
.subject
);
1287 if (a
== "subgroupfrom") {
1288 scope
.tokenfunc("subfrom", e
, scope
.mailA
.subject
);
1291 if (a
== "subgrouptwoa") {
1292 scope
.tokenfunc("twomaila", e
, scope
.mailA
.subject
);
1295 if (a
== "subgrouptwob") {
1296 scope
.tokenfunc("twomailb", e
, scope
.mailB
.subject
);
1317 crmMailingAB
.directive('stopa', function () {
1320 link: function (scope
, element
, attrs
) {
1321 scope
.$watch('aastop', function () {
1322 if (scope
.aastop
== true) {
1324 title
: 'Confirmation',
1331 'Yes': function () {
1332 scope
.aastop
= false;
1334 $(element
).dialog("close");
1337 scope
.aastop
= false;
1338 $(element
).dialog("close");
1341 close: function () {
1342 scope
.aastop
= false;
1353 crmMailingAB
.directive('stopb', function () {
1356 link: function (scope
, element
, attrs
) {
1358 scope
.$watch('bbstop', function () {
1359 if (scope
.bbstop
== true) {
1361 title
: 'Confirmation',
1368 'Yes': function () {
1369 scope
.bbstop
= false;
1371 $(element
).dialog("close");
1374 scope
.bbstop
= false;
1375 $(element
).dialog("close");
1378 close: function () {
1379 scope
.bbstop
= false;
1391 crmMailingAB
.directive('checktimeentry', function () {
1394 link: function (scope
, element
, attrs
) {
1395 $(element
).timeEntry({show24Hours
: true});
1400 crmMailingAB
.directive('ckedit', function ($parse
) {
1401 CKEDITOR
.disableAutoInline
= true;
1407 link: function (scope
, element
, attrs
, controller
) {
1408 var getter
= $parse(attrs
.ckedit
),
1409 setter
= getter
.assign
;
1411 attrs
.$set('contenteditable', true); // inline ckeditor needs this
1413 attrs
.$set('id', prefix
+ (++counter
));
1417 // Override the normal CKEditor save plugin
1419 CKEDITOR
.plugins
.registered
['save'] =
1421 init: function (editor
) {
1422 editor
.addCommand('save',
1424 modes
: { wysiwyg
: 1, source
: 1 },
1425 exec: function (editor
) {
1426 if (editor
.checkDirty()) {
1427 var ckValue
= editor
.getData();
1428 scope
.$apply(function () {
1429 setter(scope
, ckValue
);
1432 editor
.resetDirty();
1437 editor
.ui
.addButton('Save', { label
: 'Save', command
: 'save', toolbar
: 'document' });
1442 blur: function (e
) {
1443 if (e
.editor
.checkDirty()) {
1444 var ckValue
= e
.editor
.getData();
1445 scope
.$apply(function () {
1446 setter(scope
, ckValue
);
1449 e
.editor
.resetDirty();
1453 options
.extraPlugins
= 'sourcedialog';
1454 options
.removePlugins
= 'sourcearea';
1455 var editorangular
= CKEDITOR
.inline(element
[0], options
); //invoke
1457 scope
.$watch(attrs
.ckedit
, function (value
) {
1458 editorangular
.setData(value
);
1465 })(angular
, CRM
.$, CRM
._
);