PageSourceSearch

https://epuletgepeszet.bezzeghkft.hu/catalog/view/theme/extension_…?v=1721974012&v=14218c9K

js bezzeghkft.hu collected 2026-10-08 02:27:25 UTC 43,652 bytes, 1,229 lines download raw bytes

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

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.