PageSourceSearch

https://book.virtuferries.com/en/wp-content/plugins/cw-standard/js/public-choosedetails.js?ver=1.1.28735

js virtuferries.com collected 2026-09-24 20:38:18 UTC 49,396 bytes, 1,361 lines download raw bytes

1var cw_standard_choosedetails_controller = (function($, CW){
2	function cw_all_must_have_cabin(value, element){
3		// Assume true so that if we have nothing to validate it is OK
4		var valid = true;
5
6		// Get element and data
7		var el = $(element);
8		var num_pax = parseInt( el.data('cw-num-pax'), 10);
9
10		// Get other cabin fields.  Should only be for the same journey
11		var selector_for_others = el.data('cw-sel-other_cabins-for-validation');
12		var others = $(selector_for_others, element.form);
13
14		// Only validate if we have others and num_pax
15		if( others.length > 0 && !isNaN(num_pax) && num_pax > 0 ) {
16			// See how many people fit in the cabins chosen
17			var num_people_with_places = 0;
18			var num_cabins = 0;
19			others.each(function(){
20				var me = $(this);
21				var num = parseInt(me.val(), 10);
22				if( !isNaN(num) && num > 0 ) {
23					num_cabins += num;
24					var berths = parseInt(me.data('cw-berths' ), 10);
25					if( !isNaN(berths) && berths > 0 ) {
26						// We have berths so we have space for that many people
27						num_people_with_places += (num * berths);
28					} else {
29						// No berths so assume one person only per cabin/seat
30						num_people_with_places += num;
31					}
32				}
33			});
34
35			// Valid if we have place for everyone
36			valid = num_people_with_places >= num_pax && num_cabins <= num_pax;
37
38			// Re-validate other elements in group so that error-classes are right
39			// Use data 'cw-being-validated' to avoid infinite loop
40			if( !el.data('cw-being-validated') ) {
41				// We need to use the same instance of the validator when checking all in the group
42				// Otherwise we get some crazy recursion problem and it breaks validation of elements after it on the form
43				var validator;
44				if( el.data('cw-cabins-validator') ) {
45					// Get cloned validator if set
46					validator = el.data( 'cw-cabins-validator' );
47				} else {
48					// Otherwise clone and save the validator
49					validator = $.extend( {}, this );
50					el.data( 'cw-cabins-validator', validator );
51				}
52
53				// Set to prevent loop
54				others.data('cw-being-validated', true);
55
56				// Revalidate everything except the current element in the group
57				others.not( element ).each(function(){
58					validator.element(this);
59				});
60
61				// Remove revalidation data
62				others.data('cw-being-validated', false);
63			}
64		}
65		return valid;
66	}
67	$.validator.addMethod('cw_all_must_have_cabin', cw_all_must_have_cabin, cw_objectL10n_core.cabins_not_valid);
68	$.validator.addClassRules({
69		'cw-all-must-have-cabin': {
70			'cw_all_must_have_cabin': true
71		}
72	});
73
74	// responsive design jquery
75	var resizeMethod = function(){
76		if (CarresWeb.is_phone()) {
77			$('.cw-choosedetails-pax-row div.first').show();
78			$('.cw-choosedetails-pax-row div.hidden').hide();
79			$('.cw-choosedetails-pax-row .toggler').show();
80		} else if (CarresWeb.is_tablet() || CarresWeb.is_desktop()) {
81			$('.cw-choosedetails-pax-row div.first').show();
82			$('.cw-choosedetails-pax-row div.hidden').show();
83			$('.cw-choosedetails-pax-row .toggler').hide();
84		}
85	};
86
87	/**
88	 * Auto selects mandatory categories and updates the shopping basket
89	 * @param component_container
90	 */
91	function update_mandatory_categories( component_container ) {
92		$('.cw-mandatory-cabin-combination').each(function() {
93			var el = $(this);
94			if( el.val() != el.data('cw-initial-value') ) {
95				update_cabins(el);
96			}
97		});
98	}
99
100	$( document ).ready(function() {
101		var context = $(".cw-choosedetails-kiosk-container");
102		//var price_cont = $('.cw-meal-price-cont', context);
103		//cw_standard_choosedetails_controller.choosedetails.hide_on_the_day_price(price_cont, 'meals');
104		context
105			.on("change",".cw-plusminus-container select", function(el, opts){
106				opts = opts || {isInit: false};
107				cw_standard_choosedetails_controller.choosedetails.change_ctg_qty(this, null, opts.isInit);
108			})
109			.on("click",".cw-meal-moreinfo", function(event){
110				cw_standard_choosedetails_controller.choosedetails.showMoreInfo(event,this);
111			});
112
113		if( context.length && $('.cw-current-component').hasClass('cw-name-assignment') ){
114			cw_standard_choosedetails_controller.choosedetails.set_default_names(context.find('.cw-requires-names .cw-meal-inner'));
115		}
116	});
117
118	/**
119	 * Collects cabin info to run UpdateShoppingBasket (and usually runs)
120	 * @param field - cabin qty dropdown
121	 * @param dont_run_add_sb - do not run actual cw_add_sb(), just collect the info and run e.g. show_hide_name_buttons()
122	 */
123	function update_cabins(field, dont_run_add_sb) {
124		var cont = field.closest('.cw-choosedetails-cab-details');
125		var container = field.closest('.cw-cabin-action-row');
126		if( container.length == 0 ) {
127			container = field.closest('.cw-cabin');
128		}
129		if($('.cw-cabin-spec', container).length > 0) {
130			if($('.cw-cabin-spec', container).hasClass('hidden')) {
131				$('.cw-cabin-spec', container).removeClass('hidden');
132			} else {
133				var args = {};
134
135				$('.cw-choosedetails-cabin-spec-ctg', container).each(function() {
136					$('input', this).each(function() {
137						args[$(this).attr('name')] = $(this).val();
138					});
139					$('select', this).each(function() {
140						if ($(this).attr('name')) {
141							args[$(this).attr('name')] = $(this).val();
142						}
143					});
144				});
145
146				var action = 'addcabin';
147
148				cw_add_sb('.cw-sb', true, args, function() {
149					$('.cw-btn-add-cabin', container).hide();
150					$('.cw-btn-upd-cabin', container).show();
151					$('.cw-btn-rem-cabin', container).show();
152					cw_reload_current_component();
153					move_sb();
154				}, action);
155
156			}
157
158			return;
159		}
160
161		cw_start_loading(cont);
162
163		var addButton = $('.cw-btn-add-cabin', container);
164		var updateButton = $('.cw-btn-upd-cabin', container);
165		var removeButton = $('.cw-btn-rem-cabin', container);
166		var qtySelect = $('.cw-cabin-select', container);
167		var cab_container = field.closest('.cw-choosedetails-cab-cont');
168		var selected_cabin_name =$('.cw-cabin-group-name',field.closest('.cw-cabin-group-content'));
169
170		var journeyNumber = $('.cw-cabin-journey-number', container).val();
171		var qty = $('.cw-cabin-qty:selected', container).val();
172		var ctg = field.attr("ctg");
173		var maxqty = field.attr("maxqty");
174
175		var spec = $('.cw-cabin-spec-option:selected', container ).val();
176		var specQty = $('.cw-cabin-spec-quantity:selected', container ).val();
177		var post_data = "";
178		post_data += "&match_spec=true";
179		post_data += "&qty="+qty;
180		post_data += "&ctg="+ctg;
181		post_data += "&journeyNumber="+journeyNumber;
182
183		if( spec ) {
184			post_data += "&spec="+spec;
185			post_data += "&specQty="+specQty;
186			post_data += "&updateBySpecQty=true";
187		}
188
189		var cabins_action = 'updcabins';
190		if (CW.is_standard_theme) {
191			// use 'update' action to not lose cabins rownums on updating qt
191y
192			cabins_action = 'updcabins_using_update';
193			// updcabins_using_update always returns JSON, so we need to let cw_add_sb to know that
194			post_data += "&notifyOnComponentError=true";
195		}
196
197		// initialize and show assigned names block without sending the actual UpdateShoppingBasket
198		if ($('.cw-current-component').hasClass('cw-name-assignment') && field.parents('.cw-cabin').hasClass('cw-requires-names') && dont_run_add_sb) {
199			cw_standard_choosedetails_controller.choosedetails.show_hide_name_buttons('.cw-cabin',
200			                                                                          '.cw-cabin-action-row',
201			                                                                          '.cw-select-input-label',
202			                                                                          field,
203			                                                                          post_data);
204			cw_stop_loading(cont);
205			return false;
206		}
207
208		cw_add_sb('.cw-sb', true, post_data, function(data) {
209
210			if($('.cw-current-component').hasClass('cw-name-assignment') && field.parents('.cw-cabin').hasClass('cw-requires-names')){
211				if( typeof data === 'object') {
212					if( data.rownum ) {
213						var old_rownum = field.data('cw-rownum');
214						if (old_rownum && old_rownum != data.rownum ) {
215							// update existing name block's rownum to avoid duplicating name blocks
216							field.parents('.cw-cabin').find('.cw-linked-names-block.cw-rownum-' + old_rownum)
217								.removeClass('cw-rownum-' + old_rownum)
218								.addClass('cw-rownum-' + data.rownum);
219						}
220						field.data('cw-rownum', data.rownum);
221					}
222				}
223				cw_standard_choosedetails_controller.choosedetails.show_hide_name_buttons('.cw-cabin',
224				                                                                          '.cw-cabin-action-row',
225				                                                                          '.cw-select-input-label',
226				                                                                          field,
227				                                                                          post_data);
228			}
229
230			addButton.hide();
231			if (maxqty > 1) {
232				updateButton.show();
233				qtySelect.show();
234			}
235			// disable hiding of return for SWT. But maybe we should think about using that later
236			if (!CW.is_standard_theme) {
237				show_hide_cabins_for_return();
238			}
239			removeButton.show();
240			cw_stop_loading(cont);
241			if( 1 <= qty ){
242				$('.cw-selected-seats-name', cab_container ).text(selected_cabin_name.text());
243			} else {
244				$('.cw-selected-seats-name', cab_container ).text('');
245			}
246			$('.cw-choosedetails-cabin-ctg .cw-selectbuttons .last-btn', $(cont).closest('.cw-choosedetails-cabin-row') ).trigger('click');
247		}, cabins_action);
248
249		return false;
250	}
251
252	/**
253	 * Checks all cabin-select inputs and returns the collected information
254	 * Use this when cabins are listed and there is one quantity select/input for each cabin
255	 * See get_chosen_cabins_grouped function for when cabins are grouped/dynamic (not all are listed at once, user gets to select type and then quantity)
256	 *
257	 * @param field - The changed input field
258	 * @returns {Array} - Array with cabin-objects with their category and quantity
259	 */
260	function get_chosen_cabins(field) {
261		var chosen_options = [];
262		var container = field.closest('.cw-choosedetails-cabins-row');
263
264		// Find all cabin selects
265		var cabin_category_inputs = container.find('.cw-cabin-select');
266
267		cabin_category_inputs.each(function(key, value) {
268			var category_input = $(this);
269			var cabin_type = category_input.attr('ctg');
270
271			if( 'undefined' !== typeof cabin_type ) {
272				var chosen_cabin = {};
273				chosen_cabin.key = key;
274				chosen_cabin.ctg = cabin_type;
275				chosen_cabin.qty = category_input.val();
276				chosen_options.push(chosen_cabin);
277			}
278		});
279
280		return chosen_options;
281	}
282
283	/**
284	 * Checks all cabin-select inputs and returns the collected information
285	 * Use this when cabins are grouped/dynamic, not all are listed at once, user gets to select type and then quantity
286	 * See get_chosen_cabins function for when cabins are listed and there is one quantity select/input for each cabin
287	 *
288	 * @param field - The changed input field
289	 * @returns {Array} - Array with cabin-objects with their category and quantity
290	 */
291	function get_chosen_cabins_grouped(field) {
292		var possible_options = [];
293		var chosen_options = [];
294		var container = field.closest('.cw-cabin-ctgs-cont');
295
296		// get selected and possible categories
297		var cabin_category_containers = container.find('.cw-cabin-category-cont');
298
299		cabin_category_containers.each(function(key, value) {
300			var category_container = $(this);
301			var type_select = category_container.find('.cw-cabin-select-type');
302			var type_option = type_select.find(':selected');
303			var cabin_type = type_option.attr('data-cw-cabin-ctg');
304			var cabin_quantity = category_container.find('.cw-cabin-select').val();
305			if( 'undefined' !== typeof cabin_type ) {
306				var chosen_cabin = {};
307				chosen_cabin.key = key;
308				chosen_cabin.ctg = cabin_type;
309				chosen_cabin.qty = cabin_quantity;
310				chosen_options.push(chosen_cabin);
311			}
312
313			if( possible_options.length === 0 ) {
314				var category_options = type_select.find('option');
315				category_options.each(function() {
316					var possible = $(this).attr('data-cw-cabin-ctg');
317					if(possible) {
318						possible_options.push(possible);
319					}
320				});
321			}
322		});
323
324		// if possible categories exist that are not selected, add them with zero value
325		$.each(possible_options, function(key, possible_value) {
326			var found = false;
327			$.map(chosen_options, function(chosen_value) {
328				if(chosen_value.ctg == possible_value ){
329					found = true;
330				}
331			});
332			if( !found ) {
333				var empty_cabin = {};
334				empty_cabin.key = chosen_options.length;
335				empty_cabin.ctg = possible_value;
336				empty_cabin.qty = 0;
337				chosen_options.push(empty_cabin);
338			}
339		});
340
341		return chosen_options;
342	}
343
344	/**
345	 * Collect data from cabin inputs and do the updjourney ajax-request
346	 *
347	 * @param field
348	 */
349	function update_dropdown_cabins(field) {
350		var chosen_options;
351
352		if(CW.choosedetails_settings.HasGroupingForCabins) {
353			if(CW.is_standard_theme) {
354				chosen_options = get_chosen_cabins(field);
355			} else {
356				chosen_options = get_chosen_cabins_grouped(field);
357			}
358		} else {
359			chosen_options = get_chosen_cabins(field);
360		}
361
362		// add cabins to request data
363		var post_data = "";
364		$.each(chosen_options, function(key, cabin){
365			var post_prefix = '&cabin[' + cabin.key + ']';
366			post_data += post_prefix + "[ctg]=" + cabin.ctg;
367			post_data += post_prefix + "[qty]=" + cabin.qty;
368		});
369
370		var cabin_container = field.closest('.cw-cabin');
371		var journeyNumber = $('.cw-cabin-journey-number', cabin_container).val();
372		post_data += "&journeyNumber="+journeyNumber;
373
374		var component_container = $('.cw-component-choosedetails');
375		cw_start_loading(component_container);
376		cw_add_sb('.cw-sb', true, post_data, function(data) {
377			if (data.indexOf("sb-error") >= 0) {
378				// The update of shoppingbasket failed so we have to set input field back to previous value
379				var previous_value = ( field.attr('data-cw-previous-value') ? field.attr('data-cw-previous-value') : 0 );
380				field.val(previous_value);
381			} else {
382				field.attr('data-cw-previous-value', field.val());
383			}
384			cw_stop_loading(component_container);
385		}, 'updjourney');
386
387		return false;
388	}
389
390	/**
391	 * Update the shopping basket to match cabin selection.
392	 * If total pax is reduced(going back/modify booking), then default value for the ctg has more value than ctg qty
393	 * So default value is reduced to max qty, this should be reflected to the shopping basket as well.
394	 * @param cabin_container
395	 */
396	function update_sb_to_match_cabins_default_value( cabin_container ) {
397		$('.default-value-reduced-to-maxqty', cabin_container).each( function(){
398			update_cabins($(this));
399		});
400	}
401
402	function show_hide_cabins_for_return() {
403		var jry_num = 1;
404		var prev_valid = true;
405		var errors_shown = $('.error' ).filter(':visible');
406		while( true ) {
407			var jry_cabins = $( '.cw-cabin-jry-' + jry_num );
408			if( jry_cabins.length ) {
409				var first_jry_cabin = jry_cabins.filter( ':first' );
410				var container = first_jry_cabin.closest( '.cw-choosedetails-cab-cont' );
411				var select_prev_first = $( '.select-previous-first-' + jry_num );
412				if( prev_valid ) {
413					container.show();
414					$('.cw-choosedetails-cab-details', container).show();
415					select_prev_first.hide();
416					prev_valid = first_jry_cabin.valid();
417				} else {
418					select_prev_first.show();
419					container.hide();
420				}
421			} else {
422				break;
423			}
424			++jry_num;
425		}
426		$('.error' ).filter(':visible' ).not(errors_shown).not('select').hide();
427	}
428
429	// This is a dirty hack since the cabin validation doesn't otherwise seem to qwork for multiple journeys.
430	// Not sure why since I use the same trick as usual to avoid the validator recursion problem.
431	function cw_recheck_all_must_have_cabins(){
432		var jry_num = 1;
433		var valid = true;
434		while( true ) {
435			var jry_cabins = $( '.cw-cabin-jry-' + jry_num );
436			if( jry_cabins.length ) {
437				var first_jry_cabin = jry_cabins.filter( ':first' );
438				var first_jry_valid = first_jry_cabin.valid();
439				if( !first_jry_valid ) {
440					valid = false;
441				}
442			} else {
443				break;
444			}
445			++jry_num;
446		}
447
448		return valid;
449	}
450
451	function add_cabin_container(element) {
452		var container = element.closest('.cw-cabin-ctgs-cont');
453		var category_container = $('.cw-cabin-category-cont:first', container);
454		var max_cabin_types = $('.cw-cabin-select-type', category_container).attr('data-cw-max-cabin-types');
455		var cabin_types_amount = container.find('.cw-cabin-category-cont').length;
456		if( cabin_types_amount < max_cabin_types ) {
457			var new_category_container = category_container.clone();
458			var select_cabin_amount = $('.cw-cabin-select', new_category_container);
459			select_cabin_amount.val(0).hide();
460			select_cabin_amount.attr('data-cw-previous-value', 0);
461			$('.cw-cabin-select-type', new_category_container).val(0);
462			$('.cw-remove-cabin', new_category_container).hide();
463			container.append(new_category_container);
464			cabin_types_amount++;
465		}
466	}
467
468	function change_cabin_type(dropdown_field) {
469		var select_type = dropdown_field;
470		var category_container = select_type.closest('.cw-cabin-category-cont');
471		var selected_cabin_type = select_type.find(":selected");
472		var max_qty = selected_cabin_type.attr('data-cw-cabin-maxqty');
473		var qty_select = category_container.find('.cw-cabin-select');
474		var min_qty = qty_select.attr('data-cw-minqty');
475		var row_remove_wrapper = $('.cw-remove-cabin', category_container);
476
477		// Select the default option based on minqty value if no value is already selected
478		var selected_qty = ( (min_qty != false && qty_select.val() == 0 ) ?  min_qty : qty_select.val() );
479		selected_qty = ( (qty_select.val() > max_qty) ? max_qty : selected_qty );
480
481		var ctg_code = selected_cabin_type.attr('data-cw-cabin-ctg');
482		qty_select.attr('maxqty', max_qty);
483		qty_select.attr('ctg', ctg_code);
484		qty_select.attr('data-cw-berths', selected_cabin_type.attr('data-cw-cabin-berths'));
485		// only keep zero-choice and generate the rest from max qty
486		qty_select.children().slice(1).remove();
487		for(var i = 0; i < max_qty; i++) {
488			// create option elements
489			var option_element = qty_select.children(':first').clone().text(i + 1);
490			if(i + 1 == selected_qty) {
491				option_element.attr('selected', 'selected').attr('value', i + 1);
492			}
493			qty_select.append(option_element);
494		}
495
496		// Hide and remove qty selectors when changing to no cabin type
497		if( 0 == selected_cabin_type.val() ) {
498			qty_select.hide();
499			row_remove_wrapper.hide();
500			if(category_container.siblings('.cw-cabin-category-cont').length > 0) {
501				category_container.find('.cw-remove-cabin-row').trigger('click');
502			}
503		} else {
504			qty_select.show();
505			row_remove_wrapper.show();
506		}
507
508		var qty_container = dropdown_field.closest('.cw-cabin-category-cont');
509		var last_child = qty_container.is(':last-child');
510
511		// Do not bother quantity change if we change to a real cabin type (not the dummy row) and still have zero qty
512		if( !(max_qty && selected_qty == 0) ) {
513			qty_container.find('.cw-cabin-select').trigger('change');
514		}
515
516		if( undefined !== ctg_code && '' != ctg_code && last_child ) {
517			add_cabin_container(dropdown_field);
518		}
519	}
520
521	function filter_available_cabins(cabin_type_field) {
522		var already_chosen_types = [];
523		var container = cabin_type_field.closest('.cw-cabin-ctgs-cont');
524
525		// find already selected cabin types
526		var category_conatiners = container.find('.cw-cabin-select-type').not(cabin_type_field);
527		category_conatiners.each(function() {
528			var chosen_type = ($(this).find(':selected').attr('data-cw-cabin-ctg'));
529			if (typeof(chosen_type) != "undefined") {
530				already_chosen_types.push(chosen_type);
531			}
532		});
533
534		// disable them, should not be possible to choose same cabin twice
535		var cabin_options = cabin_type_field.find('option');
536		cabin_options.each(function() {
537			var cabin_option = $(this);
538			cabin_option.removeAttr('disabled');
539			var cabin_category = (cabin_option.attr('data-cw-cabin-ctg'));
540			if( $.inArray(cabin_category, already_chosen_types) != -1 ) {
541				cabin_option.attr('disabled','disabled');
542			}
543		});
544	}
545	function select_link_names(label, parent_class,  unlink_from_others) {
546		var parent_div = label.closest(parent_class);
547		var checkbox_id = label.attr('for');
548		var chosen_name_rownum = $('input#' + checkbox_id).val();
549
550		if (!label.hasClass('cw-chosen-name')){
551			// avoid selecting more names than max
552			var current_chosen_names_count = label.closest('.cw-linked-names-block').find('.cw-chosen-name').length;
553			if (current_chosen_names_count >= label.closest('.cw-linked-names-block').data('cw-max-names') ) {
554				return false;
555			}
556			// unlink selected name from other cabins for current journey
557			if (unlink_from_others) {
558				parent_div.find('.cw-chosen-name').each(function(){
559					var checkbox_id = $(this).attr('for');
560					var unlink_candidate = $('input#' + checkbox_id);
561					if(unlink_candidate.val() === chosen_name_rownum){
562						$(this).removeClass('cw-chosen-name');
563						unlink_candidate.prop('checked', false);
564					}
565				});
566			}
567			label.addClass('cw-chosen-name');
568		} else {
569			label.removeClass('cw-chosen-name');
570		}
571
572	}
573
574	function show_hide_cabins_no_pax_error() {
575		if( $('.cw-choosedetails-cabins-no-pax').length ) {
576			$('.cw-sb-tools .cw-choosedetails-cabins-no-pax-error-out-of-form').show();
577		} else {
578			$('.cw-sb-tools .cw-choosedetails-cabins-no-pax-error-out-of-form').hide();
579		}
580	}
581
582	$(document).on('cw_ready',function() {
583		var component_container = $('.cw-component-choosedetails');
584		var cabin_container = $('.cw-choosedetails-cab-cont');
585		var price_cont = $('.cw-cabin-group-price-cont', cabin_container);
586		choosedetails_controller.hide_on_the_day_price(price_cont, 'cabins');
587		// disable hiding of return for SWT. But maybe we should think about using that later
588		if (!CW.is_standard_theme) {
589			show_hide_cabins_for_return();
590		}
591		var settings = CarresWeb.choosedetails_settings;
592		// show or hide add more cabin button according to the amount of cabins per cabins ctg
593		$('.cw-cabin-ctgs-cont', '.cw-choosedetails-cab-details' ).each( function(){
594			var container = $(this);
595			var category_container = $('.cw-cabin-category-cont:first', container);
596			var max_cabin_types = $('.cw-cabin-select-type', category_container).attr('data-cw-max-cabin-types');
597			var cabin_types_amount = container.find('.cw-cabin-category-cont').length;
598
599		});
600
601		if (cabin_container.length) {
602			show_hide_cabins_no_pax_error();
603			$(document).on('cw_sb_changed', function () {
604				show_hide_cabins_no_pax_error();
605			});
606		}
607
608
609		// Update cabins on page load if default value reduced to match max qty
610		if( $('.default-value-reduced-to-maxqty').length > 0 ) {
611			update_sb_to_match_cabins_default_value( cabin_container );
612		}
613
614		// Use dirty hack to avoid recursion problem.  TODO: Fix this!
615		if( $('.cw-all-must-have-cabin' ).length ){
616			component_container.closest('form' ).data('cw-extra-submit-handler', cw_recheck_all_must_have_cabins);
617		}
618
619		$('.cw-choosedetails-pax-row', component_container).each(function() {
620			// assign classes to passanger-button groups
621			$('.cw-choosedetails-pax-row div:eq(0)', this).addClass('first');
622			$('.cw-choosedetails-pax-row div', this).not('.first').addClass('hidden');
623			$('.cw-choosedetails-pax-row div.first', this).append('<p><div class="toggler">More passenger types</div></p>').hide();
624
625			var _this = this;
626			$('.cw-choosedetails-pax-row .toggler', this).click(function(){
627				$('.cw-choosedetails-pax-row div.hidden', _this).slideToggle();
628			});
629		});
630
631		resizeMethod();
632		//Attach event for resizing
633		window.addEventListener("resize", resizeMethod, true);
634
635		/* ******************* */
636
637		update_mandatory_categories(component_container);
638
639		$('.cw-meals-container')
640		.on('click', '.cw-choosedetails-assign-names-button', function() {
641			return select_link_names($(this), '.cw-meals-container', false);
642		});
643
644		$('.cw-choosedetails-cab-details')
645			.on('click', '.cw-btn-add-cabin, .cw-btn-upd-cabin', function(){
646				    update_cabins($(this));
647			    })
648			.on('change', '.cw-cabin-select', function(el, opts) {
649				opts = opts || {isInit: false};
650				if (CW.choosedetails_settings.ChooseCabinsWithDropdownOnly) {
651					if(CW.choosedetails_settings.GroupCabinCategories) {
652						update_dropdown_cabins($(this));
653					} else {
654						update_cabins($(this), opts.isInit);
655					}
656			    }
657		    })
658
659			.on('focus', '.cw-cabin-select-type', function() {
660				filter_available_cabins($(this));
661			})
662
663			.on('change', '.cw-cabin-select-type', function() {
664				if (CW.choosedetails_settings.ChooseCabinsWithDropdownOnly) {
665					change_cabin_type($(this));
666					}
667			})
668			.on('click', '.cw-choosedetails-assign-names-button', function() {
669				return select_link_names($(this),'.cw-choosedetails-cab-details', true);
670			})
671			.on('click', '.cw-cabin-show-hide button', function() {
672				$(this).closest('.cw-cabin-group-cont').toggleClass('open').siblings().removeClass('open');
673			})
674
675			.on('click', '.cw-cabin-spec-show-hide button', function() {
676				$(this).closest('.cw-cabin-ctgs-cont').toggleClass('open');
677			})
678
679			.on('click', '.cw-btn-rem-cabin', function(){
680
681				    var cont = $(this).closest('.cw-choosedetails-cab-details');
682				    var container = $(this).closest('.cw-cabin');
683				    cw_start_loading(cont);
684
685				    var addButton = $('.cw-btn-add-cabin', container);
686				    var updateButton = $('.cw-btn-upd-cabin', container);
687				    var removeButton = $('.cw-btn-rem-cabin', container);
688				    var qtySelect = $('.cw-cabin-select', container);
689
690				    var journeyNumber = $('.cw-cabin-journey-number', $(this).closest('.cw-action-buttons')).val();
691
692				    var qty = $('.cw-cabin-qty:selected', container).val();
693				    var ctg = $(this).attr("ctg");
694				    var maxqty = $(this).attr("maxqty");
695
696				    var post_data = "";
697				    post_data += "&qty="+qty;
698				    post_data += "&ctg="+ctg;
699				    post_data += "&journeyNumber="+journeyNumber;
700
701				    cw_add_sb('.cw-sb', true, post_data, function() {
702					    removeButton.hide();
703					    updateButton.hide();
704					    qtySelect.hide();
705					    addButton.show();
706					    cw_stop_loading(cont);
707				    }, 'remcabins');
708
709				    return false;
710			    });
711
712		$('.cw-choosedetails-misc-details')
713			.on('click', '.cw-btn-add-misc, .cw-btn-upd-misc', function(){
714
715				    var cont = $(this).closest('.cw-choosedetails-misc-details');
716				    var container = $(this).closest('.cw-misc');
717
718				    if($('.cw-misc-spec', container).length > 0) {
719					    if($('.cw-misc-spec', container).hasClass('hidden')) {
720						    $('.cw-misc-spec', container).removeClass('hidden');
721					    } else {
722						    var args = {};
723
724						    $('.cw-choosedetails-misc-spec-ctg', container).each(function() {
725							    $('input', this).each(function() {
726								    args[$(this).attr('name')] = $(this).val();
727							    });
728							    $('select', this).each(function() {
729								    if ($(this).attr('name')) {
730									    args[$(this).attr('name')] = $(this).val();
731								    }
732							    });
733						    });
734
735						    var action = 'addmisc';
736
737						    cw_add_sb('.cw-sb', true, args, function() {
738							    $('.cw-btn-add-misc', container).hide();
739							    $('.cw-btn-upd-misc', container).show();
740							    $('.cw-btn-rem-misc', container).show();
741
742							    cw_reload_current_component();
743							    move_sb();
744						    }, action);
745
746					    }
747
748					    return;
749				    }
750
751				    cw_start_loading(cont);
752
753				    var addButton = $('.cw-btn-add-misc', container);
754				    var updateButton = $('.cw-btn-upd-misc', container);
755				    var removeButton = $('.cw-btn-rem-misc', container);
756				    var qtySelect = $('.cw-misc-select', container);
757
758				    var journeyNumber = $('.cw-misc-journey-number', container).val();
759				    var qty = $('.cw-misc-qty:selected', container).val();
760				    var ctg = $(this).attr("ctg");
761				    var maxqty = $(this).attr("maxqty");
762				    var specQty = "";
763				    var spec = "";
764
765				    var post_data = "";
766				    post_data += "&qty="+qty;
767				    post_data += "&ctg="+ctg;
768				    post_data += "&journeyNumber="+journeyNumber;
769				    //post_data += "&specQty="+specQty;
770				    //post_data += "&spec="+spec;
771
772					post_data += "&notifyOnComponentError=true";
773
774				    cw_add_sb('.cw-sb', true, post_data, function() {
775					    addButton.hide();
776					    if (maxqty > 1) {
777						    updateButton.show();
778						    qtySelect.show();
779					    }
780					    removeButton.show();
781					    cw_stop_loading(cont);
782
783					    $('.cw-choosedetails-misc-ctg .cw-selectbuttons .last-btn', $(cont).closest('.cw-choosedetails-misc-row') ).trigger('click');
784
785					    cw_reload_current_component();
786				    }, 'updmisc');
787
788
789
790				    return false;
791			    })
792			.on('click', '.cw-choosedetails-assign-names-button', function() {
793				return select_link_names($(this), '.cw-choosedetails-misc-details', false);
794			})
795			.on('click', '.cw-btn-rem-misc', function(){
796
797				    var cont = $(this).closest('.cw-choosedetails-misc-detail
797s');
798				    var container = $(this).closest('.cw-misc');
799				    cw_start_loading(cont);
800
801				    var addButton = $('.cw-btn-add-misc', container);
802				    var updateButton = $('.cw-btn-upd-misc', container);
803				    var removeButton = $('.cw-btn-rem-misc', container);
804				    var qtySelect = $('.cw-misc-select', container);
805
806				    var journeyNumber;
807				    journeyNumber = '';
808				    $('.cw-misc-li-select-journey.button.active', container).each(function(){
809					    journeyNumber += $(this).attr("journeyNumber") + ',';
810				    });
811
812				    if (!journeyNumber){
813					    journeyNumber = $('.cw-misc-li-select-journey.selected', container).attr("journeyNumber");
814					    if (!journeyNumber) {
815						    alert("Error in post data!");
816						    return;
817					    }
818				    }
819				    var qty = $('.cw-misc-qty:selected', container).val();
820				    var ctg = $(this).attr("ctg");
821				    var maxqty = $(this).attr("maxqty");
822				    var specQty = "";
823				    var spec = "";
824
825				    var post_data = "";
826				    post_data += "&qty="+qty;
827				    post_data += "&ctg="+ctg;
828				    post_data += "&journeyNumber="+journeyNumber;
829				    //post_data += "&specQty="+specQty;
830				    //post_data += "&spec="+spec;
831
832
833				    cw_add_sb('.cw-sb', true, post_data, function() {
834					    removeButton.hide();
835					    updateButton.hide();
836					    qtySelect.hide();
837					    addButton.show();
838					    cw_stop_loading(cont);
839				    }, 'remmisc');
840
841				    return false;
842			    });
843
844		$('.cw-choosedetails-veh-details')
845			.on('click', '.cw-btn-add-vehicles, .cw-btn-upd-vehicles', function(){
846
847				    var cont = $(this).closest('.cw-choosedetails-veh-details');
848				    var container = $(this).closest('.cw-vehicle');
849				    //alert(catcont.length);
850
851				    var addButton = $('.cw-btn-add-vehicles', container);
852				    var updateButton = $('.cw-btn-upd-vehicles', container);
853				    var removeButton = $('.cw-btn-rem-vehicles', container);
854				    var qtySelect = $('.cw-vehicle-select', container);
855
856				    var journeyNumber;
857				    journeyNumber = '';
858				    $('.cw-vehicle-li-select-journey.button.active', container).each(function(){
859					    journeyNumber += $(this).attr("journeyNumber") + ',';
860				    });
861
862				    if (!journeyNumber) {
863					    journeyNumber = $('.cw-vehicle-li-select-journey.selected', container).attr("journeyNumber");
864					    if (!journeyNumber) {
865						    //alert("Error in post data!");
866						    return;
867					    }
868				    }
869
870				    var qty = $('.cw-vehicle-qty:selected', container).val();
871				    var ctg = $(this).attr("ctg");
872				    var maxqty = $(this).attr("maxqty");
873				    var specQty = "";
874				    var spec = "";
875
876				    var post_data = "";
877				    post_data += "&qty="+qty;
878				    post_data += "&ctg="+ctg;
879				    post_data += "&journeyNumber="+journeyNumber;
880				    //post_data += "&specQty="+specQty;
881				    //post_data += "&spec="+spec;
882
883				    cw_start_loading(cont);
884				    cw_add_sb('.cw-sb', true, post_data, function() {
885					    addButton.hide();
886					    if (maxqty > 1) {
887						    updateButton.show();
888						    qtySelect.show();
889					    }
890					    removeButton.show();
891
892					    // close vehicle options
893					    $('.cw-choosedetails-veh-ctg .cw-selectbuttons .last-btn', $(cont).closest('.cw-choosedetails-vehicles-row') ).trigger('click');
894					    cw_stop_loading(cont);
895				    }, 'updvehicles');
896
897
898				    return false;
899			    })
900			.on('click', '.cw-btn-rem-vehicles', function(){
901
902				    var cont = $(this).closest('.cw-choosedetails-veh-details');
903				    var container = $(this).closest('.cw-vehicle');
904				    cw_start_loading(cont);
905
906				    var addButton = $('.cw-btn-add-vehicles', container);
907				    var updateButton = $('.cw-btn-upd-vehicles', container);
908				    var removeButton = $('.cw-btn-rem-vehicles', container);
909				    var qtySelect = $('.cw-vehicle-select', container);
910
911				    var journeyNumber;
912				    journeyNumber = $('.cw-vehicle-li-select-journey.button.active', container).attr("journeyNumber");
913				    if (!journeyNumber){
914					    journeyNumber = $('.cw-vehicle-li-select-journey.selected', container).attr("journeyNumber");
915					    if (!journeyNumber) {
916						    alert("Error in post data!");
917						    return;
918					    }
919				    }
920
921				    var qty = $('.cw-vehicles-qty:selected', container).val();
922				    var ctg = $(this).attr("ctg");
923				    var maxqty = $(this).attr("maxqty");
924				    var specQty = "";
925				    var spec = "";
926
927				    var post_data = "";
928				    //post_data += "&qty="+qty;
929				    post_data += "&ctg="+ctg;
930				    post_data += "&journeyNumber="+journeyNumber;
931				    //post_data += "&specQty="+specQty;
932				    //post_data += "&spec="+spec;
933
934
935				    cw_add_sb('.cw-sb', true, post_data, function() {
936					    removeButton.hide();
937					    updateButton.hide();
938					    qtySelect.hide();
939					    addButton.show();
940					    cw_stop_loading(cont);
941				    }, 'remvehicles');
942
943				    return false;
944			    });
945
946		$(component_container)
947		/**
948		 * Update car selection, uses cw_ajax=rep
949		 */
950			.on('change', '.cw-choosedetails-veh', function() {
951				    var cont = $(this).closest('.cw-choosedetails-veh-ctg');
952				    var args = {};
953
954				    cw_start_loading(cont);
955
956				    $(cont).each(function() {
957					    $('.cw-submit-data', this).each(function() {
958						    args[$(this).attr('name')] = $(this).val();
959					    });
960				    });
961
962				    cw_add_sb('.cw-sb', true, args, function(){
963					    $('.cw-btn-rem-vehicles', $('.cw-choosedetails-veh-details')).hide();
964					    $('.cw-btn-upd-vehicles', $('.cw-choosedetails-veh-details')).hide();
965					    $('.cw-btn-add-vehicles', $('.cw-choosedetails-veh-details')).show();
966					    cw_stop_loading(cont);
967				    }, 'rep');
968			    })
969		/**
970		 * Removes the corresponding cabin selection row
971		 */
972		.on('click', '.cw-remove-cabin-row', function(){
973		    var cabin_container = $(this).closest('.cw-cabin-category-cont');
974		    var cabin_selector = $('.cw-cabin-select', cabin_container);
975			var cabin_type = $('.cw-cabin-select-type', cabin_container);
976			var cabins_cont = cabin_container.closest('.cw-cabin-ctgs-cont');
977		    cabin_selector.val(0).trigger('change');
978			var cabin_type_containers = cabins_cont.children('.cw-cabin-category-cont');
979			var amount_cabin_types = 0;
980			cabin_type_containers.each(function(i, element) {
981				var cabin_type = $('.cw-cabin-select-type', element).val();
982				if( 0 != cabin_type ) {
983					amount_cabin_types++;
984				}
985			});
986
987			var max_cabin_types = cabin_type.attr('data-cw-max-cabin-types');
988
989		    // Add a new placeholder row if this is our only row
990		    if(cabins_cont.find('.cw-cabin-category-cont').length === 1) {
991			    cabin_type.val(0).trigger('change');
992		    } else {
993			    $(cabin_container).remove();
994		    }
995
996			// Add cabin container if we removed the last one
997			if(amount_cabin_types >= max_cabin_types) {
998				add_cabin_container(cabins_cont.children().first());
999			}
1000
1001	    })
1002		/**
1003		 * Show the hidden cabins/seats selection on mobile view
1004		 */
1005			.on('click', '.cw-edit-selected-seats, .cw-selected-seats-name, .cw-selected-seats-qty ', function(){
1006				    var cont = $(this ).closest('.cw-choosedetails-cab-cont' );
1007				    if(cont.hasClass('selected')){
1008					    cont.removeClass('selected');
1009				    }
1010			    })
1011		/**
1012		 * Show moreinfo content of the corresponding cabins/seats
1013		 */
1014			.on('click', '.cw-cabin-moreinfo', function(e){
1015				    e.preventDefault();
1016
1017				    var options = cw_prepare_custom_fancybox_options();
1018				    options.href = $(this).attr('href') + '?popup #in-popup';
1019				    options.type = 'ajax';
1020				    options.afterLoad = function() {
1021					    init_gallery(100);
1022				    };
1023
1024				    $.fancybox.open(options);
1025
1026				    return false;
1027			    })
1028		/**
1029		 * Update cabin selection, uses cw_ajax=rep
1030		 */
1031			.on('change', '.cw-choosedetails-cab', function() {
1032				    var cont = $(this).closest('.cw-choosedetails-cab-ctg');
1033				    var args = {};
1034
1035				    cw_start_loading(cont);
1036
1037				    $(cont).each(function() {
1038					    $('.cw-submit-data', this).each(function() {
1039						    args[$(this).attr('name')] = $(this).val();
1040					    });
1041				    });
1042
1043				    cw_add_sb('.cw-sb', true, args, function(){
1044					    $('.cw-btn-rem-cabins', $('.cw-choosedetails-cab-details')).hide();
1045					    $('.cw-btn-upd-cabins', $('.cw-choosedetails-cab-details')).hide();
1046					    $('.cw-btn-add-cabins', $('.cw-choosedetails-cab-details')).show();
1047					    cw_stop_loading(cont);
1048				    }, 'rep');
1049			    })
1050		/**
1051		 * Update passengers, uses cw_ajax=remadd
1052		 */
1053			.on('change', '.cw-choosedetails-pax', function() {
1054				    var cont = $(this).closest('.cw-choosedetails-pax-ctg');
1055				    var args = {};
1056
1057				    cw_start_loading(cont);
1058
1059				    $(cont).each(function() {
1060					    $('.cw-submit-data', this).each(function() {
1061						    args[$(this).attr('name')] = $(this).val();
1062					    });
1063				    });
1064
1065				    cw_add_sb('.cw-sb', true, args, function(){
1066					    var hide = true;
1067					    $('.cw-choosedetails-pax', component_container).each(function() {
1068						    if($(this).val() > 0) {
1069							    hide = false;
1070						    }
1071					    });
1072
1073					    if(hide) {
1074						    $('.cw-action-next', component_container).hide();
1075					    } else {
1076						    $('.cw-action-next', component_container).show();
1077					    }
1078
1079					    cw_stop_loading(cont);
1080				    }, 'remadd');
1081			    });
1082
1083		if($('.cw-current-component').hasClass('cw-name-assignment')){
1084			if(cabin_container.length > 0){
1085				choosedetails_controller.set_default_names(cabin_container.find('.cw-cabin.cw-requires-names'));
1086				var action_row = cabin_container.find('.cw-cabin.cw-requires-names .cw-action-buttons .cw-cabin-action-row');
1087				action_row.find('.cw-cabin-select').each(function(){
1088					if($(this).val() > 0){
1089						$(this).trigger('change', [{ isInit: true }]);
1090					}
1091				});
1092			}
1093		}
1094	});
1095
1096	var choosedetails_controller = function() {
1097
1098		/**
1099		 * Runs updrow_using_update ajax request to update shopping basket
1100		 * based on the selected ctg/spec/specQty, qty, startDate
1101		 * @param element
1102		 * @param quantity
1103		 * @param dont_run_add_sb
1104		 */
1105		function change_ctg_qty(element, quantity, dont_run_add_sb) {
1106			var el = $(element);
1107			var container = el.parents(".cw-action-buttons" );
1108			quantity = (typeof(quantity) != 'undefined' && quantity != null ? quantity : el.val());
1109			var category = container.data("category");
1110			var journeyNumber = container.data("journeynumber");
1111			var bookas = container.data("bookas") ? container.data("bookas") : false;
1112			var spec = container.data("spec") ? container.data("spec") : false;
1113			var plus_minus_cont = el.closest('.cw-plusminus-container');
1114			var start_date_field = $('.cw-field-startDate', plus_minus_cont);
1115			var dep_code_field = $('.cw-field-depCode', plus_minus_cont);
1116			var start_date = false;
1117			var dep_code = false;
1118
1119			var type = container.data("cw-type");
1120			var specQty = container.data("specqty");
1121
1122
1123			/* from cabins
1124
1125			var qty = $('.cw-cabin-qty:selected', container).val();
1126			var ctg = field.attr("ctg");
1127			var maxqty = field.attr("maxqty");
1128
1129			var spec = $('.cw-cabin-spec-option:selected', container ).val();
1130			var specQty = $('.cw-cabin-spec-quantity:selected', container ).val();
1131			var post_data = "";
1132			post_data += "&match_spec=true";
1133			post_data += "&qty="+qty;
1134			post_data += "&ctg="+ctg;
1135			post_data += "&journeyNumber="+journeyNumber;
1136
1137			if( spec ) {
1138				post_data += "&spec="+spec;
1139				post_data += "&specQty="+specQty;
1140				post_data += "&updateBySpecQty=true";
1141			}
1142			*/
1143
1144
1145			// If ctg has multiple spec take the spec code from the clicked element
1146			if( container.hasClass('cw-has-multiple-spec') ) {
1147				spec = el.data('spec');
1148			}
1149			if( start_date_field.length > 0  ) {
1150				start_date = start_date_field.val();
1151			}
1152			if( dep_code_field.length > 0 ) {
1153				dep_code = dep_code_field.val();
1154			}
1155
1156			var post_data = "qty="+quantity+
1157			                "&ctg="+category+
1158			                "&journeyNumber="+ journeyNumber +
1159			                (bookas ? "&bookAs="+bookas : '')+
1160			                (spec ? "&spec="+spec : '')+
1161			                (start_date ? "&startDate="+start_date : '')+
1162			                (dep_code ? "&depCode="+dep_code : '');
1163
1164			post_data += "&match_spec=true";
1165			if ( spec ) {
1166				if ( specQty ) {
1167					post_data += "&specQty="+specQty;
1168					post_data += "&updateBySpecQty=true";
1169				}
1170			}
1171
1172			post_data += "&type=" + type;
1173			post_data += "&notifyOnComponentError=true";
1174
1175			if($('.cw-current-component').hasClass('cw-name-assignment') && el.parents('.cw-meal').hasClass('cw-requires-names') && dont_run_add_sb) {
1176				cw_standard_choosedetails_controller.choosedetails.show_hide_name_buttons('.cw-meal',
1177				                                                                          '.cw-meal-spec-cont',
1178				                                                                          'h4',
1179				                                                                          el,
1180				                                                                          post_data);
1181				return false;
1182			}
1183			cw_add_sb('.cw-sb', true, post_data, function(data) {
1184
1185				if($('.cw-current-component').hasClass('cw-name-assignment') && el.parents('.cw-meal').hasClass('cw-requires-names')){
1186					if( typeof data === 'object') {
1187						if( data.rownum ) {
1188							var old_rownum = el.data('cw-rownum');
1189							if (old_rownum && old_rownum != data.rownum ) {
1190								// update existing name block's rownum to avoid duplicating name blocks
1191								el.parents('.cw-meal').find('.cw-linked-names-block.cw-rownum-' + old_rownum)
1192									.removeClass('cw-rownum-' + old_rownum)
1193									.addClass('cw-rownum-' + data.rownum);
1194							}
1195							el.data('cw-rownum', data.rownum);
1196						}
1197					}
1198					cw_standard_choosedetails_controller.choosedetails.show_hide_name_buttons('.cw-meal',
1199					                                                                          '.cw-meal-spec-cont',
1200					                                                                          'h4',
1201					                                                                          el,
1202					                                                                          post_data);
1203				}
1204
1205			}, 'updrow_using_update');
1206		}
1207
1208		function set_default_names(cont){
1209			cont.find('.cw-field-qty').each(function(){
1210				if($(this).val() >= 1){
1211					$(this).trigger('change', [{ isInit: true }]);
1212				}
1213			});
1214		}
1215		function change_name_cloned_div(names_container, qty_dropdown, item_data = []) {
1216			// names already assigned to current
1217			var namelist_group_array;
1218			// need string value
1219			var namelist_rownums = "" + $(qty_dropdown).data('cw-namelist-rownum');
1220			if( namelist_rownums) {
1221				//does not support names grouping (i.e. cabins with berth qty > 1), so converts names on a category to a flat list
1222				namelist_group_array = namelist_rownums.replace(';', ',').split(',');
1223			}
1224			names_container.find('input').each( function(){
1225				var checked = namelist_group_array && namelist_group_array.includes(""+$(this).data('cw-name-rownum'));
1226				var name_template = $(this).data('cw-name-template');
1227				// template is [{ROWNUM}][{JRYNUM}_{CTG}_{QTY}_{SPEC}_{SPECQTY}]
1228				name_template = name_template.replace('{JRYNUM}', item_data['journeyNumber'] ? item_data['journeyNumber'] : "");
1229				name_template = name_template.replace('{CTG}', item_data['ctg'] ? item_data['ctg'] : "");
1230				name_template = name_template.replace('{QTY}', item_data['qty'] ? item_data['qty'] : "");
1231				name_template = name_template.replace('{SPEC}', item_data['spec'] ? item_data['spec'] : "");
1232				name_template = name_template.replace('{SPECQTY}', item_data['specQty'] ? item_data['specQty'] : "");
1233				name_template = name_template.replace('{ROWNUM}', qty_dropdown.data('cw-rownum'));
1234
1235				$(this).prop('name', name_template);
1236
1237				var id_template = $(this).data('cw-id-template');
1238				id_template = id_template.replace('{JRYNUM}', item_data['journeyNumber'] ? item_data['journeyNumber'] : "");
1239				id_template = id_template.replace('{CTG}', item_data['ctg'] ? item_data['ctg'] : "");
1240				id_template = id_template.replace('{QTY}', item_data['qty'] ? item_data['qty'] : "");
1241				id_template = id_template.replace('{ROWNUM}', qty_dropdown.data('cw-rownum'));
1242
1243				$(this).prop('id', id_template);
1244				$(this).next('label').prop('for', id_template);
1245
1246				if( checked ) {
1247					$(this).prop('checked', true);
1248					$(this).next('label').addClass('cw-chosen-name');
1249				}
1250			});
1251		}
1252
1253		/**
1254		 * adds/updates/removes linked names row for the selected cabin/meal/misc
1255		 *
1256		 * @param main_div_class - class of the container for particular cabin/meal/misc category
1257		 * @param item_div_class - class for the category+spec+specQty selection
1258		 * @param label_selector - selector to find item label, to copy it's content to names block label
1259		 * @param qty_dropdown   - just changed dropdown
1260		 * @param query_string   - query string sent to cw_add_sb(), parsed into array and used to get needed params
1261		 */
1262		function show_hide_name_buttons(main_div_class, item_div_class, label_selector, qty_dropdown, query_string){
1263			var main_div = qty_dropdown.closest(main_div_class);
1264			var item_div = qty_dropdown.closest(item_div_class);
1265			var item_data = [];
1266			query_string.split("&").forEach( function(item) {
1267				item_data[item.split("=")[0]] = item.split("=")[1];
1268			});
1269
1270			var qty = parseInt(qty_dropdown.find('option:selected').val());
1271
1272			var names_div_selector = '.cw-linked-names-block.cw-rownum-' + qty_dropdown.data('cw-rownum');
1273
1274			if(qty == 0){
1275				main_div.find(names_div_selector).remove();
1276				qty_dropdown.data('cw-namelist-rownum', '');
1277			} else {
1278				if ( !main_div.find(names_div_selector).length) {
1279					var new_div = $('<div></div>').addClass('cw-linked-names-block').addClass('cw-rownum-' + qty_dropdown.data('cw-rownum'));
1280
1281					var cloned_div = main_div.find('.cw-linked-names-template').clone();
1282
1283					cloned_div.children('input').prop('checked', false);
1284					cloned_div.children('input').prop('disabled', false);
1285					cloned_div.removeClass('cw-linked-names-template').removeClass('hidden').show();
1286					new_div.append(cloned_div);
1287					main_div.append(new_div);
1288				}
1289				// TODO should look also at berths num for cabins
1290				main_div.find(names_div_selector).data('cw-max-names', qty).attr('cw-max-names', qty);
1291				main_div.find(names_div_selector).find('.cw-assign-names-cabin-label').text(item_div.find(label_selector).text());
1292				change_name_cloned_div(main_div.find(names_div_selector), qty_dropdown, item_data);
1293			}
1294		}
1295
1296		/**
1297		 * Hides on the day price if it is the same with today's price
1298		 * Or on the day price is not set
1299		 *
1300		 * @param price_container - container for today's and on the day prices
1301		 * @param group - choose details group name
1302		 */
1303		var hide_on_the_day_price = function( price_container, group ) {
1304			if( price_container.length > 0 ) {
1305				price_container.each( function() {
1306					var cont = $(this);
1307					var has_multiple_prices = true;
1308
1309					// When we have only one price,  on the day price is hidden
1310					// For cabins - when ctg price is included
1311					// For misc and meals - when today's price is the only price
1312					switch( group) {
1313						case 'cabins':
1314							if( $('.cw-cabin-group-price-included', cont).length > 0 ) {
1315								has_multiple_prices = false;
1316							}
1317							break;
1318						case 'misc':
1319						case 'meals':
1320						case 'ashore':
1321							if( $('.cw-only-one-price', cont).length > 0 ) {
1322								has_multiple_prices = false;
1323							}
1324							break;
1325						default:
1326							break;
1327					}
1328
1329					if( true === has_multiple_prices ) {
1330						var todays_price = $('.cw-todays-price', cont).data('cw-todays-price');
1331						var on_the_day_price_cont = $('.cw-on-the-day-price', cont);
1332						var on_the_day_price = $('.price', on_the_day_price_cont).data('cw-price');
1333
1334						todays_price = parseFloat(todays_price).toFixed(2);
1335						on_the_day_price = parseFloat(on_the_day_price).toFixed(2);
1336
1337						// Hide on the day price if it's not set
1338						if( isNaN(on_the_day_price) ) {
1339							on_the_day_price_cont.addClass('cw-price-not-found');
1340						}
1341
1342						// Hide on the day price if it's the same with today's price
1343						if( todays_price === on_the_day_price ) {
1344							on_the_day_price_cont.addClass('cw-identical-on-the-day-price');
1345						}
1346					}
1347				});
1348			}
1349		};
1350		return {
1351			hide_on_the_day_price: hide_on_the_day_price,
1352			show_hide_name_buttons: show_hide_name_buttons,
1353			set_default_names: set_default_names,
1354			change_ctg_qty: change_ctg_qty
1355		};
1356	}();
1357
1358	return {
1359		choosedetails: choosedetails_controller
1360	};
1361})(jQuery, CarresWeb);

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.