1 2var __gf_timeout_handle; 3 4gform.addAction( 'gform_input_change', function( elem, formId, fieldId ) { 5 if( ! window.gf_form_conditional_logic ) { 6 return; 7 } 8 var dependentFieldIds = rgars( gf_form_conditional_logic, [ formId, 'fields', gformExtractFieldId( fieldId ) ].join( '/' ) ); 9 if( dependentFieldIds.length ) { 10 gf_apply_rules( formId, dependentFieldIds ); 11 } 12}, 10 ); 13 14function gf_apply_rules(formId, fields, isInit){ 15 16 jQuery(document).trigger( 'gform_pre_conditional_logic', [ formId, fields, isInit ] ); 17 gform.utils.trigger( { 18 event: 'gform/conditionalLogic/applyRules/start', 19 native: false, 20 data: { formId: formId, fields: fields, isInit: isInit }, 21 } ); 22 for(var i=0; i < fields.length; i++){ 23 gf_apply_field_rule(formId, fields[i], isInit, function(){ 24 var is_last_field = ( i >= fields.length - 1 ); 25 if( is_last_field ) { 26 27 // Gather the fields that are dependents of the processed fields (inside pages/sections). 28 var dependentFields = []; 29 var dependents = window["gf_form_conditional_logic"][formId]["dependents"][fields[i]]; 30 if ( dependents ) { 31 dependents.forEach( function ( dependentFieldId ) { 32 if ( dependentFields.indexOf( dependentFieldId ) === -1 ) { 33 dependentFields.push( dependentFieldId ); 34 } 35 }); 36 } 37 38 jQuery(document).trigger('gform_post_conditional_logic', [formId, fields, isInit]); 39 gform.utils.trigger( { 40 event: 'gform/conditionalLogic/applyRules/end', 41 native: false, 42 data: { formId: formId, fields: fields, dependentFields: dependentFields, isInit: isInit }, 43 } ); 44 } 45 }); 46 } 47} 48 49function gf_check_field_rule(formId, fieldId, isInit, callback){ 50 51 //if conditional logic is not specified for that field, it is supposed to be displayed 52 var conditionalLogic = gf_get_field_logic( formId, fieldId ); 53 if ( ! conditionalLogic ) { 54 return 'show'; 55 } 56 57 var action = gf_get_field_action(formId, conditionalLogic["section"]); 58 59 //If section is hidden, always hide field. If section is displayed, see if field is supposed to be displayed or hidden 60 if(action != "hide") 61 action = gf_get_field_action(formId, conditionalLogic["field"]); 62 63 return action; 64} 65 66/** 67 * Retrieves the conditional logic properties for the specified field. 68 * 69 * @since 2.4.16 70 * 71 * @param {(string|number)} formId The ID of the current form. 72 * @param {(string|number)} fieldId The ID of the current field. 73 * 74 * @return {(boolean|object)} False or the field conditional logic properties. 75 */ 76function gf_get_field_logic(formId, fieldId) { 77 var formConditionalLogic = rgars( window, 'gf_form_conditional_logic/' + formId ); 78 if ( ! formConditionalLogic ) { 79 return false; 80 } 81 82 var conditionalLogic = rgars( formConditionalLogic, 'logic/' + fieldId ); 83 if ( conditionalLogic ) { 84 return conditionalLogic; 85 } 86 87 var dependents = rgar( formConditionalLogic, 'dependents' ); 88 if ( ! dependents ) { 89 return false; 90 } 91 92 // Attempting to get section field conditional logic instead. 93 for ( var key in dependents ) { 94 if ( dependents[key].indexOf( fieldId ) !== -1 ) { 95 return rgars( formConditionalLogic, 'logic/' + key ); 96 } 97 } 98 99 return false; 100} 101 102function gf_apply_field_rule(formId, fieldId, isInit, callback){ 103 104 var action = gf_check_field_rule(formId, fieldId, isInit, callback); 105 106 gf_do_field_action(formId, action, fieldId, isInit, callback); 107 108 var conditionalLogic = window["gf_form_conditional_logic"][formId]["logic"][fieldId]; 109 //perform conditional logic for the next button 110 if(conditionalLogic["nextButton"]){ 111 action = gf_get_field_action(formId, conditionalLogic["nextButton"]); 112 gf_do_next_button_action(formId, action, fieldId, isInit); 113 } 114 115} 116 117function gf_get_field_action(formId, conditionalLogic){ 118 if(!conditionalLogic) 119 return "show"; 120 121 var matches = 0; 122 for(var i = 0; i < conditionalLogic["rules"].length; i++){ 123 /** 124 * Filter the conditional logic rule before it is evaluated on the frontend. 125 * 126 * @param {object} rule The conditional logic rule about to be evaluated. 127 * @param {(string|number)} formId The current form ID. 128 * @param {object} conditionalLogic All details required to evaluate an objects conditional logic. 129 * 130 * @since 2.4.22 131 */ 132 var rule = gform.applyFilters( 'gform_rule_pre_evaluation', jQuery.extend( {}, conditionalLogic["rules"][i] ), formId, conditionalLogic ); 133 if(gf_is_match(formId, rule)) 134 matches++; 135 } 136 137 var action; 138 if( (conditionalLogic["logicType"] == "all" && matches == conditionalLogic["rules"].length) || (conditionalLogic["logicType"] == "any" && matches > 0) ) 139 action = conditionalLogic["actionType"]; 140 else
141 action = conditionalLogic["actionType"] == "show" ? "hide" : "show"; 142 143 return action; 144} 145 146function gf_is_match( formId, rule ) { 147 148 var $ = jQuery, 149 inputId = rule['fieldId'], 150 fieldId = gformExtractFieldId( inputId ), 151 inputIndex = gformExtractInputIndex( inputId ), 152 isInputSpecific = inputIndex !== false, 153 $inputs; 154 155 if( isInputSpecific ) { 156 $inputs = $( '#input_{0}_{1}_{2}, #choice_{0}_{1}_{2}'.gformFormat( formId, fieldId, inputIndex ) ); 157 } else { 158 $inputs = $( 'input[id="input_{0}_{1}"], input[id^="input_{0}_{1}_"], input[id^="choice_{0}_{1}_"], select#input_{0}_{1}, textarea#input_{0}_{1}'.gformFormat( formId, fieldId ) ); 159 } 160 161 var isCheckable = $.inArray( $inputs.attr( 'type' ), [ 'checkbox', 'radio' ] ) !== -1; 162 var isMatch = isCheckable ? gf_is_match_checkable( $inputs, rule, formId, fieldId ) : gf_is_match_default( $inputs.eq( 0 ), rule, formId, fieldId ); 163 164 return gform.applyFilters( 'gform_is_value_match', isMatch, formId, rule ); 165} 166 167function gf_is_match_checkable( $inputs, rule, formId, fieldId ) { 168 169 // Rule is checking if the checkable is/isn't blank. Return a specific check for that use-case. 170 if ( rule.value === '' ) { 171 return rule.operator === 'is' ? gf_is_checkable_empty( $inputs ) : ! gf_is_checkable_empty( $inputs ); 172 } 173 174 var isMatch = false; 175 176 $inputs.each( function() { 177 178 var $input = jQuery( this ), 179 fieldValue = gf_get_value( $input.val(), $input ), 180 isRangeOperator = jQuery.inArray( rule.operator, [ '<', '>' ] ) !== -1, 181 isStringOperator = jQuery.inArray( rule.operator, [ 'contains', 'starts_with', 'ends_with' ] ) !== -1; 182 183 // if we are looking for a specific value and this is not it, skip 184 if( fieldValue != rule.value && ! isRangeOperator && ! isStringOperator ) { 185 return; // continue 186 } 187 188 // force an empty value for unchecked items 189 if( ! $input.is( ':checked' ) ) { 190 fieldValue = ''; 191 } 192 // if the 'other' choice is selected, get the value from the 'other' text input 193 else if ( fieldValue == 'gf_other_choice' ) { 194 fieldValue = jQuery( '#input_{0}_{1}_other'.gformFormat( formId, fieldId ) ).val(); 195 } 196 197 if( gf_matches_operation( fieldValue, rule.value, rule.operator ) ) { 198 isMatch = true; 199 return false; // break 200 } 201 202 } ); 203 204 return isMatch; 205} 206 207/** 208 * Check if a collection of checkable inputs has any checked, 209 * or if they are all unchecked. 210 * 211 * @param {jQuery} $inputs A collection of inputs to check. 212 * 213 * @returns {boolean} 214 */ 215function gf_is_checkable_empty( $inputs ) { 216 var isEmpty = true; 217 218 $inputs.each( function() { 219 if ( jQuery( this ).is( ':checked' ) ) { 220 isEmpty = false; 221 } 222 } ); 223 224 return isEmpty; 225} 226 227function gf_is_match_default( $input, rule, formId, fieldId ) { 228 229 var val = $input.val(); 230 if ( val === undefined ) { 231 val = []; 232 } 233 234 var values = ( val instanceof Array ) ? val : [ val ], // transform regular value into array to support multi-select (which returns an array of selected items) 235 matchCount = 0, 236 valuesLength = Math.max( values.length, 1 ); // jQuery 3.0: Make sure our length is at least 1 so that the following loop fires. 237 238 // Back-compat for rules based on the address field country input that are still using the country name instead of the code; gets the code from the default countries list in gf_global. 239 if ( rule.fieldId === `${ fieldId }.6` && rule.value.length > 2 && $input.closest( '.ginput_container_address' ).length === 1 && val.length === 2 ) { 240 const ruleValueLowerCase = rule.value.toLowerCase(); 241 242 rule.value = Object.entries( window.gf_global?.countries || {} ).find( 243 ( [ code, name ] ) => name.toLowerCase() === ruleValueLowerCase 244 )?.[ 0 ] || rule.value; 245 } 246 247 for( var i = 0; i < valuesLength; i++ ) { 248 249 var isPriceField = $input.closest( '.gfield_price' ).length > 0, 250 hasLabel = ! values[i] || ( isPriceField && values[i].indexOf( '|' ) >= 0 ), 251 fieldValue = gf_get_value( values[i], $input ); 252 253 var fieldNumberFormat = gf_get_field_number_format( rule.fieldId, formId, 'value' ); 254 if( fieldNumberFormat && ! hasLabel ) { 255 fieldValue = gf_format_number( fieldValue, fieldNumberFormat ); 256 } 257 258 var ruleValue = rule.value; 259 //if ( fieldNumberFormat ) { 260 // ruleValue = gf_format_number( ruleValue, fieldNumberFormat ); 261 //} 262 263 if( gf_matches_operation( fieldValue, ruleValue, rule.operator ) ) { 264 matchCount++; 265 } 266 267 } 268 269 // if operator is 'isnot', none of the values can match 270 var isMatch = rule.operator == 'isnot' ? matchCount == valuesLength : matchCount > 0; 271 272 return isMatch; 273} 274 275function gf_format_number( value, fieldNumberFormat ) { 276 277 decimalSeparator = '.'; 278 279 if( fieldNumberFormat == 'currency' ) { 280 decimalSeparator = gform.Currency.getDecimalSeparator( 'currency' ); 281 } else if( fieldNumberFormat == 'decimal_comma' ) { 282 decimalSeparator = ','; 283 } else if( fieldNumberFormat == 'decimal_dot' ) { 284 decimalSeparator = '.'; 285 } 286 287 // transform to a decimal dot number 288 value = gform.Currency.cleanNumber( value, '', '', decimalSeparator ); 289 290 /** 291 * Looking at format specified by wp locale creates issues. When performing conditional logic, all numbers will be formatted to decimal dot and then compared that way. AC 292 */
293 // now transform to number specified by locale 294 // if( window['gf_number_format'] && window['gf_number_format'] == 'decimal_comma' ) { 295 // value = gformFormatNumber( value, -1, ',', '.' ); 296 // } 297 298 if( ! value ) { 299 value = 0; 300 } 301 302 number = value.toString(); 303 304 return number; 305} 306 307function gf_try_convert_float(text){ 308 309 /* 310 * The only format that should matter is the field format. Attempting to do this by WP locale creates a lot of issues with consistency. 311 * var format = window["gf_number_format"] == "decimal_comma" ? "decimal_comma" : "decimal_dot"; 312 */ 313 314 var format = 'decimal_dot'; 315 if( gformIsNumeric( text, format ) ) { 316 var decimal_separator = format == "decimal_comma" ? "," : "."; 317 return gform.Currency.cleanNumber( text, "", "", decimal_separator ); 318 } 319 320 return text; 321} 322 323function gf_matches_operation(val1, val2, operation){ 324 val1 = val1 ? val1.toLowerCase() : ""; 325 val2 = val2 ? val2.toLowerCase() : ""; 326 327 switch(operation){ 328 case "is" : 329 return val1 == val2; 330 break; 331 332 case "isnot" : 333 return val1 != val2; 334 break; 335 336 case ">" : 337 val1 = gf_try_convert_float(val1); 338 val2 = gf_try_convert_float(val2); 339 340 return gform.utils.isNumber(val1) && gform.utils.isNumber(val2) ? val1 > val2 : false; 341 break; 342 343 case "<" : 344 val1 = gf_try_convert_float(val1); 345 val2 = gf_try_convert_float(val2); 346 347 return gform.utils.isNumber(val1) && gform.utils.isNumber(val2) ? val1 < val2 : false; 348 break; 349 350 case "contains" : 351 return val1.indexOf(val2) >=0; 352 break; 353 354 case "starts_with" : 355 return val1.indexOf(val2) ==0; 356 break; 357 358 case "ends_with" : 359 var start = val1.length - val2.length; 360 if(start < 0) 361 return false; 362 363 var tail = val1.substring(start); 364 return val2 == tail; 365 break; 366 } 367 return false; 368} 369 370function gf_get_value( val, $input ) { 371 if ( ! val ) { 372 return ''; 373 } 374 375 // Selection pricing fields are formatted as value|price. Split on the | to get the field label or value that is in the first position. 376 // For all other pricing fields, splitting on the | won't have any effect. 377 if ( $input && $input.closest( '.gfield_price' ).length ) { 378 val = gformParseChoiceValue( val )['name']; 379 } 380 381 return val; 382} 383 384function gf_do_field_action(formId, action, fieldId, isInit, callback){ 385 var conditional_logic = window["gf_form_conditional_logic"][formId]; 386 var dependent_fields = conditional_logic["dependents"][fieldId]; 387 388 for(var i=0; i < dependent_fields.length; i++){ 389 var targetId = fieldId == 0 ? "#gform_submit_button_" + formId : "#field_" + formId + "_" + depen
389dent_fields[i]; 390 var defaultValues = conditional_logic["defaults"][dependent_fields[i]]; 391 392 //calling callback function on the last dependent field, to make sure it is only called once 393 do_callback = (i+1) == dependent_fields.length ? callback : null; 394 395 /** 396 * Allow add-ons to abort gf_do_action() function. 397 * 398 * @since 2.6.2 399 * 400 * @param bool $doAbort The value being filtered. True to abort conditional logic action, false to continue. Defaults to false. 401 * @param string $action The conditional logic action that will be performed. Possible values: show or hide 402 * @param string $targetId HTML element id that will be the targed of the conditional logic action. 403 * @param bool $doAnimation True to perform animation while showing/hiding field. False to hide/show field without animation. 404 * @param array $defaultValue Array containg default field values. 405 * @param bool $isInit True if form is being initialized (i.e. before user has interacted with any input). False otherwise. 406 * @param array $formId The current form ID. 407 * @param func $do_callback Callback function to be executed after conditional logic is executed. 408 */ 409 let abort = gform.applyFilters( 'gform_abort_conditional_logic_do_action', false, action, targetId, conditional_logic[ "animation" ], defaultValues, isInit, formId, do_callback ); 410 if ( ! abort ) { 411 gf_do_action( action, targetId, conditional_logic[ "animation" ], defaultValues, isInit, do_callback, formId ); 412 } else if ( do_callback ) { 413 do_callback(); 414 } 415 416 gform.doAction('gform_post_conditional_logic_field_action', formId, action, targetId, defaultValues, isInit); 417 } 418} 419 420function gf_do_next_button_action(formId, action, fieldId, isInit){ 421 var conditional_logic = window["gf_form_conditional_logic"][formId]; 422 var targetId = "#gform_next_button_" + formId + "_" + fieldId; 423 424 /** 425 * Allow add-ons to abort gf_do_action() function. 426 * 427 * @since 2.6.2 428 * 429 * @param bool $doAbort The value being filtered. True to abort conditional logic action, false to continue. Defaults to false. 430 * @param string $action The conditional logic action that will be performed. Possible values: show or hide 431 * @param string $targetId HTML element id that will be the targed of the conditional logic action. 432 * @param bool $doAnimation True to perform animation while showing/hiding field. False to hide/show field without animation. 433 * @param array $defaultValue Array containg default field values. 434 * @param bool $isInit True if form is being initialized (i.e. before user has interacted with any input). False otherwise. 435 * @param array $formId The current form ID. 436 * @param func $do_callback Callback function to be executed after conditional logic is executed. 437 */ 438 let abort = gform.applyFilters( 'gform_abort_conditional_logic_do_action', false, action, targetId, conditional_logic[ "animation" ], null, isInit, formId, null ); 439 if ( ! abort ) { 440 gf_do_action( action, targetId, conditional_logic[ "animation" ], null, isInit, null, formId ); 441 } 442} 443 444function gf_do_action(action, targetId, useAnimation, defaultValues, isInit, callback, formId){ 445 var $target = jQuery( targetId ); 446 447 /** 448 * Do not re-enable inputs that are disabled by default. Check if field's inputs have been assessed. If not, add 449 * designator class so these inputs are exempted below. 450 */ 451 if( ! $target.data( 'gf-disabled-assessed' ) ) { 452 $target.find( ':input:disabled' ).addClass( 'gf-default-disabled' ); 453 $target.data( 'gf-disabled-assessed', true ); 454 } 455 456 // honeypot should not be impacted by conditional logic. 457 if( $target.hasClass( 'gfield--type-honeypot') ) { 458 return; 459 } 460 461 if(action == "show"){ 462 // reset tabindex for selects 463 $target.find( 'select' ).each( function() { 464 var $select = jQuery( this ); 465 $select.attr( 'tabindex', $select.data( 'tabindex' ) ); 466 } ); 467 468 if(useAnimation && !isInit){ 469 if($target.length > 0){ 470 $target.find(':input:hidden:not(.gf-default-disabled)').prop( 'disabled', false ); 471 if ( $target.is( 'input[type="submit"]' ) || $target.hasClass( 'gform_next_button' ) ) { 472 gf_show_button( $target ); 473 } 474 $target.slideDown(callback); 475 $target.attr( 'data-conditional-logic', 'visible' ); 476 } else if(callback){ 477 callback(); 478 } 479 } 480 else{ 481 var display = $target.data('gf_display'); 482 483 // set display if previous (saved) display isn't set for any reason 484 if ( display == '' || display == 'none' ){ 485 display = '1' === gf_legacy.is_legacy ? 'list-item' : 'block'; 486 } 487 $target.find(':input:hidden:not(.gf-default-disabled)').prop( 'disabled', false ).attr( 'data-conditional-logic', 'visible' ); 488 489 // Handle conditional submit and next buttons. 490 if ( $target.is( 'input[type="submit"]' ) || $target.hasClass( 'gform_next_button' ) ) { 491 gf_show_button( $target ); 492 } else { 493 $target.css( 'display', display );
494 if( display == 'none' ) { 495 $target.attr( 'data-conditional-logic', 'hidden' ); 496 } else { 497 $target.attr( 'data-conditional-logic', 'visible' ); 498 } 499 } 500 501 if(callback){ 502 callback(); 503 } 504 } 505 } 506 else{ 507 508 //if field is not already hidden, reset its values to the default 509 var child = $target.children().first(); 510 if (child.length > 0){ 511 var reset = gform.applyFilters('gform_reset_pre_conditional_logic_field_action', true, formId, targetId, defaultValues, isInit); 512 513 if(reset && !gformIsHidden(child)){ 514 gf_reset_to_default(targetId, defaultValues); 515 } 516 } 517 518 // remove tabindex and stash as a data attr for selects 519 $target.find( 'select' ).each( function() { 520 var $select = jQuery( this ); 521 $select.data( 'tabindex', $select.attr( 'tabindex' ) ).removeAttr( 'tabindex' ); 522 } ); 523 524 //Saving existing display so that it can be reset when showing the field 525 if( ! $target.data('gf_display') ){ 526 $target.data('gf_display', $target.css('display')); 527 } 528 529 if(useAnimation && !isInit){ 530 if( $target.is( 'input[type="submit"]' ) || $target.hasClass( 'gform_next_button' ) ) { 531 gf_hide_button( $target ); 532 } else if ( $target.length > 0 && $target.is( ":visible" ) ) { 533 $target.slideUp( callback ); 534 $target.attr( 'data-conditional-logic', 'hidden' ); 535 } else if ( callback ) { 536 callback(); 537 } 538 } else{ 539 540 // Handle conditional submit and next buttons. 541 if ( $target.is( 'input[type="submit"]' ) || $target.hasClass( 'gform_next_button' ) ) { 542 gf_hide_button( $target ); 543 } else { 544 $target.css( 'display', 'none' ); 545 $target.attr( 'data-conditional-logic', 'hidden' ); 546 } 547 $target.find(':input:hidden:not(.gf-default-disabled)').attr( 'disabled', 'disabled' ); 548 if(callback){ 549 callback(); 550 } 551 } 552 } 553 554} 555 556function gf_show_button( $target ) { 557 $target.prop( 'disabled', false ).css( 'display', '' ); 558 $target.attr( 'data-conditional-logic', 'visible' ); 559 if ( '1' == gf_legacy.is_legacy ) { 560 // for legacy markup, remove screen reader class. 561 $target.removeClass( 'screen-reader-text' ); 562 } 563 564 // Sometimes the next button is pretending to be a submit button, so it needs conditional logic too. 565 var fauxSubmitButton = jQuery( 'input.gform_next_button[type="button"][value="Submit"]' ); 566 if ( fauxSubmitButton ) { 567 fauxSubmitButton.prop( 'disabled', false ).css( 'display', '' ); 568 fauxSubmitButton.attr( 'data-conditional-logic', 'visible' ); 569 } 570} 571 572function gf_hide_button( $target ) { 573 $target.attr( 'disabled', 'disabled' ).hide(); 574 $target.attr( 'data-conditional-logic', 'hidden' ); 575 if ( '1' === gf_legacy.is_legacy ) { 576 // for legacy markup, let screen readers read the button. 577 $target.addClass( 'screen-reader-text' ); 578 } 579 580 // Sometimes the next button is pretending to be a submit button, so it needs conditional logic too. 581 var fauxSubmitButton = jQuery( 'input.gform_next_button[type="button"][value="Submit"]' ); 582 if ( fauxSubmitButton ) { 583 fauxSubmitButton.attr( 'disabled', 'disabled' ).hide(); 584 fauxSubmitButton.attr( 'data-conditional-logic', 'hidden' ); 585 } 586} 587 588function gf_reset_to_default(targetId, defaultValue){ 589 590 var $target = jQuery( targetId ); 591 if( $target.hasClass('gfield_shipping') || $target.hasClass('gfield_total') || 592 $target.hasClass('gfield--type-shipping') || $target.hasClass('gfield--type-total') ) { 593 return; 594 } 595 596 var dateFields = jQuery( targetId ).find( '.gfield_date_month input, .gfield_date_day input, .gfield_date_year input, .gfield_date_dropdown_month select, .gfield_date_dropdown_day select, .gfield_date_dropdown_year select' ); 597 if( dateFields.length > 0 ) { 598 599 dateFields.each( function(){ 600 601 var element = jQuery( this ); 602 603 // defaultValue is associative array (i.e. [ m: 1, d: 13, y: 1987 ] ) 604 if( defaultValue ) { 605 606 var key = 'd'; 607 if (element.parents().hasClass('gfield_date_month') || element.parents().hasClass('gfield_date_dropdown_month') ){ 608 key = 'm'; 609 } 610 else if(element.parents().hasClass('gfield_date_year') || element.parents().hasClass('gfield_date_dropdown_year') ){ 611 key = 'y'; 612 } 613 614 val = defaultValue[ key ]; 615 616 } 617 else{ 618 val = ""; 619 } 620 621 if(element.prop("tagName") == "SELECT" && val != '' ) 622 val = parseInt(val, 10); 623 624 625 if(element.val() != val) 626 element.val(val).trigger("change"); 627 else 628 element.val(val); 629 630 }); 631 632 return; 633 } 634 635 //cascading down conditional logic to children to support nested conditions 636 //text fields and drop downs, filter out list field text fields name with "_shim" 637 var target = jQuery(targetId).find( 'select, input[type="text"]:not([id*="_shim"]), input[type="number"], input[type="hidden"], input[type="email"], input[type="tel"], input[type="url"], textarea' ); 638 var target_index = 0; 639 640 // When a List field is hidden via conditional logic during a page submission, the markup
640will be reduced to a 641 // single row. Add enough rows/inputs to satisfy the default value. 642 if( defaultValue && target.parents( '.ginput_list' ).length > 0 && target.length < defaultValue.length ) { 643 while( target.length < defaultValue.length ) { 644 gformAddListItem( target.eq( 0 ), 0 ); 645 target = jQuery(targetId).find( 'select, input[type="text"]:not([id*="_shim"]), input[type="number"], textarea' ); 646 } 647 } 648 649 target.each(function(){ 650 651 var val = ""; 652 653 var element = jQuery(this); 654 655 // Only reset Single Product and Shipping hidden inputs. 656 if( element.is( '[type="hidden"]' ) && ! gf_is_hidden_pricing_input( element ) ) { 657 return; 658 } 659 660 //get name of previous input field to see if it is the radio button which goes with the "Other" text box 661 //otherwise field is populated with input field name 662 var radio_button_name = element.prevAll("input").first().attr("value"); 663 if(radio_button_name == "gf_other_choice"){ 664 val = element.attr("value"); 665 } 666 else if( Array.isArray( defaultValue ) && ! element.is( 'select[multiple]' ) ) { 667 val = defaultValue[target_index]; 668 } 669 else if(jQuery.isPlainObject(defaultValue)){ 670 val = defaultValue[element.attr("name")]; 671 if( ! val && element.attr( 'id' ) ) { 672 // 'input_123_3_1' => '3.1' 673 var inputId = element.attr( 'id' ).split( '_' ).slice( 2 ).join( '.' ); 674 val = defaultValue[ inputId ]; 675 } 676 if( ! val && element.attr( 'name' ) && element.attr( 'type' ) != 'email' ) { 677 var inputId = element.attr( 'name' ).split( '_' )[1]; 678 val = defaultValue[ inputId ]; 679 } 680 } 681 else if(defaultValue){ 682 val = defaultValue; 683 } 684 685 if( element.is('select:not([multiple])') && ! val ) { 686 val = element.find( 'option' ).not( ':disabled' ).eq(0).val(); 687 } 688 689 if(element.val() != val) { 690 element.val(val).trigger('change'); 691 if (element.is('select') && element.next().hasClass('chosen-container')) { 692 element.trigger('chosen:updated'); 693 } 694 // Check for Single Product & Shipping input and force visual price update. 695 if( gf_is_hidden_pricing_input( element ) ) { 696 var ids = gf_get_ids_by_html_id( element.parents( '.gfield' ).attr( 'id' ) ); 697 jQuery( '#input_' + ids[0] + '_' + ids[1] ).text( gformFormatMoney( element.val() ) ); 698 element.val( gformFormatMoney( element.val() ) ); 699 } 700 } 701 else{ 702 element.val(val); 703 } 704 705 target_index++; 706 }); 707 708 //checkboxes and radio buttons 709 var elements = jQuery(targetId).find('input[type="radio"], input[type="checkbox"]:not(".copy_values_activated")'); 710 711 elements.each(function(){ 712 713 //is input currently checked? 714 var isChecked = jQuery(this).is(':checked') ? true : false; 715 716 //does input need to be marked as checked or unchecked? 717 var doCheck = defaultValue ? jQuery.inArray(jQuery(this).attr('id'), defaultValue) > -1 : false; 718 719 //if value changed, trigger click event 720 if(isChecked != doCheck){ 721 //setting input as checked or unchecked appropriately 722 723 if(jQuery(this).attr("type") == "checkbox"){ 724 jQuery(this).trigger('click'); 725 } 726 else{ 727 jQuery(this).prop('checked', doCheck).change(); 728 // Triggering native change event so that non-jQuery code can listen to it. 729 this.dispatchEvent( new Event( 'change', { bubbles: true } ) ); 730 } 731 732 } 733 }); 734 735} 736 737function gf_is_hidden_pricing_input( element ) { 738 739 // Check for Single Product fields. 740 if( element.attr( 'id' ) && element.attr( 'id' ).indexOf( 'ginput_base_price' ) === 0 ) { 741 return true; 742 } 743 744 if( element.attr( 'type' ) !== 'hidden' ) { 745 return false; 746 } 747 748 // Check for Shipping fields. 749 return element.parents( '.gfield_shipping' ).length; 750}
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.