1function applyPricingUIToCustomFieldOptionsInDOM( currency ){ 2 $('option').each(function(){ 3 var thisAmount = $(this).data('adjustment-amount'); 4 if( thisAmount ){ 5 var amountString = ''; 6 if( thisAmount > 0){ 7 var niceAmount = formatPriceForCurrency(currency, thisAmount); 8 amountString += ' ( + '+niceAmount+' )'; 9 }else if(thisAmount < 0){ 10 var niceAmount = formatPriceForCurrency(currency, thisAmount); 11 amountString += ' ( '+niceAmount+' )'; 12 } 13 $(this).html( sanitize_string( $(this).data('response') + amountString ) ); 14 } 15 }); 16 $('.checkmarkCard').each(function(){ 17 var thisAmount = $(this).data('adjustment-amount'); 18 if( thisAmount ){ 19 var amountString = ''; 20 if( thisAmount > 0){ 21 var niceAmount = formatPriceForCurrency(currency, thisAmount); 22 amountString += ' ( + '+niceAmount+' )'; 23 }else if(thisAmount < 0){ 24 var niceAmount = formatPriceForCurrency(currency, thisAmount); 25 amountString += ' ( '+niceAmount+' )'; 26 } 27 $(this).find('p').text( $(this).find('p').text() + amountString ); 28 } 29 }); 30} 31 32function custom_field_has_cost(customFieldObject){ 33 var options = customFieldObject.get('dropdownOptionsArray') || []; 34 var hasCost = false; 35 for (var i = 0; i <= options.length - 1; i++) { 36 var thisOption = options[i]; 37 if( thisOption.get('amount') ){ 38 hasCost = true; 39 } 40 } 41 return hasCost; 42} 43
44function returnMarkupForCustomFieldResponse( customFieldObject, locked_if_field_has_cost ){ 45 var content = ''; 46 if( customFieldObject ){ 47 let locked = false; 48 if( locked_if_field_has_cost && custom_field_has_cost(customFieldObject) ){ 49 locked = true; 50 } 51 content += '<div class="flexNoWrap tinyPaddingTop inline-pair inline-pair_'+ customFieldObject.id +'" data-type="custom-field" data-locked="'+ locked +'" data-admin-only="'+ customFieldObject.get('admin_only') +'">' + 52 '<p class="inline-label">'; 53 if( locked ){ 54 content += '<i class="fa-regular fa-lock" style="padding-right:3px;"></i>'; 55 } 56 content += customFieldObject.get('name') + '</p>' + 57 '<p class="flexGrowOne inline-value marginLeft" data-custom-field-id="'+ customFieldObject.id +'"></p>' + 58 '</div>'; 59 } 60 return content; 61} 62 63function returnMarkupForCustomFieldResponse_v2( customFieldObject, customFieldResponseObject ){ 64 var content = ''; 65 if( customFieldObject && customFieldResponseObject){ 66 content += '<div class="flexNoWrap tinyPaddingTop inline-pair inline-pair_'+ customFieldObject.id +'" data-type="custom-field" data-admin-only="'+ customFieldObject.get('admin_only') +'">' + 67 '<p class="inline-label">' + customFieldResponseObject + '</p>' + 68 '<p class="flexGrowOne inline-value marginLeft" data-custom-field-id="'+ customFieldObject.id +'"></p>' + 69 '</div>'; 70 } 71 return content; 72} 73 74function plugCustomFieldResponsesWithinWrapper( wrapper, customFieldResponseArray ){ 75 $(wrapper + ' .inline-value').each(function(){ 76 var customFieldID = $(this).data('custom-field-id'); 77 if( customFieldID && customFieldResponseArray ){ 78 for (var c = customFieldResponseArray.length - 1; c >= 0; c--) { 79 var thisPair = customFieldResponseArray[c]; 80 if(thisPair){ 81 if( thisPair.customFieldID == customFieldID ){ 82 if( thisPair.optionsObjectIDsArray ){ 83 //it's a radio situation 84 var string = returnStringForCustomFieldDropdownSelections( thisPair ); 85 if( string.length >= 1 ){ 86 $(this).text( string ); 87 $(this).removeClass('incomplete'); 88 } 89 }else if( thisPair.url ){ 90 //it's a file 91 $(this).html( "<a target='_blank' href="+ thisPair.url +">Click to view</a>" ); 92 $(this).removeClass('incomplete'); 93 }else if( thisPair.response ){ 94 $(this).text( thisPair.response ); 95 $(this).removeClass('incomplete'); 96 } 97 } 98 } 99 } 100 } 101 if( ! $(this).text() ){ 102 $(this).text("Not provided"); 103 $(this).addClass('incomplete'); 104 } 105 }); 106} 107 108//a field filed under an archived category reads as uncategorized 109function return_membership_custom_field_category(custom_field) { 110 const category_object = custom_field.get("categoryObject"); 111 if (!category_object || category_object.get("archived") === true) { 112 return null; 113 } 114 return category_object; 115} 116 117//categorized fields are ordered by category_priority and uncategorized fields by the legacy 118//priority, but both markers are optional: a field with neither keeps the position it had in the 119//array it was loaded from (historically membership_settings.customFieldsArray), so clubs that 120//never reordered anything keep the order they already had 121function return_membership_custom_field_priority(custom_field, source_index) { 122 if (typeof custom_field.get("category_priority") === "number") { 123 return custom_field.get("category_priority"); 124 } 125 if (typeof custom_field.get("priority") === "number") { 126 return custom_field.get("priority"); 127 } 128 return source_index; 129} 130 131function return_membership_custom_fields_for_member(params) { 132 const { 133 membership_settings, 134 member_object, 135 member_facing, 136 } = params; 137 const custom_fields = membership_settings 138 ? membership_settings.get("customFieldsArray") || [] 139 : []; 140 const filtered_custom_fields = custom_fields.filter((custom_field) => { 141 const applies_to_members = 142 custom_field.get("applies_to") === "applicants_and_members" || 143 custom_field.get("applies_to") === "members"; 144 if ( 145 !applies_to_members || 146 custom_field.get("archived") 147 ) { 148 return false;
149 } 150 if (!member_facing) { 151 return true; 152 } 153 const applies_to_primary = 154 !custom_field.get("primary_only") || 155 ( 156 member_object && 157 member_object.get("primary") 158 ); 159 return ( 160 applies_to_primary && 161 custom_field.get("active") !== false && 162 custom_field.get("hide_from_member") !== true 163 ); 164 }); 165 return sort_membership_custom_fields(filtered_custom_fields); 166} 167 168//This is the one place membership custom field order is defined: uncategorized fields first, then 169//a section per category. Pass custom_field_categories to render a section for every category the 170//club has, including the empty ones - the configuration UI needs that, display views do not. 171function return_membership_custom_field_sections(custom_fields, custom_field_categories) { 172 const priority_by_field = new Map(); 173 const categories_by_id = new Map(); 174 const fields_by_category_id = new Map(); 175 const uncategorized_fields = []; 176 (custom_fields || []).forEach((custom_field, index) => { 177 priority_by_field.set(custom_field, return_membership_custom_field_priority(custom_field, index)); 178 const category_object = return_membership_custom_field_category(custom_field); 179 if (!category_object) { 180 uncategorized_fields.push(custom_field); 181 return; 182 } 183 categories_by_id.set(category_object.id, category_object); 184 if (!fields_by_category_id.has(category_object.id)) { 185 fields_by_category_id.set(category_object.id, []); 186 } 187 fields_by_category_id.get(category_object.id).push(custom_field); 188 }); 189 (custom_field_categories || []).forEach((category_object) => { 190 if (category_object.get("archived") !== true) { 191 categories_by_id.set(category_object.id, category_object); 192 } 193 }); 194 195 const sections = []; 196 if (uncategorized_fields.length > 0 || custom_field_categories) { 197 sections.push({ 198 category_object: null, 199 name: "Uncategorized", 200 custom_fields: uncategorized_fields, 201 }); 202 } 203 Array.from(categories_by_id.values()).sort((first_category, second_category) => { 204 return (first_category.get("priority") || 0) - (second_category.get("priority") || 0) 205 || (first_category.get("name") || "").localeCompare(second_category.get("name") || "") 206 || first_category.id.localeCompare(second_category.id); 207 }
207).forEach((category_object) => { 208 sections.push({ 209 category_object: category_object, 210 name: category_object.get("name"), 211 custom_fields: fields_by_category_id.get(category_object.id) || [], 212 }); 213 }); 214 sections.forEach((section) => { 215 section.custom_fields.sort((first_field, second_field) => { 216 return priority_by_field.get(first_field) - priority_by_field.get(second_field) 217 || first_field.id.localeCompare(second_field.id); 218 }); 219 }); 220 return sections; 221} 222 223function sort_membership_custom_fields(custom_fields) { 224 return return_membership_custom_field_sections(custom_fields).reduce((sorted_fields, section) => { 225 return sorted_fields.concat(section.custom_fields); 226 }, []); 227} 228 229function returnCustomFieldsForType(clubObject, type, primary) { 230 const custom_fields_array = clubObject.get("membership_settings").get("customFieldsArray") || []; 231 const custom_fields = custom_fields_array.filter((custom_field) => { 232 if ( 233 custom_field.get("archived") || 234 custom_field.get("active") === false || 235 (!primary && custom_field.get("primary_only")) 236 ) { 237 return false; 238 } 239 return ( 240 custom_field.get("applies_to") === "applicants_and_members" || 241 custom_field.get("applies_to") === type 242 ); 243 }); 244 return sort_membership_custom_fields(custom_fields); 245} 246 247function returnMembershipCustomFieldsArrayForClub(clubObject, memberObject) { 248 let primary = true; 249 if (memberObject && !memberObject.get("primary")) { 250 primary = false; 251 } 252 return returnCustomFieldsForType(clubObject, "members", primary); 253} 254 255function returnSelectedOptionsForRadioCustomField(customFieldInput){ 256 var array = []; 257 if( customFieldInput ){ 258 customFieldInput.find('.checkmarkCard').each(function(){ 259 if( $(this).data('option-id') && $(this).hasClass('active') ){ 260 array.push( $(this).data('option-id') ); 261 } 262 }); 263 } 264 return array; 265} 266 267function returnSelectedOptionStringsForRadioCustomField(customFieldInput){ 268 var array = []; 269 if( customFieldInput ){ 270 customFieldInput.find('.checkmarkCard').each(function(){ 271 if( $(this).find('p').text() && $(this).hasClass('active') ){ 272 array.push( $(this).find('p').text() ); 273 } 274 }); 275 } 276 return array; 277} 278 279function returnCustomFieldSelectionsWithinWrapper(wrapper){ 280 var customFieldsArray = []; 281 var classSituation = '.customFieldInput'; 282 if(wrapper){ 283 classSituation = wrapper+' .customFieldInput'; 284 } 285 $(classSituation).each(function(){ 286 var hidden = false; 287 if( $(this).parents('.inputWrap') ){ 288 if( $(this).parents('.inputWrap').hasClass('hidden') ){ 289 hidden = true; 290 } 291 } 292 if( ! hidden ){ 293 var customFieldID = $(this).data('custom-field-id'); 294 if(customFieldID){ 295 var selectedDropdownOptionID, selectedDropdownOptionIDsArray, response, optionsStringsArray; 296 if( $(this).is( 'select' ) ){ 297 selectedDropdownOptionID = $(this).find('option:selected').data('option-id'); 298 response = $(this).find('option:selected').text(); 299 }else if( $(this).hasClass('radioWrap') ){ 300 //figure out array of selections 301 selectedDropdownOptionIDsArray = returnSelectedOptionsForRadioCustomField( $(this) ); 302 optionsStringsArray = returnSelectedOptionStringsForRadioCustomField( $(this) ); 303 }else if( $(this).attr('type') == "file" ){ 304 response = $(this).data('url'); 305 }else{ 306 response = $(this).val(); 307 } 308 customFieldsArray.push({ 309 'customFieldID': customFieldID, 310 'response': response, 311 'optionObjectID': selectedDropdownOptionID, 312 'optionsObjectIDsArray': selectedDropdownOptionIDsArray, 313 'optionsStringsArray': optionsStringsArray, 314 'url': $(this).data('url') 315 }); 316 } 317 } 318 }); 319 return customFieldsArray; 320} 321 322function returnSelectedOptionIDForCustomField(customFieldObject, idPrefix) { 323 var optionID; 324 if(customFieldObject){ 325 if( !idPrefix ){ 326 idPrefix = 'customFieldInput_'; 327 } 328 if( $('#'+idPrefix+customFieldObject.id).length >= 1 ){ 329 //find the selected option 330 optionID = $('#'+idPrefix+customFieldObject.id).find('option:selected').data('option-id'); 331 } 332 } 333 return optionID; 334} 335 336function returnSelectedOptionIDForCustomFieldV2(customFieldObject) { 337 var optionID; 338 if(customFieldObject){ 339 if( $('.customFieldInput_'+customFieldObject.id).length >= 1 ){ 340 //find the selected option 341 optionID = $('.customFieldInput_'+customFieldObject.id).find('option:selected').data('option-id'); 342 } 343 } 344 return optionID; 345} 346 347function plugCustomFieldResponsesForObject(customFieldsArray, inputString){ 348 if(customFieldsArray && inputString){ 349 for (var c = customFieldsArray.length - 1; c >= 0; c--) { 350 var thisPair = customFieldsArray[c]; 351 if(thisPair){ 352 if( thisPair.customFieldID ){ 353 if( $('#'+inputString+'_'+thisPair.customFieldID).length >= 1 ){ 354 if( $('#'+inputString+'_'+thisPair.customFieldID).hasClass('radioWra
354p') ){ 355 //it's a multi select situation (div) 356 var optionsObjectIDsArray = thisPair.optionsObjectIDsArray; 357 if(optionsObjectIDsArray){ 358 $('#'+inputString+'_'+thisPair.customFieldID).find('.checkmarkCard').each(function(){ 359 var thisID = $(this).data('option-id'); 360 if(thisID){ 361 if( optionsObjectIDsArray.indexOf(thisID) > -1 ){ 362 $(this).addClass('active'); 363 } 364 } 365 }); 366 } 367 }else if( $('#'+inputString+'_'+thisPair.customFieldID).is('select') ){ 368 if( thisPair.optionObjectID ){ 369 $('#'+inputString+'_'+thisPair.customFieldID).val( thisPair.optionObjectID ).change(); 370 }else{ 371 $('#'+inputString+'_'+thisPair.customFieldID).val( thisPair.response ).change(); 372 } 373 }else{ 374 //it's an input or textarea 375 $('#'+inputString+'_'+thisPair.customFieldID).val( thisPair.response ).change(); 376 } 377 } 378 } 379 } 380 } 381 } 382} 383 384function returnResponseObjectForCustomFieldID( customFieldsArray, customFieldID ){ 385 var object = {}; 386 if( customFieldsArray && customFieldID ){ 387 for (var i = customFieldsArray.length - 1; i >= 0; i--) { 388 var thisPair = customFieldsArray[i]; 389 if( thisPair ){ 390 if( thisPair.customFieldID == customFieldID ){ 391 object = thisPair; 392 } 393 } 394 } 395 } 396 return object; 397} 398 399function plugCustomFieldResponsesV2(customFieldsArray, wrapper){ 400 if(customFieldsArray && wrapper){ 401 $(wrapper+' .customFieldInput').each(function(){ 402 var customFieldID = $(this).data('custom-field-id'); 403 if( customFieldID ){ 404 var object = returnResponseObjectForCustomFieldID( customFieldsArray , customFieldID ); 405 if( $(this).hasClass('radioWrap') ){ 406 //it's a multi select situation (div) 407 var optionsObjectIDsArray = object.optionsObjectIDsArray; 408 if(optionsObjectIDsArray){ 409 $(this).find('.checkmarkCard').each(function(){ 410 var thisID = $(this).data('option-id'); 411 if(thisID){ 412 if( optionsObjectIDsArray.indexOf(thisID) > -1 ){ 413 $(this).addClass('active'); 414 } 415 } 416 }); 417 } 418 }else if( $(this).is('select') ){ 419 if( object.optionObjectID ){ 420 $(this).val( object.optionObjectID ).change(); 421 }else{ 422 $(this).val( object.response ).change(); 423 } 424 }else if( $(this).attr('type') == "file" ){ 425 if( object.url ){ 426 $(this).data('url', object.url); 427 $(this).change(); 428 } 429 }else{ 430 //it's an input or textarea 431 $(this).val( object.response ).change(); 432 } 433 } 434 }); 435 } 436} 437 438function returnStringForCustomFieldDropdownSelections( customFieldResponseObject ){ 439 var string = ''; 440 if( customFieldResponseObject ){ 441 var optionsStringsArray = customFieldResponseObject.optionsStringsArray; 442 if(optionsStringsArray){ 443 for (var i = 0; i <= optionsStringsArray.length - 1; i++) { 444 var thisString = optionsStringsArray[i]; 445 if( string.length >= 1 ){
446 string += ', ' + thisString; 447 }else{ 448 string += thisString; 449 } 450 } 451 } 452 } 453 return string; 454} 455 456function returnMarkupForCustomFieldV2(customFieldObject, inputClasses, currency){ 457 var content = ''; 458 if(customFieldObject){ 459 //handle input class 460 if( !inputClasses ){ 461 inputClasses = ''; 462 } 463 if( customFieldObject.get('required') ){ 464 inputClasses += ' required'; 465 } 466 //add for identification 467 inputClasses += ' customFieldInput_'+customFieldObject.id; 468 //now generate more markup 469 if( customFieldObject.get('type') == 'select' || customFieldObject.get('type') == 'searchable_select' ){ 470 var optionsArray = customFieldObject.get('dropdownOptionsArray'); 471 if(optionsArray){ 472 if(optionsArray.length >= 1){ 473 if( customFieldObject.get('name').length <= 30 ) { 474 //short name 475 content += '<div class="inputWrap smallMarginBottom"><label class="inputLabel easeFast">'+customFieldObject.get('name')+'</label><select data-custom-field-id="'+customFieldObject.id+'" class="customFieldInput '+inputClasses+'">'; 476 content += '<option data-non-option="true"></option>'; 477 for (var o = 0; o <= optionsArray.length - 1; o++) { 478 var thisOption = optionsArray[o]; 479 if(thisOption){ 480 if( thisOption.get('name') ){ 481 //handle additional amounts 482 var amountString = ''; 483 var thisAmount; 484 if( currency ){ 485 thisAmount = thisOption.get('amount'); 486 if(thisAmount > 0){ 487 var niceAmount = formatPriceForCurrency(currency, thisAmount); 488 amountString += ' ( + '+niceAmount+' )'; 489 }else if(thisAmount < 0){ 490 var niceAmount = formatPriceForCurrency(currency, thisAmount); 491 amountString += ' ( '+niceAmount+' )'; 492 } 493 } 494 //plug it in 495 content += '<option data-option-id="'+thisOption.id+'" data-adjustment-amount="'+thisAmount+'" value="'+thisOption.id+'">'+thisOption.get('name')+amountString+'</option>'; 496 } 497 } 498 } 499 content += '</select></div>'; 500 } else { 501 //long name 502 content += '<p class="secondaryCardSubtext smallMarginBottom">'+ customFieldObject.get('name') +'</p>'; 503 content += '<div class="inputWrap smallMarginBottom"><label class="inputLabel easeFast">Click to enter</label><select data-custom-field-id="'+customFieldObject.id+'" class="customFieldInput '+inputClasses+'">'; 504 content += '<option data-non-option="true"></option>'; 505 for (var o = 0; o <= optionsArray.length - 1; o++) { 506 var thisOption = optionsArray[o]; 507 if(thisOption){ 508 if( thisOption.get('name') ){ 509 //handle additional amounts 510 var amountString = ''; 511 var thisAmount; 512 if( currency ){ 513 thisAmount = thisOption.get('amount'); 514 if(thisAmount > 0){ 515 var niceAmount = formatPriceForCurrency(currency, thisAmount); 516 amountString += ' ( + '+niceAmount+' )'; 517 }else if(thisAmount < 0){ 518 var niceAmount = formatPriceForCurrency(currency, thisAmount); 519 amountString += ' ( '+niceAmount+' )'; 520 } 521 } 522 //plug it in 523 content += '<option data-option-id="'+thisOption.id+'" data-adjustment-amount="'+thisAmount+'" value="'+thisOption.id+'">'+thisOption.get('name')+amountString+'</option>'; 524 } 525 } 526 } 527 content += '</select></div>'; 528 } 529 } 530 } 531 }else if( customFieldObject.get('type') == 'textarea' ){ 532 content += '<div><p class="secondaryCardSubtext tinyMarginBottom">'+customFieldObject.get('name')+'</p><div class="textareaWrap marginBottom"><textarea data-custom-field-id="'+customFieldObject.id+'" class="customFieldInput '+inputClasses+'"></textarea></div></div>'; 533 }else if( customFieldObject.get('type') == 'radio' ){ 534 //multi select 535 var optionsArray = customFieldObject.get('dropdownOptionsArray'); 536 if(optionsArray){ 537 if(optionsArray.length >= 1){ 538 content += '<p class="secondaryCardSubtext tinyMarginBottom">'+customFieldObject.get('name')+'</p><div data-custom-field-id="'+customFieldObject.id+'" class="customFieldInput radioWra
538p flexWrapLeftAlign '+inputClasses+'">'; 539 for (var o = 0; o <= optionsArray.length - 1; o++) { 540 var thisOption = optionsArray[o]; 541 if(thisOption){ 542 if( thisOption.get('name') ){ 543 //plug it in 544 content += '<div data-option-id="'+thisOption.id+'" value="'+thisOption.id+'" class="checkmarkCard easeFast flexNoWrap"><div class="checkmark tinyIcon"></div><p>'+thisOption.get('name')+'</p></div>'; 545 } 546 } 547 } 548 content += '</div>'; 549 } 550 } 551 }else if( customFieldObject.get('type') == 'file_upload' ){ 552 content += '<p class="secondaryCardSubtext smallMarginBottom">'+ customFieldObject.get('name') +'</p>' + 553 '<div class="inputWrap wider centeredBlock smallMarginBottom">' + 554 '<label class="inputLabel">Click to upload</label>' + 555 '<input data-custom-field-id="'+ customFieldObject.id +'" class="customFieldInput absoluteInput" type="file" accept="application/pdf, image/*">' + 556 '<div class="successfulFileUploadWrap flexNoWrap">' + 557 '<div class="tinyIcon successIcon"></div>' + 558 '<p>File selected</p>' + 559 '</div>' + 560 '</div>'; 561 }else if (customFieldObject.get('type') == 'date') { 562 content += ` 563 <div> 564 <p class="secondaryCardSubtext tinyMarginBottom">${customFieldObject.get('name')}</p> 565 <div class="inputWrap wider centeredBlock smallMarginBottom"> 566 <input 567 data-custom-field-id="${customFieldObject.id}" 568 class="customFieldInput ${inputClasses}" 569 type="date" 570 > 571 </div> 572 </div> 573 `; 574 }else{ 575 //numbers and text treated the same because of complications with numbers on safari 576 if( customFieldObject.get('name').length <= 30 ) { 577 //short name 578 content += '<div class="inputWrap wider centeredBlock smallMarginBottom"><label class="inputLabel easeFast">'+ customFieldObject.get('name') +'</label><input data-custom-field-id="'+ customFieldObject.id +'" class="customFieldInput '+inputClasses+'" autocomplete="disabled,off"></div>'; 579 } else { 580 //long name 581 content += '<p class="secondaryCardSubtext smallMarginBottom">'+ customFieldObject.get('name') +'</p>'; 582 content += '<div class="inputWrap wider centeredBlock smallMarginBottom"><label class="inputLabel easeFast">Click to enter</label><input data-custom-field-id="'+ customFieldObject.id +'" class="customFieldInput '+inputClasses+'" autocomplete="disabled,off"></div>'; 583 } 584 } 585 } 586 return content; 587} 588
589function returnMarkupForCustomFieldJSON(customFieldObject, currency) { 590 //uses JSON object instead of Parse object for vue compatibility 591 var content = ''; 592 var readOnly = false; 593 if (customFieldObject) { 594 // Handle input class 595 var inputClasses = ''; 596 if (customFieldObject.required) { 597 inputClasses += ' required'; 598 } 599 600 // Check if any dropdown option has a price adjustment 601 if ((customFieldObject.type === 'select' || customFieldObject.type === 'searchable_select') && customFieldObject.dropdownOptionsArray) { 602 customFieldObject.dropdownOptionsArray.forEach(function (thisOption) { 603 if (thisOption && thisOption.amount) { 604 readOnly = true; // A price adjustment exists, set to readOnly 605 } 606 }); 607 } 608 609 // Add readOnly and unclickable classes if necessary 610 var extraClasses = readOnly ? ' readOnly unclickable' : ''; 611 if (extraClasses){ 612 inputClasses += extraClasses; 613 } 614 615 // Add for identification 616 inputClasses += ' customFieldInput_' + customFieldObject.objectId; 617 618 // Now generate markup based on type 619 if (customFieldObject.type === 'select' || customFieldObject.type === 'searchable_select') { 620 var optionsArray = customFieldObject.dropdownOptionsArray; 621 if (optionsArray && optionsArray.length >= 1) { 622 if (customFieldObject.name.length <= 30) { 623 // Short name 624 content += '<div class="inputWrap smallMarginBottom"><label class="inputLabel easeFast">' + customFieldObject.name + '</label><select data-custom-field-id="' + customFieldObject.objectId + '" class="customFieldInput ' + inputClasses + '"' + (readOnly ? ' disabled' : '') + '>'; 625 content += '<option data-non-option="true"></option>'; 626 optionsArray.forEach(function(thisOption) { 627 if (thisOption && thisOption.name) { 628 // Handle additional amounts 629 var amountString = ''; 630 var thisAmount = thisOption.amount; 631 if (currency) { 632 if (thisAmount > 0) { 633 var niceAmount = formatPriceForCurrency(currency, thisAmount); 634 amountString += ' ( + ' + niceAmount + ' )'; 635 } else if (thisAmount < 0) { 636 var niceAmount = formatPriceForCurrency(currency, thisAmount); 637 amountString += ' ( ' + niceAmount + ' )'; 638 } 639 // Need to add the class unclickable to the dic for the input wrap if readonly is true 640 } 641 // Plug it in 642 content += '<option data-option-id="' + thisOption.objectId + '" data-adjustment-amount="' + thisAmount + '" value="' + thisOption.objectId + '">' + thisOption.name + amountString + '</option>'; 643 } 644 }); 645 content += '</select></div>'; 646 } else { 647 // Long name 648 content += '<p class="secondaryCardSubtext smallMarginBottom">' + customFieldObject.name + '</p>'; 649 content += '<div class="inputWrap smallMarginBottom"><label class="inputLabel easeFast">Click to enter</label><select data-custom-field-id="' + customFieldObject.objectId + '" class="customFieldInput ' + inputClasses + '">'; 650 content += '<option data-non-option="true"></option>'; 651 optionsArray.forEach(function(thisOption) { 652 if (thisOption && thisOption.name) { 653 // Handle additional amounts 654 var amountString = ''; 655 var thisAmount = thisOption.amount; 656 if (currency) { 657 if (thisAmount > 0) { 658 var niceAmount = formatPriceForCurrency(currency, thisAmount); 659 amountString += ' ( + ' + niceAmount + ' )'; 660 } else if (thisAmount < 0) { 661 var niceAmount = formatPriceForCurrency(currency, thisAmount); 662 amountString += ' ( ' + niceAmount + ' )'; 663 } 664 } 665 // Plug it in 666 content += '<option data-option-id="' + thisOption.objectId + '" data-adjustment-amount="' + thisAmount + '" value="' + thisOption.objectId + '">' + thisOption.name + amountString + '</option>'; 667 } 668 }); 669 content += '</select></div>'; 670 } 671 } 672 } else if (customFieldObject.type === 'textarea') { 673 content += '<div><p class="secondaryCardSubtext tinyMarginBottom">' + customFieldObject.name + '</p><div class="textareaWrap marginBottom"><textarea data-custom-field-id="' + customFieldObject.objectId + '" class="customFieldInput ' + inputClasses + '"></textarea></div></div>'; 674 } else if (customFieldObject.type === 'radio') { 675 // Multi-select 676 var optionsArray = customFieldObject.dropdownOptionsArray; 677 if (optionsArray && optionsArray.length >= 1) { 678 content += '<p class="secondaryCardSubtext tinyMarginBottom">' + customFieldObject.name + '</p><div data-custom-field-id="' + customFieldObject.objectId + '" class="customFieldInput radioWra
678p flexWrapLeftAlign ' + inputClasses + '">'; 679 optionsArray.forEach(function(thisOption) { 680 if (thisOption && thisOption.name) { 681 // Plug it in 682 content += '<div data-option-id="' + thisOption.objectId + '" value="' + thisOption.objectId + '" class="checkmarkCard easeFast flexNoWrap"><div class="checkmark tinyIcon"></div><p>' + thisOption.name + '</p></div>'; 683 } 684 }); 685 content += '</div>'; 686 } 687 } else if (customFieldObject.type === 'file_upload') { 688 content += '<p class="secondaryCardSubtext smallMarginBottom">' + customFieldObject.name + '</p>' + 689 '<div class="inputWrap wider centeredBlock smallMarginBottom">' + 690 '<label class="inputLabel">Click to upload</label>' + 691 '<input data-custom-field-id="' + customFieldObject.objectId + '" class="customFieldInput absoluteInput" type="file" accept="application/pdf, image/*">' + 692 '<div class="successfulFileUploadWrap flexNoWrap">' + 693 '<div class="tinyIcon successIcon"></div>' + 694 '<p>File selected</p>' + 695 '</div>' + 696 '</div>'; 697 } else { 698 // Numbers and text treated the same because of complications with numbers on Safari 699 if (customFieldObject.name.length <= 30) { 700 // Short name 701 content += '<div class="inputWrap wider centeredBlock smallMarginBottom"><label class="inputLabel easeFast">' + customFieldObject.name + '</label><input data-custom-field-id="' + customFieldObject.objectId + '" class="customFieldInput ' + inputClasses + '" autocomplete="disabled,off"></div>'; 702 } else { 703 // Long name 704 content += '<p class="secondaryCardSubtext smallMarginBottom">' + customFieldObject.name + '</p>'; 705 content += '<div class="inputWrap wider centeredBlock smallMarginBottom"><label class="inputLabel easeFast">Click to enter</label><input data-custom-field-id="' + customFieldObject.objectId + '" class="customFieldInput ' + inputClasses + '" autocomplete="disabled,off"></div>'; 706 } 707 } 708 } 709 return content; 710} 711 712 713function returnRelevantCustomFieldsForCampClasses( classes, campObject ){ 714 var array = []; 715 if( ! classes ){ 716 classes = []; 717 } 718 var ids = []; 719 if(campObject){ 720 //check custom fields array 721 var customFieldsArray = campObject.get('customFieldsArray'); 722 if(customFieldsArray){ 723 if(customFieldsArray.length >= 1){ 724 for (var i = 0; i <= customFieldsArray.length - 1; i++) { 725 var thisCustomField = customFieldsArray[i]; 726 if(thisCustomField){ 727 if( ids.indexOf( thisCustomField.id ) == -1 ){ 728 var campClassesArray = thisCustomField.get('campClassesArray'); 729 if( thisCustomField.get('allClasses') ){ 730 array.push( thisCustomField ); 731 ids.push( thisCustomField.id ); 732 }else if(campClassesArray){ 733 for (var c = campClassesArray.length - 1; c >= 0; c--) { 734 var thisCampClass = campClassesArray[c]; 735 if(thisCampClass){ 736 for (var g = classes.length - 1; g >= 0; g--) { 737 var thisClass = classes[g]; 738 if( thisClass ){ 739 if( thisClass.id == thisCampClass.id ){ 740 array.push( thisCustomField ); 741 ids.push( thisCustomField.id ); 742 } 743 } 744 } 745 } 746 } 747 } 748 } 749 } 750 } 751 } 752 } 753 } 754 return array; 755} 756 757function returnRelevantCustomFieldsForBoatClass( boatClassObject, regattaObject ){ 758 var array = []; 759 var ids = []; 760 if(regattaObject && boatClassObject){ 761 //check custom fields array 762 var customFieldsArray = regattaObject.get('customFieldsArray'); 763 if(customFieldsArray){ 764 if(customFieldsArray.length >= 1){ 765 for (var i = 0; i <= customFieldsArray.length - 1; i++) { 766 var thisCustomField = customFieldsArray[i]; 767 if(thisCustomField){ 768 if( ids.indexOf( thisCustomField.id ) == -1 ){ 769 var boatClassesArray = thisCustomField.get('boatClassesArray'); 770 if( thisCustomField.get('allClasses') ){ 771 array.push( thisCustomField ); 772 ids.push( thisCustomField.id ); 773 }else if(boatClassesArray){ 774 for (var c = boatClassesArray.length - 1; c >= 0; c--) { 775 var thisBoatClass = boatClassesArray[c]; 776 if(thisBoatClass){ 777 if( thisBoatClass.id == boatClassObject.id ){ 778 array.push( thisCustomField ); 779 ids.push( thisCustomField.id ); 780 } 781 } 782 } 783 } 784 } 785 } 786 } 787 } 788 } 789 } 790 return array; 791} 792 793$(document).ready(function(){ 794 $(document).on('change', '.customFieldInput.absoluteInput', function(){ 795 //check if there's something in the input 796 var file = $(this).prop('files')[0]; 797 if(file){ 798 var timestamp = Date.now(); 799 var client_id = generateClientID(); 800 var newFileName = "upload_" + client_id + "_" + timestamp; 801 //upload it 802 uploadFileToAWS(file, newFileName, (url) => { 803 //add the url 804 $(this).data('url', url); 805 }); 806 } 807 }); 808 809 $(document).on('click', '.customFieldInput.absoluteInput', function(){ 810 //reset data 811 $(this).data('url', null); 812 $('#confirmUniversalEdit').removeClass('inactive'); 813 }); 814 815});
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.