PluginProbe
Leyka / 3.17
Leyka v3.17
3.32.3 2.3.2 2.3.3 2.3.4 2.3.5 2.3.6 2.3.6.1 2.3.7 2.3.8 2.3.9 3.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1 3.10 3.11 3.11.1 3.12 3.13 3.14 3.15 3.16 3.17 All 89 releases
leyka / js / public.js

public.js in Leyka 3.17, at js/public.js

680 lines 22.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 jQuery(document).ready(function($){
2
3 // Auto-select the code to embed:
4 $('.embed-code').on('focus.leyka keyup.leyka', function(e){
5
6 var keycode = e.keyCode ? e.keyCode : e.which ? e.which : e.charCode;
7
8 if( !keycode || keycode == 9 ) { // Click or tab
9
10 var $this = $(this);
11 $this.select();
12
13 $this.on('mouseup', function() { // Work around Chrome's little problem
14
15 $this.off('mouseup');
16 return false;
17
18 });
19 }
20 });
21
22 $('.read-only').on('keydown.leyka', function(e){ // Keep the iframe code from manual changing
23
24 if( // Allowed special keys
25 e.keyCode == 9 || // Tab
26 (e.keyCode == 65 && e.ctrlKey) || // Ctrl+A
27 (e.keyCode == 67 && e.ctrlKey) || // Ctrl+C
28 (e.keyCode >= 35 && e.keyCode <= 40) // Home, end, left, right, down, up
29 ) {
30 return; // Let it happen
31 }
32
33 e.preventDefault();
34
35 });
36
37 $('#embed_iframe_w, #embed_iframe_h').keydown(function(e){
38
39 if(e.keyCode == 13) { // Enter pressed - do not let the form be submitted
40
41 e.preventDefault();
42 $(this).change();
43 return;
44
45 }
46
47 if( // Allowed special keys
48 $.inArray(e.keyCode, [46, 8, 9]) != -1 || // Backspace, delete, tab
49 (e.keyCode == 65 && e.ctrlKey) || // Ctrl+A
50 (e.keyCode >= 35 && e.keyCode <= 40) // Home, end, left, right, down, up
51 ) {
52 return; // Let it happen
53 }
54
55 if( !leyka_is_digit_key(e) ){
56 e.preventDefault();
57 }
58
59 }).change(function(e){
60
61 var $this = $(this),
62 $embed_code = $('#campaign-embed-code'),
63 $text = $($embed_code.text());
64
65 $text.attr($this.attr('id') == 'embed_iframe_w' ? 'width' : 'height', $this.val());
66 $('.leyka-embed-preview iframe').attr($this.attr('id') == 'embed_iframe_w' ? 'width' : 'height', $this.val());
67
68 $embed_code.html($text.prop('outerHTML'));
69
70 });
71
72 function leyka_value_length_count(e){
73
74 var $this = $(this),
75 $wrapper = $(this).parents('.leyka-field:first'),
76 length = $this.val().length,
77 max_length = $this.data('max-length');
78
79 if(typeof max_length == 'undefined' || max_length == 0) {
80 return;
81 }
82
83 if(length >= max_length) {
84
85 $wrapper.find('.donation-comment-current-length').html(length);
86 if( // Allowed special keys
87 $.inArray(e.keyCode, [46, 8, 9]) != -1 || // Backspace, delete, tab
88 (e.keyCode == 65 && e.ctrlKey) || // Ctrl+A
89 (e.keyCode == 88 && e.ctrlKey) || // Ctrl+X
90 (e.keyCode == 67 && e.ctrlKey) || // Ctrl+C
91 (e.keyCode == 86 && e.ctrlKey) || // Ctrl+V
92 (e.keyCode >= 35 && e.keyCode <= 40) // Home, end, left, right, down, up
93 ) {
94 $wrapper.find('.donation-comment-current-length').html(length);
95 } else {
96 e.preventDefault();
97 }
98
99 } else if(length < max_length) {
100 $wrapper.find('.donation-comment-current-length').html(length);
101 } else {
102 e.preventDefault();
103 }
104
105 } // input.leyka
106 $(':input.leyka-donor-comment[data-max-length]').on('keydown.leyka keyup.leyka', leyka_value_length_count);
107
108 // Get donation amount currently selected on the given form:
109 function leyka_get_donation_amount($form) {
110
111 var amount = 0,
112 $field = $form.find('input.donate_amount_flex:visible');
113
114 if($field.length && $field.val() > 0) { // Flexible or mixed sum field type
115 amount = $field.val();
116 } else { // Fixed sum field type
117 amount = $form.find('input[name="leyka_donation_amount"]:checked:visible').val();
118 }
119
120 return amount;
121
122 }
123
124 // Get donation currency currently selected on the given form:
125 function leyka_get_donation_currency($form) {
126
127 var currency = '',
128 $field = $form.find('.leyka_donation_currency:visible').find('option:selected');
129
130 if($field.length) {
131 currency = $field.val();
132 } else {
133 currency = $form.find('.leyka_donation_currency', '.currency:visible').val();
134 }
135
136 return currency;
137 }
138
139 // Toggles template behavior:
140 $('.toggle.toggled').find('.leyka-toggle-area').css({display: 'block'});
141
142 $('.leyka-toggle-trigger').on('click.leyka', function(){
143
144 var $this = $(this),
145 toggleCont = $this.parents('.toggle');
146
147 if($this.hasClass('toggle-inactive')) {
148 return;
149 }
150
151 if(toggleCont.hasClass('toggled')) {
152
153 toggleCont.removeClass('toggled');
154 toggleCont.find('.leyka-toggle-area').slideUp('normal', function(){
155 toggleCont.find('.leyka-pm-form .field-error').hide();
156 });
157
158 } else {
159
160 $this.parents('#leyka-payment-form').find('.leyka-payment-option.toggled .leyka-toggle-trigger').click();
161 toggleCont.addClass('toggled');
162 toggleCont.find('.leyka-toggle-area').slideDown('normal');
163 }
164 });
165
166 // Mixed sum fields behavior:
167 $('form.leyka-pm-form').on('click.leyka', 'input[name="leyka_donation_amount"]', function(){
168
169 var $field = $(this),
170 $form = $field.parents('form.leyka-pm-form');
171
172 if($field.attr('type') == 'radio') {
173 $form.find('input.donate_amount_flex:visible').val($field.val());
174 } else if($field.hasClass('donate_amount_flex')) {
175 $form.find('input[name="leyka_donation_amount"]:checked:visible').removeAttr('checked');
176 }
177
178 })
179 .on('keydown.leyka', 'input.donate_amount_flex', function(e){
180
181 if( !leyka_is_digit_key(e, true) ) {
182
183 e.preventDefault();
184 e.stopImmediatePropagation();
185 }
186 });
187
188 // PM switching on Radios template:
189 $('.pm-selector').on('change.leyka', 'input', function(e){
190
191 var $form = $(this).parents('form:first'),
192 sum = leyka_get_donation_amount($form),
193 curr = leyka_get_donation_currency($form),
194 pm_full_id = $(e.target).val(),
195 amount_field_type = $form.find('input.leyka_amount_field_type').val();
196
197 if(sum) {
198 $form.data('amount-last-chosen', sum);
199 } else {
200 sum = $form.data('amount-last-chosen');
201 }
202
203 $form.find('.leyka-pm-selector .active').removeClass('active');
204 $(e.target).parents('li:first').addClass('active');
205
206 $form.find('.field-error').html('').hide(); // Hide the errors of current form before changing to a new one
207
208 var $amount_field_new = $form.find('.pm-amount-field.'+pm_full_id),
209 $amount_field_old = $form.find('.pm-amount-field:visible');
210
211 // Form serialization includes all "leyka_donation_amount" fields, whether they are visible/disabled or not:
212 $amount_field_old.hide();
213 $amount_field_new.show();
214
215 // Selected amount & currency synchronization:
216 if(sum) {
217
218 $amount_field_new.find('.'+curr+'.amount-variants-container')
219 .find('input[name="leyka_donation_amount"][value="'+sum+'"]:radio')
220 .attr('checked', 'checked');
221 $amount_field_new.find('input.donate_amount_flex').val(sum);
222
223 }
224
225 $form.find('select.leyka_donation_currency > option[value="'+curr+'"]').attr('selected', 'selected');
226
227 $form.find('.leyka-hidden-fields > .pm-hidden-field:visible').hide();
228 $form.find('.leyka-hidden-fields > .pm-hidden-field.'+pm_full_id).show();
229
230 var $pm_fields_old = $form.find('.leyka-pm-fields:visible'),
231 $pm_fields_new = $form.find('.leyka-pm-fields.'+pm_full_id),
232 fields_vals = {}; // To populate form fields' values between different PMs
233
234 $pm_fields_old.find('.leyka-user-data :input:visible:not(:button,:submit)').each(function(){
235
236 var $this = $(this);
237 fields_vals[$this.attr('name')] = $this.val();
238
239 });
240
241 $pm_fields_old.hide();
242 $form.find('.leyka-pm-desc:visible').hide();
243
244 // Prevent a submission of an inactive form's fields:
245 $form.find('.amount-selector :input').attr('disabled', 'disabled');
246 $form.find('.leyka-pm-fields :input').attr('disabled', 'disabled');
247
248 $amount_field_new.find('.'+curr+'.amount-variants-container').find(':input:disabled').removeAttr('disabled');
249 $amount_field_new.find('.currency').find(':input:disabled').removeAttr('disabled');
250 $pm_fields_new.find(':input:disabled').removeAttr('disabled');
251
252 // Re-populate a form fields' values from a previous PM:
253 $pm_fields_new.find('.leyka-user-data :input:not(:button,:submit)').each(function(){
254
255 var $this = $(this);
256 if( fields_vals[$this.attr('name')] ) {
257 $this.val( fields_vals[$this.attr('name')] );
258 }
259 });
260 $pm_fields_new.show();
261 $form.find('.leyka-pm-desc.'+pm_full_id).show();
262 })
263 .find('input[name="leyka_payment_method"]:checked').change();
264
265 // Switches of currency:
266 $('select.leyka_donation_currency', '.amount-selector').on('change.leyka', function(e){
267
268 e.stopImmediatePropagation();
269
270 var $this = $(this),
271 $form = $this.parents('form:first'),
272 $pm_variants = $form.find('.pm-selector').find('.leyka-pm-variant'),
273 currency = $this.find('option:selected').val();
274
275 $pm_variants.each(function(){ // Toggle PMs in their list
276
277 var $this = $(this); // PM option line
278 $this.find('input[data-curr-supported*='+currency+']').length ? $this.show() : $this.hide();
279 });
280
281 // Hide the errors of current amoount before changing to a new one:
282 $form.find('.leyka_donation_amount-error.field-error').html('').hide();
283
284 // Toggle the donation amount variants for a different currencies:
285 $form.find('.amount-variants-container').hide().find('input').attr('disabled', 'disabled');
286 $form.find('.amount-variants-container.'+currency).show().find('input').removeAttr('disabled');
287 });
288
289 function leyka_validate_required_field($form, $field) {
290
291 var field_is_valid = true;
292
293 if($field.attr('type') === 'checkbox') {
294
295 var $required_checkbox_fields = $form.find('input[type="checkbox"].required:visible:not(:checked)');
296 if( !$field.prop('checked') || $required_checkbox_fields.length ) {
297
298 field_is_valid = false;
299 $form.find('.'+$field.attr('name')+'-error').html(leyka.checkbox_check_required_msg).show();
300
301 } else if( !$required_checkbox_fields.length ) {
302 $form.find('.'+$field.attr('name')+'-error').html('').hide();
303 }
304
305 } else if($field.attr('type') === 'text' && $field.attr('name') !== 'leyka_donation_amount') {
306
307 if( !$field.val().length ) {
308
309 field_is_valid = false;
310 $form.find('.'+$field.attr('name')+'-error').html(leyka.text_required_msg).show();
311
312 } else {
313 $form.find('.'+$field.attr('name')+'-error').html('').hide();
314 }
315 }
316
317 return field_is_valid;
318
319 }
320
321 function leyka_validate_donation_form($form) {
322
323 var is_valid = true;
324
325 /** @var leyka object Localization strings */
326
327 var pm_full_id = leyka_get_pm_full_id($form),
328 amount_field_type = $form.find('input.leyka_amount_field_type').val(),
329 $amount_flex_field = $form.find('input.donate_amount_flex:visible'),
330 $amount_fixed_field = $form.find('input[name="leyka_donation_amount"]:checked:visible'),
331 $amount_field = amount_field_type == 'flexible' ?
332 $amount_flex_field : (
333 amount_field_type == 'fixed' ?
334 $amount_fixed_field : ($amount_fixed_field.length ? $amount_fixed_field : $amount_flex_field)
335 ),
336 $error;
337
338 $(':input:visible', $form).each(function(){
339
340 var $field = $(this),
341 field_is_valid = true;
342
343 // Validate field requireness:
344 if($field.hasClass('required') && !leyka_validate_required_field($form, $field)) {
345 field_is_valid = false;
346 }
347
348 if(field_is_valid) { // Validate the other field requirements
349
350 if($field.prop('type') === 'text' && $field.hasClass('email')) {
351
352 if( !$field.val().length ) {
353
354 field_is_valid = false;
355 $form.find('.'+$field.attr('name')+'-error').html(leyka.email_required_msg).show();
356
357 } else {
358
359 var value_tmp = $.trim($field.val());
360
361 if( !is_email(value_tmp) ) {
362
363 field_is_valid = false;
364 $form.find('.'+$field.attr('name')+'-error').html(leyka.email_invalid_msg).show();
365
366 } else {
367 $form.find('.'+$field.attr('name')+'-error').html('').hide();
368 }
369
370 }
371
372 } else if($field.attr('type') === 'text' && $field.hasClass('non-email')) {
373
374 if( !$field.val().length ) {
375
376 field_is_valid = false;
377 $form.find('.'+$field.attr('name')+'-error').html(leyka.text_required_msg).show();
378
379 } else if(is_email($field.val())) {
380
381 field_is_valid = false;
382 $form.find('.'+$field.attr('name')+'-error').html(leyka.must_not_be_email_msg).show();
383
384 } else {
385 $form.find('.'+$field.attr('name')+'-error').html('').hide();
386 }
387
388 } else if($field.data('max-length')) {
389
390 if($field.val().length > $field.data('max-length')) {
391
392 field_is_valid = false;
393 $form.find('.'+$field.attr('name')+'-error').html(leyka.value_too_long_msg).show();
394
395 } else {
396 $form.find('.'+$field.attr('name')+'-error').html('').hide();
397 }
398
399 }
400 }
401
402 if( !field_is_valid ) {
403 is_valid = false;
404 }
405
406 });
407
408 var amount_is_valid = true;
409 $error = $form.find('.leyka_donation_amount-error', '.leyka-pm-fields.'+pm_full_id);
410 if( !$amount_field.val() || parseInt($amount_field.val()) <= 0 || isNaN($amount_field.val()) ) {
411
412 amount_is_valid = is_valid = false;
413 $error.html(leyka.correct_donation_amount_required_msg).show();
414
415 } else {
416 $error.html('').hide();
417 }
418
419 var currency = '',
420 currency_label = '';
421
422 if($('.leyka_donation_currency option').length) {
423
424 currency = $form.find('.leyka_donation_currency option:selected').val();
425 currency_label = $form.find('.leyka_donation_currency option:selected').data('currency-label');
426
427 } else {
428
429 currency = $form.find('.leyka_donation_currency').val();
430 currency_label = $form.find('.leyka_donation_currency').data('currency-label');
431 }
432
433 var top_amount = parseInt($form.find('input[name="top_'+currency+'"]').val()),
434 bottom_amount = parseInt($form.find('input[name="bottom_'+currency+'"]').val());
435
436 if(amount_is_valid && $amount_field.val() > top_amount) {
437
438 is_valid = false;
439 $error.html(leyka.donation_amount_too_great_msg.replace('%s', top_amount+' '+currency_label)).show();
440
441 } else if(amount_is_valid && $amount_field.val() < bottom_amount) {
442
443 is_valid = false;
444 $error.html(leyka.donation_amount_too_small_msg.replace('%s', bottom_amount+' '+currency_label)).show();
445
446 } else if(amount_is_valid) {
447 $error.html('').hide();
448 }
449
450 $form.trigger('validate-custom-form-fields.leyka', [$form]);
451 if($form.data('custom-fields-are-invalid')) {
452
453 is_valid = false;
454 $form.removeData('custom-fields-are-invalid');
455 }
456
457 return is_valid;
458
459 }
460
461 $(document).on('submit.leyka', 'form.leyka-pm-form', function(e){
462
463 var $form = $(this);
464
465 if( !$form.hasClass('leyka-no-validation') && !leyka_validate_donation_form($form) ) {
466
467 e.preventDefault();
468 e.stopImmediatePropagation();
469
470 } else {
471
472 $(':input:visible', $form).each(function() {
473
474 var $field = $(this);
475
476 if($field.prop('type') === 'text' || $field.prop('type') === 'email') {
477 $field.val( $.trim($field.val()) );
478 } else if($field.prop('tagName') === 'textarea') {
479 $field.text( $.trim($field.text()) );
480 }
481
482 });
483
484 if(typeof ga === 'function') { // GA Events on form submit
485
486 var label = 'undefined_payment_method',
487 action = 'undefined_campaign';
488
489 if($form.find('[name="leyka_ga_payment_method"]').length) {
490 label = $form.find('[name="leyka_ga_payment_method"]').prop('value');
491 }
492
493 if($form.find('[name="leyka_ga_campaign_title"]').length) {
494 action = $form.find('[name="leyka_ga_campaign_title"]').prop('value');
495 }
496
497 ga('send', 'event', 'click_donation_button', action, label, 1);
498
499 }
500
501 }
502
503 });
504
505 // Terms of Agreement modal:
506 $('.leyka-oferta-text').easyModal({
507 top: 100,
508 autoOpen: false,
509 closeButtonClass: '.leyka-modal-close',
510 onOpen: function() {
511 $('html').addClass('leyka-js--open-modal');
512 },
513 onClose: function() {
514 $('html').removeClass('leyka-js--open-modal');
515 }
516 });
517
518 $('.leyka-legal-terms-trigger').on('click.leyka', function(e){
519
520 e.preventDefault();
521 $( $(this).data('terms-content') ).trigger('openModal');
522
523 });
524
525 // Donors list width detection:
526 function leyka_widths() {
527 $('.leyka-donors-list').each(function(){
528
529 var w = $(this).width();
530 if (parseInt(w) > 400) {
531 $(this).addClass('wide');
532 } else {
533 $(this).removeClass('wide');
534 }
535 });
536
537 $('.leyka-scale').each(function(){
538
539 var $this = $(this),
540 w = $(this).width();
541
542 if(parseInt(w) > 500) {
543 $this.addClass('wide');
544 } else {
545 $this.removeClass('wide');
546 }
547 });
548
549 $('.leyka-campaign-card').each(function(){
550
551 var w = $(this).width();
552
553 if(parseInt(w) > 500) {
554 $(this).addClass('wide');
555 } else {
556 $(this).removeClass('wide');
557 }
558 });
559
560 $('.leyka-campaign-list-item.has-thumb').each(function(){
561
562 var w = $(this).width();
563
564 if(parseInt(w) < 280) {
565 $(this).addClass('narrow');
566 } else {
567 $(this).removeClass('narrow');
568 }
569 });
570 }
571
572 leyka_widths();
573 $(window).resize(function(){
574 leyka_widths();
575 });
576
577 // Scroll:
578 $('a.leyka-scroll').on('click.leyka', function(e){
579
580 if( !$(this).parents('.leyka-campaign-card').length ) {
581
582 e.preventDefault();
583 var target_top = parseInt($("#leyka-payment-form").offset().top) - 50;
584
585 $('html, body').animate({scrollTop:target_top}, 500);
586 }
587 });
588 });
589
590 /** Change "&lt;" to "<", "&rt;" to ">", etc. */
591 function leyka_decode_htmlentities(encoded_text) {
592
593 var textArea = document.createElement('textarea');
594 textArea.innerHTML = encoded_text;
595
596 return textArea.value;
597 }
598
599 /** Get currenly selected PM's full ID */
600 function leyka_get_pm_full_id($form) {
601
602 var template = leyka_get_template_id($form),
603 pm_full_id = '';
604
605 switch(template) {
606 case 'radio': pm_full_id = $form.find('input[name="leyka_payment_method"]:checked').val(); break;
607 case 'toggles': pm_full_id = $form.find('input[name="leyka_payment_method"]').val(); break;
608 default:
609 }
610
611 return pm_full_id;
612 }
613
614 /** * @return mixed Form template id (if found) or false (if not found). */
615 function leyka_get_template_id($form) {
616
617 var $tmp = $form.closest('#leyka-payment-form'),
618 template_id = false;
619
620 if($tmp.length) {
621 template_id = $tmp.data('template');
622 } else {
623
624 $tmp = $form.closest('.leyka-pf');
625
626 if($tmp.length) {
627 template_id = $tmp.find('.leyka-inline-campaign-form').data('template');
628 }
629
630 }
631
632 return template_id;
633 }
634
635 /** @var e JS keyup/keydown event */
636 function leyka_is_special_key(e) {
637
638 // Allowed special keys
639 return (
640 e.keyCode === 9 || // Tab
641 (e.keyCode === 65 && e.ctrlKey) || // Ctrl+A
642 (e.keyCode === 67 && e.ctrlKey) || // Ctrl+C
643 (e.keyCode >= 35 && e.keyCode <= 40) // Home, end, left, right, down, up
644 );
645 }
646
647 /** @var e JS keyup/keydown event */
648 function leyka_is_digit_key(e, numpad_allowed) {
649
650 if(typeof numpad_allowed == 'undefined') {
651 numpad_allowed = true;
652 } else {
653 numpad_allowed = !!numpad_allowed;
654 }
655
656 // Allowed special keys:
657 if( // Backspace, delete, tab, enter:
658 e.keyCode === 46 || e.keyCode === 8 || e.keyCode === 9 || e.keyCode === 13 ||
659 (e.keyCode === 65 && e.ctrlKey) || // Ctrl+A
660 (e.keyCode === 67 && e.ctrlKey) || // Ctrl+C
661 (e.keyCode >= 35 && e.keyCode <= 40) // Home, end, left, right, down, up
662 ) {
663 return true;
664 }
665
666 if(numpad_allowed) {
667 if( !e.shiftKey && e.keyCode >= 48 && e.keyCode <= 57 ) {
668 return true;
669 } else {
670 return e.keyCode >= 96 && e.keyCode <= 105;
671 }
672 } else {
673 return !(e.shiftKey || e.keyCode < 48 || e.keyCode > 57);
674 }
675
676 }
677
678 function is_email(email) {
679 return /^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*@([a-z0-9_][-a-z0-9_]*(\.[-a-z0-9_]+)*\.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|expert|[a-z]+)|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?$/i.test(email);
680 }