1// LIVEOPENCART: Related Options 2 3(function ($) { $.fn.liveopencart_RelatedOptions = function(p_params){ 4 5 $this = this; 6 7 var inst = { 8 9 was_called: {}, // to control that some specific methods was called (they regiter them there themselves) 10 11 each : function(collection, fn){ 12 for ( var i_item in collection ) { 13 if ( !collection.hasOwnProperty(i_item) ) continue; 14 if ( fn(collection[i_item], i_item) === false ) { 15 return; 16 } 17 } 18 }, 19 20 isInArray : function(val, arr) { 21 return (arr.indexOf(val) != -1); 22 }, 23 24 getSetting : function(p_setting_name, p_default) { 25 26 if ( inst.ro_settings[p_setting_name] || typeof(inst.ro_settings[p_setting_name]) != 'undefined' ) { 27 if ( inst.ro_settings[p_setting_name] !== '0' ) { 28 return inst.ro_settings[p_setting_name]; 29 } else { 30 return 0; 31 } 32 } else { 33 return p_default; 34 } 35 36 //if ( typeof(inst.ro_settings[p_setting_name]) != 'undefined' ) { 37 // if ( inst.ro_settings[p_setting_name] !== '0' ) { 38 // return inst.ro_settings[p_setting_name]; 39 // } else { 40 // return 0; 41 // } 42 //} else { 43 // return p_default; 44 //} 45 46 }, 47 48 bind : function(trigger_name, event_function) { 49 inst.parentBlock.on(trigger_name, event_function); 50 }, 51 trigger : function(trigger_name, values) { 52 inst.getBlockOfOptions().trigger(trigger_name, values); 53 }, 54 55 initSpecFunctions: function(){ 56 if (inst.theme_methods && inst.theme_methods.spec_fn) { 57 ro_common.proxyObjectMethods(inst.spec_fn, !'debug', inst.theme_methods.spec_fn); 58 } 59 }, 60 61 initCommonFunctions: function(){ 62 if (inst.theme_methods && inst.theme_methods.common_fn) { 63 ro_common.proxyObjectMethods(inst.common_fn, !'debug', inst.theme_methods.common_fn); 64 } 65 }, 66 67 initRO : function(ro_init_cnt) { 68 69 if ( !inst.ro_data || inst.ro_data == {} || inst.ro_data == [] ) { 70 return; // no related options 71 } 72 73 // add specifically displayed options (quantity input/select per option value) 74 inst.getOptionElement('[data-quantity-per-option][data-product-option-id]').each(function(){ 75 var product_option_id = $(this).attr('data-product-option-id'); 76 if ( inst.isInArray(product_option_id, inst.ro_product_options) ) { 77 inst.input_quantity_per_options.push( product_option_id ); 78 } 79 }); 80 81 // assign for global variable 82 inst.options_step_by_step = inst.getOptionsAsStepsFromHTML(); 83 84 if ( !inst.options_step_by_step.length && !ro_init_cnt ) { 85 // in some themes page options may be not available on this stage, so recall init on document.ready 86 $().ready( function() { 87 inst.initRO(1); 88 }); 89 return; 90 } 91 92 93 inst.each(inst.options_step_by_step, function(option_step){ // we need all options, even not visible on this action 94 inst.all_values_of_options[option_step] = inst.getAllValuesOfProductOption(option_step); 95 }); 96 97 inst.each(inst.ro_data, function(ro_dt){ 98 inst.each(ro_dt.ro, function(ro_comb){ 99 inst.each(ro_dt.options_ids, function(po_id){ 100 let pov_id = ro_comb.options[po_id]; 101 if ( pov_id || inst.getSetting('allow_empty')) { 102 if ( !inst.all_values_of_options[po_id] ) { 103 inst.all_values_of_options[po_id] = []; 104 } 105 inst.all_values_of_options[po_id].push(pov_id); 106 } 107 }); 108 }); 109 }); 110 111 inst.getOptionElement('select[name^="'+inst.option_prefix+'"]').change(function(){ 112 inst.controlAccessToValuesOfAllOptions(); 113 }); 114 115 inst.getOptionElement('input[type=radio][name^="'+inst.option_prefix+'"]').change(function(){ 116 inst.controlAccessToValuesOfAllOptions(); 117 }); 118 119 inst.controlAccessToValuesOfAllOptions(); 120 121 $().ready( function() { 122 123 if ( typeof(inst.ros_to_select) != 'undefined' && inst.ros_to_select && inst.ros_to_select.length) { 124 let ro_id_last = false; 125 if ( !inst.poip_ov ) { 126 127 inst.each(inst.ros_to_select, function(ro_id){ 128 ro_id_last = ro_id; 129 inst.setSelectedCombination(ro_id, true); // without limitaions 130 });
131 if (ro_id_last) { 132 inst.setSelectedCombination(ro_id_last); /// with limitations 133 } 134 } 135 136 } else { 137 138 inst.setSelectedCombinationByModel(inst.filter_name); 139 inst.controlAccessToValuesOfAllOptions(); 140 141 inst.initialAutoSelect(); 142 143 } 144 145 }); 146 147 inst.trigger('init_after.ro'); 148 149 }, 150 151 getOptionsAsSteps : function() { 152 153 let steps = []; 154 inst.each(inst.options_step_by_step, function(product_option_id){ 155 // skip options hidden by pcop 156 if ( typeof(pcop_front) != 'undefined' && typeof(pcop_front.getHiddenOptions) == 'function' ) { 157 if ( !inst.isInArray(product_option_id, pcop_front.getHiddenOptions()) ) { 158 steps.push(product_option_id); 159 } 160 } else { 161 steps.push(product_option_id); 162 } 163 164 }); 165 166 return steps; 167 }, 168 169 getQuantityInput : function() { 170 return inst.getElement('#input-quantity, input[name="quantity"]'); 171 }, 172 173 setOptionValue : function(product_option_id, product_option_value_id) { 174 175 var $touched_elems = ''; 176 if ( inst.getOptionElement('select[name="'+inst.getOptionNameByPOId(product_option_id)+'"]').length > 0) { 177 178 $touched_elems = inst.getOptionElement('[name="'+inst.getOptionNameByPOId(product_option_id)+'"]').val(product_option_value_id); 179 180 } else if ( inst.getOptionElement('input:radio[name="'+inst.getOptionNameByPOId(product_option_id)+'"]').length > 0) { 181 var radio_elems = inst.getOptionElement('input:radio[name="'+inst.getOptionNameByPOId(product_option_id)+'"]'); 182 radio_elems.prop('checked', false); 183 184 if ( product_option_value_id ) { 185 var radio_elem = inst.getOptionElement('input:radio[name="'+inst.getOptionNameByPOId(product_option_id)+'"][value='+product_option_value_id+']'); 186 radio_elem.prop('checked', true); 187 } 188 189 $touched_elems = radio_elems; 190 } 191 192 inst.trigger('setOptionValue_after.ro', [product_option_id, product_option_value_id, $touched_elems]); 193 194 // Product Option Image PRO compatibility 195 if ( typeof(poipExternalOptionChange)=='function' ) { 196 poipExternalOptionChange(); 197 } 198 if ( typeof(poip_product)!='undefined' && typeof(poip_product.externalOptionChange) == 'function' ) { 199 poip_product.externalOptionChange(); 200 } 201 if ( typeof(poip_common)!='undefined' && typeof(poip_common.externalOptionChangeEvent) == 'function' ) { 202 poip_common.externalOptionChangeEvent($touched_elems); 203 } 204 205 }, 206 207 getBlockOfOptions : function() { 208 return inst.parentBlock; 209 }, 210 211 getOptionElement : function(selector) { 212 return inst.getBlockOfOptions().find(selector); 213 }, 214 215 getProductOptionIdFromName : function(name) { 216 return name.substr(inst.option_prefix_length+1, name.substr(inst.option_prefix_length+1).indexOf(']') ); 217 }, 218 219 getElement : function(selector) { 220 return inst.parentBlock.find(selector); 221 }, 222 223 getContainer : function() { 224 return inst.parentBlock; 225 }, 226 227 getValuesOfSelectOption : function(param_product_option_id) { 228 if ( $.isEmptyObject(inst.all_select_ov) ) { 229 inst.getOptionElement('select[name^="'+inst.option_prefix+'["]').each( function (si, sel_elem) { 230 var product_option_id = inst.getProductOptionIdFromName(sel_elem.name); 231 232 inst.all_select_ov[product_option_id] = []; 233 234 $.each(sel_elem.options, function (oi, op_elem) { 235 inst.all_select_ov[product_option_id].push(op_elem.value); 236 }); 237 238 } ); 239 } 240 return inst.all_select_ov[param_product_option_id]; 241 }, 242 243 getSelectedROCombsByOptions : function(options_values){ 244 return inst.getROIdsByOptions(options_values, true); // rewrite to getROCombsByOptions ? 245 }, 246 247 getROIdsByOptions : function(options_values, strict) { 248 let ro_ids = []; 249 let ro_combs = inst.getROCombsByOptions(options_values, strict); 250 inst.each(ro_combs, function(ro_comb){ 251 ro_ids.push(ro_comb.relatedoptions_id); 252 }); 253 return ro_ids; 254 }, 255 256 getCurrentROCombs : function(strict){ 257 let selected_option_values = inst.getOptionValues([]); 258 return inst.getROCombsByOptions(selected_option_values, strict); 259 }, 260 261 getROCombsByOptions : function(options_values, strict) { 262 let ro_combs = []; 263 inst.each(inst.ro_data, function(ro_dt){ 264 265 let all_ok; 266 inst.each(ro_dt.ro, function(ro_comb){ 267 268 all_ok = true; 269 inst.each(ro_comb.options, function(pov_id, product_option_id){ 270 271 all_ok = all_ok && ((product_option_id in options_values && options_values[product_option_id]==pov_id) || (!strict && !options_values[product_option_id] ) ); 272 });
273 if (all_ok) ro_combs.push(ro_comb); 274 }); 275 }); 276 return ro_combs; 277 }, 278 279 arrayIntersection : function(arr1, arr2) { 280 var new_arr = []; 281 for (let i in arr1) { 282 if ( arr1.hasOwnProperty(i) ) { 283 if (inst.isInArray(arr1[i], arr2)) { 284 new_arr.push(arr1[i]); 285 } 286 } 287 } 288 return new_arr; 289 }, 290 291 arrayCopy : function(arr) { 292 293 if (!arr) { 294 return []; 295 } else { 296 return arr.map(function(val){ 297 if ( Array.isArray(val) ) { 298 return inst.arrayCopy(val); 299 } else { 300 return val; 301 } 302 }); 303 } 304 305 }, 306 307 getAllValuesOfProductOption : function(product_option_id) { 308 var values = []; 309 if ( inst.getOptionElement('select[name="'+inst.getOptionNameByPOId(product_option_id)+'"]').length) { 310 var select_options = inst.getValuesOfSelectOption(product_option_id); 311 inst.each(select_options, function(select_option){ 312 if (select_option) { 313 values.push(select_option); 314 } 315 }); 316 } else if ( inst.getOptionElement('input[type=radio][name="'+inst.getOptionNameByPOId(product_option_id)+'"]').length) { 317 inst.getOptionElement('input[type=radio][name="'+inst.getOptionNameByPOId(product_option_id)+'"]').each(function(){ 318 values.push($(this).val()); 319 }); 320 } 321 // add specifically displayed options (quantity input/select per option value) 322 if ( inst.isInArray(product_option_id, inst.input_quantity_per_options) ) { 323 inst.getElement('[name^="quantity_per_option['+product_option_id+']["]').each(function(){ 324 var product_option_value_id = $(this).attr('data-value'); 325 if ( product_option_value_id ) { 326 values.push(product_option_value_id); 327 } 328 }); 329 } 330 return values; 331 }, 332 333 getOptionsWithDirectRelations : function(prodict_option_id) { 334 335 if ( inst.linked_options_cache[prodict_option_id] ) { 336 return inst.linked_options_cache[prodict_option_id]; 337 } else { 338 339 var linked_options = []; 340 inst.each(inst.ro_data, function(ro_dt){ 341 if ( inst.isInArray(prodict_option_id, ro_dt.options_ids) ) { 342 inst.each(ro_dt.options_ids, function(current_option_id){ 343 if ( current_option_id != prodict_option_id && !inst.isInArray(current_option_id, linked_options) ) { 344 linked_options.push(current_option_id); 345 } 346 }); 347 } 348 }); 349 inst.linked_options_cache[prodict_option_id] = linked_options; 350 return linked_options; 351 } 352 }, 353 354 // get available options values 355 // option_id - (product_option_id) 356 // param_options_values - current options values (selected) - only for related options 357 // param_skip_ropv_ids - don't make values addition for this related options combinations 358 getAccessibleOptionValues : function(option_id, param_options_values, param_skip_options) { 359 360 // make copies od arrays 361 let options_values = inst.arrayCopy(param_options_values); 362 let skip_options = inst.arrayCopy(param_skip_options); 363 skip_options.push(option_id); 364 365 let linked_options = inst.getOptionsWithDirectRelations(option_id); 366 367 inst.each(linked_options, function(current_option_id){ 368 if ( options_values[current_option_id] && !options_values[current_option_id].length && current_option_id != option_id) { 369 if ( !inst.isInArray(current_option_id, skip_options) ) { 370 options_values[current_option_id] = inst.getAccessibleOptionValues(current_option_id, options_values, skip_options); 371 } 372 } 373 }); 374 375 let common_accessible_values = false; 376 377 let possible_current_option_values = inst.arrayCopy(inst.all_values_of_options[option_id]); 378 379 380 inst.each(inst.ro_data, function(ro_dt){ 381 382 if ( !inst.isInArray(option_id, ro_dt.options_ids) ) { 383 return; 384 } 385 386 let accessible_values = []; 387 let ro_combs = ro_dt.ro; 388 389 let options_for_check = []; // optimization 390 inst.each(options_values, function(values, current_po_id){ 391 if (current_po_id != option_id && values.length && !inst.isInArray(current_po_id, skip_options) && inst.isInArray(current_po_id, ro_dt.options_ids)) { 392 options_for_check.push(current_po_id); 393 } 394 }); 395 396 if (!options_for_check.length) { 397
398 if (ro_dt.options_ids.length == 1) { // combination contains only one option (this option) 399 inst.each(ro_combs, function(ro_comb){ 400 let ro_comb_pov_id = ro_comb.options[option_id]; 401 if ( ro_comb_pov_id && !inst.isInArray(ro_comb_pov_id, accessible_values) ) { 402 accessible_values.push(ro_comb_pov_id); 403 } 404 }); 405 } else { 406 accessible_values = inst.arrayCopy(possible_current_option_values); 407 } 408 } else { 409 inst.each(ro_combs, function(ro_comb){ 410 411 let all_ok = true; 412 inst.each(options_for_check, function(current_po_id){ 413 let current_pov_id = ro_comb.options[current_po_id]; 414 415 if ( !inst.isInArray(current_pov_id, options_values[current_po_id]) || (!inst.getSetting('allow_empty') && typeof(current_pov_id) == 'undefined') ) { 416 all_ok = false; 417 } 418 419 if (!all_ok) { 420 return false; 421 } 422 }); 423 424 if (all_ok && ( !inst.isInArray(ro_comb.options[option_id], accessible_values) )) { 425 426 accessible_values.push(ro_comb.options[option_id]); 427 if (possible_current_option_values.length == accessible_values.length) { // optimization 428 429 return false; 430 } 431 } 432 }); 433 } 434 435 if (common_accessible_values === false) { 436 common_accessible_values = accessible_values; 437 } else { 438 common_accessible_values = inst.arrayIntersection(common_accessible_values, accessible_values); 439 } 440 }); 441 442 return common_accessible_values; 443 }, 444 445 // only for options with values 446 // returns array of accessible values 447 controlAccessToValuesOfOption : function(param_options_values, option_id) { 448 449 var options_values = []; 450 inst.each(param_options_values, function(product_option_value_id, product_option_id){ 451 452 options_values[product_option_id] = []; 453 if (product_option_value_id || typeof(product_option_value_id) == 'undefined' ) { // for normally selected value or for not selected options in step-by-step mode 454 options_values[product_option_id].push(product_option_value_id); 455 } 456 }); 457 var skip_ropv_ids = []; 458 var accessible_values = inst.getAccessibleOptionValues(option_id, options_values, skip_ropv_ids); 459 460 inst.setAccessibleOptionValues(option_id, accessible_values); 461 462 return accessible_values; 463 }, 464 465 toggleOptionElement : function(option_id, toggle_flag) { 466 inst.getOptionElement('#input-option'+option_id).parent().toggle(toggle_flag); 467 if ( inst.getOptionElement('#input-option'+option_id).parent().is('div.select') && inst.getOptionElement('#input-option'+option_id).parent().parent().is('div.form-group') ) { // additional compatibility (fastor theme or custom modification) 468 inst.getOptionElement('#input-option'+option_id).parent().parent().toggle(toggle_flag); 469 } 470 inst.getOptionElement('label[for="input-option'+option_id+'"]').toggle(toggle_flag); 471 }, 472 473 optionIsAccessible : function(option_id) { 474 if ( inst.getOptionElement('select[name="'+inst.getOptionNameByPOId(option_id)+'"]').length) { 475 return inst.getOptionElement('select[name="'+inst.getOptionNameByPOId(option_id)+'"] option[value][value!=""]:not(:disabled)').length ? true : false; 476 } else if ( inst.getOptionElement('input[type=radio][name="'+inst.getOptionNameByPOId(option_id)+'"]').length) { 477 return inst.getOptionElement('input[type=radio][name="'+inst.getOptionNameByPOId(option_id)+'"]:not(:disabled)').length ? true : false; 478 } else if ( inst.getOptionElement('input[name^="quantity_per_option['+option_id+']["]').length) { 479 return inst.getOptionElement('input[name^="quantity_per_option['+option_id+']["]:not(:disabled)').length ? true : false; 480 } 481 }, 482 483 hideInaccessibleOptionIfNeeded : function(option_id) { 484 if (inst.ro_settings && inst.ro_settings.hide_option) { 485 inst.toggleOptionElement(option_id, inst.optionIsAccessible(option_id)); 486 } 487 }, 488 489 getContainerForInputNotRequired: function() { 490 let $cont = inst.getElement('#product'); 491 if ($cont.length) { 492 return $cont; 493 } else { 494 return inst.getContainer(); 495 } 496 }, 497 498 getElementNotRequired: function() { 499 500 if ( !inst.getElement('[name="ro_not_required"]').length ) { 501 inst.getContainerForInputNotRequired().append('<input type="hidden" name="ro_not_required" value="">'); 502 } 503 return inst.getElement('[name="ro_not_required"]'); 504 }, 505 506 makeInaccessibleOptionsNotRequired : function(option_id) { 507 508 if (inst.ro_settings && inst.ro_settings.unavailable_not_required) { 509 var current_ids = ( inst.getElementNotRequired().val() || '' ).split(','); 510 511 var new_ids = []; 512 inst.each(current_ids, function(current_id){ 513 if (current_id != option_id) { 514 new_ids.push(current_id); 515 } 516 }); 517 if ( !inst.optionIsAccessible(option_id) ) { 518 new_ids.push(option_id); 519 } 520 inst.getElementNotRequired().val( new_ids.toString()); 521 } 522 }, 523 524 setAccessibleOptionValues : function(option_id, accessible_values) { 525 526 var current_value = ( inst.getOptionElement('input[type=radio][name="'+inst.getOptionNameByPOId(option_id)+'"]:checked').val() || inst.getOptionElement('select[name="'+inst.getOptionNameByPOId(option_id)+'"]').val()); 527 528 if (!inst.setAccessibleOptionValuesTypeSelect(option_id, accessible_values, current_value) && !inst.setAccessibleOptionValuesTypeRadio(option_id, accessible_values, current_value) && !inst.setAccessibleOptionValuesQPO(option_id, accessible_values)) { 529 inst.setAccessibleOptionValuesTypeOthers(option_id, accessible_values, current_value); 530 } 531 532 inst.hideInaccessibleOptionIfNeeded(option_id); 533 inst.makeInaccessibleOptionsNotRequired(option_id); 534 }, 535 536 setAccessibleOptionValuesTypeOthers: function(option_id, accessible_values) {
537 // used for comp with themes and mods working with custom HTML option implementations 538 }, 539 540 541 setAccessibleOptionValuesQPO: function(option_id, accessible_values) { 542 if ( inst.isInArray(option_id, inst.input_quantity_per_options) ) { // for specifically displayed options (quantity input/select per option value) 543 544 inst.getOptionElement('[name^="quantity_per_option['+option_id+']["]').each(function(){ 545 var $qpo_input = $(this); 546 var product_option_value_id = inst.getQPOPOVIdByName( $qpo_input.attr('name') ); 547 if ( product_option_value_id ) { 548 option_value_disabled = ( !inst.isInArray(product_option_value_id, accessible_values) ); 549 if ( option_value_disabled ) { 550 $qpo_input.val(''); 551 } else if ( $qpo_input.prop('disabled') ) { // re-enable the input - place default values 552 $qpo_input.val( $qpo_input.attr('data-default-value' || '0') ); 553 } 554 $qpo_input.prop('disabled', option_value_disabled); 555 var $option_value_container = $qpo_input.closest('[data-qpo-pov-id], tr'); 556 if ( !$option_value_container.length ) { 557 $option_value_container = $qpo_input.closest('div'); 558 } 559 if (inst.hide_inaccessible) { 560 $option_value_container.toggle(!option_value_disabled); 561 } else { 562 if ( option_value_disabled ) { 563 inst.fadeToForElement($option_value_container, 0.1); 564 } else { 565 inst.fadeToForElement($option_value_container, 1); 566 } 567 } 568 } 569 }); 570 return true; 571 } 572 }, 573 574 setAccessibleOptionValuesTypeRadio: function(option_id, accessible_values, current_value) { 575 if ( inst.getOptionElement('input[type=radio][name="'+inst.getOptionNameByPOId(option_id)+'"]').length) { 576 577 if (current_value && !inst.isInArray(current_value, accessible_values)) { 578 579 var elem_to_uncheck = inst.getOptionElement('input[type=radio][name="'+inst.getOptionNameByPOId(option_id)+'"]:checked'); 580 581 if ( elem_to_uncheck.length ) { 582 inst.setOptionValue(option_id, ''); 583 //elem_to_uncheck.prop('checked', false); 584 inst.accessibility_check_restart_needed = true; 585 } 586 587 inst.trigger( 'setAccessibleOptionValues_radioUncheck_after.ro', [elem_to_uncheck] ); 588 } 589 590 $radio_options = inst.getOptionElement('input[type=radio][name="'+inst.getOptionNameByPOId(option_id)+'"]'); 591 $radio_options.each(function(){ 592 let $radio_option = $(this); 593 594 option_value_disabled = (!inst.isInArray($radio_option.val(), accessible_values)); 595 596 $radio_option.prop('disabled', option_value_disabled); // hidden should be disabled too 597 598 if (inst.hide_inaccessible) { 599 600 inst.toggleOptionValueRadio($radio_option, option_value_disabled); 601 inst.trigger( 'setAccessibleOptionValues_radioToggle_after.ro', [ option_id, $radio_option, option_value_disabled ] ); 602 603 } else { 604 605 if ( typeof(inst.custom_radioEnableDisable) != 'undefined' && inst.custom_radioEnableDisable( $radio_option, option_value_disabled ) ) { 606 // do nothing 607 } else { 608 609 if (option_value_disabled) { 610 inst.fadeToOptionRadio($radio_option, 0.1); 611 } else { 612 inst.fadeToOptionRadio($radio_option, 1); 613 } 614 615 } 616 617 inst.trigger( 'setAccessibleOptionValues_radioEnableDisable_after.ro', [ option_id, $radio_option, option_value_disabled ] ); 618 619 } 620 //} 621 }); 622 return true; 623 } 624 }, 625 626 setAccessibleOptionValuesTypeSelect : function(option_id, accessible_values, current_value) { 627 628 if ( inst.getOptionElement('select[name="'+inst.getOptionNameByPOId(option_id)+'"]').length) { 629 630 if ( current_value && !inst.isInArray(current_value, accessible_values) ) { 631 inst.getOptionElement('select[name="'+inst.getOptionNameByPOId(option_id)+'"]').val(''); 632 inst.accessibility_check_restart_needed = true; 633 } else { 634 // .find('option').filter(function(){return $(this).prop('selected'); }) for cases when option value selected by external .prop('selected'); 635 let $so_selected_by_prop = inst.getOptionElement('select[name="'+inst.getOptionNameByPOId(option_id)+'"] option[value!=""]').filter(function(){return $(this).prop('selected'); }); 636 if (!current_value && $so_selected_by_prop.length ) { 637 $so_selected_by_prop.prop('selected', false); 638 inst.getOptionElement('select[name="'+inst.getOptionNameByPOId(option_id)+'"]').val(''); 639 inst.accessibility_check_restart_needed = true; 640 } 641 } 642 643 if (inst.hide_inaccessible) { 644 645 let select_options = inst.getValuesOfSelectOption(option_id); 646 inst.each(select_options, function(select_option){ 647 if (select_option) { 648 option_value_disabled = ( !inst.isInArray(select_option,accessible_values) ); 649 // hiding options for IE 650 inst.getOptionElement('select[name="'+inst.getOptionNameByPOId(option_id)+'"]').toggleOption(select_option, !option_value_disabled); 651 inst.trigger( 'setAccessibleOptionValues_selectToggle_after.ro', [option_id, select_option, option_value_disabled] ); 652 } 653 });
654 655 } else { 656 657 let select_options = inst.getOptionElement('select[name="'+inst.getOptionNameByPOId(option_id)+'"]')[0].options; 658 inst.each(select_options, function(select_option){ 659 if (select_option.value) { 660 option_value_disabled = ( !inst.isInArray(select_option.value,accessible_values) ); 661 select_option.disabled = option_value_disabled; 662 if (option_value_disabled) { 663 $(select_option).addClass('ro_option_disabled'); 664 } else { 665 $(select_option).removeClass('ro_option_disabled'); 666 } 667 inst.trigger( 'setAccessibleOptionValues_selectEnableDisable_after.ro', [option_id, select_option.value, option_value_disabled] ); 668 } 669 }); 670 } 671 672 inst.trigger( 'setAccessibleOptionValues_select_after.ro', [option_id, accessible_values] ); 673 674 return true; 675 } 676 }, 677 678 getQPOPOVIdByName: function(name){ // quantity_per_option[..][X] 679 return name.split('][')[1].replace(']',''); 680 }, 681 682 toggleOptionValueRadio: function($radio, option_value_disabled) { 683 684 if ( typeof(inst.custom_radioToggle) != 'undefined' && inst.custom_radioToggle( $radio, option_value_disabled ) ) { 685 // do nothing 686 } else { 687 $radio.parent().parent().toggle(!option_value_disabled); 688 $radio.toggle(!option_value_disabled); 689 } 690 691 // style change for padding change 692 if (option_value_disabled) { 693 if ($radio.parent().parent().hasClass('radio')) { 694 $radio.parent().parent().removeClass('radio'); 695 $radio.parent().parent().addClass('_radio_ro'); 696 } 697 } else { 698 if ($radio.parent().parent().hasClass('_radio_ro')) { 699 $radio.parent().parent().removeClass('_radio_ro'); 700 $radio.parent().parent().addClass('radio'); 701 } 702 } 703 704 705 }, 706 707 getSelectedOptionValue: function(po_id) { 708 let $elem = inst.getOptionElement('select[name="'+inst.getOptionNameByPOId(po_id)+'"], input[type=radio][name="'+inst.getOptionNameByPOId(po_id)+'"]:checked'); 709 if ( $elem.length && $elem.val() ) { 710 return $elem.val(); 711 } 712 }, 713 714 getOptionValues : function() { 715 716 var options_values = {}; 717 718 inst.getOptionElement('select[name^="'+inst.option_prefix+'["], input[type=radio][name^="'+inst.option_prefix+'["]').each(function(){ 719 option_id = inst.getProductOptionIdFromName( $(this).attr('name') ); 720 if (inst.isInArray(option_id,inst.ro_product_options)) { 721 722 if ( typeof(options_values[option_id]) == 'undefined' ) { 723 options_values[option_id] = 0; 724 } 725 726 if ( $(this).find('option[value]').length ) { // select 727 options_values[option_id] = $(this).val(); 728 } else { // radio 729 if ( $(this).is(':checked') ) { 730 options_values[option_id] = $(this).val(); 731 } 732 } 733 734 } 735 }); 736 737 // add specifically displayed options (quantity input/select per option value) 738 inst.each(inst.input_quantity_per_options, function(product_option_id){ 739 options_values[product_option_id] = 0; 740 }); 741 742 return options_values; 743 }, 744 745 getSelectedRelatedOptions : function(){ 746 let related_options = inst.getOptionValues(); 747 let selected_related_options = {}; 748 inst.each(related_options, function(pov_id, po_id){ 749 if (pov_id) { 750 selected_related_options[po_id] = pov_id; 751 } 752 }); 753 return selected_related_options; 754 }, 755 756 setSelectedCombination : function(ro_id, skip_access) { 757 758 let options_to_set = {}; 759 if (inst.ro_data) { 760 inst.each(inst.ro_data, function(ro_dt){ 761 if (ro_dt.ro[ro_id]) { 762 763 inst.each(ro_dt.ro[ro_id].options, function(pov_id, po_id){ 764 options_to_set[po_id] = pov_id; 765 }); 766 767 return false; 768 } 769 }); 770 } 771 772 if ( !$.isEmptyObject(options_to_set) ) { // we should set option values in the order of options on the page (to make it working with the step-by-step mode) 773 inst.each(inst.getOptionsAsSteps(), function(po_id){ 774 if ( options_to_set[po_id] ) { 775 inst.setOptionValue(po_id, options_to_set[po_id]); 776 if ( inst.step_by_step && inst.hide_inaccessible ) { // control access, otherwise next option may do not have values to make selected at all 777 inst.controlAccessToValuesOfAllOptions(); 778 } 779 } 780 }); 781 } 782 783 // access should be checked also for step by step because there may be selects with removed options 784 if ( typeof(skip_access) == 'undefined' || !skip_access || (inst.step_by_step && inst.hide_inaccessible) ) { 785 786 inst.controlAccessToValuesOfAllOptions(); 787 788 inst.trigger('setSelectedCombination_withAccessControl_after.ro'); 789 790 } 791 792 inst.executeFunctionsFromOtherExtensionsOnOptionChange(); 793 }, 794 795 executeFunctionsFromOtherExtensionsOnOptionChange : function() { 796 797 // Parent-child options - compatibility 798 if ( typeof(pcop_front) != 'undefined' && typeof(pcop_front.checkVisibility) == 'function' ) { 799 pcop_front.checkVisibility(); 800 } 801
802 // very old Product Option Image PRO compatibility 803 if ( typeof(poipExternalOptionChange)=='function' ) { 804 poipExternalOptionChange(); 805 } 806 // old Product Option Image PRO compatibility 807 if ( typeof(poip_product)!='undefined' && typeof(poip_product.externalOptionChange) == 'function' ) { 808 poip_product.externalOptionChange(); 809 } 810 811 if ( typeof(poip_common)!='undefined' && poip_common && typeof(poip_common.externalOptionChangeEvent) == 'function' ) { 812 poip_common.externalOptionChangeEvent( inst.getBlockOfOptions() ); 813 } 814 815 // Live Price OLD 816 if ( typeof(liveprice_recalc) == 'function' ) { 817 liveprice_recalc(100); 818 } 819 820 // Live Price NEW 821 if ( window.liveopencart && (window.liveopencart.live_price_instances || (window.liveopencart.live_price && window.liveopencart.live_price.instances) ) ) { 822 var lp_instances = window.liveopencart.live_price_instances || window.liveopencart.live_price.instances; 823 if ( Array.isArray(lp_instances) && lp_instances.length ) { 824 inst.each(lp_instances, function(lp_instance){ 825 lp_instance.updatePrice(100); 826 }); 827 } 828 } 829 830 $(document).trigger('external_option_change'); // io supported 831 }, 832 833 setSelectedCombinationByModel : function(model) { 834 if (model && inst.ro_data) { 835 inst.each(inst.ro_data, function(ro_dt){ 836 inst.each(ro_dt.ro, function(ro_comb, ro_id){ 837 if (ro_comb.model && ro_comb.model.toLowerCase() == model.toLowerCase()) { 838 ro_set_selected_combination(ro_id); 839 return true; 840 } 841 }); 842 }); 843 } 844 return false; 845 }, 846 847 // for step-by-step way 848 getOptionsAsStepsFromHTML : function() { 849 var options_steps = []; 850 851 inst.getOptionElement('input[name^="'+inst.option_prefix+'["], select[name^="'+inst.option_prefix+'["]').each(function(){ 852 853 854 let product_option_id = inst.getProductOptionIdFromName( inst.getOptionElement(this).attr('name')); 855 856 if (inst.isInArray(product_option_id, inst.ro_product_options)) { 857 if (!inst.isInArray(product_option_id, options_steps)) { 858 options_steps.push(product_option_id); 859 } 860 } 861 862 }); 863 864 // add specifically displayed options (quantity input/select per option value) 865 inst.each(inst.input_quantity_per_options, function(product_option_id){ 866 options_steps.push(product_option_id); 867 }); 868 869 return options_steps; 870 }, 871 872 controlAccessToValuesOfAllOptions : function() { 873 874 if (!inst.ro_data || !Object.keys(inst.ro_data).length) return; 875 876 inst.accessibility_check_restart_needed = false; 877 878 if (inst.step_by_step) { 879 880 var prev_options_values = {}; 881 var prev_options = []; 882 var option_accessible_values = []; 883 var one_prev_value_is_not_set = false; 884 885 inst.each(inst.getOptionsAsSteps(), function(option_step_po_id, i){ 886 887 if (i>0) { 888 // if previous option value is selected or if previous option has no available values 889 //if (!one_prev_value_is_not_set) { 890 // limitaion on previous 891 option_accessible_values = inst.controlAccessToValuesOfOption(prev_options_values, option_step_po_id); 892 893 //} else { 894 // // disable all 895 // inst.setAccessibleOptionValues(option_step_po_id, []); 896 // option_accessible_values = []; 897 //} 898 } 899 900 901 prev_options.push(inst.getSelectedOptionValue(option_step_po_id)); 902 prev_options_values[option_step_po_id] = prev_options[prev_options.length-1]; 903 904 if ((option_accessible_values.length || i==0) && !prev_options[i] ) { // option has available values, but none of them is selected 905 one_prev_value_is_not_set = true; 906 } 907 908 if ( inst.accessibility_check_restart_needed ) { 909 inst.controlAccessToValuesOfAllOptions(); 910 return; 911 } 912 913 }); 914 915 } else { 916 917 var options_values = inst.getOptionValues(); 918 var options_keys = Object.keys(options_values); 919 920 inst.each(options_keys, function(option_key){ 921 922 inst.controlAccessToValuesOfOption(options_values, option_key); 923 924 if ( inst.accessibility_check_restart_needed ) { 925 inst.controlAccessToValuesOfAllOptions(); 926 return false; 927 } 928 }); 929 930 } 931 932 inst.controlOutOfStockOptionViewAll(); 933 934 inst.checkAutoSelect(); 935 936 inst.trigger('controlAccessToValuesOfAllOptions_after.ro'); 937 938 }, 939 940 getMixesAllowZeroSelect: function() { 941 if ( typeof(inst.mixed_allow_zero_select) == 'undefined' ) { 942 inst.mixed_allow_zero_select = false; 943 inst.each(inst.ro_data, function(ro_dt){ 944 inst.mixed_allow_zero_select = ro_dt.allow_zero_select || inst.mixed_allow_zero_select; 945 }); 946 } 947 return inst.mixed_allow_zero_select; 948 }, 949 950 controlOutOfStockOptionViewAll : function() { 951 if ( inst.getMixesAllowZeroSelect() && inst.ro_settings.fade_out_of_stock_option_values ) { 952 953 let po_ids = inst.getOptionsAsSteps(); 954 let selected_option_values = inst.getOptionValues([]); 955 956 if ( inst.ro_settings.fade_out_of_stock_option_values == 1 ) { 957 958 inst.each(po_ids, function(po_id){ 959 960 inst.controlOutOfStockOptionViewOneOption(po_id, selected_option_values); 961 962 });
963 } else if ( inst.ro_settings.fade_out_of_stock_option_values == 2 ) { 964 if ( po_ids.length ) { 965 inst.controlOutOfStockOptionViewOneOption(po_ids[po_ids.length-1], selected_option_values); 966 } 967 } 968 } 969 }, 970 971 controlOutOfStockOptionViewOneOption : function(po_id, selected_option_values) { 972 973 if ( inst.getMixesAllowZeroSelect() && inst.ro_settings.fade_out_of_stock_option_values ) { 974 975 let current_option_values = $.extend(true, {}, selected_option_values); 976 delete current_option_values[po_id]; 977 978 let ro_combs = inst.getROCombsByOptions(current_option_values); 979 let pov_ids_stock = inst.getPOVStockByROCombs(po_id, ro_combs); 980 981 let $ov_elements = inst.getOptionElement('select[name="'+inst.getOptionNameByPOId(po_id)+'"]').find('option[value]'); 982 if ( !$ov_elements.length ) { 983 $ov_elements = inst.getOptionElement(':radio[name="'+inst.getOptionNameByPOId(po_id)+'"]'); 984 } 985 986 if ( $ov_elements.length ) { 987 $ov_elements.each(function(){ 988 let $ov_element = $(this); 989 990 if ( $ov_element.is(':disabled') ) { 991 inst.controlOutOfStockOptionViewOneOptionIsDisabled($ov_element); 992 } else { 993 let pov_id = $ov_element.val(); 994 if ( typeof(pov_ids_stock[pov_id]) != 'undefined' ) { 995 let pov_stock_data = pov_ids_stock[pov_id]; 996 if ( pov_stock_data.in_stock ) { // in stock 997 inst.controlOutOfStockOptionViewOneOptionIsInStock($ov_element); 998 } else { 999 inst.controlOutOfStockOptionViewOneOptionIsOutOfStock($ov_element, (pov_ids_stock[pov_id].last_ro_comb ? pov_stock_data.last_ro_comb.stock_status || pov_stock_data.last_ro_comb.product_stock_status : '')); 1000 1001 } 1002 } 1003 } 1004 }); 1005 } 1006 1007 1008 } 1009 }, 1010 1011 controlOutOfStockOptionViewOneOptionIsDisabled : function($ov_element){ 1012 if ( $ov_element.is('option') ) { 1013 $ov_element.removeClass('ro_option_faded'); 1014 } else { // radio 1015 inst.setOriginalTitleForRadio($ov_element); 1016 } 1017 }, 1018 1019 controlOutOfStockOptionViewOneOptionIsOutOfStock : function($ov_element, title){ 1020 if ( $ov_element.is('option') ) { 1021 $ov_element.addClass('ro_option_faded'); 1022 } else { // radio 1023 inst.fadeToOptionRadio($ov_element, 0.3); 1024 if ( inst.ro_settings.spec_ofs ) { 1025 if ( title ) { 1026 inst.appendToTitleForRadio($ov_element, title ); 1027 } 1028 } 1029 } 1030 }, 1031 1032 controlOutOfStockOptionViewOneOptionIsInStock : function($ov_element){ 1033 if ( $ov_element.is('option') ) { 1034 $ov_element.removeClass('ro_option_faded'); 1035 } else { // radio 1036 inst.fadeToOptionRadio($ov_element, 1); 1037 if ( inst.ro_settings.spec_ofs ) { 1038 inst.setOriginalTitleForRadio($ov_element); 1039 } 1040 } 1041 }, 1042 1043 getPOVStockByROCombs(po_id_current, ro_combs) { 1044 let pov_ids_stock = {}; 1045 1046 inst.each(ro_combs, function(ro_comb){ 1047 inst.each(ro_comb.options, function(pov_id, po_id){ 1048 if ( po_id == po_id_current ) { 1049 if ( !pov_ids_stock[pov_id] ) { 1050 pov_ids_stock[pov_id] = { 1051 in_stock : false, 1052 last_ro_comb : '', 1053 }; 1054 } 1055 pov_ids_stock[pov_id].in_stock = pov_ids_stock[pov_id].in_stock || ro_comb.in_stock; 1056 pov_ids_stock[pov_id].last_ro_comb = ro_comb; 1057 } 1058 }); 1059 }); 1060 return pov_ids_stock; 1061 }, 1062 1063 fadeToOptionRadio : function($radio, fade_to){ 1064 inst.fadeToForElement($radio.parent(), fade_to); 1065 }, 1066 fadeToForElement : function($elem, fade_to) { 1067 $elem.stop().fadeTo('fast', fade_to); 1068 }, 1069 1070 setOriginalTitleForRadio : function($radio){ 1071 let $elem = $radio.parent(); 1072 if ( typeof($elem.attr('data-ro-original-title')) != 'undefined' ) { 1073 $elem.attr('title', $elem.attr('data-ro-original-title')); 1074 } 1075 }, 1076 appendToTitleForRadio : function($radio, title_append) { 1077 let $elem = $radio.parent(); 1078 if ( typeof($elem.attr('data-ro-original-title')) == 'undefined' ) { 1079 $elem.attr('data-ro-original-title', $elem.attr('title')||''); 1080 } 1081 $elem.attr('title', ($elem.attr('data-ro-original-title')+' '+title_append).trim() ); 1082 }, 1083 1084 getOptionNameByPOId: function(po_id) { 1085 return inst.option_prefix+'['+po_id+']'+inst.option_suffix; 1086 }, 1087 1088 getOptionInputElements: function(po_id, filter=''){ 1089 let name = inst.getOptionNameByPOId(po_id); 1090 //let name = inst.option_prefix+'['+po_id+']'; 1091 let $elements = inst.getOptionElement('select[name="'+name+'"], :radio[name="'+name+'"]'); 1092 if ( filter ) { 1093 $elements = $elements.filter(filter); 1094 } 1095 return $elements; 1096 }, 1097 1098 getROCombsPrioritized: function(){ 1099 1100 if ( !inst.ro_combs_proritized ) { 1101 let ro_combs = []; 1102 inst.each(inst.ro_data, function(ro_dt){ 1103 inst.each(ro_dt.ro, function(ro_comb){ 1104 ro_combs.push(ro_comb); 1105 });
1106 }); 1107 1108 ro_combs.sort(function(a,b){ 1109 let a_defaultselect = a.defaultselect ? (parseInt(a.defaultselect) || 0) : 0; 1110 let a_defaultselectpriority = a.defaultselectpriority ? (parseInt(a.defaultselectpriority) || 0) : 0; 1111 let b_defaultselect = b.defaultselect ? (parseInt(b.defaultselect) || 0) : 0; 1112 let b_defaultselectpriority = b.defaultselectpriority ? (parseInt(b.defaultselectpriority) || 0) : 0; 1113 1114 if ( a_defaultselect != b_defaultselect ) { 1115 return b_defaultselect - a_defaultselect; // enabled (1) /not enabled (0) - reversed order 1116 } else if ( a_defaultselect != 0 ) { // both equal and default enabled 1117 return a_defaultselectpriority - b_defaultselectpriority; // prorities - direct order 1118 } 1119 return 0; 1120 }); 1121 1122 inst.ro_combs_proritized = ro_combs; 1123 } 1124 return inst.ro_combs_proritized; 1125 }, 1126 1127 getROCombsCurrentPrioritized: function() { 1128 let ro_combs_current = inst.getCurrentROCombs(); 1129 let ro_combs_current_prioritized = []; 1130 inst.each(inst.getROCombsPrioritized(), function(ro_comb){ 1131 if ( inst.isInArray(ro_comb, ro_combs_current) ) { 1132 ro_combs_current_prioritized.push(ro_comb); 1133 } 1134 }); 1135 return ro_combs_current_prioritized; 1136 }, 1137 1138 getPrefferedAvailableOptionValue: function(product_option_id, values_available) { 1139 let value = false; 1140 let ro_combs_current_prioritized = inst.getROCombsCurrentPrioritized(); 1141 inst.each(ro_combs_current_prioritized, function(ro_comb){ 1142 if (ro_comb.options[product_option_id]) { 1143 let value_pos = $.inArray(ro_comb.options[product_option_id], values_available); 1144 if ( value_pos != -1 ) { 1145 value = values_available[value_pos]; 1146 return false; 1147 } 1148 } 1149 }); 1150 return value; 1151 }, 1152 1153 getValuesOfPassedElements: function($elements) { 1154 return $elements.map(function(){ return $(this).val(); }).get(); 1155 }, 1156 1157 // autoselection for last available option value & first available always 1158 checkAutoSelect : function() { 1159 1160 if (inst.auto_select_last || inst.auto_select_first_always) { 1161 1162 inst.each(inst.getOptionsAsSteps(), function(product_option_id){ 1163 1164 if ( inst.getOptionElement('select[name="'+inst.getOptionNameByPOId(product_option_id)+'"]').length ) { 1165 1166 var $options_elems = inst.getOptionElement('select[name="'+inst.getOptionNameByPOId(product_option_id)+'"]').find('option[value][value!=""]:not(:disabled)'); 1167 1168 if ( inst.auto_select_last && $options_elems.length == 1 && !$($options_elems[0]).is(':selected') || ( inst.auto_select_first_always && $options_elems.length && !$options_elems.filter(':selected').length ) ) { 1169 1170 let values_available = inst.getValuesOfPassedElements($options_elems); 1171 1172 let product_option_value_id = 0; 1173 if ( inst.getSetting('select_first') == 3 ) { 1174 product_option_value_id = inst.getPrefferedAvailableOptionValue(product_option_id, values_available); 1175 } 1176 if ( !product_option_value_id ) { 1177 product_option_value_id = $($options_elems[0]).val(); 1178 } 1179 inst.setOptionValue(product_option_id, product_option_value_id); 1180 $($options_elems[0]).parent().change(); 1181 return false; 1182 } 1183 1184 } else if ( inst.getOptionElement('input:radio[name="'+inst.getOptionNameByPOId(product_option_id)+'"]').length ) { 1185 1186 var $radio_elems = inst.getOptionElement('input:radio[name="'+inst.getOptionNameByPOId(product_option_id)+'"]:not(:disabled)'); 1187 1188 if ( inst.auto_select_last && $radio_elems.length == 1 && !$($radio_elems[0]).is(':checked') || ( inst.auto_select_first_always && $radio_elems.length && !$radio_elems.filter(':checked').length ) ) { 1189 1190 let values_available = inst.getValuesOfPassedElements($radio_elems); 1191 let product_option_value_id = 0; 1192 if ( inst.getSetting('select_first') == 3 ) { 1193 product_option_value_id = inst.getPrefferedAvailableOptionValue(product_option_id, values_available); 1194 } 1195 if ( !product_option_value_id ) { 1196 product_option_value_id = $($radio_elems[0]).val(); 1197 } 1198 //let product_option_value_id = $($radio_elems[0]).val(); 1199 1200 inst.setOptionValue(product_option_id, product_option_value_id); 1201 1202 $($radio_elems[0]).change(); 1203 return false; 1204 1205 } 1206 } 1207 }); 1208 1209 } else if ( inst.getSetting('select_first') == 4 && !inst.was_called.checkAutoSelect ) { // select only the first value of the first option 1210 let option_steps = inst.getOptionsAsSteps(); 1211 if ( option_steps.length ) { 1212 let product_option_id = option_steps[0]; 1213 let $option_element = inst.getOptionInputElements(product_option_id).first(); 1214 if ( $option_element.length ) { 1215 let pov_id = false; 1216 if ( $option_element.is('select') ) { 1217 if ( !$option_element.val() ) { 1218 pov_id = $option_element.find('option[value][value!=""]:not(:disabled):first').val(); 1219 } 1220 } else { // radio 1221 if ( !inst.getOptionInputElements(product_option_id, ':checked').length ) { 1222 pov_id = $option_element.val(); 1223 } 1224 } 1225 if ( pov_id !== false ) { 1226 1227 inst.setOptionValue(product_option_id, pov_id); 1228 $option_element.change(); 1229 $().ready(function(){ 1230 $option_element.change(); 1231 });
1232 1233 } 1234 } 1235 1236 } 1237 } 1238 1239 inst.was_called.checkAutoSelect = true; 1240 }, 1241 1242 // autorelection for first values (initial) 1243 initialAutoSelect : function() { 1244 1245 if (inst.ro_settings && inst.ro_settings.select_first && inst.ro_settings.select_first == 1) { 1246 inst.each(inst.getOptionsAsSteps(), function(product_option_id){ 1247 1248 if ( inst.getOptionElement('select[name="'+inst.getOptionNameByPOId(product_option_id)+'"]').length ) { 1249 1250 let elem = inst.getOptionElement('select[name="'+inst.getOptionNameByPOId(product_option_id)+'"]'); 1251 if ( !elem.val() ) { 1252 1253 let elem_option = elem.find('option[value][value!=""]:not(:disabled)'); 1254 if (elem_option.length) { 1255 1256 inst.setOptionValue(product_option_id, elem_option.val() ); 1257 1258 elem.change(); 1259 } 1260 1261 } 1262 1263 } else if ( inst.getOptionElement('input:radio[name="'+inst.getOptionNameByPOId(product_option_id)+'"]').length ) { 1264 1265 if ( !inst.getOptionElement('input:radio[name="'+inst.getOptionNameByPOId(product_option_id)+'"]:checked').length ) { 1266 let elem = inst.getOptionElement('input:radio[name="'+inst.getOptionNameByPOId(product_option_id)+'"]:not(:disabled):first'); 1267 if (elem.length) { 1268 1269 inst.setOptionValue(product_option_id, elem.attr('value') ); 1270 1271 elem.change(); 1272 1273 } 1274 } 1275 } 1276 1277 1278 }); 1279 } 1280 }, 1281 1282 1283 }; 1284 1285 if ( p_params.key_of_getROProductThemeMethods && window[p_params.key_of_getROProductThemeMethods] ) { // params - higher priority 1286 inst.theme_methods = window[p_params.key_of_getROProductThemeMethods](inst); 1287 let debug = false; 1288 ro_common.proxyObjectMethods(inst, debug, inst.theme_methods); 1289 } else if ( typeof(getROProductThemeMethods) == 'function' ) { 1290 inst.theme_methods = getROProductThemeMethods(inst); 1291 let debug = false; 1292 ro_common.proxyObjectMethods(inst, debug, inst.theme_methods); 1293 } 1294 1295 1296 inst.parentBlock = this; 1297 1298 var params = $.extend( { 1299 'ro_settings' : {}, 1300 'ro_texts' : {}, 1301 'ro_data' : false, 1302 'ro_theme_name' : '', 1303 'ros_to_select' : '', 1304 'poip_ov' : '', 1305 'filter_name' : '', 1306 'product_id' : 0, 1307 }, p_params); 1308 inst.ro_settings = params.ro_settings; 1309 inst.ro_theme_name = params.ro_theme_name; 1310 inst.ro_texts = params.ro_texts; 1311 inst.ro_data = params.ro_data; 1312 inst.ros_to_select = params.ros_to_select; 1313 inst.poip_ov = params.poip_ov; 1314 inst.filter_name = params.filter_name; 1315 inst.product_id = params.product_id; 1316 inst.first_stock_control_only_on_add_to_cart = params.first_stock_control_only_on_add_to_cart || false; 1317 1318 // settings 1319 inst.hide_inaccessible = inst.getSetting('hide_inaccessible'); 1320 inst.step_by_step = inst.getSetting('step_by_step'); 1321 1322 inst.auto_select_last = inst.getSetting('select_first') == 2; 1323 inst.auto_select_first_always = inst.getSetting('select_first') == 3; 1324 1325 inst.option_prefix = params.option_prefix || 'option'; 1326 if ( !$('[name^="option["]').length ) { 1327 if ( $('[name^="option_oc["]').length ) { // mijoshop 1328 inst.option_prefix = "option_oc"; 1329 } 1330 } 1331 inst.option_prefix_length = inst.option_prefix.length; 1332 1333 inst.option_suffix = params.option_suffix || ''; 1334 1335 // data 1336 inst.ro_product_options = []; 1337 if ( inst.ro_data ) { 1338 inst.each(inst.ro_data, function(ro_dt){ 1339 var option_ids = ro_dt.options_ids; 1340 inst.each(option_ids, function(product_option_id){ 1341 if ( !inst.isInArray(product_option_id, inst.ro_product_options) ) { 1342 inst.ro_product_options.push(product_option_id); 1343 } 1344 }); 1345 }); 1346 } 1347 //var ro_exists = false; 1348 1349 // variables 1350 inst.linked_options_cache = {}; // cache 1351 inst.all_select_ov = {}; // selects cache 1352 inst.input_quantity_per_options = []; 1353 inst.ro_stock_control_last_call = ''; 1354 inst.options_types = []; 1355 inst.options_step_by_step = []; 1356 inst.all_values_of_options = []; 1357 1358 //inst.initRO(); // init should be started from outside, after assigning all additional functions/triggers 1359 1360 $this.data('liveopencart_relatedOptions', inst); 1361 1362 if ( !window.liveopencart ) { 1363 window.liveopencart = {}; 1364 } 1365 if ( !window.liveopencart.related_options_instances ) { 1366 window.liveopencart.related_options_instances = []; 1367 } 1368 window.liveopencart.related_options_instances.push(inst); 1369 1370 return inst; 1371 1372}; })(jQuery); 1373
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.