PageSourceSearch

https://cdn.ca.yapla.com/js/membogo/form/field.js?v=v6.287.1&v=v6.…=f12cd42963af87decf8fb38310e594efb1fa5109

js yapla.com collected 2026-10-01 10:23:34 UTC 36,589 bytes, 937 lines download raw bytes

1// Promises are used extensively and it is not compatible with IE11
2/* eslint-disable */
3if (typeof memboGo === 'undefined') {
4    var memboGo = {};
5}
6
7if (typeof memboGo.Field === 'undefined') {
8    memboGo.Field = {};
9}
10
11memboGo.Field.Conditional = {
12    init: function () {
13        $(document)
14            .off('change', '[data-conditional-field]')
15            .off('change', '[data-display-conditions]')
16            .on('change', '[data-conditional-field]', function (e) {
17                const $this = $(this);
18                const values = Array.from($this.get(0).querySelectorAll('input:checked, select'))
19                    .filter((element) => parseInt(element.value) > 0)
20                    .map((element) => parseInt(element.value));
21                $this.data('conditional-field').forEach(function (rule) {
22                    const show = rule?.options?.some(option => values.includes(option));
23                    $this.closest('.row')[0].querySelectorAll('[data-conditional-field-child="' + rule.id + '"]')
24                        .forEach((el) => {
25                            el.style.display = show ? 'block' : 'none';
26                            memboGo.Field.Conditional.updateSectionDisplay(el, show);
27                        });
28                });
29            })
30            .on('change', '[data-display-conditions]', function () {
31                memboGo.Field.Conditional.updateSectionDisplay(this, true);
32            })
33            .ready(function () {
34                $('[data-conditional-field], [data-display-conditions]').trigger('change');
35            })
36    },
37    updateSectionDisplay: function (element, parentVisibility) {
38
39        if (!element.dataset.displayConditions) {
40            return;
41        }
42
43        if (parentVisibility) {
44            parentVisibility = element.style.display !== 'none' && (!element.closest('.section') || element.closest('.section').style.display !== 'none');
45        }
46
47        const displayConditions = JSON.parse(element.dataset.displayConditions);
48
49        for (const sectionId in displayConditions) {
50            let sectionVisibility = false;
51
52            if (parentVisibility) {
53                const allowedValues = Object.values(displayConditions[sectionId]);
54                const elements = element.querySelectorAll('input:checked, select option:checked');
55                if (elements.length === 0) {
56                    sectionVisibility = allowedValues.includes(0);
57                } else {
58                    const intersectionValues = Array.from(elements).filter((el) => allowedValues.includes(parseInt(el.value)));
59                    sectionVisibility = intersectionValues.length > 0;
60                }
61            }
62
63            const section = document.getElementById(sectionId);
64            if (section) {
65                section.style.display = sectionVisibility ? 'block' : 'none';
66                section.querySelectorAll('[data-display-conditions]')
67                    .forEach((el) => memboGo.Field.Conditional.updateSectionDisplay(el, parentVisibility && sectionVisibility));
68
69                memboGo.Field.Conditional.syncWithRelatedSections(sectionId, sectionVisibility);
70            }
71
72            memboGo.core.event.dispatch('change-section-display-conditions', {
73                sectionId: sectionId,
74                visible: sectionVisibility
75            });
76        }
77
78        memboGo.core.event.dispatch('mgo-event-field-object-change-sections');
79    },
80    syncWithRelatedSections: function (sectionId, sectionVisibility) {
81        const sections = document.querySelectorAll('[data-related-section="' + sectionId + '"]');
82        sections.forEach((section) => {
83            section.style.display = sectionVisibility ? 'block' : 'none';
84            memboGo.Field.Conditional.syncWithRelatedSections(section.getAttribute('id'), sectionVisibility);
85        });
86    }
87};
88
89memboGo.Field.File = {
90    text: {
91        cancel: 'Remove',
92        errorsize: 'Error size must be between __MIN__ - __MAX__',
93    },
94
95    add: function (element, params) {
96        var self = this;
97        if (typeof params.crop !== 'undefined') {
98            params.crop = new memboGo.Field.Crop(element, params.crop);
99        }
100        Formstone.Ready(function () {
101            window.addEventListener("dragover", function (e) {
102                e = e || event;
103                e.preventDefault();
104            }, false);
105            window.addEventListener("drop", function (e) {
106                e = e || event;
107                e.preventDefault();
108            }, false);
109            $(element).hide();
110            if (!$(element).siblings('.field_file__draggablecomplete').length) {
111                $(element).before($('<ul />', {class: 'field_file__draggablecomplete'}));
112            }
113            var elementAttr = {class: 'field_file__draggable', 'data-preview': '0'};
114            if (typeof params['showPreview'] != 'undefined' && !!params['showPreview']) {
115                elementAttr['data-preview'] = '1';
116                $(element).siblings('.field_file__draggablecomplete').before($('<div />', elementAttr));
117            } else {
118                $(element).siblings('.field_file__draggablecomplete').after($('<div />', elementAttr));
119            }
120            $(element)
121                .data('name', $(element).attr('name'))
122                .removeAttr('name')
123                .siblings('.field_file__draggable')
124                .upload(params)
125                .on("start.upload", self.onStart)
126                .on("complete.upload", self.onComplete)
127                .on("filestart.upload", self.onFileStart)
128                .on("fileprogress.upload", self.onFileProgress)
129                .on("filecomplete.upload", self.onFileComplete)
130                .on("fileerror.upload", self.onFileError)
131                .on("chunkstart.upload", self.onChunkStart)
132                .on("chunkprogress.upload", self.onChunkProgress)
133                .on("chunkcomplete.upload", self.onChunkComplete)
134                .on("chunkerror.upload", self.onChunkError)
135                .on("queued.upload", self.onQueued);
136
137            $(document)
138                .off('click', ".filelist.queue")
139                .off('click', ".file_cancel_all")
140                .off('click', '.remove-upload-file')
141                .off('click', '.cancel-pre-upload-file')
142
143                .on('click', ".filelist.queue", self.onCancel)
144                .on('click', ".file_cancel_all", self.onCancelAll)
145                .on('click', '.remove-upload-file', function () {
146                    $(this).closest('li').remove();
147                })
148                .on('click', '.cancel-pre-upload-file', function () {
149                    var ul = $(this).closest('ul'),
150                        _p = $(this).closest(".field_file__draggablecomplete");
151
152                    $(this).closest('li').remove();
153
154                    ul.siblings('.field_file__draggable').upload('removeUpload');
155
156                    if (!_p.find('li').length) {
157                        _p.append($('<input />', {
158                            type: "hidden",
159                            class: 'empty-value',
160                            name: _p.siblings('input[type="file"]').data('name') + '[]'
161                        }));
162                    }
163
164                    memboGo.core.event.dispatch('eventFormFieldDraggablecomplete', {element: _p.get(0)});
165                });
166
167            if (typeof params.preUpload !== 'undefined') {
168                var drawUploadFile = !$(element).closest(".form-group").find(".field_file__draggablecomplete").find('li').length;
169                element = $(element).siblings('.field_file__draggable');
170                if (typeof params.preUpload === 'object') {
171                    for (var i in params.preUpload) {
172                        if (drawUploadFile) {
173                            memboGo.Field.File.addUploadedFile(element, params.preUpload[i]);
174                        }
175                        $(element).upload('incrementUpload');
176                    }
177                } else {
178                    if (drawUploadFile) {
179                        memboGo.Field.File.addUploadedFile(element, params.preUpload, params.urlDownload);
180                    }
181                    $(element).upload('incrementUpload');
182                }
183            }
184
185            if (typeof params['presetError'] != 'undefined' && !!params['presetError'] && params['presetError'].length > 0) {
186                self.addErrorMessages(element, params['presetError']);
187            }
188        });
189    },
190
191    onCancel: function (e) {
192        var index = $(this).parents("li").data("index");
193        $(this).parents("form").find(".upload").upload("abort", parseInt(index, 10));
194    },
195
196    onCancelAll: function (e) {
197        $(this).parents("form").find(".upload").upload("abort");
198    },
199
200    onQueued: function (e, files) {
201    },
202
203    onStart: function (e, files) {
204        HPJUtils.displayLoadingBox();
205    },
206
207    onComplete: function (e) {
208        HPJUtils.hideLoadingBox();
209    },
210
211    onFileStart: function (e, file) {
212    },
213
214    onFileProgress: function (e, file, percent) {
215    },
216
217    onFileComplete: function (e, file, response, status, jqXHR, crop) {
218        const parent = $(e.target).closest('.form-group');
219        parent.removeClass('has-error');
220        parent.find('.errors').remove();
221        if (response['success'] == '1') {
222            memboGo.Field.File.addUploadedFile(this, response.data);
223            crop ? crop.addRestore() : null;
224        } else {
225            if (typeof response['messages'] !== 'undefined') {
226                memboGo.Field.File.addErrorMessages(e.target, response['messages']);
227            }
228        }
229    },
230
231    onFileError: function (e, file, error) {
232        if (error == 'size') {
233            $(this).closest(".form-group").find(".field_file__draggablecomplete").append($('<li />').append($('<div />', {class: 'error'}).text(memboGo.Field.File.text.errorsize)));
234            var last = $(this).closest(".form-group").find(".field_file__draggablecomplete").find('li').last();
235            setTimeout(function () {
236                $(last).remove();
237            }, 3000);
238        }
239    },
240
241    onChunkStart: function (e, file) {
242        console.log("Chunk Start");
243    },
244
245    onChunkProgress: function (e, file, percent) {
246        console.log("Chunk Progress");
247    },
248
249    onChunkComplete: function (e, file, response) {
250        console.log("Chunk Complete");
251    },
252
253    onChunkError: function (e, file, error) {
254        console.log("Chunk Error");
255    },
256
257    addUploadedFile: function (that, file, urlDownload) {
258        if (typeof file === 'string') {
259            file = {link: file, name: file.split('\\').pop().split('/').pop()};
260        }
261
262        if (urlDownload && urlDownload.length) {
263            file['link'] = urlDownload;
264        }
265
266        var element;
267        if (parseInt($(that).data('preview'), 2)) {
268            element = $('<img />', {
269                class: "file",
270                style: "max-width:400px;margin:20px 0 0;",
271                src: file['link'],
272                alt: file['file_name']
273            });
274        } else {
275            element = $('<a />', {class: "file", target: 'blank', href: file['link']});
276        }
277        element.text(file['name']);
278
279        $(that).closest(".form-group").find(".field_file__draggablecomplete").each(function () {
280            $(this).find('.empty-value').remove();
281
282            var name = $(this).siblings('input[type="file"]').data('name') + '[]';
283            $(this).append(
284                $('<li />').append(
285                    $('<div />', {class: 'content'})
286                        .append(element,
287                            '<div class="multifile__actions-file">'
288                            + '<span class="cancel-pre-upload-file multifile__remove-file"><i class="fontawesome-icon icon-trash fa fa-times"></i></span>'
289                            + '</div>',
290                            $('<input />', {
291                                type: "hidden",
292                                name: name,
293                                value: JSON.stringify(file)
294                            }))
295                )
296            );
297            memboGo.core.event.dispatch('eventFormFieldDraggablecomplete', {
298                element: this,
299                file: file['link']
300            });
301        });
302    },
303
304    addErrorMessages: function (element, errors) {
305        const formGroupElement = $(element).closest('.form-group')
306        if (!formGroupElement) {
307            return;
308        }
309        formGroupElement.find('.cancel-pre-upload-file').click();
310        formGroupElement.addClass('has-error');
311        let htmlError = '<ul class="errors">';
312        for (let i in errors) {
313            htmlError += '<li>' + errors[i] + '</li>';
314        }
315        htmlError += '</ul>';
316        formGroupElement.append(htmlError);
317        const ul = formGroupElement.find('.field_file__draggablecomplete');
318        ul.siblings('.field_file__draggable').upload('removeUpload');
319    }
320};
321
322memboGo.Field.Crop = function (element, options) {
323    this.image = null;
324    this.opts = {
325        viewMode: 2,
326        background: false,
327        rotatable: true,
328        scalable: true,
329        modal: false,
330        guides: false,
331        highlight: false,
332        center: true,
333        autoCrop: true,
334    };
335    this.rotateDegree = 45;
336    this.maxWidth = 0;
337    this.maxHeight = 0;
338    this.crop = null;
339    this.modal = null;
340    this.file = null;
341    this.fileType = 'image/jpeg';
342    for (i in options) {
343        if (i === 'maxWidth') {
344            this.maxWidth = options[i];
345        } else if (i === 'maxHeight') {
346            this.maxHeight = options[i];
347        } else {
348            this.opts[i] = options[i];
349        }
350    }
351
352    this.read = function (data, file) {
353        var self = this;
354        return new Promise(function (resolve, reject) {
355            if (typeof 'FileReader' !== 'undefined') {
356                memboGo.core.event.remove('remove.before.crop.save');
357                self.file = file || self.file;
358                memboGo.Field.File.canUseImage(self.file)
359                    .then(function (result) {
360                        if (result) {
361                            self.data = data || self.data;
362                            var reader = new FileReader();
363                            reader.onload = function (e) {
364                                self.initCropper(e);
365                            };
366                            reader.readAsDataURL(self.file);
367                            self.data.$input.val("");
368                        }
369                        resolve(result);
370                    });
371            } else {
372                resolve(false);
373            }
374        });
375    };
376
377    this.reset = function () {
378        if (this.crop !== null) {
379            this.crop.destroy();
380        }
381        if (this.crop === null) {
382            this.modal = new HPJUtils.modal('#modal-crop');
383        }
384        this.modal.close();
385    };
386
387    this.initCropper = function (e) {
388        var self = this;
389
390        this.reset();
391        this.modal.open();
392
393        $('#modal-crop').find('img').attr('src', e.target.result);
394
395        // Set Max Size
396        this.opts.crop = function (event) {
397            if (parseInt(self.opts.maxWidth) > 0
398                && parseInt(self.opts.maxHeight) > 0
399                && (event.detail.width > self.opts.maxWidth || event.detail.height > self.opts.maxHeight)
400            ) {
401                self.crop.setData({width: self.opts.maxWidth, height: self.opts.maxHeight});
402            } else {
403                $('.cropbox-width').val(Math.floor(event.detail.width));
404                $('.cropbox-height').val(Math.floor(event.detail.height));
405            }
406        };
407
408        // Center and push to max crop box
409        this.opts.ready = function (e, aspectRatio) {
410            if (!aspectRatio && typeof self.opts.aspectRatio !== 'undefined') {
411                aspectRatio = self.opts.aspectRatio;
412            }
413            if (aspectRatio) {
414                self.crop.setAspectRatio(eval(aspectRatio));
415            } else {
416                self.crop.setAspectRatio(null);
417            }
418            const data = self.crop.cropBoxData;
419            const canvas = self.crop.getCanvasData();
420            const maxWidth = Math.floor(data.maxWidth);
421            let boxData = {
422                width: maxWidth,
423                left: canvas.left + ((canvas.width - maxWidth) / 2),
424                height: data.maxHeight,
425                top: (canvas.height - data.maxHeight) / 2
426            };
427            if (aspectRatio) {
428                if (canvas.width >= canvas.height) {
429                    delete boxData.height;
430                    delete boxData.top;
431                } else {
432                    delete boxData.width;
433                    delete boxData.left;
434                }
435            }
436            self.crop.setCropBoxData(boxData);
437            $(".ratio").removeClass("active");
438            if (aspectRatio) {
439                $('#modal-crop [data-aspectratio]').filter(function () {
440                    return eval($(this).data('aspectratio')) == aspectRatio;
441                }).addClass("active");
442                $('.input-group-crop .cropbox-height').parent('div')[aspectRatio == 1 ? 'hide' : 'show']();
443            }
444        };
445
446        this.crop = new Cropper($('#modal-crop').find('img').get(0), this.opts);
447        this._event();
448
449        const type = e.target.result.match(/^data:image\/(png|jpeg|gif|webp);/);
450
451        this.fileType = `image/${type?.[1] ?? 'jpeg'}`;
452    };
453
454    this._event = function () {
455        var self = this;
456
457        $('#modal-crop .drag').unbind('click').click(self.reset);
458
459        $('#modal-crop .modal-yes')
460            .unbind('click')
461            .click(function (e) {
462                e.preventDefault();
463                memboGo.core.event.dispatch('remove.before.crop.save');
464                self.crop.getCroppedCanvas().toBlob(function (blob) {
465                    self.compressImage(blob)
466                        .then(function (blob) {
467                            if (blob) {
468                                var formData = new FormData();
469                                formData.append(self.data.postKey, blob, self.file.name);
470                                for (var i in self.data.postData) {
471                                    if (self.data.postData.hasOwnProperty(i)) {
472                                        formData.append(i, self.data.postData[i]);
473                                    }
474                                }
475                                HPJUtils.displayLoadingBox();
476                                $.ajax({
477                                    url: self.data.action,
478                                    data: formData,
479                                    dataType: self.data.dataType,
480                                    type: "POST",
481                                    contentType: false,
482                                    processData: false,
483                                    cache: false,
484                                    success: function (response, status, jqXHR) {
485                                        self.reset();
486                                        self.data.uploaded++;
487                                        self.data.$el.trigger("filecomplete.upload", [{}, response, status, jqXHR, self]);
488                                        if (self.data.maxFiles && self.data.maxFiles <= self.data.uploaded) {
489                                            self.data.$el.upload("disable");
490                                        }
491                                        memboGo.core.trackEvent('Dashboard - Confirm Logo');
492                                    },
493                                    complete: function () {
494                                        HPJUtils.hideLoadingBox();
495                                    },
496                                    error: function (jqXHR, status, error) {
497                                    }
498                                });
499                            }
500                        });
501                })
502            });
503
504        $('#modal-crop .rotate-plus')
505            .unbind('click')
506            .click(function (e) {
507                e.preventDefault();
508                self.crop.rotate(self.rotateDegree);
509            });
510
511        $('#modal-crop .rotate-minus')
512            .unbind('click')
513            .click(function (e) {
514                e.preventDefault();
515                self.crop.rotate(-self.rotateDegree);
516            });
517
518        $('#modal-crop .scale-x')
519            .unbind('click')
520            .click(function (e) {
521                e.preventDefault();
522                self.crop.scaleX(self.crop.getData().scaleX * -1);
523            });
524
525        $('#modal-crop [data-aspectratio]')
526            .unbind('click')
527            .click(function (e) {
528                e.preventDefault();
529                self.crop.options.ready(null, eval($(this).data('aspectratio')));
530            });
531
532        $('#modal-crop .reset')
533            .unbind('click')
534            .click(function (e) {
535                e.preventDefault();
536                self.crop.reset();
537                self.crop.options.ready();
538            });
539
540        $('.cropbox-width,.cropbox-height')
541            .on('keypress', function (e) {
542                if (e.key === 'Enter') {
543                    e.preventDefault();
544                } else if (e.key === '+' || e.key === '-') {
545                    e.preventDefault();
546                    if (!isNaN(parseInt(this.value))) {
547                        $(this).val(parseInt(this.value) + (e.key === '+' ? 1 : -1));
548                    }
549                }
550            })
551            .on('keyup', function (e) {
552                if (e.key === '+' || e.key === '-' || e.key === 'Enter') {
553                    $(this).trigger('change');
554                }
555            })
556            .on('change', function (e) {
557                e.preventDefault();
558                var side = $(this).hasClass('cropbox-height') ? 'height' : 'width',
559                    v = parseInt(this.value),
560                    i = self.crop.getImageData().width / self.crop.getImageData().naturalWidth,
561                    max = Math.round((side === 'height' ? self.crop.cropBoxData.maxHeight : self.crop.cropBoxData.maxWidth) / i);
562
563                this.value = !isNaN(v) && v > 0 && v <= max ? v : max;
564                var cropBoxData = {};
565                cropBoxData[side] = Math.floor(this.value * i);
566                self.crop.setCropBoxData(cropBoxData);
567            });
568    };
569
570    /**
571     * Compress blob image before save it
572     *
573     * @param blob
574     * @returns {Promise<string>}
575     */
576    this.compressImage = function (blob) {
577        var self = this, img = new Image();
578        img.src = URL.createObjectURL(blob);
579        return new Promise(function (resolve, reject) {
580            img.onload = function () {
581                var width = img.width, height = img.height;
582                if (self.maxWidth > 0 && width > self.maxWidth && width >= height) {
583                    height = Math.floor((height *= self.maxWidth / width));
584                    width = self.maxWidth;
585                } else if (self.maxHeight > 0 && height > self.maxHeight) {
586                    width = Math.floor((width *= self.maxHeight / height));
587                    height = self.maxHeight;
588                }
589                const canvas = document.createElement('canvas');
590                canvas.width = width;
591                canvas.height = height;
592                const ctx = canvas.getContext('2d', { alpha: true });
593                ctx.drawImage(img, 0, 0, width, height);
594
595                canvas.toBlob(function (blob) {
596                    resolve(blob);
597                }, self.fileType, 0.8);
598            };
599            img.onerror = function (err) {
600                reject(null);
601            }
602        })
603    };
604
605    /**
606     * Add Restore Action
607     */
608    this.addRestore = function () {
609        var crop = this, _p = this.data.$input.closest('.form-group');
610        _p.find('.multifile__actions-file').each(function () {
611            $(this).append('<a class="js-crop-file-again"><i class="fontawesome-icon icon-edit fa fa-times"></i></a>');
612        });
613        _p.on('click', '.js-crop-file-again', function () {
614            crop.read();
615            memboGo.core.event.listen('remove.before.crop.save', function (e) {
616                _p.find('.cancel-pre-upload-file').trigger('click');
617            });
618        });
619    }
620};
621
622// Check if file is animated
623memboGo.Field.File.canUseImage = function (file) {
624    return new Promise(function (resolve, reject) {
625        if (typeof file === 'object') {
626            var reader = new FileReader();
627            reader.readAsArrayBuffer(file);
628            return reader.onload = function (e) {
629                var dv = new DataView(e.target.result, 10);
630                var offset = 0;
631                var globalColorTable = dv.getUint8(0);
632                var globalColorTableSize = 0;
633                if (globalColorTable & 0x80) {
634                    globalColorTableSize = 3 * Math.pow(2, (globalColorTable & 0x7) + 1);
635                }
636                offset = 3 + globalColorTableSize;
637                var extensionIntroducer = dv.getUint8(offset);
638                var graphicsConrolLabel = dv.getUint8(offset + 1);
639                var delayTime = 0;
640                if ((extensionIntroducer & 0x21) && (graphicsConrolLabel & 0xF9)) {
641                    delayTime = dv.getUint16(offset + 4);
642                }
643                return resolve(delayTime <= 0);
644            }
645        }
646        resolve(false);
647    }).catch(function (error) {
648        return false;
649    });
650};
651
652memboGo.Field.Group = {
653    _url: null,
654    _default: {
655        no_results_text: "",
656        placeholder_text_multiple: "",
657        inherit_select_classes: true,
658        width: "",
659        allow_single_deselect: true,
660        search_contains: true
661    },
662    init: function (url, options) {
663        if (url.length > 0) {
664            try {
665                for (a in options) {
666                    this._default[a] = options[a];
667                }
668            } catch (e) {
669            }
670            this._url = url;
671            this.getScript('/js/jquery/ajax-chosen.min.js', function () {
672                memboGo.Field.Group.events();
673            });
674        } else {
675            $(".select-other-group:not(.chosen-container),.select-main-group:not(.chosen-container)").each(
676                function () {
677                    $(this).chosen({
678                        no_results_text: "",
679                        placeholder_text_multiple: "",
680                        inherit_select_classes: true,
681                        width: "",
682                        allow_single_deselect: true,
683                        search_contains: true
684                    });
685                });
686        }
687    },
688    events: function () {
689        var self = this;
690        $(".select-other-group:not(.chosen-container),.select-main-group:not(.chosen-container)").each(
691            function () {
692                $(this).ajaxChosen(
693                    {
694                        type: 'GET',
695                        url: self._url,
696                        dataType: 'json',
697                        minTermLength: 1,
698                        afterTypeDelay: 500,
699                        jsonTermKey: "search",
700                    },
701                    function (data) {
702                        var results = [];
703                        $.map(data, function (name, id) {
704                            results.push({value: id, text: name});
705                        });
706                        return results;
707                    },
708                    self._default
709                );
710            }
711        )
712    },
713    getScript: function (url, success) {
714        var script = document.createElement('script');
715        script.src = url;
716        var head = document.getElementsByTagName('head')[0],
717            done = false;
718        script.onload = script.onreadystatechange = function () {
719            if (!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) {
720                done = true;
721                success();
722                script.onload = script.onreadystatechange = null;
723                head.removeChild(script);
724            }
725        };
726        head.appendChild(script);
727    }
728};
729
730memboGo.Field.checkIsUniqueValue = {
731    campaignId: null,
732    url: null,
733    /**
734     * Check if a given value is unique
735     * @param url string
736     */
737    init: function (url, campaignId) {
738        this.campaignId = campaignId;
739        this.url = url;
740        var self = this;
741        $(document).find('input[type="email"]').each(function () {
742            this.setAttribute('data-initialval', this.value);
743        });
744
745        $(document)
746            .off('change', '[data-is-unique-email]')
747            .on('change', '[data-is-unique-email]', function () {
748                $(this).closest('.form-group').removeClass('has-error');
749                $(this).closest('.form-group').find('.errors, .error').remove();
750                if (this.value.length > 0 && this.value !== this.getAttribute('data-initialval')) {
751                    self.validate(this);
752                }
753            });
754    },
755    validate: function (element) {
756        $.ajax({
757            type: 'POST',
758            url: this.url,
759            data: {
760                campaignId: this.campaignId,
761                alias: $(element).data('is-unique-email'),
762                email: $(element).val()
763            },
764            dataType: 'json',
765            success: function (data) {
766                if (!data.result) {
767                    $(element).closest('.form-group').addClass('has-error');
768                    $(element).after(data.error);
769                }
770            }
771        });
772    }
773};
774
775memboGo.Field.Autocomplete = {
776    types: ['city', 'state', 'country', 'zip_code', 'zip'],
777    mapKey: null,
778    word: '~@~',
779    init: function () {
780        if (!memboGo.core.googlePlace?.key?.length) {
781            return;
782        }
783        var items = document.querySelectorAll('[data-autocomplete-address]'), i, form;
784        if (items.length) {
785            if (items.length) {
786                for (i = 0; i < items.length; i++) {
787                    try {
788                        items[i].parentElement.dataset.id = items[i].id.replace('_street', '_' + this.word);
789                        items[i].removeAttribute('data-autocomplete-address');
790                        if ((form = this.getForm(items[i])) !== null) {
791                            this.initElementMap(form, items[i]);
792                        }
793                    } catch (e) {
794                        memboGo.core.dispatchException(e);
795                    }
796                }
797            }
798
799            if (memboGo.core.googlePlace.init(memboGo.Field.Autocomplete.initAutocomplete)) {
800                memboGo.Field.Autocomplete.initAutocomplete();
801            }
802        }
803    },
804    initElementMap: function (form, element) {
805        var clone = element.cloneNode(), i;
806        clone.removeAttribute('id');
807        clone.removeAttribute('name');
808        clone.classList.add('form-field-autocomplete');
809        clone.style.display = 'none';
810        clone.value = '';
811        element.parentNode.insertBefore(clone, element);
812        this.addAction(element, false);
813        this.addAction(clone, true);
814        clone.addEventListener('keypress', function (e) {
815            if (e.keyCode === 13) {
816                e.stopPropagation();
817                e.preventDefault();
818            }
819        });
820        if (this.isAddressEmpty(form, element.parentElement.dataset.id)) {
821            this.autocomplete(element);
822        }
823    },
824    getForm: function (el) {
825        while (el) {
826            el = el.parentElement;
827            if (el === null || el.tagName === 'FORM') {
828                return el;
829            }
830        }
831    },
832    addAction: function (el, manual) {
833        var nodeElement = document.createElement('a');
834        if (manual) {
835            nodeElement.setAttribute('class', 'address_autocomplete_off');
836            nodeElement.innerText = fieldText.manual;
837            nodeElement.style.display = 'none';
838        } else {
839            nodeElement.setAttribute('class', 'address_autocomplete_on');
840            nodeElement.innerText = fieldText.autocomplete;
841        }
842        nodeElement.addEventListener('click', function (e) {
843            e.stopPropagation();
844            memboGo.Field.Autocomplete.autocomplete(this);
845        });
846        el.parentNode.insertBefore(nodeElement, el.nextSibling);
847    },
848    autocomplete: function (element) {
849        var form = this.getForm(element), id = element.parentElement.dataset.id, i, elementId;
850        if (form !== null) {
851            var childs = element.parentElement.children;
852            for (i = 0; i < childs.length; i++) {
853                childs[i].style.display = childs[i].style.display === 'none' ? 'block' : 'none';
854            }
855            for (i in this.types) {
856                elementId = id.replace(this.word, this.types[i]);
857                if (typeof form.elements[elementId] !== 'undefined') {
858                    this.toggle(form.elements[elementId]);
859                }
860            }
861        }
862    },
863    toggle: function (el) {
864        while (el) {
865            el = el.parentElement;
866            if (el.classList.contains('form-group')) {
867                if (el.parentElement.children.length === 1) {
868                    el = el.parentElement;
869                }
870                if (el.classList.contains('hidden')) {
871                    el.classList.remove('hidden');
872                } else {
873                    el.classList.add('hidden');
874                }
875                break;
876            }
877        }
878    },
879    isAddressEmpty: function (form, id) {
880        var address = ['street', 'city', 'zip_code', 'zip'];
881        for (i in address) {
882            var elementId = id.replace(this.word, address[i]);
883            if (typeof form.elements[elementId] !== 'undefined' && form.elements[elementId].value.length > 0) {
884                return false;
885            }
886        }
887        return true;
888    },
889    initAutocomplete: function () {
890        var items = document.getElementsByClassName('form-field-autocomplete'),
891            i,
892            form,
893            mapField,
894            self = memboGo.Field.Autocomplete;
895        if (items.length) {
896            for (i = 0; i < items.length; i++) {
897                var element = items[i];
898                if ((form = self.getForm(element)) !== null) {
899                    mapField = self.getMapField(element.parentElement.dataset.id);
900                    (new google.maps.places.Autocomplete(element, {types: ['geocode'], fields: ['address_component']}))
901                        .addListener('place_changed', function () {
902                            var data = memboGo.core.googlePlace.placeData(this.getPlace());
903                            for (i in mapField) {
904                                if (typeof form.elements[mapField[i]] !== 'undefined') {
905                                    form.elements[mapField[i]].value = data[i] || '';
906                                    if (i === 'country') {
907                                        form.elements[mapField[i]].dispatchEvent(new Event('change', {bubbles: true}));
908                                    } else if (i === 'administrative_area_level_1') {
909                                        form.elements[mapField[i]].dataset.targetValue = data[i] || '';
910                                    }
911                                }
912                            }
913                        });
914
915                    // Fix for Chrome
916                    if (navigator.userAgent.indexOf("Chrome") !== -1) {
917                        setTimeout(function () {
918                            element.setAttribute('autocomplete', 'disabled');
919                        }, 500);
920                    }
921                }
922            }
923        }
924    },
925    getMapField: function (name) {
926        return {
927            'street': name.replace(this.word, 'street'),
928            'locality': name.replace(this.word, 'city'),
929            'administrative_area_level_1': name.replace(this.word, 'state'),
930            'country': name.replace(this.word, 'country'),
931            'zip': name.replace(this.word, 'zip'),
932            'zip_code': name.replace(this.word, 'zip_code'),
933        };
934    },
935};
936
937memboGo.Field.Conditional.init();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.