From b07d7341eb03678bb834d4d85c44e22254e87c55 Mon Sep 17 00:00:00 2001 From: Ryan Cramer Date: Tue, 11 Sep 2018 11:31:34 -0400 Subject: [PATCH] Improvements and refactorings to inputfields.js, plus add processwire/processwire-requests#224, and addition of new public API methods: InputfieldFocus($inputfield) which finds, opens and focuses an Inputfield (making it visible) regardless of where it is in the interface; InputfieldOpen($inputfield) which opens a collapsed Inputfield; and InputfieldClose($inputfield) which does the opposite. Thanks to @Toutouwai for the feature request and example code that got this started. --- wire/templates-admin/scripts/inputfields.js | 334 ++++++++++++++---- .../scripts/inputfields.min.js | 2 +- 2 files changed, 265 insertions(+), 71 deletions(-) diff --git a/wire/templates-admin/scripts/inputfields.js b/wire/templates-admin/scripts/inputfields.js index 1278d856..3e1724ee 100644 --- a/wire/templates-admin/scripts/inputfields.js +++ b/wire/templates-admin/scripts/inputfields.js @@ -33,6 +33,7 @@ var InputfieldDependenciesProcessing = false; * */ function InputfieldDependencies($target) { + var $ = jQuery; if(InputfieldDependenciesProcessing) return; @@ -644,6 +645,7 @@ function InputfieldDependencies($target) { function InputfieldColumnWidths($target) { + var $ = jQuery; var hasTarget = true; if(typeof $target == "undefined") { hasTarget = false; @@ -899,6 +901,7 @@ function InputfieldColumnWidths($target) { * */ function InputfieldFormBeforeUnloadEvent(e) { + var $ = jQuery; var $changes = $(".InputfieldFormConfirm:not(.InputfieldFormSubmitted) .InputfieldStateChanged"); if($changes.length == 0) return; var msg = $('.InputfieldFormConfirm:eq(0)').attr('data-confirm') + "\n"; @@ -918,9 +921,196 @@ function InputfieldFormBeforeUnloadEvent(e) { return msg; // Gecko and WebKit } +/** + * Focus the Inputfield + * + * If the Inputfield is not visible, this method will track it down and reveal it. + * If the Inputfield is collapsed, this method will open it. + * If the Inputfield has an input that can be focused, it will be focused. + * + * @param $inputfield + * + */ +function InputfieldFocus($inputfield) { + + if(!$inputfield.hasClass('Inputfield')) $inputfield = $inputfield.closest('.Inputfield'); + if(!$inputfield.length) return; + + if($inputfield.hasClass('InputfieldStateCollapsed') || !$inputfield.is(':visible')) { + InputfieldToggle($inputfield, true, 0, function($in, open, duration) { + InputfieldFocus($in); + }); + return; + } + + var focused = false; + if($inputfield.hasClass('InputfieldNoFocus')) { + // does not support focusing + } else { + var $input = $inputfield.find(":input:visible:enabled:not(button):not(.InputfieldNoFocus):first"); + if($input.length) { + if($input.css('position') == 'absolute' || $input.is('button')) { + // do not attempt to focus absolute positioned inputs or button elements + } else { + var t = $input.attr('type'); + if($input.is('textarea') || t == 'text' || t == 'email' || t == 'url' || t == 'number') { + $input.focus(); + focused = true; + } + } + } + } + + if(!focused) { + // item could not be directly focused, see if we can make make it visible + var pageTop = jQuery(window).scrollTop(); + var pageBottom = pageTop + jQuery(window).height(); + var inputTop = $inputfield.offset().top; + var inputBottom = inputTop + $inputfield.height(); + var inView = ((inputTop <= pageBottom) && (inputBottom >= pageTop)); + // var fullyInView = ((pageTop < inputTop) && (pageBottom > inputBottom)); + if(!inView) setTimeout(function() { + // if the browser couldn't focus the inputfield, at least show where it is + jQuery('html, body').animate({ + scrollTop: $inputfield.offset().top - 10 + }, 100); + }, 100); + } +} + +/** + * Toggle the given $inputfield open or closed + * + * Also triggers these events on $inputfield: openReady, closeReady, opened, closed + * + * @param $inputfield Inputfield to toggle, or some element within it + * @param open Boolean true to open, false to close, or null for opposite of current state + * @param duration How many milliseconds for animation? (default=100) + * @param completedCallback Optional function to call upon completion, given $inputfield as argument + * @returns {boolean} + * + */ +function InputfieldToggle($inputfield, open, duration, completedCallback) { + + if(!$inputfield.length) return; + if(!$inputfield.hasClass('Inputfield')) $inputfield = $inputfield.closest('.Inputfield'); + + var $header = $inputfield.children('.InputfieldHeader, .ui-widget-header'); + var $content = $inputfield.children('.InputfieldContent, .ui-widget-content'); + var $toggleIcon = $header.find('.toggle-icon'); + var isCollapsed = $inputfield.hasClass("InputfieldStateCollapsed"); + + if($inputfield.hasClass('InputfieldAjaxLoading')) return false; + if($inputfield.hasClass('InputfieldStateToggling')) return false; + + if(typeof open == "undefined" || open === null) var open = isCollapsed; + if(typeof duration == "undefined") var duration = 100; + + function completed() { + if(typeof completedCallback != "undefined") completedCallback($inputfield, open, duration); + } + + function toggled() { + // jQuery seems to add overflow:hidden, and this interferes with outline CSS property on Inputfields + if($inputfield.css('overflow') == 'hidden') $inputfield.css('overflow', ''); + $toggleIcon.toggleClass($toggleIcon.attr('data-to')); // data-to=classes to toggle + $inputfield.removeClass('InputfieldStateToggling'); + setTimeout('InputfieldColumnWidths()', 500); + completed(); + } + + function opened() { + $inputfield.trigger('opened'); + if($inputfield.hasClass('InputfieldColumnWidth')) { + $inputfield.children('.InputfieldContent').show(); + } + if(!$inputfield.hasClass('InputfieldNoFocus')) InputfieldFocus($inputfield); + toggled(); + } + + function closed() { + if($inputfield.css('overflow') == 'hidden') $inputfield.css('overflow', ''); + $inputfield.trigger('closed'); + if($inputfield.hasClass('InputfieldColumnWidth')) { + $inputfield.children('.InputfieldContent').hide(); + } + toggled(); + } + + // check if we need to open parent inputfields first + if(open && !$inputfield.is(':visible')) { + // if Inputfield is in a non-visible tab, open the tab + var $tabContent = $inputfield.parents('.InputfieldWrapper').last(); + if($tabContent.length && !$tabContent.is(':visible')) { + var $tabButton = jQuery('#_' + $tabContent.attr('id')); + if($tabButton.length) { + $tabContent.show(); + setTimeout(function() { $tabButton.click(); }, 25); + } + } + // inputfield is not visible likely due to parents being hidden + var $collapsedParent = $inputfield.closest('.InputfieldStateCollapsed'); + if($collapsedParent.length) { + InputfieldToggle($collapsedParent, true, duration, function($in) { + InputfieldToggle($in, true, duration, completedCallback); + }); + // InputfieldToggle($collapsedParent, true, 0); + } + } + + // if open requested and inputfield already open, no action is needed + if(open && !isCollapsed) { + completed(); + return; + } + + // if close requested and inputfield already closed, no action is needed + if(!open && isCollapsed) { + completed(); + return; + } + + // if ajax loaded, force InputfieldStates() click handler to open this one + if(isCollapsed && ($inputfield.hasClass('collapsed10') || $inputfield.hasClass('collapsed11'))) { + $toggleIcon.click(); + return; + } + + // handle either open or close + if(open && isCollapsed) { + $inputfield.addClass('InputfieldStateToggling').trigger('openReady'); + $inputfield.toggleClass('InputfieldStateCollapsed', duration, opened); + } else if(!open && !isCollapsed) { + $inputfield.addClass('InputfieldStateToggling').trigger('closeReady'); + $inputfield.toggleClass('InputfieldStateCollapsed', duration, closed); + } +} + +/** + * Open a collapsed Inputfield + * + * @param $inputfield + * @param duration Optional number of milliseconds for animation or 0 for none (default=100) + * + */ +function InputfieldOpen($inputfield, duration) { + InputfieldToggle($inputfield, true, duration); +} + +/** + * Close/collapse an open Inputfield + * + * @param $inputfield + * @param duration Optional number of milliseconds for animation or 0 for none (default=100) + * + */ +function InputfieldClose($inputfield, duration) { + InputfieldToggle($inputfield, false, duration); +} + /***************************************************************************************************** * Setup the toggles for Inputfields and the animations that occur between opening and closing - * + * */ function InputfieldStates($target) { @@ -997,6 +1187,7 @@ function InputfieldStates($target) { if($inputfields.length) { $inputfields.trigger('reloaded', [ 'InputfieldAjaxLoad' ]); InputfieldStates($li); + InputfieldRequirements($li); InputfieldColumnWidths(); } else { $li.trigger('reloaded', [ 'InputfieldAjaxLoad' ]); @@ -1064,8 +1255,10 @@ function InputfieldStates($target) { var isCollapsed = $li.hasClass("InputfieldStateCollapsed"); var wasCollapsed = $li.hasClass("InputfieldStateWasCollapsed"); var duration = 100; - + + if(!$li.length) return; if($li.hasClass('InputfieldAjaxLoading')) return false; + if($li.hasClass('InputfieldStateToggling')) return false; if(typeof data != "undefined") { if(typeof data.duration != "undefined") duration = data.duration; @@ -1077,31 +1270,9 @@ function InputfieldStates($target) { if(isCollapsed || wasCollapsed || isIcon) { $li.addClass('InputfieldStateWasCollapsed'); // this class only used here - $li.trigger(isCollapsed ? 'openReady' : 'closeReady'); - $li.toggleClass('InputfieldStateCollapsed', duration, function() { - // jQuery seems to add overflow:hidden, and this interferes with outline CSS property on Inputfields - if($li.css('overflow') == 'hidden') $li.css('overflow', ''); - if(isCollapsed) { - $li.trigger('opened'); - if($li.hasClass('InputfieldColumnWidth')) $li.children('.InputfieldContent').show(); - if($li.hasClass('InputfieldNoFocus')) return; - var $input = $li.find(":input:visible"); - if($input.length == 1 && !$input.is('button')) { - if($input.css('position') != 'absolute') { - var t = $input.attr('type'); - if($input.is('textarea') || t == 'text' || t == 'email' || t == 'url' || t == 'number') { - $input.focus(); - } - } - } - } else { - $li.trigger('closed'); - if($li.hasClass('InputfieldColumnWidth')) $li.children('.InputfieldContent').hide(); - } - }); - $icon.toggleClass($icon.attr('data-to')); // data-to=classes to toggle - setTimeout('InputfieldColumnWidths()', 500); + InputfieldToggle($li, null, duration); } else { + // Inputfield not collapsible unless toggle icon clicked, so pulsate the toggle icon and focus any inputs if(typeof jQuery.ui != 'undefined') { var color1 = $icon.css('color'); var color2 = $li.children('.InputfieldHeader, .ui-widget-header').css('color'); @@ -1110,7 +1281,7 @@ function InputfieldStates($target) { $icon.css('color', color1); }); } - if(!$li.hasClass('InputfieldNoFocus')) $li.find(":input:visible:eq(0)").focus(); + InputfieldFocus($li); } return false; @@ -1183,6 +1354,7 @@ function overflowAdjustments() { * */ function InputfieldIntentions() { + var $ = jQuery; // adjustments for unintended actions, like hitting enter in a text field in a multi-button form $(".InputfieldForm").each(function() { @@ -1250,7 +1422,7 @@ function InputfieldWindowResizeActions1() { // notify all Inputfields that they have been resized // note: event is not triggered at ready() so Inputfield should trigger its own // resize event if it needs this as part of setup - $(".Inputfield").trigger('resized'); + jQuery(".Inputfield").trigger('resized'); } function InputfieldWindowResizeActions2() { @@ -1259,6 +1431,58 @@ function InputfieldWindowResizeActions2() { InputfieldWindowResizeQueued = false; } +/** + * Manage required attributes on Inputfields + * + */ +function InputfieldRequirements($target) { + // show tab that input[required] is in, via @Toutouwai + jQuery(':input[required]', $target).on('invalid', function() { + var $input = jQuery(this); + InputfieldFocus(jQuery(this)); + }); +} + +/** + * Event handler called when 'reload' event is triggered on an Inputfield + * + */ +function InputfieldReloadEvent(event, extraData) { + console.log('InputfieldReloadEvent ' + $(this).attr('id')); + var $t = $(this); + var $form = $t.closest('form'); + var fieldName = $t.attr('id').replace('wrap_Inputfield_', ''); + var url = $form.attr('action'); + if(fieldName.indexOf('_repeater') > 0) { + var pageID = $t.closest('.InputfieldRepeaterItem').attr('data-page'); + url = url.replace(/\?id=\d+/, '?id=' + pageID); + fieldName = fieldName.replace(/_repeater\d+$/, ''); + } + url += url.indexOf('?') > -1 ? '&' : '?'; + url += 'field=' + fieldName + '&reloadInputfieldAjax=' + fieldName; + if(typeof extraData != "undefined") { + if(typeof extraData['queryString'] != "undefined") { + url += '&' + extraData['queryString']; + } + } + consoleLog('Inputfield reload: ' + fieldName); + $.get(url, function(data) { + var id = $t.attr('id'); + var $content = jQuery(data).find("#" + id).children(".InputfieldContent"); + if(!$content.length && id.indexOf('_repeater') > -1) { + id = 'wrap_Inputfield_' + fieldName; + $content = jQuery(data).find("#" + id).children(".InputfieldContent"); + if(!$content.length) { + console.log("Unable to find #" + $t.attr('id') + " in response from " + url); + } + } + $t.children(".InputfieldContent").html($content.html()); + // if(typeof jQuery.ui != 'undefined') $t.effect("highlight", 1000); + $t.trigger('reloaded', [ 'reload' ]); + }); + event.stopPropagation(); +} + /** * Function for external initialization of new Inputfields content (perhaps ajax loaded) * @@ -1266,6 +1490,7 @@ function InputfieldWindowResizeActions2() { function InputfieldsInit($target) { InputfieldStates($target); InputfieldDependencies($target); + InputfieldRequirements($target); setTimeout(function() { InputfieldColumnWidths(); }, 100); } @@ -1274,7 +1499,9 @@ function InputfieldsInit($target) { jQuery(document).ready(function($) { InputfieldStates(); + InputfieldDependencies($(".InputfieldForm:not(.InputfieldFormNoDependencies)")); + InputfieldIntentions(); setTimeout(function() { InputfieldColumnWidths(); }, 100); @@ -1285,52 +1512,20 @@ jQuery(document).ready(function($) { setTimeout('InputfieldWindowResizeActions1()', 1000); setTimeout('InputfieldWindowResizeActions2()', 2000); }; + + $(window).resize(windowResized); - var tabClicked = function() { + $("ul.WireTabs > li > a").click(function() { if(InputfieldWindowResizeQueued) return; InputfieldWindowResizeQueued = true; setTimeout('InputfieldWindowResizeActions1()', 250); - setTimeout('InputfieldWindowResizeActions2()', 500); - return true; - }; + setTimeout('InputfieldWindowResizeActions2()', 500); + return true; + }); + + InputfieldRequirements($('.InputfieldForm')); - $(window).resize(windowResized); - $("ul.WireTabs > li > a").click(tabClicked); - - $(document).on('reload', '.Inputfield', function(event, extraData) { - var $t = $(this); - var $form = $t.closest('form'); - var fieldName = $t.attr('id').replace('wrap_Inputfield_', ''); - var url = $form.attr('action'); - if(fieldName.indexOf('_repeater') > 0) { - var pageID = $t.closest('.InputfieldRepeaterItem').attr('data-page'); - url = url.replace(/\?id=\d+/, '?id=' + pageID); - fieldName = fieldName.replace(/_repeater\d+$/, ''); - } - url += url.indexOf('?') > -1 ? '&' : '?'; - url += 'field=' + fieldName + '&reloadInputfieldAjax=' + fieldName; - if(typeof extraData != "undefined") { - if(typeof extraData['queryString'] != "undefined") { - url += '&' + extraData['queryString']; - } - } - consoleLog('Inputfield reload: ' + fieldName); - $.get(url, function(data) { - var id = $t.attr('id'); - var $content = $(data).find("#" + id).children(".InputfieldContent"); - if(!$content.length && id.indexOf('_repeater') > -1) { - id = 'wrap_Inputfield_' + fieldName; - $content = $(data).find("#" + id).children(".InputfieldContent"); - if(!$content.length) { - console.log("Unable to find #" + $t.attr('id') + " in response from " + url); - } - } - $t.children(".InputfieldContent").html($content.html()); - // if(typeof jQuery.ui != 'undefined') $t.effect("highlight", 1000); - $t.trigger('reloaded', [ 'reload' ]); - }); - event.stopPropagation(); - }); + $(document).on('reload', '.Inputfield', InputfieldReloadEvent); /* // for testing: @@ -1338,5 +1533,4 @@ jQuery(document).ready(function($) { console.log($(this).attr('id')); }); */ - }); diff --git a/wire/templates-admin/scripts/inputfields.min.js b/wire/templates-admin/scripts/inputfields.min.js index ba9f761c..974afa6c 100644 --- a/wire/templates-admin/scripts/inputfields.min.js +++ b/wire/templates-admin/scripts/inputfields.min.js @@ -1 +1 @@ -var InputfieldDebugMode=false;function consoleLog(a){if(InputfieldDebugMode){console.log(a)}}var InputfieldDependenciesProcessing=false;function InputfieldDependencies(d){if(InputfieldDependenciesProcessing){return}if(typeof d=="undefined"){var d=$(".InputfieldForm:not(.InputfieldFormNoDependencies)")}else{if(d.hasClass("InputfieldForm")){if(d.hasClass("InputfieldFormNoDependencies")){return}}else{if(d.closest(".InputfieldFormNoDependencies").length>0){return}}}function h(l){l=jQuery.trim(l);var m=l.substring(0,1);var k=l.substring(l.length-1,l.length);if((m=='"'||m=="'")&&m==k){l=l.substring(1,l.length-1)}return l}function i(k){return g(h(k))}function b(m){var l="";var k=m.indexOf(".");if(k>0){l=m.substring(k+1);m=m.substring(0,k)}return{field:m,subfield:l}}function g(n,l){n=jQuery.trim(n);if(n.length>0&&!jQuery.isNumeric(n)){return n}if(n.length==0){var k=typeof l;if(k!="undefined"){if(k=="integer"){return 0}if(k=="float"){return 0}return n}else{return n}}var o=n.indexOf(".");var m=n.lastIndexOf(".");if(o==-1&&/^-?\d+$/.test(n)){return parseInt(n)}if(m>-1&&o!=m){return n}if(/^-?[\d.]+$/.test(n)){return parseFloat(n)}return n}function c(n,l,m,o){var k=0;switch(l){case"=":if(m==o){k++}break;case"!=":if(m!=o){k++}break;case">":if(m>o){k++}break;case"<":if(m=":if(m>=o){k++}break;case"<=":if(m<=o){k++}break;case"*=":case"%=":if(m.indexOf(o)>-1){k++}break}consoleLog("Field "+n+" - Current value: "+m);consoleLog("Field "+n+" - Matched? "+(k>0?"YES":"NO"));return k}function e(p,s,m){var w=null;var z;consoleLog("getCheckboxFieldAndValue(see-next-line, "+s+", "+m+")");consoleLog(p);if(m=="count"||m=="count-checkbox"){consoleLog("Using count checkbox condition");w=$("#wrap_Inputfield_"+s+" :input");if(w.length){z=$("#wrap_Inputfield_"+s+" :checked").length;p.subfield="count-checkbox";return{field:w,value:z,condition:p}}return null}consoleLog("Using checkbox value or label comparison option");z=[];for(var q=0;q0){consoleLog("Subfield: "+E.subfield)}consoleLog("Operator: "+E.operator);consoleLog("Required value: "+E.value)}var s=0;for(var q=0;q=G){break}}consoleLog("----");if(E.type=="show"){if(s>=G){}else{J=false}}else{if(E.type=="required"){if(s>0){w++}else{u++}}}}var t=w>0&&u==0;if(J){consoleLog('Determined that field "'+C+'" should be visible.');if(y.is(".InputfieldStateHidden")){y.removeClass("InputfieldStateHidden").show();$(document).trigger("showInputfield",y);o++;consoleLog("Field is now visible.")}else{consoleLog("Field is already visible.")}}else{consoleLog('Determined that field "'+C+'" should be hidden.');if(!y.is(".InputfieldStateHidden")){y.addClass("InputfieldStateHidden").hide();$(document).trigger("hideInputfield",y);consoleLog("Field is now hidden.");o++}else{consoleLog("Field is already hidden.")}if(t){consoleLog("Field is required but cancelling that since it is not visible.");t=false}}if(t&&w>0){consoleLog('Determined that field "'+C+'" should be required.');y.addClass("InputfieldStateRequired").find(":input:visible[type!=hidden]").addClass("required")}else{if(!t&&u>0){consoleLog('Determined that field "'+C+'" should not be required.');y.removeClass("InputfieldStateRequired").find(":input.required").removeClass("required")}}if(o>0){consoleLog(o+" visibility changes were made.");InputfieldColumnWidths();$(window).resize()}InputfieldDependenciesProcessing=false}function a(z,m,s){var A=s.attr("data-"+z+"-if");if(!A||A.length<1){return m}A=$("
").html(A).text();consoleLog("-------------------------------------------------------------------");consoleLog('Analyzing "'+z+'" selector: '+A);var v=A.match(/(^|,)([^,]+)/g);for(var w=0;w=|<|>|%=)([^,]+),?$/);if(!o){continue}var k=o[1];var q=o[2];var x=o[3];var r="";var t=[];var l=[];if(k.indexOf("|")>-1){consoleLog("OR field dependency: "+k);t=k.split("|")}else{t=[k]}var D=b(k);k=D.field;r=D.subfield;if(InputfieldDebugMode){consoleLog("Field: "+k);if(r.length){consoleLog("Subfield: "+r)}consoleLog("Operator: "+q);consoleLog("value: "+x)}if(x.indexOf("|")>-1){consoleLog("OR value dependency: "+x);l=x.split("|");for(var B=0;B> "+q+" ("+o+")");if(o==q){return}if(n.hasClass("InputfieldStateCollapsed")){return}var r=q-o;if(r<0){r=0}var s=n.children(".InputfieldContent, .ui-widget-content");if(r==0){}else{consoleLog("Adjusting "+n.attr("id")+" from "+o+" to "+q);var p=$("
");s.append(p);s.hide();p.height(r);s.show()}}function b(r){var v=r.nextUntil(".InputfieldColumnWidthFirst",".InputfieldColumnWidth:not(.InputfieldStateHidden)");var q=r.is(".InputfieldStateHidden")?0:i(r);var y=r.is(".InputfieldStateHidden")?null:r;var w=y==null?0:q;var x=v.length;if(r.is(".InputfieldStateHidden")){x--;var s=v.eq(0)}else{var s=r}if(m){s.find(".maxColHeightSpacer").remove();v.find(".maxColHeightSpacer").remove()}var o=100-(x*l);var n=m?e(s):0;v.removeClass("InputfieldColumnWidthFirstTmp");v.each(function(){y=$(this);w=i(y);q+=w;if(m){var z=e(y);if(z>n){n=z}}});if(m){if(InputfieldDebugMode){var t=s.find("label").text();consoleLog("maxColHeight: "+t+" = "+n)}if(n>0){h(s,n);v.each(function(){h($(this),n)})}}if(q0&&wo){consoleLog("Reduce width of row because rowWidth > maxRowWidth ("+q+" > "+o+")");if(!r.is(".InputfieldStateHidden")){v=r.add(v)}q=0;v.each(function(){y=$(this);w=k(y);if(w>0){f(y,w,false)}q+=w});var u=o-q;w+=u;var p=k(y);if(p>0&&w");var t=p.offset();var o;var q=10;var s=0;var n=0.8;f("body").append(r.hide());if(p.is("a")&&p.closest("ul").hasClass("uk-tab")){n=0.1}r.css({position:"absolute",top:t.top-(r.height()+5),left:t.left+(p.width()/2)+(r.width()*n)}).fadeIn();o=setInterval(function(){if(++s>q||!u.hasClass("InputfieldAjaxLoading")){clearInterval(o);r.fadeOut("normal",function(){r.remove()})}},500)}var l=m.children(".InputfieldContent").children(".renderInputfieldAjax");var g=false;if(!l.length){l=m.children(".renderInputfieldAjax");g=true}var j=l.children("input").attr("value");if(typeof j=="undefined"||j.length<1){return false}var i=null;if(g){var h=f("#_"+m.attr("id"));k(h,m)}else{var h=m.children(".InputfieldHeader");i=f("");i.css("margin-left","0.5em");h.append(i)}m.removeClass("collapsed10 collapsed11").addClass("InputfieldAjaxLoading");f.get(j,function(p){m.removeClass("InputfieldAjaxLoading InputfieldStateCollapsed");var n=m.children(".InputfieldHeader").find(".toggle-icon");if(n.length){n.toggleClass(n.attr("data-to"))}l.replaceWith(f(p)).hide();l.slideDown();var o=m.find(".Inputfield");if(o.length){o.trigger("reloaded",["InputfieldAjaxLoad"]);InputfieldStates(m);InputfieldColumnWidths()}else{m.trigger("reloaded",["InputfieldAjaxLoad"])}if(m.closest(".InputfieldFormNoDependencies").length==0){InputfieldDependencies(m.parent())}setTimeout(function(){if(i){i.fadeOut("fast",function(){i.remove()})}if(g){h.effect("highlight",500)}else{h.click()}},500)},"html");return true}f(".Inputfield:not(.collapsed9) > .InputfieldHeader, .Inputfield:not(.collapsed9) > .ui-widget-header",a).addClass("InputfieldStateToggle");var b=f(".Inputfields .InputfieldStateCollapsed > .InputfieldHeader i.toggle-icon, .Inputfields .InputfieldStateCollapsed > .ui-widget-header i.toggle-icon",a);b.toggleClass(b.attr("data-to"));if(typeof ProcessWire!="undefined"){var d=ProcessWire.config}if(typeof d!=="undefined"&&d.debug){f("label.InputfieldHeader > i.toggle-icon",a).hover(function(){var g=f(this).parent("label");if(g.length==0){return}var i=g.attr("for").replace(/^Inputfield_/,"");if(i.length){var h=f(" "+i+" ");h.css("float","right");g.append(h)}},function(){var g=f(this).parent("label");if(g.length==0){return}g.find(".InputfieldNameTip").remove()})}if(e){return}f(document).on("wiretabclick",function(i,h,g){if(h.hasClass("collapsed10")){c(h)}});f(document).on("click",".InputfieldStateToggle, .toggle-icon",function(g,k){var j=f(this);var n=j.closest(".Inputfield");var h=j.hasClass("toggle-icon");var m=h?j:n.children(".InputfieldHeader, .ui-widget-header").find(".toggle-icon");var l=n.hasClass("InputfieldStateCollapsed");var q=n.hasClass("InputfieldStateWasCollapsed");var i=100;if(n.hasClass("InputfieldAjaxLoading")){return false}if(typeof k!="undefined"){if(typeof k.duration!="undefined"){i=k.duration}}if(l&&(n.hasClass("collapsed10")||n.hasClass("collapsed11"))){if(c(n)){return false}}if(l||q||h){n.addClass("InputfieldStateWasCollapsed");n.trigger(l?"openReady":"closeReady");n.toggleClass("InputfieldStateCollapsed",i,function(){if(n.css("overflow")=="hidden"){n.css("overflow","")}if(l){n.trigger("opened");if(n.hasClass("InputfieldColumnWidth")){n.children(".InputfieldContent").show()}if(n.hasClass("InputfieldNoFocus")){return}var s=n.find(":input:visible");if(s.length==1&&!s.is("button")){if(s.css("position")!="absolute"){var r=s.attr("type");if(s.is("textarea")||r=="text"||r=="email"||r=="url"||r=="number"){s.focus()}}}}else{n.trigger("closed");if(n.hasClass("InputfieldColumnWidth")){n.children(".InputfieldContent").hide()}}});m.toggleClass(m.attr("data-to"));setTimeout("InputfieldColumnWidths()",500)}else{if(typeof jQuery.ui!="undefined"){var p=m.css("color");var o=n.children(".InputfieldHeader, .ui-widget-header").css("color");m.css("color",o);m.effect("pulsate",300,function(){m.css("color",p)})}if(!n.hasClass("InputfieldNoFocus")){n.find(":input:visible:eq(0)").focus()}}return false});f("#content .InputfieldFormFocusFirst:not(.InputfieldFormNoFocus)").find("input[type=text]:enabled:first:not(.hasDatepicker):not(.InputfieldNoFocus)").each(function(){var g=f(this);if(g.val()){return}if(g.offset().top0){break}d=d.parent().closest(".Inputfields")}while(d.length>0);if(e.length>0){var f=e.eq(0);$("html, body").animate({scrollTop:f.offset().top},"fast");f.focus()}return false}).on("focus","input, select",function(){if(b===null){b=a.find("input[type=submit], button[type=submit]").length}if(b<2){return}a.addClass("nosubmit");c=$(this)}).on("blur","input, select",function(){a.removeClass("nosubmit")})});if($("input[type=file]").length){$(document).on({dragover:function(){if($(this).is("input[type=file]")){return}return false},drop:function(){if($(this).is("input[type=file]")){return}return false}})}}var InputfieldWindowResizeQueued=false;function InputfieldWindowResizeActions1(){consoleLog("InputfieldWindowResizeActions1()");$(".Inputfield").trigger("resized")}function InputfieldWindowResizeActions2(){consoleLog("InputfieldWindowResizeActions2()");InputfieldColumnWidths();InputfieldWindowResizeQueued=false}function InputfieldsInit(a){InputfieldStates(a);InputfieldDependencies(a);setTimeout(function(){InputfieldColumnWidths()},100)}jQuery(document).ready(function(b){InputfieldStates();InputfieldDependencies(b(".InputfieldForm:not(.InputfieldFormNoDependencies)"));InputfieldIntentions();setTimeout(function(){InputfieldColumnWidths()},100);var c=function(){if(InputfieldWindowResizeQueued){return}InputfieldWindowResizeQueued=true;setTimeout("InputfieldWindowResizeActions1()",1000);setTimeout("InputfieldWindowResizeActions2()",2000)};var a=function(){if(InputfieldWindowResizeQueued){return}InputfieldWindowResizeQueued=true;setTimeout("InputfieldWindowResizeActions1()",250);setTimeout("InputfieldWindowResizeActions2()",500);return true};b(window).resize(c);b("ul.WireTabs > li > a").click(a);b(document).on("reload",".Inputfield",function(h,g){var j=b(this);var e=j.closest("form");var i=j.attr("id").replace("wrap_Inputfield_","");var f=e.attr("action");if(i.indexOf("_repeater")>0){var d=j.closest(".InputfieldRepeaterItem").attr("data-page");f=f.replace(/\?id=\d+/,"?id="+d);i=i.replace(/_repeater\d+$/,"")}f+=f.indexOf("?")>-1?"&":"?";f+="field="+i+"&reloadInputfieldAjax="+i;if(typeof g!="undefined"){if(typeof g.queryString!="undefined"){f+="&"+g.queryString}}consoleLog("Inputfield reload: "+i);b.get(f,function(l){var m=j.attr("id");var k=b(l).find("#"+m).children(".InputfieldContent");if(!k.length&&m.indexOf("_repeater")>-1){m="wrap_Inputfield_"+i;k=b(l).find("#"+m).children(".InputfieldContent");if(!k.length){console.log("Unable to find #"+j.attr("id")+" in response from "+f)}}j.children(".InputfieldContent").html(k.html());j.trigger("reloaded",["reload"])});h.stopPropagation()})}); \ No newline at end of file +var InputfieldDebugMode=false;function consoleLog(a){if(InputfieldDebugMode){console.log(a)}}var InputfieldDependenciesProcessing=false;function InputfieldDependencies(d){var f=jQuery;if(InputfieldDependenciesProcessing){return}if(typeof d=="undefined"){var d=f(".InputfieldForm:not(.InputfieldFormNoDependencies)")}else{if(d.hasClass("InputfieldForm")){if(d.hasClass("InputfieldFormNoDependencies")){return}}else{if(d.closest(".InputfieldFormNoDependencies").length>0){return}}}function i(m){m=jQuery.trim(m);var n=m.substring(0,1);var l=m.substring(m.length-1,m.length);if((n=='"'||n=="'")&&n==l){m=m.substring(1,m.length-1)}return m}function j(l){return h(i(l))}function b(n){var m="";var l=n.indexOf(".");if(l>0){m=n.substring(l+1);n=n.substring(0,l)}return{field:n,subfield:m}}function h(o,m){o=jQuery.trim(o);if(o.length>0&&!jQuery.isNumeric(o)){return o}if(o.length==0){var l=typeof m;if(l!="undefined"){if(l=="integer"){return 0}if(l=="float"){return 0}return o}else{return o}}var p=o.indexOf(".");var n=o.lastIndexOf(".");if(p==-1&&/^-?\d+$/.test(o)){return parseInt(o)}if(n>-1&&p!=n){return o}if(/^-?[\d.]+$/.test(o)){return parseFloat(o)}return o}function c(o,m,n,p){var l=0;switch(m){case"=":if(n==p){l++}break;case"!=":if(n!=p){l++}break;case">":if(n>p){l++}break;case"<":if(n=":if(n>=p){l++}break;case"<=":if(n<=p){l++}break;case"*=":case"%=":if(n.indexOf(p)>-1){l++}break}consoleLog("Field "+o+" - Current value: "+n);consoleLog("Field "+o+" - Matched? "+(l>0?"YES":"NO"));return l}function e(q,t,n){var x=null;var A;consoleLog("getCheckboxFieldAndValue(see-next-line, "+t+", "+n+")");consoleLog(q);if(n=="count"||n=="count-checkbox"){consoleLog("Using count checkbox condition");x=f("#wrap_Inputfield_"+t+" :input");if(x.length){A=f("#wrap_Inputfield_"+t+" :checked").length;q.subfield="count-checkbox";return{field:x,value:A,condition:q}}return null}consoleLog("Using checkbox value or label comparison option");A=[];for(var r=0;r0){consoleLog("Subfield: "+F.subfield)}consoleLog("Operator: "+F.operator);consoleLog("Required value: "+F.value)}var t=0;for(var r=0;r=H){break}}consoleLog("----");if(F.type=="show"){if(t>=H){}else{K=false}}else{if(F.type=="required"){if(t>0){x++}else{w++}}}}var u=x>0&&w==0;if(K){consoleLog('Determined that field "'+D+'" should be visible.');if(z.is(".InputfieldStateHidden")){z.removeClass("InputfieldStateHidden").show();f(document).trigger("showInputfield",z);p++;consoleLog("Field is now visible.")}else{consoleLog("Field is already visible.")}}else{consoleLog('Determined that field "'+D+'" should be hidden.');if(!z.is(".InputfieldStateHidden")){z.addClass("InputfieldStateHidden").hide();f(document).trigger("hideInputfield",z);consoleLog("Field is now hidden.");p++}else{consoleLog("Field is already hidden.")}if(u){consoleLog("Field is required but cancelling that since it is not visible.");u=false}}if(u&&x>0){consoleLog('Determined that field "'+D+'" should be required.');z.addClass("InputfieldStateRequired").find(":input:visible[type!=hidden]").addClass("required")}else{if(!u&&w>0){consoleLog('Determined that field "'+D+'" should not be required.');z.removeClass("InputfieldStateRequired").find(":input.required").removeClass("required")}}if(p>0){consoleLog(p+" visibility changes were made.");InputfieldColumnWidths();f(window).resize()}InputfieldDependenciesProcessing=false}function a(A,o,t){var B=t.attr("data-"+A+"-if");if(!B||B.length<1){return o}B=f("
").html(B).text();consoleLog("-------------------------------------------------------------------");consoleLog('Analyzing "'+A+'" selector: '+B);var w=B.match(/(^|,)([^,]+)/g);for(var x=0;x=|<|>|%=)([^,]+),?$/);if(!p){continue}var l=p[1];var r=p[2];var y=p[3];var s="";var u=[];var m=[];if(l.indexOf("|")>-1){consoleLog("OR field dependency: "+l);u=l.split("|")}else{u=[l]}var E=b(l);l=E.field;s=E.subfield;if(InputfieldDebugMode){consoleLog("Field: "+l);if(s.length){consoleLog("Subfield: "+s)}consoleLog("Operator: "+r);consoleLog("value: "+y)}if(y.indexOf("|")>-1){consoleLog("OR value dependency: "+y);m=y.split("|");for(var C=0;C> "+r+" ("+p+")");if(p==r){return}if(o.hasClass("InputfieldStateCollapsed")){return}var s=r-p;if(s<0){s=0}var t=o.children(".InputfieldContent, .ui-widget-content");if(s==0){}else{consoleLog("Adjusting "+o.attr("id")+" from "+p+" to "+r);var q=e("
");t.append(q);t.hide();q.height(s);t.show()}}function b(s){var w=s.nextUntil(".InputfieldColumnWidthFirst",".InputfieldColumnWidth:not(.InputfieldStateHidden)");var r=s.is(".InputfieldStateHidden")?0:j(s);var z=s.is(".InputfieldStateHidden")?null:s;var x=z==null?0:r;var y=w.length;if(s.is(".InputfieldStateHidden")){y--;var t=w.eq(0)}else{var t=s}if(n){t.find(".maxColHeightSpacer").remove();w.find(".maxColHeightSpacer").remove()}var p=100-(y*m);var o=n?f(t):0;w.removeClass("InputfieldColumnWidthFirstTmp");w.each(function(){z=e(this);x=j(z);r+=x;if(n){var A=f(z);if(A>o){o=A}}});if(n){if(InputfieldDebugMode){var u=t.find("label").text();consoleLog("maxColHeight: "+u+" = "+o)}if(o>0){i(t,o);w.each(function(){i(e(this),o)})}}if(r0&&xp){consoleLog("Reduce width of row because rowWidth > maxRowWidth ("+r+" > "+p+")");if(!s.is(".InputfieldStateHidden")){w=s.add(w)}r=0;w.each(function(){z=e(this);x=l(z);if(x>0){g(z,x,false)}r+=x});var v=p-r;x+=v;var q=l(z);if(q>0&&x=i));if(!e){setTimeout(function(){jQuery("html, body").animate({scrollTop:a.offset().top-10},100)},100)}}}function InputfieldToggle(a,k,f,l){if(!a.length){return}if(!a.hasClass("Inputfield")){a=a.closest(".Inputfield")}var b=a.children(".InputfieldHeader, .ui-widget-header");var c=a.children(".InputfieldContent, .ui-widget-content");var d=b.find(".toggle-icon");var j=a.hasClass("InputfieldStateCollapsed");if(a.hasClass("InputfieldAjaxLoading")){return false}if(a.hasClass("InputfieldStateToggling")){return false}if(typeof k=="undefined"||k===null){var k=j}if(typeof f=="undefined"){var f=100}function i(){if(typeof l!="undefined"){l(a,k,f)}}function e(){if(a.css("overflow")=="hidden"){a.css("overflow","")}d.toggleClass(d.attr("data-to"));a.removeClass("InputfieldStateToggling");setTimeout("InputfieldColumnWidths()",500);i()}function h(){a.trigger("opened");if(a.hasClass("InputfieldColumnWidth")){a.children(".InputfieldContent").show()}if(!a.hasClass("InputfieldNoFocus")){InputfieldFocus(a)}e()}function m(){if(a.css("overflow")=="hidden"){a.css("overflow","")}a.trigger("closed");if(a.hasClass("InputfieldColumnWidth")){a.children(".InputfieldContent").hide()}e()}if(k&&!a.is(":visible")){var o=a.parents(".InputfieldWrapper").last();if(o.length&&!o.is(":visible")){var g=jQuery("#_"+o.attr("id"));if(g.length){o.show();setTimeout(function(){g.click()},25)}}var n=a.closest(".InputfieldStateCollapsed");if(n.length){InputfieldToggle(n,true,f,function(p){InputfieldToggle(p,true,f,l)})}}if(k&&!j){i();return}if(!k&&j){i();return}if(j&&(a.hasClass("collapsed10")||a.hasClass("collapsed11"))){d.click();return}if(k&&j){a.addClass("InputfieldStateToggling").trigger("openReady");a.toggleClass("InputfieldStateCollapsed",f,h)}else{if(!k&&!j){a.addClass("InputfieldStateToggling").trigger("closeReady");a.toggleClass("InputfieldStateCollapsed",f,m)}}}function InputfieldOpen(a,b){InputfieldToggle(a,true,b)}function InputfieldClose(a,b){InputfieldToggle(a,false,b)}function InputfieldStates(a){var e=true;var f=jQuery;if(typeof a=="undefined"){a=f("body");e=false}function c(m){function k(p,u){var r=f("");var t=p.offset();var o;var q=10;var s=0;var n=0.8;f("body").append(r.hide());if(p.is("a")&&p.closest("ul").hasClass("uk-tab")){n=0.1}r.css({position:"absolute",top:t.top-(r.height()+5),left:t.left+(p.width()/2)+(r.width()*n)}).fadeIn();o=setInterval(function(){if(++s>q||!u.hasClass("InputfieldAjaxLoading")){clearInterval(o);r.fadeOut("normal",function(){r.remove()})}},500)}var l=m.children(".InputfieldContent").children(".renderInputfieldAjax");var g=false;if(!l.length){l=m.children(".renderInputfieldAjax");g=true}var j=l.children("input").attr("value");if(typeof j=="undefined"||j.length<1){return false}var i=null;if(g){var h=f("#_"+m.attr("id"));k(h,m)}else{var h=m.children(".InputfieldHeader");i=f("");i.css("margin-left","0.5em");h.append(i)}m.removeClass("collapsed10 collapsed11").addClass("InputfieldAjaxLoading");f.get(j,function(p){m.removeClass("InputfieldAjaxLoading InputfieldStateCollapsed");var n=m.children(".InputfieldHeader").find(".toggle-icon");if(n.length){n.toggleClass(n.attr("data-to"))}l.replaceWith(f(p)).hide();l.slideDown();var o=m.find(".Inputfield");if(o.length){o.trigger("reloaded",["InputfieldAjaxLoad"]);InputfieldStates(m);InputfieldRequirements(m);InputfieldColumnWidths()}else{m.trigger("reloaded",["InputfieldAjaxLoad"])}if(m.closest(".InputfieldFormNoDependencies").length==0){InputfieldDependencies(m.parent())}setTimeout(function(){if(i){i.fadeOut("fast",function(){i.remove()})}if(g){h.effect("highlight",500)}else{h.click()}},500)},"html");return true}f(".Inputfield:not(.collapsed9) > .InputfieldHeader, .Inputfield:not(.collapsed9) > .ui-widget-header",a).addClass("InputfieldStateToggle");var b=f(".Inputfields .InputfieldStateCollapsed > .InputfieldHeader i.toggle-icon, .Inputfields .InputfieldStateCollapsed > .ui-widget-header i.toggle-icon",a);b.toggleClass(b.attr("data-to"));if(typeof ProcessWire!="undefined"){var d=ProcessWire.config}if(typeof d!=="undefined"&&d.debug){f("label.InputfieldHeader > i.toggle-icon",a).hover(function(){var g=f(this).parent("label");if(g.length==0){return}var i=g.attr("for").replace(/^Inputfield_/,"");if(i.length){var h=f(" "+i+" ");h.css("float","right");g.append(h)}},function(){var g=f(this).parent("label");if(g.length==0){return}g.find(".InputfieldNameTip").remove()})}if(e){return}f(document).on("wiretabclick",function(i,h,g){if(h.hasClass("collapsed10")){c(h)}});f(document).on("click",".InputfieldStateToggle, .toggle-icon",function(g,k){var j=f(this);var n=j.closest(".Inputfield");var h=j.hasClass("toggle-icon");var m=h?j:n.children(".InputfieldHeader, .ui-widget-header").find(".toggle-icon");var l=n.hasClass("InputfieldStateCollapsed");var q=n.hasClass("InputfieldStateWasCollapsed");var i=100;if(!n.length){return}if(n.hasClass("InputfieldAjaxLoading")){return false}if(n.hasClass("InputfieldStateToggling")){return false}if(typeof k!="undefined"){if(typeof k.duration!="undefined"){i=k.duration}}if(l&&(n.hasClass("collapsed10")||n.hasClass("collapsed11"))){if(c(n)){return false}}if(l||q||h){n.addClass("InputfieldStateWasCollapsed");InputfieldToggle(n,null,i)}else{if(typeof jQuery.ui!="undefined"){var p=m.css("color");var o=n.children(".InputfieldHeader, .ui-widget-header").css("color");m.css("color",o);m.effect("pulsate",300,function(){m.css("color",p)})}InputfieldFocus(n)}return false});f("#content .InputfieldFormFocusFirst:not(.InputfieldFormNoFocus)").find("input[type=text]:enabled:first:not(.hasDatepicker):not(.InputfieldNoFocus)").each(function(){var g=f(this);if(g.val()){return}if(g.offset().top0){break}e=e.parent().closest(".Inputfields")}while(e.length>0);if(f.length>0){var g=f.eq(0);a("html, body").animate({scrollTop:g.offset().top},"fast");g.focus()}return false}).on("focus","input, select",function(){if(c===null){c=b.find("input[type=submit], button[type=submit]").length}if(c<2){return}b.addClass("nosubmit");d=a(this)}).on("blur","input, select",function(){b.removeClass("nosubmit")})});if(a("input[type=file]").length){a(document).on({dragover:function(){if(a(this).is("input[type=file]")){return}return false},drop:function(){if(a(this).is("input[type=file]")){return}return false}})}}var InputfieldWindowResizeQueued=false;function InputfieldWindowResizeActions1(){consoleLog("InputfieldWindowResizeActions1()");jQuery(".Inputfield").trigger("resized")}function InputfieldWindowResizeActions2(){consoleLog("InputfieldWindowResizeActions2()");InputfieldColumnWidths();InputfieldWindowResizeQueued=false}function InputfieldRequirements(a){jQuery(":input[required]",a).on("invalid",function(){var b=jQuery(this);InputfieldFocus(jQuery(this))})}function InputfieldReloadEvent(e,d){console.log("InputfieldReloadEvent "+$(this).attr("id"));var g=$(this);var b=g.closest("form");var f=g.attr("id").replace("wrap_Inputfield_","");var c=b.attr("action");if(f.indexOf("_repeater")>0){var a=g.closest(".InputfieldRepeaterItem").attr("data-page");c=c.replace(/\?id=\d+/,"?id="+a);f=f.replace(/_repeater\d+$/,"")}c+=c.indexOf("?")>-1?"&":"?";c+="field="+f+"&reloadInputfieldAjax="+f;if(typeof d!="undefined"){if(typeof d.queryString!="undefined"){c+="&"+d.queryString}}consoleLog("Inputfield reload: "+f);$.get(c,function(i){var j=g.attr("id");var h=jQuery(i).find("#"+j).children(".InputfieldContent");if(!h.length&&j.indexOf("_repeater")>-1){j="wrap_Inputfield_"+f;h=jQuery(i).find("#"+j).children(".InputfieldContent");if(!h.length){console.log("Unable to find #"+g.attr("id")+" in response from "+c)}}g.children(".InputfieldContent").html(h.html());g.trigger("reloaded",["reload"])});e.stopPropagation()}function InputfieldsInit(a){InputfieldStates(a);InputfieldDependencies(a);InputfieldRequirements(a);setTimeout(function(){InputfieldColumnWidths()},100)}jQuery(document).ready(function(a){InputfieldStates();InputfieldDependencies(a(".InputfieldForm:not(.InputfieldFormNoDependencies)"));InputfieldIntentions();setTimeout(function(){InputfieldColumnWidths()},100);var b=function(){if(InputfieldWindowResizeQueued){return}InputfieldWindowResizeQueued=true;setTimeout("InputfieldWindowResizeActions1()",1000);setTimeout("InputfieldWindowResizeActions2()",2000)};a(window).resize(b);a("ul.WireTabs > li > a").click(function(){if(InputfieldWindowResizeQueued){return}InputfieldWindowResizeQueued=true;setTimeout("InputfieldWindowResizeActions1()",250);setTimeout("InputfieldWindowResizeActions2()",500);return true});InputfieldRequirements(a(".InputfieldForm"));a(document).on("reload",".Inputfield",InputfieldReloadEvent)}); \ No newline at end of file