1 2// "prop" method fix for previous versions of jQuery (1.5 and below) 3if( typeof jQuery.fn.prop === 'undefined' ) { 4 jQuery.fn.prop = jQuery.fn.attr; 5} 6 7//Formatting free form currency fields to currency 8jQuery(document).ready(function(){ 9 jQuery(document).bind('gform_post_render', gformBindFormatPricingFields); 10}); 11 12function gformBindFormatPricingFields(){ 13 jQuery(".ginput_amount, .ginput_donation_amount").bind("change", function(){ 14 gformFormatPricingField(this); 15 }); 16 17 jQuery(".ginput_amount, .ginput_donation_amount").each(function(){ 18 gformFormatPricingField(this); 19 }); 20} 21 22 23//------------------------------------------------ 24//---------- CURRENCY ---------------------------- 25//------------------------------------------------ 26function Currency(currency){ 27 this.currency = currency; 28 29 this.toNumber = function(text){ 30 if(this.isNumeric(text)) 31 return parseFloat(text); 32 33 return gformCleanNumber(text, this.currency["symbol_right"], this.currency["symbol_left"], this.currency["decimal_separator"]); 34 }; 35 36 this.toMoney = function(number){ 37 if(!this.isNumeric(number)) 38 number = this.toNumber(number); 39 40 if(number === false) 41 return ""; 42 43 number = number + ""; 44 negative = ""; 45 if(number[0] == "-"){ 46 negative = "-"; 47 number = parseFloat(number.substr(1)); 48 } 49 money = this.numberFormat(number, this.currency["decimals"], this.currency["decimal_separator"], this.currency["thousand_separator"]); 50 51 if ( money == '0.00' ){ 52 negative = ''; 53 } 54 55 var symbol_left = this.currency["symbol_left"] ? this.currency["symbol_left"] + this.currency["symbol_padding"] : ""; 56 var symbol_right = this.currency["symbol_right"] ? this.currency["symbol_padding"] + this.currency["symbol_right"] : ""; 57 money = negative + this.htmlDecode(symbol_left) + money + this.htmlDecode(symbol_right); 58 return money; 59 }; 60 61 this.numberFormat = function(number, decimals, dec_point, thousands_sep, padded){ 62 var padded = typeof padded == 'undefined'; 63 number = (number+'').replace(',', '').replace(' ', ''); 64 var n = !isFinite(+number) ? 0 : +number, 65 prec = !isFinite(+decimals) ? 0 : Math.abs(decimals), 66 sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep, dec = (typeof dec_point === 'undefined') ? '.' : dec_point, 67 s = '', 68 69 toFixedFix = function (n, prec) { 70 var k = Math.pow(10, prec); 71 return '' + Math.round(n * k) / k; 72 }; 73 74 if(decimals == '0') { 75 s = ('' + Math.round(n)).split('.'); 76 } else 77 if(decimals == -1) { 78 s = ('' + n).split('.'); 79 } else { 80 // Fix for IE parseFloat(0.55).toFixed(0) = 0; 81 s = toFixedFix(n, prec).split('.'); 82 } 83 84 if (s[0].length > 3) { 85 s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep); 86 } 87 88 if(padded) { 89 if ((s[1] || '').length < prec) { 90 s[1] = s[1] || ''; 91 s[1] += new Array(prec - s[1].length + 1).join('0'); 92 } 93 } 94 95 return s.join(dec); 96 } 97 98 this.isNumeric = function(number){ 99 return gformIsNumber(number); 100 }; 101 102 this.htmlDecode = function(text) { 103 var c,m,d = text; 104 105 // look for numerical entities " 106 var arr=d.match(/&#[0-9]{1,5};/g); 107 108 // if no matches found in string then skip 109 if(arr!=null){ 110 for(var x=0;x<arr.length;x++){ 111 m = arr[x]; 112 c = m.substring(2,m.length-1); //get numeric part which is refernce to unicode character 113 // if its a valid number we can decode 114 if(c >= -32768 && c <= 65535){ 115 // decode every single match within string 116 d = d.replace(m, String.fromCharCode(c)); 117 }else{ 118 d = d.replace(m, ""); //invalid so replace with nada 119 } 120 } 121 } 122 return d; 123 }; 124} 125 126function gformCleanNumber(text, symbol_right, symbol_left, decimal_separator){ 127 //converting to a string if a number as passed 128 text = text + " "; 129 130 //Removing symbol in unicode format (i.e. ᅜ) 131 text = text.replace(/&.*?;/, "", text); 132 133 //Removing symbol from text 134 text = text.replace(symbol_right, ""); 135 text = text.replace(symbol_left, ""); 136 137 138 //Removing all non-numeric characters 139 var clean_number = ""; 140 var is_negative = false;
141 for(var i=0; i<text.length; i++){ 142 var digit = text.substr(i,1); 143 if( (parseInt(digit) >= 0 && parseInt(digit) <= 9) || digit == decimal_separator ) 144 clean_number += digit; 145 else if(digit == '-') 146 is_negative = true; 147 } 148 149 //Removing thousand separators but keeping decimal point 150 var float_number = ""; 151 152 for(var i=0; i<clean_number.length; i++) 153 { 154 var char = clean_number.substr(i,1); 155 if (char >= '0' && char <= '9') 156 float_number += char; 157 else if(char == decimal_separator){ 158 float_number += "."; 159 } 160 } 161 162 if(is_negative) 163 float_number = "-" + float_number; 164 165 return gformIsNumber(float_number) ? parseFloat(float_number) : false; 166} 167 168function gformGetDecimalSeparator(numberFormat){ 169 var s; 170 switch (numberFormat){ 171 case 'currency' : 172 var currency = new Currency(gf_global.gf_currency_config); 173 s = currency.currency["decimal_separator"]; 174 break; 175 case 'decimal_comma' : 176 s = ','; 177 break; 178 default : 179 s = "." 180 } 181 return s; 182} 183 184function gformIsNumber(n) { 185 return !isNaN(parseFloat(n)) && isFinite(n); 186} 187 188function gformIsNumeric(value, number_format){ 189 190 switch(number_format){ 191 case "decimal_dot" : 192 var r = new RegExp("^(-?[0-9]{1,3}(?:,?[0-9]{3})*(?:\.[0-9]+)?)$"); 193 return r.test(value); 194 break; 195 196 case "decimal_comma" : 197 var r = new RegExp("^(-?[0-9]{1,3}(?:\.?[0-9]{3})*(?:,[0-9]+)?)$"); 198 return r.test(value); 199 break; 200 } 201 return false; 202} 203 204//------------------------------------------------ 205//---------- MULTI-PAGE -------------------------- 206//------------------------------------------------ 207function gformDeleteUploadedFile(formId, fieldId, deleteButton){ 208 var parent = jQuery("#field_" + formId + "_" + fieldId); 209 210 var fileIndex = jQuery(deleteButton).parent().index(); 211 212 parent.find(".ginput_preview").eq(fileIndex).remove(); 213 214 //displaying single file upload field 215 parent.find("input[type=\"file\"]").removeClass("gform_hidden"); 216 217 //displaying post image label 218 parent.find(".ginput_post_image_file").show(); 219 220 //clearing post image meta fields 221 parent.find("input[type=\"text\"]").val(''); 222 223 //removing file from uploaded meta 224 var files = jQuery.secureEvalJSON(jQuery('#gform_uploaded_files_' + formId).val()); 225 if(files){ 226 var inputName = "input_" + fieldId; 227 var $multfile = parent.find("#gform_multifile_upload_" + formId + "_" + fieldId ); 228 if( $multfile.length > 0 ) { 229 files[inputName].splice(fileIndex, 1); 230 var settings = $multfile.data('settings'); 231 var max = settings.gf_vars.max_files; 232 jQuery("#" + settings.gf_vars.message_id).html(''); 233 if(files[inputName].length < max) 234 gfMultiFileUploader.toggleDisabled(settings, false); 235 236 } else { 237 files[inputName] = null; 238 } 239 240 jQuery('#gform_uploaded_files_' + formId).val(jQuery.toJSON(files)); 241 } 242} 243 244 245//------------------------------------------------ 246//---------- PRICE ------------------------------- 247//------------------------------------------------ 248var _gformPriceFields = new Array(); 249var _anyProductSelected; 250 251function gformIsHidden(element){ 252 return element.parents('.gfield').not(".gfield_hidden_product").css("display") == "none"; 253} 254 255function gformCalculateTotalPrice(formId){ 256 257 if(!_gformPriceFields[formId]) 258 return; 259 260 var price = 0; 261 262 _anyProductSelected = false; //Will be used by gformCalculateProductPrice(). 263 for(var i=0; i<_gformPriceFields[formId].length; i++){ 264 price += gformCalculateProductPrice(formId, _gformPriceFields[formId][i]); 265 } 266 267 //add shipping price if a product has been selected 268 if(_anyProductSelected){ 269 //shipping price 270 var shipping = gformGetShippingPrice(formId) 271 price += shipping; 272 } 273 274 //gform_product_total filter. Allows uers to perform custom price calculation 275 if(window["gform_product_total"]) 276 price = window["gform_product_total"](formId, price); 277 278 279 price = gform.applyFilters('gform_product_total', price, formId); 280 281 //updating total 282 var totalElement = jQuery(".ginput_total_" + formId); 283 if(totalElement.length > 0){ 284 totalElement.next().val(price); 285 totalElement.html(gformFormatMoney(price)); 286 } 287} 288 289function gformGetShippingPrice(formId){ 290 var shippingField = jQuery(".gfield_shipping_" + formId + " input[type=\"hidden\"], .gfield_shipping_" + formId + " select, .gfield_shipping_" + formId + " input:checked"); 291 var shipping = 0; 292 if(shippingField.length == 1 && !gformIsHidden(shippingField)){ 293 if(shippingField.attr("type") && shippingField.attr("type").toLowerCase() == "hidden") 294 shipping = shippingField.val(); 295 else 296 shipping = gformGetPrice(shippingField.val()); 297 } 298 299 return gformToNumber(shipping); 300} 301 302function gformGetFieldId(element){ 303 var id = jQuery(element).attr("id"); 304 var pieces = id.split("_"); 305 if(pieces.length <=0) 306 return 0; 307 308 var fieldId = pieces[pieces.length-1]; 309 return fieldId; 310 311} 312 313function gformCalculateProductPrice(form_id, productFieldId){ 314 315 var price = gformGetBasePrice(form_id, productFieldId); 316 317 var suffix = "_" + form_id + "_" + productFieldId; 318 319 320 //Drop down auto-calculating labels 321 jQuery(".gfield_option" + suffix + ", .gfield_shipping_" + form_id).find("select").each(function(){ 322 323 var dropdown_field = jQuery(this); 324 var selected_price = gformGetPrice(dropdown_field.val()); 325 var field_id = dropdown_field.attr("id").split("_")[2]; 326 dropdown_field.children("option").each(function(){ 327 var choice_element = jQuery(this);
328 var label = gformGetOptionLabel(choice_element, choice_element.val(), selected_price, form_id, field_id); 329 choice_element.html(label); 330 }); 331 }); 332 333 334 //Checkboxes labels with prices 335 jQuery(".gfield_option" + suffix).find(".gfield_checkbox").find("input").each(function(){ 336 var checkbox_item = jQuery(this); 337 var id = checkbox_item.attr("id"); 338 var field_id = id.split("_")[3]; 339 var label_id = id.replace("choice_", "#label_"); 340 var label_element = jQuery(label_id); 341 342 var label = gformGetOptionLabel(label_element, checkbox_item.val(), 0, form_id, field_id); 343 label_element.html(label); 344 }); 345 346 347 //Radio button auto-calculating lables 348 jQuery(".gfield_option" + suffix + ", .gfield_shipping_" + form_id).find(".gfield_radio").each(function(){ 349 var selected_price = 0; 350 var radio_field = jQuery(this); 351 var id = radio_field.attr("id"); 352 var fieldId = id.split("_")[3]; 353 var selected_value = radio_field.find("input:checked").val(); 354 355 if(selected_value) 356 selected_price = gformGetPrice(selected_value); 357 358 jQuery(this).find("input").each(function(){ 359 var radio_item = jQuery(this); 360 var label_id = radio_item.attr("id").replace("choice_", "#label_"); 361 var label_element = jQuery(label_id); 362 var label = gformGetOptionLabel(label_element, radio_item.val(), selected_price, form_id, fieldId); 363 label_element.html(label); 364 }); 365 }); 366 367 jQuery(".gfield_option" + suffix).find("input:checked, select").each(function(){ 368 if(!gformIsHidden(jQuery(this))) 369 price += gformGetPrice(jQuery(this).val()); 370 }); 371 372 var quantity = gformGetProductQuantity( form_id, productFieldId ); 373 374 //setting global variable if quantity is more than 0 (a product was selected). Will be used when calculating total 375 if(quantity > 0) 376 _anyProductSelected = true; 377 378 price = price * quantity; 379 price = Math.round(price * 100) / 100; 380 381 return price; 382} 383 384function gformGetProductQuantity( formId, productFieldId ) { 385 386 var quantity, 387 quantityInput = jQuery( '#ginput_quantity_' + formId + '_' + productFieldId); 388 389 if( quantityInput.length > 0 ) { 390 391 quantity = ! gformIsNumber( quantityInput.val() ) ? 0 : quantityInput.val(); 392 393 } else { 394 395 quantityElement = jQuery( '.gfield_quantity_' + formId + '_' + productFieldId); 396 quantity = 1; 397 398 if( quantityElement.find( 'select' ).length > 0 ) { 399 quantity = quantityElement.find( 'select' ).val(); 400 } else if( quantityElement.find( 'input' ).length > 0 ) { 401 quantity = quantityElement.find( 'input' ).val(); 402 } 403 404 if( ! gformIsNumber( quantity ) ) 405 quantity = 0; 406 407 } 408 409 quantity = parseFloat( quantity ); 410 411 return quantity; 412} 413 414function gformGetBasePrice(formId, productFieldId){ 415 416 var suffix = "_" + formId + "_" + productFieldId; 417 var price = 0; 418 var productField = jQuery("#ginput_base_price" + suffix+ ", .gfield_donation" + suffix + " input[type=\"text\"], .gfield_product" + suffix + " .ginput_amount"); 419 if(productField.length > 0){ 420 price = productField.val(); 421 422 //If field is hidden by conditional logic, don't count it for the total 423 if(gformIsHidden(productField)){ 424 price = 0; 425 } 426 } 427 else 428 { 429 productField = jQuery(".gfield_product" + suffix + " select, .gfield_product" + suffix + " input:checked, .gfield_donation" + suffix + " select, .gfield_donation" + suffix + " input:checked"); 430 var val = productField.val(); 431 if(val){ 432 val = val.split("|"); 433 price = val.length > 1 ? val[1] : 0; 434 } 435 436 //If field is hidden by conditional logic, don't count it for the total 437 if(gformIsHidden(productField)) 438 price = 0; 439 440 } 441 442 var c = new Currency(gf_global.gf_currency_config); 443 price = c.toNumber(price); 444 return price === false ? 0 : price; 445} 446 447function gformFormatMoney(text){ 448 if(!gf_global.gf_currency_config) 449 return text; 450 451 var currency = new Currency(gf_global.gf_currency_config); 452 return currency.toMoney(text); 453} 454 455function gformFormatPricingField(element){ 456 if(gf_global.gf_currency_config){ 457 var currency = new Currency(gf_global.gf_currency_config); 458 var price = currency.toMoney(jQuery(element).val()); 459 jQuery(element).val(price); 460 } 461} 462 463function gformToNumber(text){ 464 var currency = new Currency(gf_global.gf_currency_config); 465 return currency.toNumber(text); 466} 467 468function gformGetPriceDifference(currentPrice, newPrice){ 469 470 //getting price difference 471 var diff = parseFloat(newPrice) - parseFloat(currentPrice); 472 price = gformFormatMoney(diff); 473 if(diff > 0) 474 price = "+" + price; 475 476 return price; 477} 478 479function gformGetOptionLabel(element, selected_value, current_price, form_id, field_id){ 480 element = jQuery(element); 481 var price = gformGetPrice(selected_value); 482 var current_diff = element.attr('price'); 483 var original_label = element.html().replace(/<span(.*)<\/span>/i, "").replace(current_diff, ""); 484 485 var diff = gformGetPriceDifference(current_price, price); 486 diff = gformToNumber(diff) == 0 ? "" : " " + diff; 487 element.attr('price', diff); 488 489 //don't add <span> for drop down items (not supported) 490 var price_label = element[0].tagName.toLowerCase() == "option" ? " " + diff : "<span class='ginput_price'>" + diff + "</span>"; 491 var label = original_label + price_label; 492 493 //calling hook to allow for custom option formatting 494 if(window["gform_format_option_label"]) 495 label = gform_format_option_label(label, original_label, price_label, current_price, price, form_id, field_id); 496 497 return label; 498} 499 500function gformGetProductIds(parent_class, element){ 501 var classes = jQuery(element).hasClass(parent_class) ? jQuery(element).attr("class").split(" ") : jQuery(element).parents("." + parent_class).attr("class").split(" "); 502 for(var i=0; i<classes.length; i++){ 503 if(classes[i].substr(0, parent_class.length) == parent_class && classes[i] != parent_class) 504 return {formId: classes[i].split("_")[2], productFieldId: classes[i].split("_")[3]}; 505 } 506 return {formId:0, fieldId:0}; 507} 508 509function gformGetPrice(text){ 510 var val = text.split("|"); 511 var currency = new Currency(gf_global.gf_currency_config); 512 513 if(val.length > 1 && currency.toNumber(val[1]) !== false) 514 return currency.toNumber(val[1]); 515 516 return 0; 517} 518 519function gformRegisterPriceField(item){ 520 521 if(!_gformPriceFields[item.formId]) 522 _gformPriceFields[item.formId] = new Array(); 523 524 //ignore price fields that have already been registered 525 for(var i=0; i<_gformPriceFields[item.formId].length; i++) 526 if(_gformPriceFields[item.formId][i] == item.productFieldId) 527 return; 528 529 //registering new price field 530 _gformPriceFields[item.formId].push(item.productFieldId); 531} 532 533function gformInitPriceFields(){ 534 535 jQuery(".gfield_price").each(function(){ 536 537 var productIds = gformGetProductIds("gfield_price", this); 538 gformRegisterPriceField(productIds); 539 540 jQuery(this).find("input[type=\"text\"], input[type=\"number\"], select").change(function(){ 541 542 var productIds = gformGetProductIds("gfield_price", this); 543 if(productIds.formId == 0) 544 productIds = gformGetProductIds("gfield_shipping", this); 545 546 jQuery(document).trigger('gform_price_change', [productIds, this]); 547 gformCalculateTotalPrice(productIds.formId); 548 }); 549 550 jQuery(this).find("input[type=\"radio\"], input[type=\"checkbox\"]").click(function(){ 551 var productIds = gformGetProductIds("gfield_price", this); 552 if(productIds.formId == 0) 553 productIds = gformGetProductIds("gfield_shipping", this); 554 555 jQuery(document).trigger('gform_price_change', [productIds, this]); 556 gformCalculateTotalPrice(productIds.formId); 557 }); 558 559 }); 560 561 for(formId in _gformPriceFields){ 562 563 //needed when implementing for in loops 564 if(!_gformPriceFields.hasOwnProperty(formId)) 565 continue; 566 567 gformCalculateTotalPrice(formId); 568 } 569 570} 571 572 573//------------------------------------------- 574//---------- PASSWORD ----------------------- 575//------------------------------------------- 576function gformShowPasswordStrength(fieldId){ 577 var password = jQuery("#" + fieldId).val(); 578 var confirm = jQuery("#" + fieldId + "_2").val(); 579 580 var result = gformPasswordStrength(password, confirm); 581 582 var text = window['gf_text']["password_" + result]; 583 584 jQuery("#" + fieldId + "_strength").val(result);
585 jQuery("#" + fieldId + "_strength_indicator").removeClass("blank mismatch short good bad strong").addClass(result).html(text); 586} 587 588// Password strength meter 589function gformPasswordStrength(password1, password2) { 590 var shortPass = 1, badPass = 2, goodPass = 3, strongPass = 4, mismatch = 5, symbolSize = 0, natLog, score; 591 592 if(password1.length <=0) 593 return "blank"; 594 595 // password 1 != password 2 596 if ( (password1 != password2) && password2.length > 0) 597 return "mismatch"; 598 599 //password < 4 600 if ( password1.length < 4 ) 601 return "short"; 602 603 if ( password1.match(/[0-9]/) ) 604 symbolSize +=10; 605 if ( password1.match(/[a-z]/) ) 606 symbolSize +=26; 607 if ( password1.match(/[A-Z]/) ) 608 symbolSize +=26; 609 if ( password1.match(/[^a-zA-Z0-9]/) ) 610 symbolSize +=31; 611 612 natLog = Math.log( Math.pow(symbolSize, password1.length) ); 613 score = natLog / Math.LN2; 614 615 if (score < 40 ) 616 return "bad"; 617 618 if (score < 56 ) 619 return "good"; 620 621 return "strong"; 622 623} 624 625//---------------------------- 626//------ LIST FIELD ---------- 627//---------------------------- 628var gfield_original_title = ""; 629function gformAddListItem(element, max){ 630 631 if(jQuery(element).hasClass("gfield_icon_disabled")) 632 return; 633 634 var tr = jQuery(element).closest('tr'); 635 var clone = tr.clone(); 636 clone.find("input, select").val("").attr("tabindex", clone.find('input:last').attr("tabindex")); 637 tr.after(clone); 638 gformToggleIcons(tr.parent(), max); 639 gformAdjustClasses(tr.parent()); 640} 641 642function gformDeleteListItem(element, max){ 643 var tr = jQuery(element).parent().parent(); 644 var parent = tr.parent(); 645 tr.remove(); 646 gformToggleIcons(parent, max); 647 gformAdjustClasses(parent); 648} 649 650function gformAdjustClasses(table){ 651 var rows = table.children(); 652 for(var i=0; i<rows.length; i++){ 653 var odd_even_class = (i+1) % 2 == 0 ? "gfield_list_row_even" : "gfield_list_row_odd"; 654 jQuery(rows[i]).removeClass("gfield_list_row_odd").removeClass("gfield_list_row_even").addClass(odd_even_class); 655 } 656} 657 658function gformToggleIcons(table, max){ 659 var rowCount = table.children().length; 660 if(rowCount == 1){ 661 table.find(".delete_list_item").css("visibility", "hidden"); 662 } 663 else{ 664 table.find(".delete_list_item").css("visibility", "visible"); 665 } 666 667 if(max > 0 && rowCount >= max){ 668 gfield_original_title = table.find(".add_list_item:first").attr("title"); 669 table.find(".add_list_item").addClass("gfield_icon_disabled").attr("title", ""); 670 } 671 else{ 672 var addIcons = table.find(".add_list_item"); 673 addIcons.removeClass("gfield_icon_disabled"); 674 if(gfield_original_title) 675 addIcons.attr("title", gfield_original_title); 676 } 677} 678 679 680//----------------------------------- 681//------ CREDIT CARD FIELD ---------- 682//----------------------------------- 683function gformMatchCard(id) { 684 685 var cardType = gformFindCardType(jQuery('#' + id).val()); 686 var cardContainer = jQuery('#' + id).parents('.gfield').find('.gform_card_icon_container'); 687 688 if(!cardType) { 689 690 jQuery(cardContainer).find('.gform_card_icon').removeClass('gform_card_icon_selected gform_card_icon_inactive'); 691 692 } else { 693 694 jQuery(cardContainer).find('.gform_card_icon').removeClass('gform_card_icon_selected').addClass('gform_card_icon_inactive'); 695 jQuery(cardContainer).find('.gform_card_icon_' + cardType).removeClass('gform_card_icon_inactive').addClass('gform_card_icon_selected'); 696 } 697} 698 699function gformFindCardType(value) { 700 701 if(value.length < 4) 702 return false; 703 704 var rules = window['gf_cc_rules']; 705 var validCardTypes = new Array(); 706 707 for(type in rules) { 708 709 //needed when implementing for in loops 710 if(!rules.hasOwnProperty(type)) 711 continue; 712 713 714 for(i in rules[type]) { 715 716 if(!rules[type].hasOwnProperty(i)) 717 continue; 718 719 if(rules[type][i].indexOf(value.substring(0, rules[type][i].length)) === 0) { 720 validCardTypes[validCardTypes.length] = type; 721 break; 722 } 723 724 } 725 } 726 727 return validCardTypes.length == 1 ? validCardTypes[0].toLowerCase() : false;
728} 729 730function gformToggleCreditCard(){ 731 if(jQuery("#gform_payment_method_creditcard").is(":checked")) 732 jQuery(".gform_card_fields_container").slideDown(); 733 else 734 jQuery(".gform_card_fields_container").slideUp(); 735} 736 737 738//---------------------------------------- 739//------ CHOSEN DROP DOWN FIELD ---------- 740//---------------------------------------- 741 742function gformInitChosenFields(fieldList, noResultsText){ 743 return jQuery(fieldList).each(function(){ 744 745 var element = jQuery(this); 746 747 //only initialize once 748 if( element.is(":visible") && element.siblings(".chosen-container").length == 0 ){ 749 var options = gform.applyFilters( 'gform_chosen_options', { no_results_text: noResultsText }, element ); 750 element.chosen( options ); 751 } 752 753 }); 754} 755 756//---------------------------------------- 757//--- CURRENCY FORMAT NUMBER FIELD ------- 758//---------------------------------------- 759 760function gformInitCurrencyFormatFields(fieldList){ 761 jQuery(fieldList).each(function(){ 762 var $this = jQuery(this); 763 $this.val( gformFormatMoney( jQuery(this).val() ) ); 764 }).change( function( event ) { 765 jQuery(this).val( gformFormatMoney( jQuery(this).val() ) ); 766 }); 767} 768 769 770 771//---------------------------------------- 772//------ CALCULATION FUNCTIONS ----------- 773//---------------------------------------- 774 775var GFCalc = function(formId, formulaFields){ 776 777 this.patt = /{[^{]*?:(\d+(\.\d+)?)(:(.*?))?}/i; 778 this.exprPatt = /^[0-9 -/*\(\)]+$/i; 779 this.isCalculating = {}; 780 781 this.init = function(formId, formulaFields) { 782 783 var calc = this; 784 jQuery(document).bind("gform_post_conditional_logic", function(){ 785 for(var i=0; i<formulaFields.length; i++) { 786 var formulaField = jQuery.extend({}, formulaFields[i]); 787 calc.runCalc(formulaField, formId); 788 } 789 }); 790 791 for(var i=0; i<formulaFields.length; i++) { 792 var formulaField = jQuery.extend({}, formulaFields[i]); 793 this.runCalc(formulaField, formId); 794 this.bindCalcEvents(formulaField, formId); 795 } 796 797 } 798 799 this.runCalc = function(formulaField, formId) { 800 801 var calcObj = this, 802 field = jQuery('#field_' + formId + '_' + formulaField.field_id), 803 formulaInput = jQuery('#input_' + formId + '_' + formulaField.field_id), 804 previous_val = formulaInput.val(), 805 formula = gform.applyFilters( 'gform_calculation_formula', formulaField.formula, formulaField, formId, calcObj ), 806 expr = calcObj.replaceFieldTags( formId, formula, formulaField ).replace(/(\r\n|\n|\r)/gm,""), 807 result = ''; 808 809 if(calcObj.exprPatt.test(expr)) { 810 try { 811 812 //run calculation 813 result = eval(expr); 814 815 } catch( e ) { } 816 } 817 818 // if result is postive infinity, negative infinity or a NaN, defaults to 0 819 if( ! isFinite( result ) ) 820 result = 0; 821 822 // allow users to modify result with their own function 823 if( window["gform_calculation_result"] ) { 824 result = window["gform_calculation_result"](result, formulaField, formId, calcObj); 825 if( window.console ) 826 console.log( '"gform_calculation_result" function is deprecated since version 1.8! Use "gform_calculation_result" JS hook instead.' ); 827 } 828 829 // allow users to modify result with their own function 830 result = gform.applyFilters( 'gform_calculation_result', result, formulaField, formId, calcObj ); 831 832 // allow result to be custom formatted 833 var formattedResult = gform.applyFilters( 'gform_calculation_format_result', false, result, formulaField, formId, calcObj ); 834 835 var numberFormat = gf_global.number_formats[formId][formulaField.field_id]; 836 837 //formatting number 838 if( formattedResult !== false) { 839 result = formattedResult; 840 } 841 else if( field.hasClass( 'gfield_price' ) || numberFormat == "currency") { 842 843 result = gformFormatMoney(result ? result : 0); 844 } 845 else { 846 847 var decimalSeparator = "."; 848 var thousandSeparator = ","; 849 850 if(numberFormat == "decimal_comma"){ 851 decimalSeparator = ","; 852 thousandSeparator = "."; 853 } 854 855 result = gformFormatNumber(result, !gformIsNumber(formulaField.rounding) ? -1 : formulaField.rounding, decimalSeparator, thousandSeparator); 856 } 857 858 //If value doesn't change, abort. 859 //This is needed to prevent an infinite loop condition with conditional logic 860 if( result == previous_val ) 861 return; 862 863 // if this is a calculation product, handle differently 864 if(field.hasClass('gfield_price')) { 865 formulaInput.text(result); 866 jQuery('#ginput_base_price_' + formId + '_' + formulaField.field_id).val(result).trigger('change'); 867 gformCalculateTotalPrice(formId); 868 } else { 869 formulaInput.val(result).trigger('change'); 870 } 871 872 } 873 874 875 this.bindCalcEvents = function(formulaField, formId) { 876 877 var calcObj = this; 878 var formulaFieldId = formulaField.field_id; 879 var matches = getMatchGroups(formulaField.formula, this.patt); 880 881 calcObj.isCalculating[formulaFieldId] = false;
882 883 for(var i in matches) { 884 885 if(! matches.hasOwnProperty(i)) 886 continue; 887 888 var inputId = matches[i][1]; 889 var fieldId = parseInt(inputId); 890 var input = jQuery('#field_' + formId + '_' + fieldId).find('input[name="input_' + inputId + '"], select[name="input_' + inputId + '"]'); 891 892 if(input.prop('type') == 'checkbox' || input.prop('type') == 'radio') { 893 jQuery(input).click(function(){ 894 calcObj.bindCalcEvent(inputId, formulaField, formId, 0); 895 }); 896 } else 897 if(input.is('select') || input.prop('type') == 'hidden') { 898 jQuery(input).change(function(){ 899 calcObj.bindCalcEvent(inputId, formulaField, formId, 0); 900 }); 901 } else { 902 jQuery(input).keydown(function(){ 903 calcObj.bindCalcEvent(inputId, formulaField, formId); 904 }).change(function(){ 905 calcObj.bindCalcEvent(inputId, formulaField, formId, 0); 906 }); 907 } 908 909 } 910 911 } 912 913 this.bindCalcEvent = function(inputId, formulaField, formId, delay) { 914 915 var calcObj = this; 916 var formulaFieldId = formulaField.field_id; 917 918 delay = delay == undefined ? 345 : delay; 919 920 if(calcObj.isCalculating[formulaFieldId][inputId]) 921 clearTimeout(calcObj.isCalculating[formulaFieldId][inputId]); 922 923 calcObj.isCalculating[formulaFieldId][inputId] = window.setTimeout(function() { 924 calcObj.runCalc(formulaField, formId); 925 }, delay); 926 927 } 928 929 this.replaceFieldTags = function( formId, expr, formulaField ) { 930 931 var matches = getMatchGroups(expr, this.patt); 932 var origExpr = expr; 933 934 for(i in matches) { 935 936 if(! matches.hasOwnProperty(i)) 937 continue; 938 939 var inputId = matches[i][1]; 940 var fieldId = parseInt(inputId); 941 var columnId = matches[i][3]; 942 var value = 0; 943 944 var input = jQuery('#field_' + formId + '_' + fieldId).find('input[name="input_' + inputId + '"], select[name="input_' + inputId + '"]'); 945 946 // radio buttons will return multiple inputs, checkboxes will only return one but it may not be selected, filter out unselected inputs 947 if( input.length > 1 || input.prop('type') == 'checkbox' ) 948 input = input.filter(':checked'); 949 950 var isVisible = window['gf_check_field_rule'] ? gf_check_field_rule( formId, fieldId, true, '' ) == 'show' : true; 951 952 if( input.length > 0 && isVisible ) { 953 954 var val = input.val(); 955 val = val.split( '|' ); 956 957 if( val.length > 1 ) { 958 value = val[1]; 959 } else { 960 value = input.val(); 961 } 962 963 } 964 965 var numberFormat = gf_global.number_formats[formId][fieldId]; 966 if( ! numberFormat ) 967 numberFormat = gf_global.number_formats[formId][formulaField.field_id]; 968 969 var decimalSeparator = gformGetDecimalSeparator(numberFormat); 970 971 972 value = gformCleanNumber( value, '', '', decimalSeparator ); 973 if( ! value ) 974 value = 0; 975 976 expr = expr.replace( matches[i][0], value ); 977 } 978 979 return expr; 980 } 981 982 this.init(formId, formulaFields); 983 984} 985 986function gformFormatNumber(number, rounding, decimalSeparator, thousandSeparator){ 987 988 if(typeof decimalSeparator == "undefined"){ 989 if(window['gf_global']){ 990 var currency = new Currency(gf_global.gf_currency_config); 991 decimalSeparator = currency.currency["decimal_separator"]; 992 } 993 else{ 994 decimalSeparator = "."; 995 } 996 } 997 998 if(typeof thousandSeparator == "undefined"){ 999 if(window['gf_global']){ 1000 var currency = new Currency(gf_global.gf_currency_config); 1001 thousandSeparator = currency.currency["thousand_separator"]; 1002 } 1003 else{ 1004 thousandSeparator = ","; 1005 } 1006 } 1007 1008 var currency = new Currency(); 1009 return currency.numberFormat(number, rounding, decimalSeparator, thousandSeparator, false) 1010} 1011 1012function gformToNumber(text) { 1013 var currency = new Currency(gf_global.gf_currency_config); 1014 return currency.toNumber(text); 1015} 1016 1017function getMatchGroups(expr, patt) { 1018 1019 var matches = new Array(); 1020 1021 while(patt.test(expr)) { 1022 1023 var i = matches.length; 1024 matches[i] = patt.exec(expr) 1025 expr = expr.replace('' + matches[i][0], ''); 1026 1027 } 1028 1029 return matches; 1030} 1031 1032 1033//---------------------------------------- 1034//------ JAVASCRIPT HOOK FUNCTIONS ------- 1035//---------------------------------------- 1036 1037var gform = { 1038 hooks: { action: {}, filter: {} }, 1039 addAction: function( action, callable, priority, tag ) { 1040 gform.addHook( 'action', action, callable, priority, tag ); 1041 }, 1042 addFilter: function( action, callable, priority, tag ) { 1043 gform.addHook( 'filter', action, callable, priority, tag ); 1044 }, 1045 doAction: function( action ) { 1046 gform.doHook( 'action', action, arguments ); 1047 }, 1048 applyFilters: function( action ) { 1049 return gform.doHook( 'filter', action, arguments ); 1050 }, 1051 removeAction: function( action, tag ) { 1052 gform.removeHook( 'action', action, tag ); 1053 }, 1054 removeFilter: function( action, priority, tag ) { 1055 gform.removeHook( 'filter', action, priority, tag ); 1056 }, 1057 addHook: function( hookType, action, callable, priority, tag ) { 1058 if ( undefined == gform.hooks[hookType][action] ) { 1059 gform.hooks[hookType][action] = []; 1060 } 1061 var hooks = gform.hooks[hookType][action]; 1062 if ( undefined == tag ) { 1063 tag = action + '_' + hooks.length; 1064 } 1065 gform.hooks[hookType][action].push( { tag:tag, callable:callable, priority:priority } ); 1066 }, 1067 doHook: function( hookType, action, args ) { 1068 1069 // splice args from object into array and remove first index which is the hook name 1070 args = Array.prototype.slice.call(args, 1); 1071 1072 if ( undefined != gform.hooks[hookType][action] ) { 1073 var hooks = gform.hooks[hookType][action], hook; 1074 //sort by priority 1075 hooks.sort(function(a,b){return a["priority"]-b["priority"]}); 1076 for( var i=0; i<hooks.length; i++) { 1077 hook = hooks[i].callable; 1078 if(typeof hook != 'function')
1079 hook = window[hook]; 1080 if ( 'action' == hookType ) { 1081 hook.apply(null, args); 1082 } else { 1083 args[0] = hook.apply(null, args); 1084 } 1085 } 1086 } 1087 if ( 'filter'==hookType ) { 1088 return args[0]; 1089 } 1090 }, 1091 removeHook: function( hookType, action, priority, tag ) { 1092 if ( undefined != gform.hooks[hookType][action] ) { 1093 var hooks = gform.hooks[hookType][action]; 1094 for( var i=hooks.length-1; i>=0; i--) { 1095 if ((undefined==tag||tag==hooks[i].tag) && (undefined==priority||priority==hooks[i].priority)){ 1096 hooks.splice(i,1); 1097 } 1098 } 1099 } 1100 } 1101}; 1102 1103 1104//---------------------------------------- 1105//------ MULTIFILE UPLOAD FUNCTIONS ------ 1106//---------------------------------------- 1107 1108(function (gfMultiFileUploader, $) { 1109 gfMultiFileUploader.uploaders = {}; 1110 var strings = typeof gform_gravityforms != 'undefined' ? gform_gravityforms.strings : {}; 1111 var imagesUrl = typeof gform_gravityforms != 'undefined' ? gform_gravityforms.vars.images_url : ""; 1112 1113 $(document).ready(function () { 1114 if((typeof adminpage !== 'undefined' && adminpage === 'toplevel_page_gf_edit_forms')|| typeof plupload == 'undefined'){ 1115 $(".gform_button_select_files").prop("disabled", true); 1116 } else if (typeof adminpage !== 'undefined'){ 1117 $(".gform_fileupload_multifile").each(function(){ 1118 setup(this); 1119 }); 1120 } else { 1121 $(document).bind('gform_post_render', function(e, formID){ 1122 1123 $("form#gform_" + formID + " .gform_fileupload_multifile").each(function(){ 1124 setup(this); 1125 }); 1126 var $form = $("form#gform_" + formID); 1127 if($form.length > 0){ 1128 $form.submit(function(){ 1129 var pendingUploads = false; 1130 $.each(gfMultiFileUploader.uploaders, function(i, uploader){ 1131 if(uploader.total.queued>0){ 1132 pendingUploads = true; 1133 return false; 1134 } 1135 }); 1136 if(pendingUploads){ 1137 alert(strings.currently_uploading); 1138 window["gf_submitting_" + formID] = false; 1139 $('#gform_ajax_spinner_' + formID).remove(); 1140 return false; 1141 } 1142 }); 1143 } 1144 1145 }); 1146 $(document).bind("gform_post_conditional_logic", function(e,formID, fields, isInit){ 1147 if(!isInit){ 1148 $.each(gfMultiFileUploader.uploaders, function(i, uploader){ 1149 uploader.refresh(); 1150 }); 1151 } 1152 }); 1153 } 1154 }); 1155 1156 function setup(uploadElement){ 1157 var settings = $(uploadElement).data('settings'); 1158 1159 var uploader = new plupload.Uploader(settings); 1160 formID = uploader.settings.multipart_params.form_id; 1161 gfMultiFileUploader.uploaders[settings.container] = uploader; 1162 var formID; 1163 var uniqueID; 1164 1165 uploader.bind('Init', function(up, params) { 1166 if(!up.features.dragdrop) 1167 $(".gform_drop_instructions").hide(); 1168 var fieldID = up.settings.multipart_params.field_id; 1169 var maxFiles = parseInt(up.settings.gf_vars.max_files); 1170 var initFileCount = countFiles(fieldID); 1171 if(maxFiles > 0 && initFileCount >= maxFiles){ 1172 gfMultiFileUploader.toggleDisabled(up.settings, true); 1173 } 1174 1175 }); 1176 1177 gfMultiFileUploader.toggleDisabled = function (settings, disabled){ 1178 1179 var button = typeof settings.browse_button == "string" ? $("#" + settings.browse_button) : $(settings.browse_button); 1180 button.prop("disabled", disabled); 1181 } 1182 1183 function addMessage(messagesID, message){ 1184 $("#" + messagesID).prepend("<li>" + message + "</li>"); 1185 } 1186 1187 uploader.init(); 1188 1189 uploader.bind('FilesAdded', function(up, files) { 1190 var max = parseInt(up.settings.gf_vars.max_files), 1191 fieldID = up.settings.multipart_params.field_id, 1192 totalCount = countFiles(fieldID), 1193 disallowed = up.settings.gf_vars.disallowed_extensions, 1194 extension; 1195 1196 if( max > 0 && totalCount >= max){ 1197 $.each(files, function(i, file) { 1198 up.removeFile(file); 1199 return; 1200 }) 1201 return; 1202 } 1203 $.each(files, function(i, file) { 1204 1205 extension = file.name.split('.').pop(); 1206 1207 if($.inArray(extension, disallowed) > -1){ 1208 addMessage(up.settings.gf_vars.message_id, file.name + " - " + strings.illegal_extension); 1209 up.removeFile(file); 1210 return; 1211 } 1212 1213 if ((file.status == plupload.FAILED) || (max > 0 && totalCount >= max)){ 1214 up.removeFile(file); 1215 return; 1216 } 1217 1218 var size = typeof file.size !== 'undefined' ? plupload.formatSize(file.size) : strings.in_progress; 1219 var status = '<div id="' 1220 + file.id 1221 + '" class="ginput_preview">' 1222 + file.name 1223 + ' (' + size + ') <b></b> ' 1224 + '<a href="javascript:void(0)" title="' + strings.cancel_upload + '" onclick=\'$this=jQuery(this); var uploader = gfMultiFileUploader.uploaders.' + up.settings.container + ';uploader.stop();uploader.removeFile(uploader.getFile("' + file.id +'"));$this.after("' + strings.cancelled + '"); uploader.start();$this.remove();\'>' + strings.cancel + '</a>' 1225 + '</div>'; 1226 $('#' + up.settings.filelist).prepend(status); 1227 totalCount++; 1228 1229 }); 1230 1231 up.refresh(); // Reposition Flash 1232 1233 var formElementID = "form#gform_" + formID; 1234 var uidElementID = "input:hidden[name='gform_unique_id']"; 1235 var uidSelector = formElementID + " " + uidElementID; 1236 var $uid = $(uidSelector); 1237 if($uid.length==0){ 1238 $uid = $(uidElementID); 1239 } 1240 1241 uniqueID = $uid.val(); 1242 if('' === uniqueID){ 1243 uniqueID = generateUniqueID(); 1244 $uid.val(uniqueID); 1245 } 1246 1247 if(max > 0 && totalCount >= max){ 1248 addMessage(up.settings.gf_vars.message_id, strings.max_reached) 1249 gfMultiFileUploader.toggleDisabled(up.settings, true); 1250 } 1251 1252 up.settings.multipart_params.gform_unique_id = uniqueID; 1253 up.start(); 1254 1255 }); 1256 1257 uploader.bind('UploadProgress', function(up, file) { 1258 var html = file.percent + "%"; 1259 $('#' + file.id + " b").html(html); 1260 }); 1261 1262 uploader.bind('Error', function(up, err) { 1263 if(err.code === plupload.FILE_EXTENSION_ERROR){ 1264 var extensions = typeof up.settings.filters.mime_types != 'undefined' ? up.settings.filters.mime_types[0].extensions /* plupoad 2 */ : up.settings.filters[0].extensions; 1265 addMessage(up.settings.gf_vars.message_id, err.file.name + " - " + strings.invalid_file_extension + " " + extensions); 1266 } else if (err.code === plupload.FILE_SIZE_ERROR) { 1267 addMessage(up.settings.gf_vars.message_id, err.file.name + " - " + strings.file_exceeds_limit); 1268 } else { 1269 var m = "<li>Error: " + err.code + 1270 ", Message: " + err.message + 1271 (err.file ? ", File: " + err.file.name : "") + 1272 "</li>"; 1273 1274 addMessage(up.settings.gf_vars.message_id, m); 1275 } 1276 $('#' + err.file.id ).html(''); 1277 1278 up.refresh(); // Reposition Flash 1279 }); 1280 1281 uploader.bind('FileUploaded', function(up, file, result) { 1282 var response = $.secureEvalJSON(result.response); 1283 if(response.status == "error"){ 1284 addMessage(up.settings.gf_vars.message_id, file.name + " - " + response.error.message); 1285 $('#' + file.id ).html(''); 1286 return; 1287 } 1288 1289 var html = '<strong>' + file.name + '</strong>'; 1290 var formId = up.settings.multipart_params.form_id; 1291 var fieldId = up.settings.multipart_params.field_id; 1292 html = "<img " 1293 + "class='gform_delete' " 1294 + "src='" + imagesUrl + "/delete.png' " 1295 + "onclick='gformDeleteUploadedFile(" + formId + "," + fieldId + ", this);' " 1296 + "alt='"+ strings.delete_file + "' " 1297 + "title='" + strings.delete_file 1298 + "' /> " 1299 + html; 1300 1301 $('#' + file.id ).html(html); 1302 1303 var fieldID = up.settings.multipart_params["field_id"]; 1304 1305 if(file.percent == 100){ 1306 if(response.status && response.status == 'ok'){ 1307 addFile(fieldID, response.data); 1308 } else { 1309 addMessage(up.settings.gf_vars.message_id, strings.unknown_error); 1310 } 1311 } 1312 1313 }); 1314 1315 1316 1317 function getAllFiles(){ 1318 var selector = '#gform_uploaded_files_' + formID, 1319 $uploadedFiles = $(selector), files; 1320 files = $uploadedFiles.val(); 1321 files = '' === files ? {}
1321 : $.parseJSON(files); 1322 return files; 1323 } 1324 1325 function getFiles(fieldID){ 1326 var allFiles = getAllFiles(); 1327 var inputName = getInputName(fieldID); 1328 1329 if(typeof allFiles[inputName] == 'undefined') 1330 allFiles[inputName] = []; 1331 return allFiles[inputName]; 1332 } 1333 1334 function countFiles(fieldID){ 1335 var files = getFiles(fieldID); 1336 return files.length; 1337 } 1338 1339 function addFile(fieldID, fileInfo){ 1340 1341 var files = getFiles(fieldID); 1342 1343 files.unshift(fileInfo); 1344 setUploadedFiles(fieldID, files); 1345 } 1346 1347 function setUploadedFiles(fieldID, files){ 1348 var allFiles = getAllFiles(); 1349 var $uploadedFiles = $('#gform_uploaded_files_' + formID); 1350 var inputName = getInputName(fieldID); 1351 allFiles[inputName] = files; 1352 $uploadedFiles.val($.toJSON(allFiles)); 1353 } 1354 1355 function getInputName(fieldID){ 1356 return "input_" + fieldID; 1357 } 1358 1359 // fixes drag and drop in IE10 1360 $("#" + settings.drop_element).on({ 1361 "dragenter": ignoreDrag, 1362 "dragover": ignoreDrag 1363 }); 1364 1365 function ignoreDrag( e ) { 1366 e.preventDefault(); 1367 } 1368 } 1369 1370 1371 function generateUniqueID() { 1372 return 'xxxxxxxx'.replace(/[xy]/g, function (c) { 1373 var r = Math.random() * 16 | 0, v = c == 'x' ? r : r & 0x3 | 0x8; 1374 return v.toString(16); 1375 }); 1376 } 1377 1378 1379}(window.gfMultiFileUploader = window.gfMultiFileUploader || {}, jQuery)); 1380 1381 1382 1383//---------------------------------------- 1384//------ GENERAL FUNCTIONS ------- 1385//---------------------------------------- 1386 1387function gformInitSpinner( formId, spinnerUrl ) { 1388 1389 if( typeof spinnerUrl == 'undefined' || ! spinnerUrl ) 1390 spinnerUrl = gform.applyFilters( "gform_spinner_url", gf_global.spinnerUrl, formId ); 1391 1392 jQuery('#gform_' + formId).submit(function () { 1393 if (jQuery('#gform_ajax_spinner_' + formId).length == 0) { 1394 jQuery('#gform_submit_button_' + formId + ', #gform_wrapper_' + formId + ' .gform_next_button') 1395 .after('<img id="gform_ajax_spinner_' + formId + '" class="gform_ajax_spinner" src="' + spinnerUrl + '" alt="" />'); 1396 } 1397 }); 1398 1399}
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.