PageSourceSearch

https://www.beechnut.com/wp-content/plugins/ninja-forms-conditionals/assets/js/min/front-end.js

js beechnut.com collected 2026-09-25 18:53:13 UTC 40,465 bytes, 1,194 lines download raw bytes

vendor: 4,507 bytes, lines 1-110
1(function () {
2/**
3 * @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.
4 * Available via the MIT or new BSD license.
5 * see: http://github.com/jrburke/almond for details
6 */
7//Going sloppy to avoid 'use strict' string cost, but strict practices should
8//be followed.
9/*jslint sloppy: true */
10/*global setTimeout: false */
11
12var requirejs, require, define;
13(function (undef) {
14    var main, req, makeMap, handlers,
15        defined = {},
16        waiting = {},
17        config = {},
18        defining = {},
19        hasOwn = Object.prototype.hasOwnProperty,
20        aps = [].slice,
21        jsSuffixRegExp = /\.js$/;
22
23    function hasProp(obj, prop) {
24        return hasOwn.call(obj, prop);
25    }
26
27    /**
28     * Given a relative module name, like ./something, normalize it to
29     * a real name that can be mapped to a path.
30     * @param {String} name the relative name
31     * @param {String} baseName a real name that the name arg is relative
32     * to.
33     * @returns {String} normalized name
34     */
35    function normalize(name, baseName) {
36        var nameParts, nameSegment, mapValue, foundMap, lastIndex,
37            foundI, foundStarMap, starI, i, j, part,
38            baseParts = baseName && baseName.split("/"),
39            map = config.map,
40            starMap = (map && map['*']) || {};
41
42        //Adjust any relative paths.
43        if (name && name.charAt(0) === ".") {
44            //If have a base name, try to normalize against it,
45            //otherwise, assume it is a top-level require that will
46            //be relative to baseUrl in the end.
47            if (baseName) {
48                name = name.split('/');
49                lastIndex = name.length - 1;
50
51                // Node .js allowance:
52                if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
53                    name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
54                }
55
56                //Lop off the last part of baseParts, so that . matches the
57                //"directory" and not name of the baseName's module. For instance,
58                //baseName of "one/two/three", maps to "one/two/three.js", but we
59                //want the directory, "one/two" for this normalization.
60                name = baseParts.slice(0, baseParts.length - 1).concat(name);
61
62                //start trimDots
63                for (i = 0; i < name.length; i += 1) {
64                    part = name[i];
65                    if (part === ".") {
66                        name.splice(i, 1);
67                        i -= 1;
68                    } else if (part === "..") {
69                        if (i === 1 && (name[2] === '..' || name[0] === '..')) {
70                            //End of the line. Keep at least one non-dot
71                            //path segment at the front so it can be mapped
72                            //correctly to disk. Otherwise, there is likely
73                            //no path mapping for a path starting with '..'.
74                            //This can still fail, but catches the most reasonable
75                            //uses of ..
76                            break;
77                        } else if (i > 0) {
78                            name.splice(i - 1, 2);
79                            i -= 2;
80                        }
81                    }
82                }
83                //end trimDots
84
85                name = name.join("/");
86            } else if (name.indexOf('./') === 0) {
87                // No baseName, so this is ID is resolved relative
88                // to baseUrl, pull off the leading dot.
89                name = name.substring(2);
90            }
91        }
92
93        //Apply map config if available.
94        if ((baseParts || starMap) && map) {
95            nameParts = name.split('/');
96
97            for (i = nameParts.length; i > 0; i -= 1) {
98                nameSegment = nameParts.slice(0, i).join("/");
99
100                if (baseParts) {
101                    //Find the longest baseName segment match in the config.
102                    //So, do joins on the biggest to smallest lengths of baseParts.
103                    for (j = baseParts.length; j > 0; j -= 1) {
104                        mapValue = map[baseParts.slice(0, j).join('/')];
105
106                        //baseName segment has  config, find if it has one for
107                        //this name.
108                        if (mapValue) {
109                            mapValue = mapValue[nameSegment];
110                            if (mapValue) {
vendor: 8,126 bytes, lines 111-348
111                                //Match, update name to the new value.
112                                foundMap = mapValue;
113                                foundI = i;
114                                break;
115                            }
116                        }
117                    }
118                }
119
120                if (foundMap) {
121                    break;
122                }
123
124                //Check for a star map match, but just hold on to it,
125                //if there is a shorter segment match later in a matching
126                //config, then favor over this star map.
127                if (!foundStarMap && starMap && starMap[nameSegment]) {
128                    foundStarMap = starMap[nameSegment];
129                    starI = i;
130                }
131            }
132
133            if (!foundMap && foundStarMap) {
134                foundMap = foundStarMap;
135                foundI = starI;
136            }
137
138            if (foundMap) {
139                nameParts.splice(0, foundI, foundMap);
140                name = nameParts.join('/');
141            }
142        }
143
144        return name;
145    }
146
147    function makeRequire(relName, forceSync) {
148        return function () {
149            //A version of a require function that passes a moduleName
150            //value for items that may need to
151            //look up paths relative to the moduleName
152            var args = aps.call(arguments, 0);
153
154            //If first arg is not require('string'), and there is only
155            //one arg, it is the array form without a callback. Insert
156            //a null so that the following concat is correct.
157            if (typeof args[0] !== 'string' && args.length === 1) {
158                args.push(null);
159            }
160            return req.apply(undef, args.concat([relName, forceSync]));
161        };
162    }
163
164    function makeNormalize(relName) {
165        return function (name) {
166            return normalize(name, relName);
167        };
168    }
169
170    function makeLoad(depName) {
171        return function (value) {
172            defined[depName] = value;
173        };
174    }
175
176    function callDep(name) {
177        if (hasProp(waiting, name)) {
178            var args = waiting[name];
179            delete waiting[name];
180            defining[name] = true;
181            main.apply(undef, args);
182        }
183
184        if (!hasProp(defined, name) && !hasProp(defining, name)) {
185            throw new Error('No ' + name);
186        }
187        return defined[name];
188    }
189
190    //Turns a plugin!resource to [plugin, resource]
191    //with the plugin being undefined if the name
192    //did not have a plugin prefix.
193    function splitPrefix(name) {
194        var prefix,
195            index = name ? name.indexOf('!') : -1;
196        if (index > -1) {
197            prefix = name.substring(0, index);
198            name = name.substring(index + 1, name.length);
199        }
200        return [prefix, name];
201    }
202
203    /**
204     * Makes a name map, normalizing the name, and using a plugin
205     * for normalization if necessary. Grabs a ref to plugin
206     * too, as an optimization.
207     */
208    makeMap = function (name, relName) {
209        var plugin,
210            parts = splitPrefix(name),
211            prefix = parts[0];
212
213        name = parts[1];
214
215        if (prefix) {
216            prefix = normalize(prefix, relName);
217            plugin = callDep(prefix);
218        }
219
220        //Normalize according
221        if (prefix) {
222            if (plugin && plugin.normalize) {
223                name = plugin.normalize(name, makeNormalize(relName));
224            } else {
225                name = normalize(name, relName);
226            }
227        } else {
228            name = normalize(name, relName);
229            parts = splitPrefix(name);
230            prefix = parts[0];
231            name = parts[1];
232            if (prefix) {
233                plugin = callDep(prefix);
234            }
235        }
236
237        //Using ridiculous property names for space reasons
238        return {
239            f: prefix ? prefix + '!' + name : name, //fullName
240            n: name,
241            pr: prefix,
242            p: plugin
243        };
244    };
245
246    function makeConfig(name) {
247        return function () {
248            return (config && config.config && config.config[name]) || {};
249        };
250    }
251
252    handlers = {
253        require: function (name) {
254            return makeRequire(name);
255        },
256        exports: function (name) {
257            var e = defined[name];
258            if (typeof e !== 'undefined') {
259                return e;
260            } else {
261                return (defined[name] = {});
262            }
263        },
264        module: function (name) {
265            return {
266                id: name,
267                uri: '',
268                exports: defined[name],
269                config: makeConfig(name)
270            };
271        }
272    };
273
274    main = function (name, deps, callback, relName) {
275        var cjsModule, depName, ret, map, i,
276            args = [],
277            callbackType = typeof callback,
278            usingExports;
279
280        //Use name if no relName
281        relName = relName || name;
282
283        //Call the callback to define the module, if necessary.
284        if (callbackType === 'undefined' || callbackType === 'function') {
285            //Pull out the defined dependencies and pass the ordered
286            //values to the callback.
287            //Default to [require, exports, module] if no deps
288            deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
289            for (i = 0; i < deps.length; i += 1) {
290                map = makeMap(deps[i], relName);
291                depName = map.f;
292
293                //Fast path CommonJS standard dependencies.
294                if (depName === "require") {
295                    args[i] = handlers.require(name);
296                } else if (depName === "exports") {
297                    //CommonJS module spec 1.1
298                    args[i] = handlers.exports(name);
299                    usingExports = true;
300                } else if (depName === "module") {
301                    //CommonJS module spec 1.1
302                    cjsModule = args[i] = handlers.module(name);
303                } else if (hasProp(defined, depName) ||
304                           hasProp(waiting, depName) ||
305                           hasProp(defining, depName)) {
306                    args[i] = callDep(depName);
307                } else if (map.p) {
308                    map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
309                    args[i] = defined[depName];
310                } else {
311                    throw new Error(name + ' missing ' + depName);
312                }
313            }
314
315            ret = callback ? callback.apply(defined[name], args) : undefined;
316
317            if (name) {
318                //If setting exports via "module" is in play,
319                //favor that over return value and exports. After that,
320                //favor a non-undefined return value over exports use.
321                if (cjsModule && cjsModule.exports !== undef &&
322                        cjsModule.exports !== defined[name]) {
323                    defined[name] = cjsModule.exports;
324                } else if (ret !== undef || !usingExports) {
325                    //Use the return value from the function.
326                    defined[name] = ret;
327                }
328            }
329        } else if (name) {
330            //May just be an object definition for the module. Only
331            //worry about defining if have a module name.
332            defined[name] = callback;
333        }
334    };
335
336    requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
337        if (typeof deps === "string") {
338            if (handlers[deps]) {
339                //callback in this case is really relName
340                return handlers[deps](callback);
341            }
342            //Just return the module wanted. In this scenario, the
343            //deps arg is the module name, and second arg (if passed)
344            //is just the relName.
345            //Normalize module name, if it contains . or ..
346            return callDep(makeMap(deps, callback).f);
347        } else if (!deps.splice) {
348            //deps is a config object, not an array.
349            config = deps;
350            if (config.deps) {
351                req(config.deps, config.callback);
352            }
353            if (!callback) {
354                return;
355            }
356
357            if (callback.splice) {
358                //callback is an array, which means it is a dependency list.
359                //Adjust args if there are dependencies
360                deps = callback;
361                callback = relName;
362                relName = null;
363            } else {
364                deps = undef;
365            }
366        }
367
368        //Support require(['a'])
369        callback = callback || function () {};
370
371        //If relName is a function, it is an errback handler,
372        //so remove it.
373        if (typeof relName === 'function') {
374            relName = forceSync;
375            forceSync = alt;
376        }
377
378        //Simulate async callback;
379        if (forceSync) {
380            main(undef, deps, callback, relName);
381        } else {
382            //Using a non-zero value because of concern for what old browsers
383            //do, and latest browsers "upgrade" to 4 if lower value is used:
384            //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
385            //If want a value immediately, use require('id') instead -- something
386            //that works in almond on the global level, but not guaranteed and
387            //unlikely to work in other AMD implementations.
388            setTimeout(function () {
389                main(undef, deps, callback, relName);
390            }, 4);
391        }
392
393        return req;
394    };
395
396    /**
397     * Just drops the config on the floor, but returns req in case
398     * the config return value is used.
399     */
400    req.config = function (cfg) {
401        return req(cfg);
402    };
403
404    /**
405     * Expose module registry for debugging and tooling
406     */
407    requirejs._defined = defined;
408
409    define = function (name, deps, callback) {
410        if (typeof name !== 'string') {
411            throw new Error('See almond README: incorrect module build, no module name');
412        }
413
414        //This module may not have dependencies
415        if (!deps.splice) {
416            //deps is not an array, so probably means
417            //an object literal or factory function for
418            //the value. Adjust args.
419            callback = deps;
420            deps = [];
421        }
422
423        if (!hasProp(defined, name) && !hasProp(waiting, name)) {
424            waiting[name] = [name, deps, callback];
425        }
426    };
427
428    define.amd = {
429        jQuery: true
430    };
431}());
432
433define("../lib/almond", function(){});
434
435define( 'models/whenModel',[], function() {
436	var model = Backbone.Model.extend( {
437		initialize: function( models, options ) {
438			/*
439			 * If our key or comparator is empty, don't do anything else.
440			 */
441			if ( ! this.get( 'key' ) || ! this.get( 'comparator' ) ) return;
442
443			/*
444			 * Our key could be a field or a calc.
445			 * We need to setup a listener on either the field or calc model for changes.
446			 */
447			if ( 'calc' == this.get( 'type' ) ) { // We have a calculation key
448				/*
449				 * Get our calc model
450				 */
451				var calcModel = nfRadio.channel( 'form-' + this.collection.options.condition.collection.formModel.get( 'id' ) ).request( 'get:calc', this.get( 'key' ) );
452
453				if( 'undefined' == typeof calcModel ) return;
454
455				/*
456				 * When we update our calculation, update our compare
457				 */
458				this.listenTo( calcModel, 'change:value', this.updateCalcCompare );
459				/*
460				 * Update our compare status.
461				 */
462				this.updateCalcCompare( calcModel );
463			} else { // We have a field key
464				// Get our field model
465				var fieldModel = nfRadio.channel( 'form-' + options.condition.collection.formModel.get( 'id' ) ).request( 'get:fieldByKey', this.get( 'key' ) );
466
467				if( 'undefined' == typeof fieldModel ) return;
468
469				// When we change the value of our field, update our compare status.
470				fieldModel.on( 'change:value', this.updateFieldCompare, this );
471				// When we keyup in our field, maybe update our compare status.
472				this.listenTo( nfRadio.channel( 'field-' + fieldModel.get( 'id' ) ), 'keyup:field', this.maybeupdateFieldCompare );
473				// Update our compare status.
474				this.updateFieldCompare( fieldModel );
475
476				/*
477				 * TODO: This should be moved to the show_field/hide_field file because it is specific to showing and hiding.
478				 * Create a radio message here so that the specific JS file can hook into whenModel init.
479				 */
480				fieldModel.on( 'change:visible', this.updateFieldCompare, this );
481			}
482		},
483
484		updateCalcCompare: function( calcModel ) {
485			this.updateCompare( calcModel.get( 'value' ) );
486		},
487
488		maybeupdateFieldCompare: function( el, fieldModel, keyCode ) {
489			if( 'checkbox' == fieldModel.get( 'type' ) ){
490                var fieldValue = ( 'checked' == jQuery( el ).attr( 'checked' ) ) ? 1 : 0;
491            } else if( 'listcheckbox' == fieldModel.get( 'type' ) ) {
492				// This field isn't a single element, so we need to reference the fieldModel, instead of the DOM.
493                var fieldValue = fieldModel.get( 'value' ).join();
494            } else if ( 'date' == fieldModel.get ('type' ) ) {
495				var fieldValue = fieldModel.get( 'value' );
496
497				if ( _.isEmpty( fieldValue ) ) {
498					fieldValue = '1970/01/01';
499				}
500
501				let date_mode = fieldModel.get( 'date_mode' );
502				if ( 'undefined' == typeof date_mode ) { // If 'date_mode' is undefined, then we assume it's date_only.
503					date_mode = 'date_only';
504				}
505				let date = 0;
506				// If we're in time_only mode, then we need to use 1970-01-01 as our date.
507				if ( 'time_only' == fieldModel.get( 'date_mode' ) ) {
508					date = '1970/01/01';
509				} else {
510					date = fieldValue;
511				}
512
513				// Convert field value into a timestamp
514				let hour = fieldModel.get( 'selected_hour' );
515				if ( 'undefined' == typeof hour ) {
516					hour = '00';
517				}
518
519				let minute = fieldModel.get( 'selected_minute' );
520				if ( 'undefined' == typeof minute ) {
521					minute = '00';
522				}
523
524				// If we have a date_and_time field, but we haven't selected a date yet, we don't need to compare.
525				if ( 'date_and_time' == date_mode && '1970/01/01' == date ) {
526					fieldValue = false;
527				} else {
528					fieldValue = date + ' ' + hour + ':' + minute + ' UT';
529
530					let dateObject = new Date( fieldValue );
531					fieldValue = Math.floor( dateObject.getTime() / 1000 );					
532				}
533			} else {
534				var fieldValue = jQuery( el ).val();
535			}
536
537			this.updateFieldCompare( fieldModel, null, fieldValue );
538		},
539
540		updateCompare: function( value ) {
541			var this_val = this.get( 'value' );
542
543			// if this is a calcModel then let's convert to number for comparison
544			if ( 'calc' === this.get( 'type' ) ) {
545				this_val = Number( this_val );
546				value = Number( value );
547			}
548			// Check to see if the value of the field model value COMPARATOR the value of our when condition is true.
549			var status = this.compareValues[ this.get( 'comparator' ) ]( value, this_val );
550			this.set( 'status', status );
551		},
552
553		updateFieldCompare: function( fieldModel, val, fieldValue ) {
554			if ( _.isEmpty( fieldValue ) ) {
555				fieldValue = fieldModel.get( 'value' );
556			}
557
558			// Change the value of checkboxes to match the new convention.
559			if( 'checkbox' == fieldModel.get( 'type' ) ) {
560				if( 0 == fieldValue ) {
561					fieldValue = 'unchecked';
562				} else {
563					fieldValue = 'checked';
564				}
565			} else if ( 'date' == fieldModel.get( 'type' ) ) {
566				if ( _.isEmpty( fieldValue ) ) {
567					fieldValue = '1970/01/01';
568				}
569
570				let date_mode = fieldModel.get( 'date_mode' );
571				if ( 'undefined' == typeof date_mode ) { // If 'date_mode' is undefined, then we assume it's date_only.
572					date_mode = 'date_only';
573				}
574				let date = 0;
575				// If we're in time_only mode, then we need to use 1970-01-01 as our date.
576				if ( 'time_only' == fieldModel.get( 'date_mode' ) ) {
577					date = '1970/01/01';
578				} else {
579					date = fieldValue;
580				}
581
582				// Convert field value into a timestamp
583				let hour = fieldModel.get( 'selected_hour' );
584				if ( 'undefined' == typeof hour ) {
585					hour = '00';
586				}
587
588				let ampm = fieldModel.get( 'selected_ampm' );
589				if ( 'undefined' != typeof ampm ) {
590					// Convert our hour into 24 hr format.
591					if ( 'pm' == ampm && '12' != hour ) {
592						hour = parseInt( hour ) + 12;
593					} else if ( 'am' == ampm && '12' == hour ) {
594						hour = '00';
595					}
596				}
597
598				let minute = fieldModel.get( 'selected_minute' );
599				if ( 'undefined' == typeof minute ) {
600					minute = '00';
601				}
602
603				// If we have a date_and_time field, but we haven't selected a date yet, we don't need to compare.
604				if ( 'date_and_time' == date_mode && '1970/01/01' == date ) {
605					fieldValue = false;
606				} else {
607					fieldValue = date + ' ' + hour + ':' + minute + ' UT';
608
609					let dateObject = new Date( fieldValue );
610					fieldValue = Math.floor( dateObject.getTime() / 1000 );					
611				}
612			}
613
614			this.updateCompare( fieldValue );
615
616			/*
617			 * TODO: This should be moved to the show_field/hide_field file because it is specific to showing and hiding.
618			 */
619			if ( ! fieldModel.get( 'visible' ) ) {
620				this.set( 'status', false );
621			}			
622		},
623
624		compareValues: {
625			'equal': function( a, b ) {
626				return a == b;
627			},
628			'notequal': function( a, b ) {
629				return a != b;
630			},
631			'contains': function( a, b ) {
632				if ( jQuery.isArray( a ) ) {
633					/*
634					 * If a is an array, then we're searching for an index.
635					 */
636					return a.indexOf( b ) >= 0;
637				} else {
638					/*
639					 * If a is a string, then we're searching for a string position.
640					 *
641					 * If our b value has quotes in it, we want to find that exact word or phrase.
642					 */
643					if ( b.indexOf( '"' ) >= 0 ) {
644						b = b.replace( /['"]+/g, '' );
645						return new RegExp("\\b" + b + "\\b").test( a );
646					}
647					return a.toLowerCase().indexOf( b.toLowerCase() ) >= 0; 				
648				}
649			},
650			'notcontains': function( a, b ) {
651				return ! this.contains( a, b );
652			},
653			'greater': function( a, b ) {
654				/*
655				 * In 2.9.x, you could use the greater and less like string count.
656				 * i.e. if textbox > (empty string) do something.
657				 * This recreates that ability.
658				 */
659				if ( jQuery.isNumeric( b ) ) {
660					return parseFloat( a ) > parseFloat( b );
661				} else if ( 'string' == typeof a ) {
662					return 0 < a.length;
663				}
664				
665			},
666			'less': function( a, b ) {
667				/*
668				 * In 2.9.x, you could use the greater and less like string count.
669				 * i.e. if textbox > (empty string) do something.
670				 * This recreates that ability.
671				 */
672				if ( jQuery.isNumeric( b ) ) {
673					return parseFloat( a ) < parseFloat( b );
674				} else if ( 'string' == typeof a ) {
675					return 0 >= a.length;
676				}
677		
678			},
679			'greaterequal': function( a, b ) {
680				return parseFloat( a ) > parseFloat( b ) || parseFloat( a ) == parseFloat( b );
681			},
682			'lessequal': function( a, b ) {
683				return parseFloat( a ) < parseFloat( b ) || parseFloat( a ) == parseFloat( b );
684			}
685		} 
686	} );
687	
688	return model;
689} );
690define( 'models/whenCollection',['models/whenModel'], function( WhenModel ) {
691	var collection = Backbone.Collection.extend( {
692		model: WhenModel,
693
694		initialize: function( models, options ) {
695			this.options = options;
696		}
697	} );
698	return collection;
699} );
700define( 'models/conditionModel',[ 'models/whenCollection' ], function( WhenCollection ) {
701	var model = Backbone.Model.extend( {
702		initialize: function( options ) {
703			/*
704			 * Our "when" statement will be like:
705			 * When field1 == value
706			 * AND field2 == value
707			 *
708			 * We need to create a collection out of this when statement, with each row as a model.
709			 */
710			this.set( 'when', new WhenCollection( this.get( 'when' ), { condition: this } ) );
711			/*
712			 * When we update any of our "when" models' status, check to see if we should send a message.
713			 */
714			this.get( 'when' ).on( 'change:status', this.checkWhen, this );
715			/*
716			 * Check our initial status;
717			 */
718			this.checkWhen();
719		},
720
721		checkWhen: function() {
722			/*
723			 * If we have any OR connectors, then any status being true should trigger pass.
724			 * Otherwise, we need every status to be true.
725			 */
726			var statusResults = this.get( 'when' ).pluck( 'status' );
727
728			var connectors = this.get( 'when' ).pluck( 'connector' );
729			var allAND = _.every( _.values( connectors ), function( v ) { return v == 'AND' }, this );
730			if ( allAND ) {
731				var status = _.every( _.values( statusResults ), function(v) { return v; }, this );
732			} else {
733				var status = _.some( _.values( statusResults ), function(v) { return v; }, this );
734			}
735
736			if ( status ) {
737			   	/*
738			 	 * Send out a request for each of our "then" statements.
739			 	 */
740				_.each( this.get( 'then' ), function( then, index ) {
741					nfRadio.channel( 'condition:trigger' ).request( then.trigger, this, then );
742				}, this );			 
743			} else {
744				/*
745				 * Send out a request for each of our "else" statements.
746				 */
747				_.each( this.get( 'else' ), function( elseData, index ) {
748					nfRadio.channel( 'condition:trigger' ).request( elseData.trigger, this, elseData );
749				}, this );
750			}
751		}
752	} );
753	
754	return model;
755} );
756define( 'models/conditionCollection',['models/conditionModel'], function( ConditionModel ) {
757	var collection = Backbone.Collection.extend( {
758		model: ConditionModel,
759
760		initialize: function( models, options ) {
761			this.formModel = options.formModel;
762		}
763	} );
764	return collection;
765} );
766/**
767 * Initialise condition collection
768 * 
769 * @package Ninja Forms Conditional Logic
770 * @copyright (c) 2016 WP Ninjas
771 * @since 3.0
772 */
773define( 'controllers/initCollection',[ 'models/conditionCollection' ], function( ConditionCollection ) {
774	var controller = Marionette.Object.extend( {
775		initialize: function( formModel ) {
776			this.collection = new ConditionCollection( formModel.get( 'conditions' ), { formModel: formModel } );
777            this.listenTo(nfRadio.channel('fields'), 'reset:collection', this.resetCollection);
778		},
779        resetCollection: function( fieldsCollection ) {
780            var formModel = fieldsCollection.options.formModel;
781            this.collection = new ConditionCollection( formModel.get( 'conditions' ), { formModel: formModel } );
782        }
783	});
784
785	return controller;
786} );
787/**
788 * Handle showing/hiding fields
789 * 
790 * @package Ninja Forms Conditional Logic
791 * @copyright (c) 2016 WP Ninjas
792 * @since 3.0
793 */
794define( 'controllers/showHide',[], function() {
795	var controller = Marionette.Object.extend( {
796		initialize: function() {
797			nfRadio.channel( 'condition:trigger' ).reply( 'hide_field', this.hideField, this );
798			nfRadio.channel( 'condition:trigger' ).reply( 'show_field', this.show
798Field, this );
799		},
800
801		hideField: function( conditionModel, then ) {
802			var targetFieldModel = nfRadio.channel( 'form-' + conditionModel.collection.formModel.get( 'id' ) ).request( 'get:fieldByKey', then.key );
803
804			if( 'undefined' == typeof targetFieldModel ) return;
805			targetFieldModel.set( 'visible', false );
806            if ( ! targetFieldModel.get( 'clean' ) ) {
807				targetFieldModel.trigger( 'change:value', targetFieldModel );
808			}
809			
810			nfRadio.channel( 'fields' ).request( 'remove:error', targetFieldModel.get( 'id' ), 'required-error' );
811		},
812
813		showField: function( conditionModel, then ) {
814			var targetFieldModel = nfRadio.channel( 'form-' + conditionModel.collection.formModel.get( 'id' ) ).request( 'get:fieldByKey', then.key );
815			//TODO: Add an error to let the user know the show/hide field is empty.
816			if( 'undefined' == typeof targetFieldModel ) return;
817			targetFieldModel.set( 'visible', true );
818            if ( ! targetFieldModel.get( 'clean' ) ) {
819                targetFieldModel.trigger( 'change:value', targetFieldModel );
820			}
821			if ( 'recaptcha' === targetFieldModel.get( 'type' ) ) {
822				this.renderRecaptcha();
823			}
824			if ( 'turnstile' === targetFieldModel.get( 'type' ) ) {
825				this.renderTurnstile();
826			}
827			var viewEl = { el: nfRadio.channel( 'form-' + conditionModel.collection.formModel.get( 'id' ) ).request( 'get:el' ) };
828            nfRadio.channel( 'form' ).request( 'init:help', viewEl );
829		},
830
831		renderRecaptcha: function() {
832			jQuery( '.g-recaptcha' ).each( function() {
833                var callback = jQuery( this ).data( 'callback' );
834                var fieldID = jQuery( this ).data( 'fieldid' );
835                if ( typeof window[ callback ] !== 'function' ){
836                    window[ callback ] = function( response ) {
837                        nfRadio.channel( 'recaptcha' ).request( 'update:response', response, fieldID );
838                    };
839                }
840				var opts = {
841					theme: jQuery( this ).data( 'theme' ),
842					sitekey: jQuery( this ).data( 'sitekey' ),
843					callback: callback
844				};
845				
846				grecaptcha.render( jQuery( this )[0], opts );
847			} );
848		},
849
850		renderTurnstile: function() {
851			// Ensure turnstile API is loaded
852			if ( typeof turnstile === 'undefined' ) {
853				return;
854			}
855
856			jQuery( '.cf-turnstile, .nf-cf-turnstile' ).each( function() {
857				var element = this;
858				var sitekey = jQuery( element ).data( 'sitekey' );
859				var fieldID = jQuery( element ).data( 'fieldid' );
860				
861				// Skip if no sitekey or already rendered
862				if ( ! sitekey || jQuery( element ).children().length > 0 ) {
863					return;
864				}
865
866				try {
867					// Create callback function for this specific field
868					var callbackName = 'nfTurnstileCallback_' + fieldID;
869					
870					// Define the callback function
871					window[ callbackName ] = function( token ) {
872						// Update the hidden input field
873						var input = document.getElementById( 'nf-field-' + fieldID );
874						if ( input ) {
875							input.value = token;
876							jQuery( input ).trigger( 'change' );
877							
878							// Remove error states
879							jQuery( input ).closest( '.field-wrap' ).removeClass( 'nf-error' );
880							jQuery( input ).closest( '.field-wrap' ).find( '.nf-error-msg' ).remove();
881						}
882
883						// Update via radio channel if available
884						if ( typeof nfRadio !== 'undefined' && nfRadio.channel ) {
885							try {
886								nfRadio.channel( 'turnstile' ).request( 'update:response', token, fieldID );
887							} catch( e ) {
888								// Silent fail
889							}
890						}
891					};
892
893					// Render the turnstile widget
894					turnstile.render( element, {
895						sitekey: sitekey,
896						theme: jQuery( element ).data( 'theme' ) || 'auto',
897						size: jQuery( element ).data( 'size' ) || 'normal',
898						callback: callbackName
899					} );
900					
901				} catch( e ) {
902					// Silent fail for turnstile render errors
903				}
904			} );
905		}
906	});
907
908	return controller;
909} );
910/**
911 * Setting/unsetting required.
912 * 
913 * @package Ninja Forms Conditional Logic
914 * @copyright (c) 2019 WP Ninjas
915 * @since 3.0
916 */
917define( 'controllers/changeRequired',[], function() {
918	var controller = Marionette.Object.extend( {
919		initialize: function() {
920			nfRadio.channel( 'condition:trigger' ).reply( 'set_required', this.setRequired, this );
921			nfRadio.channel( 'condition:trigger' ).reply( 'unset_required', this.unsetRequired, this );
922		},
923
924		setRequired: function( conditionModel, then ) {
925			var targetFieldModel = nfRadio.channel( 'form-' + conditionModel.collection.formModel.get( 'id' ) ).request( 'get:fieldByKey', then.key );
926
927			if( 'undefined' == typeof targetFieldModel ) return;
928            targetFieldModel.set( 'required', 1 );
929			targetFieldModel.trigger( 'reRender', targetFieldModel );
930		},
931
932		unsetRequired: function( conditionModel, then ) {
933			var targetFieldModel = nfRadio.channel( 'form-' + conditionModel.collection.formModel.get( 'id' ) ).request( 'get:fieldByKey', then.key );
934
935			if( 'undefined' == typeof targetFieldModel ) return;
936            targetFieldModel.set( 'required', 0 );
937            targetFieldModel.trigger( 'reRender', targetFieldModel );
938            // Ensure we resolve any errors when the field is no longer required.
939			nfRadio.channel( 'fields' ).request( 'remove:error', targetFieldModel.get( 'id' ), 'required-error' );
940        }
941        
942	});
943
944	return controller;
945} );
946/**
947 * Handle adding or removing an option from our list
948 * 
949 * @package Ninja Forms Conditional Logic
950 * @copyright (c) 2016 WP Ninjas
951 * @since 3.0
952 */
953define( 'controllers/showHideOption',[], function() {
954	var controller = Marionette.Object.extend( {
955		initialize: function() {
956			nfRadio.channel( 'condition:trigger' ).reply( 'show_option', this.showOption, this );
957
958			nfRadio.channel( 'condition:trigger' ).reply( 'hide_option', this.hideOption, this );
959		},
960
961		showOption: function( conditionModel, then ) {
962			var option = this.getOption( conditionModel, then );
963			option.visible = true;
964			this.updateFieldModel( conditionModel, then );
965		},
966
967		hideOption: function( conditionModel, then ) {
968			var option = this.getOption( conditionModel, then );
969			option.visible = false;
970			this.updateFieldModel( conditionModel, then );
971		},
972
973		getFieldModel: function( conditionModel, then ) {
974			return nfRadio.channel( 'form-' + conditionModel.collection.formModel.get( 'id' ) ).request( 'get:fieldByKey', then.key );
975		},
976
977		getOption: function( conditionModel, then ) {
978			var targetFieldModel = this.getFieldModel( conditionModel, then );
979			var options = targetFieldModel.get( 'options' );
980			return _.find( options, function( option ) { return option.value == then.value } );
981		},
982
983		updateFieldModel: function( conditionModel, then ) {
984			var targetFieldModel = this.getFieldModel( conditionModel, then );
985			var options = targetFieldModel.get( 'options' );
986			targetFieldModel.set( 'options', options );
987			targetFieldModel.trigger( 'reRender' );
988		}
989	});
990
991	return controller;
992} );
993/**
994 * Handle changing a field's value
995 * 
996 * @package Ninja Forms Conditional Logic
997 * @copyright (c) 2016 WP Ninjas
998 * @since 3.0
999 */
1000define( 'controllers/changeValue',[], function() {
1001	var controller = Marionette.Object.extend( {
1002		initialize: function() {
1003			nfRadio.channel( 'condition:trigger' ).reply( 'change_value', this.changeValue, this );
1004		},
1005
1006		changeValue: function( conditionModel, then ) {
1007			var targetFieldModel = nfRadio.channel( 'form-' + conditionModel.collection.formModel.get( 'id' ) ).request( 'get:fieldByKey', then.key );
1008			/*
1009			 * If we have a checkbox then we need to change the value that is set
1010			 * of the then variable to a 1 or 0 to re-render on the front end when
1011			 * the condition is met.
1012			 */
1013			if( 'checkbox' == targetFieldModel.get( 'type' ) ) {
1014				// We also need to do the opposite of the value that is in the changed model.
1015				if( 'unchecked' == targetFieldModel.changed.value ) {
1016					then.value = 1;
1017                } else if( 'checked' == targetFieldModel ) {
1018					then.value = 0;
1019				}
1020			}
1021            /*
1022             * Change the value of our field model, and then trigger a re-render of its view.
1023             */
1024			targetFieldModel.set( 'value', then.value );
1025			targetFieldModel.trigger( 'reRender', targetFieldModel );
1026		},
1027
1028	});
1029	return controller;
1030} );
1031/**
1032 * Handle selecting/deselecting list options
1033 * 
1034 * @package Ninja Forms Conditional Logic
1035 * @copyright (c) 2016 WP Ninjas
1036 * @since 3.0
1037 */
1038define( 'controllers/selectDeselect',[], function() {
1039	var controller = Marionette.Object.extend( {
1040		initialize: function() {
1041			nfRadio.channel( 'condition:trigger' ).reply( 'select_option', this.selectOption, this );
1042
1043			nfRadio.channel( 'condition:trigger' ).reply( 'deselect_option', this.deselectOption, this );
1044		},
1045
1046		selectOption: function( conditionModel, then ) {
1047			/*
1048			 * Get our field model and set this option's "selected" property to 1
1049			 */
1050			var targetFieldModel = nfRadio.channel( 'form-' + conditionModel.collection.formModel.get( 'id' ) ).request( 'get:fieldByKey', then.key );
1051
1052
1053			if( _.contains( [ 'listselect', 'listcountry', 'liststate' ], targetFieldModel.get( 'type' ) ) ) { // TODO: Make this more dynamic.
1054				targetFieldModel.set('clean', false); // Allows for changes to default values.
1055			}
1056
1057			var options = targetFieldModel.get( 'options' );
1058
1059			var option = _.find( options, { value: then.value } );
1060			option.selected = 1;
1061
1062			targetFieldModel.set( 'options', options );
1063
1064			if( _.contains( [ 'listselect', 'listcountry', 'liststate' ], targetFieldModel.get( 'type' ) ) ) { // TODO: Make this more dynamic.
1065				targetFieldModel.set( 'value', option.value ); // Propagate the selected option to the model's value.
1066			} else {
1067				var value = targetFieldModel.get( 'value' );
1068				if ( _.isArray( value ) ) {
1069                    if ( 0 > value.indexOf( option.value ) ) {
1070                        value.push( option.value );
1071                        // Set the value to nothing so it knows that something has changed.
1072                        targetFieldModel.set( 'value', '' );
1073                    }
1074				} else {
1075					value = option.value;
1076				}
1077				
1078				targetFieldModel.set( 'value', value ); // Propagate the selected option to the model's value.
1079			}
1080
1081			/*
1082			 * Re render our field
1083			 */
1084			targetFieldModel.trigger( 'reRender', targetFieldModel );
1085		},
1086
1087		deselectOption: function( conditionModel, then ) {
1088			/*
1089			 * When we are trying to deselect our option, we need to change it's "selected" property to 0 AND change its value.
1090			 */
1091			var targetFieldModel = nfRadio.channel( 'form-' + conditionModel.collection.formModel.get( 'id' ) ).request( 'get:fieldByKey', then.key );
1092
1093			/*
1094			 * Set "selected" to 0.
1095			 */
1096			var options = targetFieldModel.get( 'options' );
1097			var option = _.find( options, { value: then.value } );
1098			option.selected = 0;
1099			targetFieldModel.set( 'options', options );
1100
1101			/*
1102			 * Update our value
1103			 */
1104			var currentValue = targetFieldModel.get( 'value' );
1105			if ( _.isArray( currentValue ) ) {
1106				currentValue = _.without( currentValue, then.value );
1107			} else {
1108				currentValue = '';
1109			}
1110			targetFieldModel.set( 'value', currentValue );
1111
1112			/*
1113			 * Re render our field
1114			 */
1115			targetFieldModel.trigger( 'reRender', targetFieldModel );
1116		},
1117
1118	});
1119
1120	return controller;
1121} );
1122/**
1123 * Keep an internal record for which actions are active and deactive.
1124 * 
1125 * @package Ninja Forms Conditional Logic
1126 * @copyright (c) 2016 WP Ninjas
1127 * @since 3.0
1128 */
1129define( 'controllers/actions',[], function() {
1130	var controller = Marionette.Object.extend( {
1131		actions: {},
1132		
1133		initialize: function() {
1134			/*
1135			 * Listen for activate/deactivate action messages.
1136			 */
1137			nfRadio.channel( 'condition:trigger' ).reply( 'activate_action', this.activateAction, this );
1138			nfRadio.channel( 'condition:trigger' ).reply( 'deactivate_action', this.deactivateAction, this );
1139		
1140			/*
1141			 * Reply to requests for action status.
1142			 */
1143			nfRadio.channel( 'actions' ).reply( 'get:status', this.getStatus, this );
1144		},
1145
1146		activateAction: function( conditionModel, thenObject ) {
1147			this.actions[ thenObject.key ] = true;
1148			console.log( 'activate action' );
1149		},
1150
1151		deactivateAction: function( conditionModel, thenObject ) {
1152			console.log( 'deactivate action' );
1153			this.actions[ thenObject.key ] = false;
1154		},
1155
1156		getStatus: function( $id ) {
1157			return this.actions[ $id ];
1158		}
1159	});
1160
1161	return controller;
1162} );
1163var nfRadio = Backbone.Radio;
1164
1165require( [ 'controllers/initCollection', 'controllers/showHide', 'controllers/changeRequired', 'controllers/showHideOption', 'controllers/changeValue', 'controllers/selectDeselect', 'controllers/actions' ], function( InitCollection, ShowHide, ChangeRequired, ShowHideOption, ChangeValue, SelectDeselect, Actions ) {
1166
1167	var NFConditionalLogic = Marionette.Application.extend( {
1168
1169		initialize: function( options ) {
1170			this.listenTo( nfRadio.channel( 'form' ), 'after:loaded', this.loadControllers );
1171		},
1172
1173		loadControllers: function( formModel ) {
1174			new ShowHide();
1175			new ChangeRequired();
1176			new ShowHideOption();
1177			new ChangeValue();
1178			new SelectDeselect();
1179			new Actions();
1180			new InitCollection( formModel );
1181		},
1182
1183		onStart: function() {
1184			
1185		}
1186	} );
1187
1188	var nfConditionalLogic = new NFConditionalLogic();
1189	nfConditionalLogic.start();
1190} );
1191define("main", function(){});
1192
1193}());
1194//# sourceMappingURL=front-end.js.map

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.