PageSourceSearch

https://www.cruiseabout.com.au/wp-content/plugins/cruiseappy/js/public.search.js?ver=1787639569

js cruiseabout.com.au collected 2026-09-25 01:20:32 UTC 90,924 bytes, 1,778 lines download raw bytes

1(function($){
2    let $search_form = $("#search-form");
3    let $selectize;
4    let $datepicker = $(".datepicker");
5    let $search_table_form = $(".search-table-form");
6    let $new_page;
7
8
9/*
10==========================================================================
11
12     ######  ########    ###    ########   ######  ##     ##    ########     ###    ########
13    ##    ## ##         ## ##   ##     ## ##    ## ##     ##    ##     ##   ## ##   ##     ##
14    ##       ##        ##   ##  ##     ## ##       ##     ##    ##     ##  ##   ##  ##     ##
15     ######  ######   ##     ## ########  ##       #########    ########  ##     ## ########
16          ## ##       ######### ##   ##   ##       ##     ##    ##     ## ######### ##   ##
17    ##    ## ##       ##     ## ##    ##  ##    ## ##     ##    ##     ## ##     ## ##    ##
18     ######  ######## ##     ## ##     ##  ######  ##     ##    ########  ##     ## ##     ##
19
20==========================================================================
21*/
22
23        if ($search_form.length > 0) {
24        	setTimeout(function(){
25	            let $options = $.ajax({
26	                method: 'POST',
27	                url: cruiseappy.ajax_url,
28	                data: {
29	                    action: 'PublicSearchSelectize'
30	                },
31	                dataType: 'json'
32	            });
33
34	            $options.done(function(data){
35	                $selectize = $('#selectize_input').selectize({
36	                    valueField: 'name',
37	                    labelField: 'test',
38	                    plugins: ['remove_button'],
39	                    searchField: ['name', 'alias'/*, 'type'*/],
40	                    sortField: [
41	                        { field: 'destination', direction: 'asc' },
42	                        { field: 'cruiseline', direction: 'asc' },
43	                        { field: 'ship', direction: 'asc' },
44	                        { field: 'port', direction: 'asc' },
45	                        { field: 'traveltype', direction: 'asc' },
46	                        { field: 'cruise_code', direction: 'asc' },
47	                        { field: 'searchmanager', direction: 'asc' },
48	                        { field: '$score' }
49	                    ],
50	                    score: function(search) {
51	                        let score = this.getScoreFunction(search);
52	                        return function(item) {
53	                            return score(item) ? 1 : 0;
54	                        };
55	                    },
56	                    openOnFocus: false,
57	                    maxItems: null,
58	                    options: data.results,
59	                    placeholder: $("#selectize_input").data("label"),
60	                    selectOnTab: true,
61	                    loadThrottle: null,
62	                    persist: false,
63	                    closeAfterSelect: true,
64	                    create: false,
65	                    render: {
66	                        item: function(item, escape) {
67	                            let icon;
68	                            if (item.type === 'cruiseline') {
69	                                icon = '<i class="fas fa-ship fa-fw"></i>';
70	                            } else if (item.type === 'destination') {
71	                                icon = '<i class="fas fa-map-marker-alt fa-fw"></i>';
72	                            } else if (item.type === 'ship') {
73	                                icon = '<i class="fas fa-ship fa-fw"></i>';
74	                            } else if (item.type === 'port') {
75	                                icon = '<i class="fas fa-passport fa-fw"></i>';
76	                            } else if (item.type === 'traveltype') {
77	                                icon = '<i class="fas fa-anchor"></i>';
78	                            } else if (item.type === 'cruise_code') {
79	                                icon = '<i class="fas fa-tag"></i>';
80	                            } else if (item.type === 'searchmanager') {
81	                                icon = '<i class="fas fa-star"></i>';
82	                            }
83
84	                            return '<div class="item item-'+item.type+'" data-post-id="'+item.post_id+'">' +
85	                                (item.name ? '<span class="name">' + item.name + '</span>' : '') +
86	                                (item.type ? '<span class="visuallyhidden type">' + escape(item.type) + '</span>' : '') +
87	                                (icon ? ' <span class="icon">' + icon + '<i class="fas fa-times fa-fw"></i></span>' : '') +
88	                            '</div>';
89	                        },
90	                        option: function(item, escape) {
91	                            let icon;
92	                            let type = escape(item.type);
93	                            if (item.type === 'cruiseline') {
94	                                icon = '<i class="fas fa-ship"></i>';
95	                                type = cruiseappy.labels.cruiseline;
96	                            } else if (item.type === 'destination') {
97	                                icon = '<i class="fas fa-map-marker-alt"></i>';
98	                                type = cruiseappy.labels.destination;
99	                            } else if (item.type === 'ship') {
100	                                icon = '<i class="fas fa-ship"></i>';
101	                                type = cruiseappy.labels.ship;
102	                            } else if (item.type === 'port') {
103	                                icon = '<i class="fas fa-passport"></i>';
104	                                type = cruiseappy.labels.depart_port;
105	                            } else if (item.type === 'traveltype') {
106	                                icon = '<i class="fas fa-anchor"></i>';
107	                                type = cruiseappy.labels.travel_type;
108	                            } else if (item.type === 'cruise_code') {
109	                                icon = '<i class="fas fa-tag"></i>';
110	                                type = 'Cruise Number';
111	                            } else if (item.type === 'searchmanager') {
112	                                icon = '<i class="fas fa-star"></i>';
113	                                type = 'Search Manager';
114	                            }
115
116	                            return '<div div class="option option-'+item.type+'">' +
117	                                (item.type ? '<span class="type">'+icon+' ' + type + '</span>' : '') +
118	                                (item.name ? '<span class="name"> ' + item.name + '</span>' : '') +
119	                                (item.alias ? '<span class="visuallyhidden"> ' + escape(item.alias) + '</span>' : '') +
120	                            '</div>';
121	                        }
122	                    },
123	                    onItemAdd: function(value, item) {
124	                        this.clearOptions();
125	                        this.renderCache = {};
126
127	                        let $type, $post_id;
128
129	                        if (item.context) {
130	                            $type = context.childNodes[1].innerText.toLowerCase();
131	                                if (!$type) {
132	                                    $type = context.childNodes[1].innerHTML.toLowerCase();
133	                                }
134	                        } else {
135	                            $type = item[0].childNodes[1].innerText.toLowerCase();
136	                                if (!$type) {
137	                                    $type = item[0].childNodes[1].innerHTML.toLowerCase();
138	                                }
139
140	                            $post_id = item[0].dataset.postId;
141	                        }
142
143	                        if ($type === 'port') { $type = 'departport'; }
144
145	                        $("select[name='"+$type+"[]']", $search_form).append('<option value="'+($post_id && $post_id !== 'undefined' ? $post_id : value)+'" selected>'+value+'</option>');
146
147	                        $("#selectize_input-selectized").val(" ").focus();
148	                    },
149	                    onItemRemove: function(value, item) {
150	                        this.clearOptions();
151	                        this.renderCache = {};
152
153	                        let $type, $post_id;
154
155	                        if (item.context) {
156	                            $type = context.childNodes[1].innerText.toLowerCase();
157	                                if (!$type) {
158	                                    $type = context.childNodes[1].innerHTML.toLowerCase();
159	                                }
160	                        } else {
161	                            $type = item[0].childNodes[1].innerText.toLowerCase();
162	                                if (!$type) {
163	                                    $type = item[0].childNodes[1].innerHTML.toLowerCase();
164	                                }
165
166	                            $post_id = item[0].dataset.postId;
167	                        }
168
169	                        if ($type === 'port') { $type = 'departport'; }
170
171	                        $("select[name='"+$type+"[]'] option[value='"+($post_id && $post_id !== 'undefined' ? $post_id : value)+"']", $search_form).remove();
172	                    }
173	                });
174
175                    if ($('#selectize_input')[0]) {
176                        $selectize = $('#selectize_input')[0].selectize;
177                    }
178	            });
179	        }, 100);
180
181            // Date From / To
182                const search_datepicker_from = document.getElementById('search-datepicker-from');
183                const search_datepicker_to = document.getElementById('search-datepicker-to');
184                let $columns = 1;
185
186                if (!search_datepicker_to) {
187                    /* If there's no 'to' field then it must be a date range */
188                    $columns = 2;
189                }
190
191                if (search_datepicker_from) {
192                    const picker_from = new Litepicker({
193                        element: search_datepicker_from,
194                        plugins: ['mobilefriendly'],
195                        singleMode: ($columns === 1 ? true : false),
196                        format: 'D MMM YYYY',
197                        minDate: (cruiseappy.custom.min_date ? cruiseappy.custom.min_date : moment().format('YYYY-MM-DD')),
198                        tooltipNumber: (totalDays) => { return 0; },
199                        autoApply: (cruiseappy.labels.apply && cruiseappy.labels.cancel ? false : true),
200                        buttonText: {
201                            apply: cruiseappy.labels.apply,
202                            cancel: cruiseappy.labels.cancel
203                        },
204                        /*resetButton: () => {
205                           let btn = document.createElement('button');
206                           btn.innerHTML = '<i class="fas fa-times-circle"></i>';
207                           return btn;
208                        },*/
209                        switchingMonths: 1,
210                        numberOfColumns: $columns,
211                        numberOfMonths: $columns,
212                        lang: cruiseappy.language,
213                        setup: (picker_from) => {
214                            search_datepicker_from.addEventListener('input', (evt) => {
215                                if (search_datepicker_from.value === '') {
216                                    picker_from.clearSelection();
217                                }
218                            });
219
220                            picker_from.on('selected', (date_from, date_to) => {
221                                $search_form.find("input[name='date_from']").val(moment(date_from.dateInstance).format('YYYY-MM-DD'));
222
223                                $(document).trigger("date-from", [{
224                                    date: moment(date_from.dateInstance).format('YYYY-MM-DD')
225                                }]);
226
227                                if (!search_datepicker_to) {
228                                    // If there's no 'to' field then we populate date_two with the 2nd date from the range.
229                                    $search_form.find("input[name='date_to']").val(moment(date_to.dateInstance).format('YYYY-MM-DD'));
230                                }
231
232                                updateSearchOptions($selectize);
233                            }).on('clear:selection', () => {
234                                $search_form.find("input[name='date_from']").val('');
235
236                                updateSearchOptions($selectize);
237                            }).on('before:show', () => {
238                                $(document).trigger("litepicker-open");
239                            });
240
241                            $('.reset').on('click',function(){
242                                picker_from.clearSelection();
243                            });
244                        }
245                    });
246                }
247
248            // Date To
249                if (search_datepicker_to) {
250                    const picker_to = new Litepicker({
251                        element: search_datepicker_to,
252                        plugins: ['mobilefriendly'],
253                        singleMode: true,
254                        format: 'D MMM YYYY',
255                        minDate: moment().format('YYYY-MM-DD'),
256                        tooltipNumber: (totalDays) => { return 0; },
257                        /*resetButton: () => {
258                           let btn = document.createElement('button');
259                           btn.innerHTML = '<i class="fas fa-times-circle"></i>';
260                           return btn;
261                        },*/
262                        numberOfColumns: 1,
263                        numberOfMonths: 1,
264                        lang: cruiseappy.language,
265                        setup: (picker_to) => {
266                            search_datepicker_to.addEventListener('input', (evt) => {
267                                if (search_datepicker_to.value === '') {
268                                    picker_to.clearSelection();
269                                }
270                            });
271
272                            picker_to.on('selected', (date) => {
273                                $search_form.find("input[name='date_to']").val(moment(date.dateInstance).format('YYYY-MM-DD'));
274
275                                updateSearchOptions($selectize);
276                            }).on('clear:selection', () => {
277                                $search_form.find("input[name='date_to']").val('');
278
279                                updateSearchOptions($selectize);
280                            }).on('before:show', () => {
281                                $(document).trigger("litepicker-open");
282                            });
283
284                            $('.reset').on('click',function(){
285                                picker_to.clearSelection();
286                            });
287                        }
288                    });
289
290                    $(document).on("date-from", function($event, $response){
291                        picker_to.setOptions({
292                            minDate: $response.date
293                        });
294
295                        var from = new Date($('#search-datepicker-from').val());
296                        var to = new Date($('#search-datepicker-to').val());
297                        var parseFrom = Date.parse(from);
298                        var parseTo = Date.parse(to);
299
300                        if (!parseTo){
301                            picker_to.setDate($response.date);
302
303                        }
304
305                        if (parseTo && parseFrom > parseTo){
306                            picker_to.setDate($response.date);
307                        }
308                    });
309                }
310
311
312            $(document).on("click", ".selectize-input .item", function(){
313                $(this).find(".remove").trigger('click');
314            });
315
316            $("input, select", $search_form).on("change", function(){
317                updateSearchOptions($selectize);
318            });
319
320            $(".meta-adults select").on("change", function(){
321                let $this = $(this);
322                let $thisVal = Number($this.find(":selected").val());
323                let $total = 4;
324                let $difference = ($total - $thisVal);
325
326                $(".meta-children select option").removeAttr("disabled");
327                $(".meta-children select option:gt("+$difference+")").attr("disabled", "disabled");
328                $(".meta-children select").niceSelect('update');
329            });
330
331            $(".meta-children select").on("change", function(){
332                let $this = $(this);
333                let $thisVal = Number($this.find(":selected").val());
334                let $total = 3;
335                let $difference = (($total + 1) - $thisVal);
336
337                $(".meta-children-age").css("display", "flex");
338
339                if ($thisVal > 0) {
340                    $(".search-form-children").css("display", "flex");
341                    $(".meta-children-age:gt("+($thisVal - 1)+")").hide();
342                } else {
343                    $(".search-form-children").css("display", "none");
344                }
345
346                $(".meta-adults select option").removeAttr("disabled");
347                $(".meta-adults select option:gt("+$difference+")").attr("disabled", "disabled");
348                $(".meta-adults select").niceSelect('update');
349            });
350
351            $(".reset", $search_form).on("click", function(){
352                $selectize.clear();
353                $search_form.find("input:checkbox").prop("checked", false);
354                $search_form.find("select.hidden").html("");
355                $search_form.find("select:not(.hidden)").val("").niceSelect('update');
356                $search_form.find(".search-form-children").hide();
357                $(".cancelBtn").trigger("click");
358                updateSearchOptions($selectize);
359            });
360
361        }
362
363/*
364==========================================================================
365
366    ########    ###    ########  ##       ########
367       ##      ## ##   ##     ## ##       ##
368       ##     ##   ##  ##     ## ##       ##
369       ##    ##     ## ########  ##       ######
370       ##    ######### ##     ## ##       ##
371       ##    ##     ## ##     ## ##       ##
372       ##    ##     ## ########  ######## ########
373
374==========================================================================
375*/
376
377    $search_table_form.on("trigger-table-search", function(){
378        let $this = $(this);
379
380        LogError("trigger-table-search");
381
382        $.ajax({
383            method: 'POST',
384            url: cruiseappy.ajax_url,
385            data: {
386                action: 'PublicSearchResults',
387                type: $this.find("input[name='type']").val(),
388                layout: $this.find("input[name='layout']").val(),
389                max_results: $this.find("input[name='max_results']").val(),
390                order: $this.find("input[name='order']").val(),
391                sm_cruises: $this.find("input[name='sm_cruises']").val(),
392				sm_campaigns: $this.find("input[name='sm_campaigns']").val(),
393                duration_from: $this.find("input[name='duration_from']").val(),
394                duration_to: $this.find("input[name='duration_to']").val(),
395                date_from: $this.find("input[name='date_from']").val(),
396                date_to: $this.find("input[name='date_to']").val(),
397                price_min: $this.find("input[name='price_min']").val(),
398                price_max: $this.find("input[name='price_max']").val(),
399                cruiseline: $this.find("input[name='cruiseline[]']").val(),
400                ship: $this.find("input[name='ship[]']").val(),
401                traveltype: $this.find("input[name='traveltype[]']").val()
402            },
403            dataType: 'json',
404            success: function($response) {
405                $(document).trigger("search-table-results", {
406                    target: $this.find("input[name='target']").val(),
407                    search: $response
408                });
409            }
410        });
411    });
412
413    if ($search_table_form.length > 0) {
414        $search_table_form.trigger("trigger-table-search");
415    }
416
417/*
418==========================================================================
419
420     ######  ########    ###    ########   ######  ##     ##    ########  ########  ######  ##     ## ##       ########  ######
421    ##    ## ##         ## ##   ##     ## ##    ## ##     ##    ##     ## ##       ##    ## ##     ## ##          ##    ##    ##
422    ##       ##        ##   ##  ##     ## ##       ##     ##    ##     ## ##       ##       ##     ## ##          ##    ##
423     ######  ######   ##     ## ########  ##       #########    ########  ######    ######  ##     ## ##          ##     ######
424          ## ##       ######### ##   ##   ##       ##     ##    ##   ##   ##             ## ##     ## ##          ##          ##
425    ##    ## ##       ##     ## ##    ##  ##    ## ##     ##    ##    ##  ##       ##    ## ##     ## ##          ##    ##    ##
426     ######  ######## ##     ## ##     ##  ######  ##     ##    ##     ## ########  ######   #######  ########    ##     ######
427
428==========================================================================
429*/
430
431        let $search = $("#search_container");
432
433        if ($search.length > 0) {
434            let $searchURL = window.location.href.split("?");
435                $searchURL = $searchURL[0];
436            let $clear = true;
437            let $documentWidth = $(window).width();
438            let $results = $(".search-results", $search);
439            let $filters = $("#filters");
440            let $quicksearch = $("#quicksearch");
441            let $actions = $("#search_actions");
442            let $sorting = $(".sort-area");
443            let $action_bar = $("#search_action_bar");
444            let $load_trigger = 0;
445            let $delay, $min, $max;
446
447            // Actions
448                $filters.find("input[name='type']").val("all");
449                updateSearch();
450
451                $(document).on("click", "#search_actions li", function(){
452                    let $this = $(this);
453                    let $thisType = $this.attr("data-type");
454                    let $thisContent = $this.attr("data-content");
455
456                    if ($thisType === 'regional') {
457
458                        $filters.find("input[name='regional']").prop("checked", false);
459
460                    } else if ($thisType === 'flexibility') {
461
462                        $("select[name='flexibility']", $search).val('');
463
464                    } else if ($thisType === 'family') {
465
466                        $filters.find("input[name='family']").prop("checked", false);
467
468                    } else if ($thisType === 'single') {
469
470                        $filters.find("input[name='single']").prop("checked", false);
471
472                    } else if ($thisType === 'duration_from') {
473
474                        $filters.find("input[name='duration_from']").val('');
475
476                    } else if ($thisType === 'duration_to') {
477
478                        $filters.find("input[name='duration_to']").val('');
479
480                    } else if ($thisType === 'date') {
481
482                        $("input.filter_datepicker").val('');
483                        $("input[name='date_from']", $search).val('');
484                        $("input[name='date_to']", $search).val('');
485
486                        $(document).trigger("filter-date-clear");
487
488                    } else if ($thisType === 'adults') {
489
490                        $("#quick-adults").val(0);
491                        $("#quick-adults option:first").prop("selected", true);
492                        $("#quick-adults").niceSelect("update");
493
494                    } else if ($thisType === 'children') {
495
496                        $("#quick-children").val(0);
497                        $("#quick-children option:first").prop("selected", true);
498                        $("#quick-children").niceSelect("update");
499
500                    } else if ($thisType === 'cruise_code') {
501
502                        $filters.find("input[name='"+$thisType+"[]'][value='"+$thisContent+"']").remove();
503
504                    } else if ($thisType === 'search_manager') {
505
506                        $filters.find("input[name='searchmanager[]'][value='"+$thisContent+"']").remove();
507
508                    } else if ($thisType === 'visitport' || $thisType === 'visit_port') {
509
510                        $filters.find("input[name='visitport[]'][value='"+$thisContent+"']").remove();
511
512                    } else if ($thisType === 'departport' || $thisType === 'depart_port') {
513
514                        $filters.find("input[name='departport[]'][value='"+$thisContent+"']").remove();
515
516                    } else if ($thisType === 'reset') {
517
518                        $("#search_action_bar").hide();
519                        $("#search_actions li").not(".action-reset").trigger("click");
520
521                    } else {
522
523                        $filters.find("input[name='"+$thisType+"[]'][value='"+$thisContent+"']").prop("checked", false);
524
525                    }
526
527                    $this.remove();
528                    updateSearch();
529                });
530
531                $(document).on("click", "[data-sort][data-order]", function(){
532                    let $this = $(this);
533                    let $thisSort = $this.attr("data-sort");
534                    let $thisOrder = $this.attr("data-order");
535
536                    if ($this.hasClass("pg-active") && $.inArray($thisSort, ['best_value', 'most_popular']) === -1){
537                        if ($thisOrder === 'ASC') {
538                            if ($thisSort === 'min_price' && $thisOrder === 'ASC') {
539                                $thisSort = 'max_price';
540                            }
541                            $this.attr("data-order", 'DESC');
542                            $("i", $this).removeClass("fa-caret-up").addClass("fa-caret-down");
543                            $filters.find("input[name='order']").val($thisSort+' DESC');
544                        } else {
545                            if ($thisSort === 'max_price' && $thisOrder === 'DESC') {
546                                $thisSort = 'min_price';
547                            }
548                            $this.attr("data-order", 'ASC');
549                            $("i", $this).removeClass("fa-caret-down").addClass("fa-caret-up");
550                            $filters.find("input[name='order']").val($thisSort+' ASC');
551                        }
552                    } else {
553                        $filters.find("input[name='order']").val($thisSort+' '+$thisOrder);
554                    }
555
556                    $(".filters span.pg-active").removeClass("pg-active");
557                    $this.addClass("pg-active");
558
559                    $results.html('<p class="loading">'+Spinner(cruiseappy.labels.loading_search)+'</p>');
560
561                    updateSearch();
562                });
563
564                $(document).on("change", "select[name='sort']", function(){
565                    let $this = $(this);
566                    let $thisVal = $this.find("option:selected").val();
567
568                    $filters.find("input[name='order']").val($thisVal);
569                    $results.html('<p class="loading">'+Spinner(cruiseappy.labels.loading_search)+'</p>');
570                    updateSearch();
571                });
572
573                function updateSearch() {
574                    clearTimeout($delay);
575                    $delay = setTimeout(function(){
576                        $results.html('<p class="loading">'+Spinner(cruiseappy.labels.loading_search)+'</p>');
577                        $filters.trigger("manual_change");
578                    }, 500);
579                }
580
581            // Filters
582                if ($documentWidth <= 767) { $filters.find("input[name='limit']").val(cruiseappy.search.results_limit_mobile); }
583
584                $(document).on("click", ".show_more", function(e){
585                    if (!e) e = window.event;
586                    e.cancelBubble = true;
587                    if (e.stopPropagation) e.stopPropagation();
588
589                    let $this = $(this);
590                    let $thisParent = $this.parent();
591                    $this.hide();
592                    $(".more, .show_less", $thisParent).show();
593                });
594
595                $(document).on("click", ".show_less", function(e){
596                    if (!e) e = window.event;
597                    e.cancelBubble = true;
598                    if (e.stopPropagation) e.stopPropagation();
599
600                    let $this = $(this);
601                    let $thisParent = $this.parent();
602
603                    $this.hide();
604                    $(".more", $thisParent).hide();
605                    $(".show_more", $thisParent).show();
606                });
607
608                $(".filter_search").on("keyup", function(){
609                    let $this = $(this);
610                    let $thisType = $this.attr("data-type");
611                    let $thisVal = $this.val();
612                    $thisVal = $thisVal.toLowerCase();
613
614					console.log($thisVal);
615
616                    if ($thisVal === '') {
617                        $("#"+$thisType+"_list li:lt(6)").show();
618                        $("#"+$thisType+"_list li:gt(6)").hide();
619                    } else {
620                        $("#"+$thisType+"_list li:not(:contains("+$thisVal+"))").hide();
621                        $("#"+$thisType+"_list li:contains("+$thisVal+")").show();
622                    }
623                });
624
625                $(document).on("click", ".list_more", function(){
626                    let $this = $(this);
627                    let $thisType = $this.attr("data-type");
628                    let $thisShow = $this.attr("data-show");
629                    	if (!$thisShow) { $thisShow = 20; }
630                    let $thisPosition = $("#"+$thisType+"_list").offset();
631
632                    if ($this.hasClass("toggle-class")) {
633                    	$("#"+$thisType+"_list").toggleClass("show");
634                    } else {
635	                    if ($("#"+$thisType+"_list li:eq(6)").is(":visible")) {
636	                        $("#"+$thisType+"_list li:gt(5)").not("#"+$thisType+"_list li[data-checked='1']").hide();
637	                    } else {
638	                        $("#"+$thisType+"_list li:lt("+$thisShow+")").not("#"+$thisType+"_list li[data-total='0']").show();
639	                    }
640	                }
641
642                    $this.find("> span").toggle();
643                });
644
645                $(document).on("focus", "#filters input[name='friendly_date']", function(){
646                    let $this = $(this);
647                    let $thisVal = $this.val();
648
649                    $this.val('').hide();
650                    $filters.find("input[name='display_depart']").show().trigger('focus');
651                    $(".datepicker").find(".active.day").removeClass("active");
652                });
653
654                $("#quick-adults").on("change", function(){
655                    let $this = $(this);
656                    let $thisVal = Number($this.find(":selected").val());
657                    let $total = 4;
658                    let $difference = ($total - $thisVal);
659
660                    $("#quick-children option").removeAttr("disabled");
661                    $("#quick-children option:gt("+$difference+")").attr("disabled", "disabled");
662                    $("#quick-children").niceSelect('update');
663                    updateSearch();
664                });
665
666                $("#quick-children").on("change", function(){
667                    let $this = $(this);
668                    let $thisVal = Number($this.find(":selected").val());
669                    let $total = 3;
670                    let $difference = ($total - $thisVal);
671
672                    $(".select-container-children-age").css("display", "flex");
673
674                    if ($thisVal > 0) {
675                        $(".select-container-children-age:gt("+($thisVal - 1)+")").hide();
676                        $(".select-container-children-age:gt("+($thisVal - 1)+") option:eq(1)").prop("selected", true);
677                        $(".select-container-children-age:gt("+($thisVal - 1)+") select").niceSelect("update");
678                    } else {
679                        $(".select-container-children-age").css("display", "none");
680                        $("#children_age_1 option:eq(1), #children_age_2 option:eq(1), #children_age_3 option:eq(1)").prop("selected", true);
681                        $("#children_age_1, #children_age_2, #children_age_3").niceSelect("update");
682                    }
683
684                    $("#quick-adults option").removeAttr("disabled");
685                    $("#quick-adults option:gt("+$difference+")").attr("disabled", "disabled");
686                    $("#quick-adults").niceSelect('update');
687                    updateSearch();
688                });
689
690                $("#children_age_1, #children_age_2, #children_age_3").on("change", function(){
691                    updateSearch();
692                });
693
694                $(document).on("change", "#filters input[type='checkbox'], #filters select", function(){
695                    let $searchContainer = $("#search_container").offset();
696
697                    if ($(this).attr("name") !== 'order') { // Re-ordering the results doesn't need to trigger a filter update.
698                        $filters.find("input[name='type']").val("all");
699                    }
700
701                    $("html, body").animate({ scrollTop: ($searchContainer.top - 100) }, { duration: 500, complete: function(){
702                        $results.html('<p class="loading">'+Spinner(cruiseappy.labels.loading_search)+'</p>');
703                        $("input[name='leaf']").val(0);
704                        updateSearch();
705                    }});
706                });
707
708            $(document).on("click", ".load_more", function(){
709                let $this = $(this);
710                let $thisLeaf = $this.attr("data-leaf");
711
712                $this.html(Spinner(cruiseappy.labels.loading_search));
713
714                $clear = false;
715                //$this.remove();
716
717                $("input[name='type']").val("results");
718                $("input[name='leaf']").val($thisLeaf);
719                updateSearch();
720            });
721
722            $(document).on("click", ".pages span", function(){
723                let $this = $(this);
724                let $thisLeaf = $this.attr("data-leaf");
725                let $searchContainer = $("#search_container").offset();
726
727                $new_page = true;
728
729                $("html, body").animate({ scrollTop: ($searchContainer.top - 100) }, { duration: 500, complete: function(){
730                    $results.html('<p class="loading">'+Spinner(cruiseappy.labels.loading_search)+'</p>');
731
732                    $clear = false;
733
734                    $("input[name='type']").val("results");
735                    $("input[name='leaf']").val($thisLeaf);
736
737                    updateSearch();
738                }});
739            });
740
741            $(document).on("click", ".layouts span", function(){
742                let $this = $(this);
743                let $thisLayout = $this.attr("data-layout");
744                let $searchContainer = $("#search_container").offset();
745
746                $("html, body").animate({ scrollTop: ($searchContainer.top - 100) }, { duration: 500, complete: function(){
747                    $results.html('<p class="loading">'+Spinner(cruiseappy.labels.loading_search)+'</p>');
748
749                    $clear = false;
750                    //$this.remove();
751
752                    $(".layout .pg-active").removeClass("pg-active");
753                    $(".layout span[data-layout='"+$thisLayout+"']").addClass("pg-active");
754
755                    $filters.find("input[name='type']").val("results");
756                    $filters.find("input[name='layout']").val($thisLayout);
757                    updateSearch();
758                }});
759            });
760
761            $(document).on("click", "#fab-filters" ,function(e){
762                e.stopPropagation();
763
764                $("#search_container .sidebar").animate({ scrollTop: 0 }, { duration: 1 });
765                $("html, body, #search_container .sidebar, #filter_background").addClass("open");
766            });
767
768            $(document).on("click", function(){
769                $("html.open, body.open, #search_container, #filter_background.open").removeClass("open");
770            });
771
772            $("#mobile-filters-close, #mobile-filters-header").on("click", function(){
773                $("html.open, body.open, #search_container, .sidebar.open, #filter_background.open").removeClass("open");
774            });
775
776            /* Breaks niceselect in filters sidebar */
777            /*$("#search_container .sidebar").on("click",function(e){
778                e.stopPropagation();
779            });*/
780
781            const filter_datepicker_range = document.getElementById('filter-datepicker');
782
783            if (filter_datepicker_range) {
784                const filter_picker_range = new Litepicker({
785                    element: filter_datepicker_range,
786                    plugins: ['mobilefriendly'],
787                    singleMode: false,
788                    format: (cruiseappy.custom.filter_date_format ? cruiseappy.custom.filter_date_format : 'D MMMM YYYY'),
789                    tooltipNumber: (totalDays) => { return 0; },
790                    numberOfColumns: 2,
791                    numberOfMonths: 2,
792                    // minDate: moment(),
793                    minDate: (cruiseappy.custom.min_date ? cruiseappy.custom.min_date : moment().format('YYYY-MM-DD')),
794                    lang: cruiseappy.language,
795                    setup: (filter_picker_range) => {
796                        filter_datepicker_range.addEventListener('input', (evt) => {
797                            if (filter_datepicker_range.value === '') {
798                                filter_picker_range.clearSelection();
799                            }
800                        });
801
802                        filter_picker_range.on('selected', (date1, date2) => {
803                            $filters.find("input[name='date_from']").val(moment(date1.dateInstance).format('YYYY-MM-DD'));
804                            $filters.find("input[name='date_to']").val(moment(date2.dateInstance).format('YYYY-MM-DD'));
805
806                            updateSearch();
807                        }).on('clear:selection', () => {
808                            $filters.find("input[name='date_from']").val('');
809                            $filters.find("input[name='date_to']").val('');
810
811                            updateSearch();
812                        }).on('before:show', () => {
813                            $(document).trigger("litepicker-open");
814                        });
815                    }
816                });
817            }
818
819            const filter_datepicker_from = document.getElementById('filter-datepicker-from');
820            const filter_datepicker_to = document.getElementById('filter-datepicker-to');
821
822            if (filter_datepicker_from && filter_datepicker_to) {
823                const filter_picker_from = new Litepicker({
824                    element: filter_datepicker_from,
825                    plugins: ['mobilefriendly'],
826                    singleMode: true,
827                    format: (cruiseappy.custom.filter_date_format ? cruiseappy.custom.filter_date_format : 'D MMMM YYYY'),
828                    // minDate: moment().format('YYYY-MM-DD'),
829                    minDate: (cruiseappy.custom.min_date ? cruiseappy.custom.min_date : moment().format('YYYY-MM-DD')),
830                    tooltipNumber: (totalDays) => { return 0; },
831                    numberOfColumns: 1,
832                    numberOfMonths: 1,
833                    lang: cruiseappy.language,
834                    setup: (filter_picker_from) => {
835                        filter_datepicker_from.addEventListener('input', (evt) => {
836                            if (filter_datepicker_from.value === '') {
837                                filter_picker_from.clearSelection();
838                            }
839                        });
840
841                        filter_picker_from.on('selected', (date) => {
842                            $filters.find("input[name='date_from']").val(moment(date.dateInstance).format('YYYY-MM-DD'));
843
844                            $(document).trigger("filter-date-from", [{
845                                date: moment(date.dateInstance).format('YYYY-MM-DD')
846                            }]);
847
848                            updateSearch();
849                        }).on('clear:selection', () => {
850                            $filters.find("input[name='date_from']").val('');
851
852                            updateSearch();
853                        }).on('before:show', () => {
854                            $(document).trigger("litepicker-open");
855                        });
856                    }
857                });
858
859                const filter_picker_to = new Litepicker({
860                    element: filter_datepicker_to,
861                    plugins: ['mobilefriendly'],
862                    singleMode: true,
863                    format: (cruiseappy.custom.filter_date_format ? cruiseappy.custom.filter_date_format : 'D MMMM YYYY'),
864                    // minDate: moment().format('YYYY-MM-DD'),
865                    minDate: (cruiseappy.custom.min_date ? cruiseappy.custom.min_date : moment().format('YYYY-MM-DD')),
866                    tooltipNumber: (totalDays) => { return 0; },
867                    numberOfColumns: 1,
868                    numberOfMonths: 1,
869                    lang: cruiseappy.language,
870                    setup: (filter_picker_to) => {
871                        filter_datepicker_to.addEventListener('input', (evt) => {
872                            if (filter_datepicker_to.value === '') {
873                                filter_picker_to.clearSelection();
874                            }
875                        });
876
877                        filter_picker_to.on('selected', (date) => {
878                            $filters.find("input[name='date_to']").val(moment(date.dateInstance).format('YYYY-MM-DD'));
879
880                            updateSearch();
881                        }).on('clear:selection', () => {
882                            $filters.find("input[name='date_to']").val('');
883
884                            updateSearch();
885                        }).on('before:show', () => {
886                            $(document).trigger("litepicker-open");
887                        });
888                    }
889                });
890
891                $(document).on("filter-date-from", function($event, $response){
892                    filter_picker_to.setOptions({
893                        minDate: $response.date
894                    });
895
896                    var from = new Date($('#filter-datepicker-from').val());
897                    var to = new Date($('#filter-datepicker-to').val());
898                    var parseFrom = Date.parse(from);
899                    var parseTo = Date.parse(to);
900
901                    if (!parseTo){
902                        filter_picker_to.setDate($response.date);
903
904                    }
905
906                    if (parseTo && parseFrom > parseTo){
907                        filter_picker_to.setDate($response.date);
908                    }
909                });
910
911                $(document).on("filter-date-clear", function($event, $response){
912                    filter_picker_from.clearSelection();
913                    filter_picker_to.clearSelection();
914                });
915            } else if (filter_datepicker_from) {
916                const filter_picker_from = new Litepicker({
917                    element: filter_datepicker_from,
918                    plugins: ['mobilefriendly'],
919                    singleMode: true,
920                    format: (cruiseappy.custom.filter_date_format ? cruiseappy.custom.filter_date_format : 'D MMMM YYYY'),
921                    // minDate: moment().format('YYYY-MM-DD'),
922                    minDate: (cruiseappy.custom.min_date ? cruiseappy.custom.min_date : moment().format('YYYY-MM-DD')),
923                    tooltipNumber: (totalDays) => { return 0; },
924                    numberOfColumns: 2,
925                    numberOfMonths: 2,
926                    lang: cruiseappy.language,
927                    setup: (filter_picker_from) => {
928                        filter_datepicker_from.addEventListener('input', (evt) => {
929                            if (filter_datepicker_from.value === '') {
930                                filter_picker_from.clearSelection();
931                            }
932                        });
933
934                        filter_picker_from.on('selected', (date) => {
935                            $filters.find("input[name='date_from']").val(moment(date.dateInstance).format('YYYY-MM-DD'));
936                            $filters.find("input[name='date_to']").val(moment(date.dateInstance).format('YYYY-MM-DD'));
937
938                            $(document).trigger("filter-date-from", [{
939                                date: moment(date.dateInstance).format('YYYY-MM-DD')
940                            }]);
941
942                            updateSearch();
943                        }).on('clear:selection', () => {
944                            $filters.find("input[name='date_from']").val('');
945
946                            updateSearch();
947                        }).on('before:show', () => {
948                            $(document).trigger("litepicker-open");
949                        });
950                    }
951                });
952            }
953
954            const filter_flex_option = document.getElementById('flex-option');
955            if (filter_flex_option) {
956                $(document).on("change", '#flex-option', function($event){
957                    let $this = $(this);
958                    let $date = $('#filter-datepicker-from').val();
959                    let $flex = Number($('input[name="flex"]').val());
960                    let $new_date_from = moment($date).subtract($flex, "days").format("YYYY-MM-DD");
961                    let $new_date_to = moment($date).add($flex, "days").format("YYYY-MM-DD");
962                    let $status = $this.prop("checked");
963                    if ($status) {
964                        $this.val(1);
965                        $filters.find("input[name='date_from']").val($new_date_from);
966                        $filters.find("input[name='date_to']").val($new_date_to);
967                    } else {
968                        $this.val(0);
969                        $filters.find("input[name='date_from']").val($date);
970                        $filters.find("input[name='date_to']").val($date);
971                    }
972                });
973            }
974
975            // Price Min & Max
976                $(".no-minimum, .up-to").hide();
977
978                $(".quick-slider").slider({
979                    range: true,
980                    min: 0,
981                    max: 50000,
982                    step: 500,
983                    values: [0, 50000],
984                    slide: function(event, ui) {
985                        $min = ui.values[0];
986                            if ($min === 0) { $(".no-minimum").hide(); }
987                            else { $(".no-minimum").show(); }
988                        $max = ui.values[1];
989                            if ($max === 50000) {
990                                $max += '+';
991                                $(".up-to").hide();
992                            } else {
993                                $(".up-to").show();
994                            }
995
996                            if ($min > 0 && $max < 50000) {
997                                $(".up-to").hide();
998                            }
999
1000                            if ($min === 0) {
1001                                $(".up-to").show();
1002                            }
1003
1004                        $("input[name='price_min']").val(ui.values[0]);
1005                        $("input[name='price_max']").val(ui.values[1]);
1006                        $(".slider-label .min").text(AddCurrency($min));
1007                        $(".slider-label .max").text(AddCurrency($max));
1008
1009                        $(".quick-slider").slider("option", "values", ui.values);
1010                    },
1011                    create: function(event, ui){
1012                        $(".quick-slider").slider("option", "values", [
1013                            $("input[name='price_min']").val(),
1014                            $("input[name='price_max']").val()
1015                        ]);
1016
1017                        $min = Number($("input[name='price_min']").val());
1018                            if ($min === 0) { $(".no-minimum").hide(); }
1019                            else { $(".no-minimum").show(); }
1020                        $max = Number($("input[name='price_max']").val());
1021
1022                            if ($max === 50000) {
1023                                $max += '+';
1024                                $(".up-to").hide();
1025                            } else {
1026                                $(".up-to").show();
1027                            }
1028
1029                            if ($min > 0 && $max < 50000) {
1030                                $(".up-to").hide();
1031                            }
1032
1033                            if ($min === 0) {
1034                                $(".up-to").show();
1035                            }
1036
1037                            $(".slider-label .min").text(AddCurrency($min));
1038                            $(".slider-label .max").text(AddCurrency($max));
1039                    },
1040                    stop: function(){ updateSearch(); }
1041                });
1042
1043            // Responsive
1044                $(".toggler.searchmob").on("click", function(){
1045                    let $this = $(this);
1046
1047                    $(".sortmob.actived").removeClass("actived");
1048                    $(".filtermob.actived").removeClass("actived");
1049                    $this.toggleClass("actived");
1050                    $("#search_container .sort-area").slideUp();
1051                    $(".search-results .mobile-hide.sidebar").slideUp();
1052                    $("#search_container .search-options").slideToggle();
1053                });
1054
1055
1056
1057                $(".toggler.sortmob").on("click", function(){
1058                    let $this = $(this);
1059
1060                    $(".filtermob.actived").removeClass("actived");
1061                    $(".searchmob.actived").removeClass("actived");
1062                    $this.toggleClass("actived");
1063                    $("#search_container .search-options").slideUp();
1064                    $(".search-results .mobile-hide.sidebar").slideUp();
1065                    $("#search_container .sort-area").slideToggle();
1066                });
1067
1068                jQuery(".toggler.filtermob").on("click", function(){
1069                    // let $this = $(this);
1070
1071                    // $(".sortmob.actived").removeClass("actived");
1072                    // $(".searchmob.actived").removeClass("actived");
1073                    // $this.toggleClass("actived");
1074                    // // $("#search_container .search-options").slideUp();
1075                    // // $("#search_container .sort-area").slideUp();
1076
1077                    // $(".side-left .widget.filter-search").slideToggle(1000);
1078                });
1079
1080
1081            $filters.on("manual_change", function(){
1082                let $this = $(this);
1083                let $limit = $("input[name='limit']").val();
1084                let $layout = $("input[name='layout']").val();
1085                let $form_data = $this.serialize();
1086
1087                if ($new_page === false) {
1088                	$filters.find("input[name='leaf']").val(0);
1089                }
1090
1091                $new_page = false;
1092
1093                if ($clear) {
1094                    $results.html('<p class="loading">'+Spinner(cruiseappy.labels.loading_search)+'</p>');
1095                }
1096
1097                $("#mobile-filters-close").html(Spinner(cruiseappy.labels.loading_search));
1098                $("input", $search).parent().parent().attr("data-checked", 0);
1099                $("input:checked", $search).parent().parent().attr("data-checked", 1);
1100
1101                // Update Actions
1102                    let $action_array = [];
1103                    let $action_html = '';
1104                    let $action_depart = $("input[name='depart']", $search).val();
1105                    let $action_date = $("input.filter_datepicker", $search).val();
1106                    let $action_date_from = $("input[name='date_from']", $search).val();
1107                    let $action_date_to = $("input[name='date_to']", $search).val();
1108                    let $action_flexibility = $("select[name='flexibility']", $search).val();
1109                    let $action_sort = $("input[name='order']", $search).val().split(" ");
1110                    let $action_adults = $("#quick-adults option:selected").val();
1111                    let $action_children = $("#quick-children option:selected").val();
1112                    let $action_date_string = [];
1113                    let $sm_duration_from = $("input[name='duration_from']").attr('value');
1114                    let $sm_duration_to = $("input[name='duration_to']").attr('value');
1115
1116                    $("li[data-sort='"+$action_sort[0]+"']", $sorting).attr("data-order", $action_sort[1]).addClass("active");
1117
1118                    if ($action_depart) {
1119                        let $action_depart_display = $("input[name='display_depart']", $search).val();
1120                        $action_array.push('<li class="action-date" data-type="date" data-content="'+$action_depart_display+'">'+$action_depart_display+' &nbsp;<i class="fas fa-calendar-alt fa-fw"></i><i class="fas fa-times fa-fw"></i></li>');
1121                    }
1122
1123                    if ($action_date_from || $action_date_to) {
1124                        if ($action_date_from) { $action_date_string.push(moment($action_date_from).format((cruiseappy.custom.date_format ? cruiseappy.custom.date_format : 'D MMM YYYY'))); }
1125                        if ($action_date_to) { $action_date_string.push(moment($action_date_to).format((cruiseappy.custom.date_format ? cruiseappy.custom.date_format : 'D MMM YYYY'))); }
1126
1127                        $action_array.push('<li class="action-date" data-type="date" data-content="'+$action_date_from+'">'+$action_date_string.join(" - ")+' &nbsp;<i class="fas fa-calendar-alt fa-fw"></i><i class="fas fa-times fa-fw"></i></li>');
1128                    }
1129
1130                    /*if ($action_date) {
1131                        $action_array.push('<li class="action-date" data-type="date" data-content="'+$action_date+'">'+$action_date+' &nbsp;<i class="fas fa-calendar-alt fa-fw"></i><i class="fas fa-times fa-fw"></i></li>');
1132                    }*/
1133
1134                    if ($action_adults > 0) {
1135                        $action_array.push('<li class="action-adults" data-type="adults" data-content="'+$action_adults+'">'+$action_adults+' '+cruiseappy.labels.adults+' &nbsp;<i class="fas fa-user fa-fw"></i><i class="fas fa-times fa-fw"></i></li>');
1136                    }
1137
1138                    if ($action_children > 0) {
1139                        $action_array.push('<li class="action-children" data-type="children" data-content="'+$action_children+'">'+$action_children+' '+cruiseappy.labels.children+' &nbsp;<i class="fas fa-baby fa-fw"></i><i class="fas fa-times fa-fw"></i></li>');
1140                    }
1141
1142                    $filters.find("input:checkbox:checked").each(function() {
1143                        let $this = $(this);
1144                        let $thisType = $this.attr("class");
1145                        let $thisVal = $this.val();
1146                        let $thisLabel = $this.attr("data-label");
1147                        let $thisIcon;
1148                        let $value;
1149
1150                        if ($thisType === 'regional') {
1151
1152                            $thisIcon = '<i class="fas fa-globe-europe fa-fw"></i>';
1153                            $value = cruiseappy.labels.regional;
1154
1155                        } else if ($thisType === 'family') {
1156
1157                            $thisIcon = '<i class="fas fa-users fa-fw"></i>';
1158                            $value = 'Family Fares';
1159
1160                        } else if ($thisType === 'single') {
1161
1162                            $thisIcon = '<i class="fas fa-user fa-fw"></i>';
1163                            $value = 'Single Fares';
1164
1165                        } else if ($thisType === 'cruiseline') {
1166
1167                            $thisIcon = '<i class="fas fa-ship fa-fw"></i>';
1168                            $value = $thisVal.replace("-", " ");
1169
1170                        } else if ($thisType === 'ship') {
1171
1172                            $thisIcon = '<i class="fas fa-ship fa-fw"></i>';
1173                            $value = $thisVal.replace("-", " ");
1174
1175                        } else if ($thisType === 'destination') {
1176
1177                            $thisIcon = '<i class="fas fa-map-marker-alt fa-fw"></i>';
1178                            $value = $thisVal.replace("-", " ");
1179
1180                        } else if ($thisType === 'departport' || $thisType === 'depart_port') {
1181
1182                            $thisIcon = '<i class="fas fa-passport fa-fw"></i>';
1183                            $value = $thisVal.replace("-", " ");
1184
1185                        } else if ($thisType === 'visitport' || $thisType === 'visit_port') {
1186
1187                            $thisIcon = '<i class="fas fa-passport fa-fw"></i>';
1188                            $value = $thisVal.replace("-", " ");
1189
1190                        } else if ($thisType === 'duration') {
1191
1192                            $thisIcon = '<i class="fas fa-arrows-alt-h fa-fw"></i>';
1193                            //$value = $thisVal.replace("-", " ");
1194                            $value = $thisVal;
1195
1196                            $filters.find("input[name='duration_from']").val('');
1197                            $filters.find("input[name='duration_to']").val('');
1198                            console.log($sm_duration_from);
1199                            console.log($sm_duration_to);
1200
1201                        } else if ($thisType === 'traveltype') {
1202
1203                            $thisIcon = '<i class="fas fa-anchor fa-fw"></i>';
1204                            $value = $thisVal.replace("-", " ");
1205
1206                        } else if ($thisType === 'cruise_code') {
1207                            $thisIcon = '<i class="fas fa-tag fa-fw"></i>';
1208                            $value = 'Cruise Number';
1209                        } else if ($thisType === 'search_manager') {
1210                            $thisIcon = '<i class="fas fa-star fa-fw"></i>';
1211                            $value = $thisLabel;
1212                        } else if ($thisType === 'flex_option') {
1213                            $thisIcon = '<i class="fas fa-star fa-fw"></i>';
1214                            $value = 'I am flexible';
1215                        }
1216                        
1217
1218                        $action_array.push('<li class="action-'+$thisType+'" data-type="'+$thisType+'" data-content="'+$thisVal+'"><span>'+$value+'</span> &nbsp;'+$thisIcon+'<i class="fas fa-times fa-fw"></i></li>');
1219                    });
1220
1221                    // If no durations are selected, but there is a saved duration from the search manager, re-apply those values.
1222                    // attr('value') is used to get the original value, .val() may have been cleared above.
1223                    if ($('#durations_list li input:checkbox:checked').length === 0) {
1224                        if ($sm_duration_from) {
1225                            $filters.find("input[name='duration_from']").val($sm_duration_from);
1226                            $filters.find("input[name='duration_to']").val($sm_duration_to);
1227                        }
1228                    }
1229
1230                    $filters.find("input.include_filter").each(function() {
1231                        let $this = $(this);
1232                        let $thisType = $this.attr("name");
1233                        let $thisVal = $this.val();
1234                        let $thisIcon;
1235                        let $value;
1236
1237                        if ($thisVal) {
1238                            if ($thisType === 'duration_from') {
1239                                $thisIcon = '<i class="fas fa-long-arrow-alt-right fa-fw"></i>';
1240                                $value = cruiseappy.labels.from+' '+$thisVal.replace("-", " ")+' '+cruiseappy.labels.nights;
1241                            } else if ($thisType === 'duration_to') {
1242                                $thisIcon = '<i class="fas fa-long-arrow-alt-left fa-fw"></i>';
1243                                $value = cruiseappy.labels.to+' '+$thisVal.replace("-", " ")+' '+cruiseappy.labels.nights;
1244                            } else if ($thisType === 'cruise_code') {
1245                                $thisIcon = '<i class="fas fa-tag fa-fw"></i>';
1246                                $value = $thisVal;
1247                            }
1248
1249                            $action_array.push('<li class="action-'+$thisType+'" data-type="'+$thisType+'" data-content="'+$thisVal+'">'+$value+' &nbsp;'+$thisIcon+'<i class="fas fa-times fa-fw"></i></li>');
1250                        }
1251                    });
1252
1253                    if ($action_array.length > 0) {
1254                        $action_array.unshift('<li class="action-reset" data-type="reset">'+cruiseappy.labels.reset+' &nbsp;<i class="fas fa-redo-alt"></i></li>');
1255                        $action_html = $action_array.join('\n');
1256                        $actions.html($action_html);
1257
1258                        $(document).trigger("search-actions", $action_array);
1259
1260                        if ($documentWidth > 767) {
1261                            $action_bar.show();
1262                            $(".search-options").show();
1263                        }
1264                    } else {
1265                        $(".search-options").hide();
1266                        $action_bar.hide();
1267                    }
1268
1269                let $destinations = GetChecked('destination[]');
1270                let $cruiselines = GetChecked('cruiseline[]');
1271                let $ships = GetChecked('ship[]');
1272                let $depart_ports = GetChecked('departport[]');
1273                let $visit_ports = GetChecked('visitport[]');
1274                let $travel_types = GetChecked('traveltype[]');
1275                let $search_managers = GetChecked('searchmanager[]');
1276                let $durations = GetChecked('duration[]');
1277
1278                $.ajax({
1279                    method: 'POST',
1280                    url: cruiseappy.ajax_url,
1281                    data: {
1282                        action: 'PublicQuickSearchResults',
1283                        destination: $destinations,
1284                        cruiseline: $cruiselines,
1285                        ship: $ships,
1286                        departport: $depart_ports,
1287                        visitport: $visit_ports,
1288                        traveltype: $travel_types,
1289                        search_manager: $search_managers,
1290                        date_from: $filters.find("input[name='date_from']").val(),
1291                        date_to: $filters.find("input[name='date_to']").val(),
1292                        adults: $filters.find("select[name='adults']").val(),
1293                        children: $filters.find("select[name='children']").val(),
1294                        duration: $durations,
1295                        children_age_1: $filters.find("select[name='children_age_1']").val(),
1296                        children_age_2: $filters.find("select[name='children_age_2']").val(),
1297                        children_age_3: $filters.find("select[name='children_age_3']").val(),
1298
1299                        type: $filters.find("input[name='type']").val(),
1300                        limit: $filters.find("input[name='limit']").val(),
1301                        leaf: $filters.find("input[name='leaf']").val(),
1302                        price_min: $filters.find("input[name='price_min']").val(),
1303                        price_max: $filters.find("input[name='price_max']").val(),
1304                        max_results: $filters.find("input[name='max_results']").val(),
1305                        layout: $filters.find("input[name='layout']").val(),
1306                        order: $filters.find("input[name='order']").val(),
1307                        singles: $filters.find("input[name='singles']:checked").val(),
1308                        family: $filters.find("input[name='family']:checked").val(),
1309                        regional: $filters.find("input[name='regional']:checked").val(),
1310                        sm_cruises: $filters.find("input[name='sm_cruises']").val(),
1311						sm_campaigns: $filters.find("input[name='sm_campaigns']").val(),
1312                        search_id: $filters.find("input[name='search_id']").val(),
1313                        duration_from: $filters.find("input[name='duration_from']").val(),
1314                        duration_to: $filters.find("input[name='duration_to']").val(),
1315                        group_ids: $filters.find("input[name='group_ids']").val(),
1316                        flex_option: $filters.find("input[name='flex_option']").val(),
1317                        alt_cruise_id: $filters.find("input[name='alt_cruise_id']").val(),
1318                    },
1319                    dataType: 'json',
1320                    success: function(data) {
1321                        $(".results .load_more, .results .loading", $search).remove();
1322                        $load_trigger = 0;
1323                        let $list_html = [];
1324
1325                        if (data.meta.total || data.meta.total === 0) {
1326                            let $totalText = "<span>"+AddCurrency(data.meta.total)+"</span> "+(data.meta.total == 1 ? cruiseappy.labels.cruise_found : cruiseappy.labels.cruises_found);
1327
1328                            if (data.meta.true_total) {
1329                                $totalText = "<span>"+AddCurrency(data.meta.true_total)+"</span> "+(data.meta.true_total == 1 ? cruiseappy.labels.cruise_found : cruiseappy.labels.cruises_found);
1330                            }
1331
1332                            $(".total_cruises").html($totalText);
1333                            $("#mobile-filters-close").html($totalText+' <i class="fas fa-chevron-circle-right"></i>');
1334                        }
1335
1336                        if (typeof TopPagination !== "undefined") {
1337                            TopPagination(data);
1338                        }
1339
1340                        // Update filter Lists
1341                            if (data.cruiselines && data.cruiselines.length > 0) {
1342                            	$filters.find("#cruiselines_list").find("li[data-checked='0']").remove();
1343                            	// $filters.find("#cruiselines_list").find("li[data-checked='1']").find(".total").text('0');
1344
1345                            	$.each(data.cruiselines, function($index, $item) {
1346									if ($item.cruiseline) {
1347                                        let $cruiseline = $item.cruiseline.toLowerCase();
1348										$filters.find("#cruiselines_list").find('li[data-value="'+$cruiseline+'"]').remove();
1349
1350                                        let $thisChecked = ($.inArray($cruiseline, $cruiselines) !== -1 ? true : false);
1351										//let $thisSort = (parseInt(($thisChecked === true ? 1 : 0)+leftPad($item.total, 5)) * 10000);
1352
1353										$list_html.push('<li data-checked="'+($thisChecked === true ? 1 : 0)+'" data-total="'+$item.total+'" data-value="'+$cruiseline+'">');
1354											$list_html.push('<label for="cruiseline_'+$index+'">');
1355												$list_html.push('<input type="checkbox" autocomplete="off" name="cruiseline[]" class="cruiseline" id="cruiseline_'+$index+'" value="'+$cruiseline+'" '+($thisChecked === true ? 'checked' : '')+'>');
1356												$list_html.push('<span>'+$item.cruiseline+'</span> <span class="hidden">'+$cruiseline+'</span> <span class="total">'+AddCommas($item.total)+'</span>');
1357											$list_html.push('</label>');
1358										$list_html.push('</li>');
1359									}
1360                            	});
1361
1362								$filters.find("#cruiselines_list").append($list_html.join("\n"));
1363								$list_html = [];
1364                            }
1365
1366                            if (data.ships && data.ships.length > 0) {
1367                            	$filters.find("#ships_list").find("li[data-checked='0']").remove();
1368                            	// $filters.find("#ships_list").find("li[data-checked='1']").find(".total").text('0');
1369
1370                            	$.each(data.ships, function($index, $item) {
1371									if ($item.ship) {
1372                                        // htmlspecialchars
1373                                        let $ship = htmlspecialchars($item.ship.toLowerCase());
1374										$filters.find("#ships_list").find('li[data-value="'+$ship+'"]').remove();
1375
1376										let $thisChecked = ($.inArray($ship, $ships) !== -1 ? true : false);
1377										//let $thisSort = (parseInt(($thisChecked === true ? 1 : 0)+leftPad($item.total, 5)) * 10000);
1378
1379										$list_html.push('<li data-checked="'+($thisChecked === true ? 1 : 0)+'" data-total="'+$item.total+'" data-value="'+$ship+'">');
1380											$list_html.push('<label for="ship_'+$index+'">');
1381												$list_html.push('<input type="checkbox" autocomplete="off" name="ship[]" class="ship" id="ship_'+$index+'" value="'+$ship+'" '+($thisChecked === true ? 'checked' : '')+'>');
1382												$list_html.push('<span>'+$item.ship+'</span> <span class="hidden">'+$ship+'</span> <span class="total">'+AddCommas($item.total)+'</span>');
1383											$list_html.push('</label>');
1384										$list_html.push('</li>');
1385									}
1386                            	});
1387
1388								$filters.find("#ships_list").append($list_html.join("\n"));
1389								$list_html = [];
1390                            }
1391
1392                            if (data.destinations && data.destinations.length > 0) {
1393                            	$filters.find("#destinations_list").find("li[data-checked='0']").remove();
1394                            	// $filters.find("#destinations_list").find("li[data-checked='1']").find(".total").text('0');
1395
1396                            	$.each(data.destinations, function($index, $item) {
1397                                    if ($item.destination && $item.destination.indexOf('{') == -1) {
1398										$filters.find("#destinations_list").find('li[data-value="'+$item.destination+'"]').remove();
1399
1400                                        let $thisChecked = ($.inArray($item.destination, $destinations) !== -1 ? true : false);
1401
1402                                        if ($thisChecked === false) {
1403                                        	$thisChecked = ($.inArray($item.destination, $search_managers) !== -1 ? true : false);
1404                                        }
1405                                        //let $thisSort = (parseInt(($thisChecked === true ? 1 : 0)+leftPad($item.total, 5)) * 10000);
1406
1407										$list_html.push('<li data-checked="'+($thisChecked === true ? 1 : 0)+'" data-total="'+$item.total+'" data-value="'+$item.destination+'">');
1408											$list_html.push('<label for="destination_'+$index+'">');
1409												$list_html.push('<input type="checkbox" autocomplete="off" name="'+($item.type && $item.type === 'search_manager' ? 'searchmanager[]' : 'destination[]')+'" class="destination" id="destination_'+$index+'" value="'+$item.destination+'" '+($thisChecked === true ? 'checked' : '')+'>');
1410												$list_html.push('<span>'+$item.destination+'</span> <span class="hidden">'+$item.destination.toLowerCase()+'</span> <span class="total">'+AddCommas($item.total)+'</span>');
1411											$list_html.push('</label>');
1412										$list_html.push('</li>');
1413
1414									}
1415                            	});
1416
1417								$filters.find("#destinations_list").append($list_html.join("\n"));
1418								$list_html = [];
1419                            }
1420
1421                            if (data.depart_ports && data.depart_ports.length > 0) {
1422                            	$filters.find("#departport_list").find("li[data-checked='0']").remove();
1423                            	// $filters.find("#departport_list").find("li[data-checked='1']").find(".total").text('0');
1424
1425                            	$.each(data.depart_ports, function($index, $item) {
1426									if ($item.depart_port) {
1427                                        let $depart_port = $item.depart_port.replace('"', '\'');
1428										$filters.find("#departport_list").find('li[data-value="'+$depart_port.toLowerCase()+'"]').remove();
1429
1430										let $thisChecked = ($.inArray($depart_port, $depart_ports) !== -1 ? true : false);
1431										//let $thisSort = (parseInt(($thisChecked === true ? 1 : 0)+leftPad($item.total, 5)) * 10000);
1432
1433										$list_html.push('<li data-checked="'+($thisChecked === true ? 1 : 0)+'" data-total="'+$item.total+'" data-value="'+$depart_port+'">');
1434											$list_html.push('<label for="depart_port_'+$index+'">');
1435												$list_html.push('<input type="checkbox" autocomplete="off" name="departport[]" class="depart_port" id="depart_port_'+$index+'" value="'+$depart_port+'" '+($thisChecked === true ? 'checked' : '')+'>');
1436												$list_html.push('<span>'+$item.depart_port+'</span> <span class="hidden">'+$depart_port.toLowerCase()+'</span> <span class="total">'+AddCommas($item.total)+'</span>');
1437											$list_html.push('</label>');
1438										$list_html.push('</li>');
1439									}
1440                            	});
1441
1442								$filters.find("#departport_list").append($list_html.join("\n"));
1443								$list_html = [];
1444                            }
1445                            if (data.visit_ports && data.visit_ports.length > 0) {
1446                            	$filters.find("#visitport_list").find("li[data-checked='0']").remove();
1447                            	// $filters.find("#visitport_list").find("li[data-checked='1']").find(".total").text('0');
1448
1449                            	$.each(data.visit_ports, function($index, $item) {
1450									if ($item.visit_port) {
1451                                        $item.visit_port.replace('"', '\'');
1452										$filters.find("#visitport_list").find('li[data-value="'+$item.visit_port+'"]').remove();
1453
1454										let $thisChecked = ($.inArray($item.visit_port, $visit_ports) !== -1 ? true : false);
1455										//let $thisSort = (parseInt(($thisChecked === true ? 1 : 0)+leftPad($item.total, 5)) * 10000);
1456
1457										$list_html.push('<li data-checked="'+($thisChecked === true ? 1 : 0)+'" data-total="'+$item.total+'" data-value="'+$item.visit_port+'">');
1458											$list_html.push('<label for="visit_port_'+$index+'">');
1459												$list_html.push('<input type="checkbox" autocomplete="off" name="visitport[]" class="visit_port" id="visit_port_'+$index+'" value="'+$item.visit_port+'" '+($thisChecked === true ? 'checked' : '')+'>');
1460												$list_html.push('<span>'+$item.visit_port+'</span> <span class="hidden">'+$item.visit_port.toLowerCase()+'</span> <span class="total">'+AddCommas($item.total)+'</span>');
1461											$list_html.push('</label>');
1462										$list_html.push('</li>');
1463									}
1464                            	});
1465
1466								$filters.find("#visitport_list").append($list_html.join("\n"));
1467								$list_html = [];
1468                            }
1469
1470                            if (data.durations && data.durations.length > 0) {
1471                            	$filters.find("#durations_list").find("li[data-checked='0']").remove();
1472                            	// $filters.find("#durations_list").find("li[data-checked='1']").find(".total").text('0');
1473
1474                            	$.each(data.durations, function($index, $item) {
1475									if ($item.duration_group) {
1476										$filters.find("#durations_list").find('li[data-value="'+$item.duration_group+'"]').remove();
1477
1478										let $thisChecked = ($.inArray($item.duration_group, $durations) !== -1 ? true : false);
1479										//let $thisSort = (parseInt(($thisChecked === true ? 1 : 0)+leftPad($item.total, 5)) * 10000);
1480
1481										$list_html.push('<li data-checked="'+($thisChecked === true ? 1 : 0)+'" data-total="'+$item.total+'" data-value="'+$item.duration_group+'">');
1482											$list_html.push('<label for="duration_'+$index+'">');
1483												$list_html.push('<input type="checkbox" autocomplete="off" name="duration[]" class="duration" id="duration_'+$index+'" value="'+$item.duration_group+'" '+($thisChecked === true ? 'checked' : '
1483')+'>');
1484												$list_html.push('<span>'+$item.duration_group+'</span> <span class="hidden">'+$item.duration_group.toLowerCase()+'</span> <span class="total">'+AddCommas($item.total)+'</span>');
1485											$list_html.push('</label>');
1486										$list_html.push('</li>');
1487									}
1488                            	});
1489
1490								$filters.find("#durations_list").append($list_html.join("\n"));
1491								$list_html = [];
1492                            }
1493
1494                            if (data.travel_types && data.travel_types.length > 0) {
1495                            	$filters.find("#traveltypes_list").find("li[data-checked='0']").remove();
1496                            	// $filters.find("#traveltypes_list").find("li[data-checked='1']").find(".total").text('0');
1497                            	$.each(data.travel_types, function($index, $item) {
1498									if ($item.cruise_type) {
1499										let $travel_type = $item.cruise_type.toLowerCase();
1500										$filters.find("#traveltypes_list").find('li[data-value="'+$travel_type+'"]').remove();
1501
1502										let $thisChecked = ($.inArray($travel_type, $travel_types) !== -1 ? true : false);
1503										//let $thisSort = (parseInt(($thisChecked === true ? 1 : 0)+leftPad($item.total, 5)) * 10000);
1504
1505										$list_html.push('<li data-checked="'+($thisChecked === true ? 1 : 0)+'" data-total="'+$item.total+'" data-value="'+$travel_type+'">');
1506											$list_html.push('<label for="traveltype_'+$index+'">');
1507												$list_html.push('<input type="checkbox" autocomplete="off" name="traveltype[]" class="traveltype" id="traveltype_'+$index+'" value="'+$travel_type+'" '+($thisChecked === true ? 'checked' : '')+'>');
1508												$list_html.push('<span>'+$item.cruise_type+'</span> <span class="hidden">'+$travel_type+'</span> <span class="total">'+AddCommas($item.total)+'</span>');
1509											$list_html.push('</label>');
1510										$list_html.push('</li>');
1511									}
1512                            	});
1513
1514								$filters.find("#traveltypes_list").append($list_html.join("\n"));
1515								$list_html = [];
1516                            }
1517
1518                        // Reset search
1519                            if ($clear) {
1520                                $results.html('');
1521                                $filters.find("input[name='leaf']").val(0);
1522                            }
1523
1524                        // Update URL
1525                            $url = $filters.serialize();
1526                            history.pushState(null, null, $searchURL+'?'+$url);
1527
1528                        // Populate Results
1529                            if (data.results) {
1530                                let $html = [];
1531                                let $pagination = [];
1532                                let $count = 0;
1533
1534                                if ($layout === 'grid') {
1535                                    $html.push('<div class="search-grid">');
1536                                }
1537
1538                                $.each(data.results, function($i, $item) {
1539                                    if ($layout === 'grid') {
1540                                        gridLayout($item, $html, $count++);
1541                                    } else if ($layout === 'list') {
1542                                        listLayout($item, $html, $count++);
1543                                    } else if ($layout === 'full') {
1544                                        listLayout($item, $html, $count++);
1545                                    }
1546                                });
1547
1548                                if ($layout === 'grid') {
1549                                    $html.push('</div>');
1550                                }
1551
1552                                //if (data.meta.leaf && data.meta.total >= $limit) {
1553                                    let $set_pages = (cruiseappy.search.pagination.pages ? Number(cruiseappy.search.pagination.pages) : 0);
1554
1555                                    let $last = (data.meta.pages - 1);
1556
1557                                    let $start = (data.meta.leaf - ($set_pages + 1));
1558                                        if ($start < 0) { $start = 0; }
1559
1560                                    let $finish = (data.meta.leaf + ($set_pages - 1));
1561                                        if (data.meta.leaf >= $last) { $finish = $last; }
1562                                        if ($finish > data.meta.pages) { $finish = $last; }
1563
1564                                    let $prev = (data.meta.leaf - 2);
1565                                    let $next = data.meta.leaf;
1566
1567                                    if ($finish > 0) {
1568                                        if ($prev >= 0) {
1569                                            if (cruiseappy.search.pagination.first) {
1570                                                $pagination.push('<span class="pg-button" data-leaf="0">'+cruiseappy.search.pagination.first+'</span>');
1571                                            }
1572
1573                                            if (cruiseappy.search.pagination.previous) {
1574                                                $pagination.push('<span class="pg-button" data-leaf="'+$prev+'">'+cruiseappy.search.pagination.previous+'</span>');
1575                                            }
1576                                        }
1577
1578                                        if ($set_pages > 0) {
1579                                            for ($k = $start; $k <= $finish; $k++) {
1580                                                if ($k <= $last) {
1581                                                    let $current = ($k === (data.meta.leaf-1) ? 'pg-active' : '');
1582                                                    $pagination.push('<span class="pg-button page-number '+$current+'" data-leaf="'+$k+'">'+AddCurrency(($k+1))+'</span>');
1583                                                }
1584                                            }
1585                                        }
1586
1587                                        if (data.meta.leaf < data.meta.pages) {
1588                                            if (cruiseappy.search.pagination.next) {
1589                                                $pagination.push('<span class="pg-button" data-leaf="'+$next+'">'+cruiseappy.search.pagination.next+'</span>');
1590                                            }
1591
1592                                            if (cruiseappy.search.pagination.last) {
1593                                                $pagination.push('<span class="pg-button" data-leaf="'+$last+'">'+cruiseappy.search.pagination.last+'</span>');
1594                                            }
1595                                        }
1596                                    }
1597                                //}
1598
1599                                $results.html($html.join("\n"));
1600                                $results.find(".pages").clone().prependTo($results);
1601                                $(".pagination-left").html($pagination.join("\n")).attr("data-page", AddCommas(data.meta.leaf)).attr("data-pages", AddCommas(data.meta.pages));
1602
1603                                $(document).trigger("search-results-loaded", data);
1604                            } else {
1605                                $results.html('<p class="loading">'+cruiseappy.labels.no_cruises_found+'</p>');
1606                            }
1607
1608                        // Show results
1609                            $total_checked = $filters.find("input[type='checkbox']:checked").length;
1610                            if ($total_checked > 0) {
1611                                $filters.find("input[name='type']").val("all");
1612                            }
1613                            $results.animate({ opacity: 1 });
1614                            $clear = false;
1615
1616                        // Scroll to anchor
1617                            $anchor = $filters.find("input[name='anchor']").val();
1618                            if ($anchor !== '') {
1619                                let $last_position = $("li#"+$anchor).position();
1620                                $("html, body").animate({ scrollTop: ($last_position.top - 130) }, { duration: 0 });
1621                                $filters.find("input[name='anchor']").val('');
1622                            }
1623                    }
1624                });
1625            });
1626
1627            $(document).on("click", ".cta.details a", function(e){
1628                let $this = $(this);
1629                let $thisID = $this.attr("data-id");
1630
1631                $filters.find("input[name='anchor']").val($thisID);
1632
1633                $url = $filters.serialize();
1634                history.pushState(null, null, $searchURL+'?'+$url);
1635            });
1636
1637            $total_checked = $filters.find("input[type='checkbox']:checked").length;
1638            if ($total_checked > 0) {
1639                $filters.find("input[name='type']").val("all");
1640            }
1641
1642            $clear = false;
1643            //updateSearch();
1644
1645            $(window).scroll(function(event){
1646                if ($load_trigger === 0) {
1647                    loadMoreResults();
1648                }
1649            });
1650
1651            jQuery.fn.sortElements = (function(){
1652                let sort = [].sort;
1653                return function(comparator, getSortable) {
1654                    getSortable = getSortable || function(){return this;};
1655                    let placements = this.map(function(){
1656                        let sortElement = getSortable.call(this),
1657                            parentNode = sortElement.parentNode,
1658                            nextSibling = parentNode.insertBefore(
1659                                document.createTextNode(''),
1660                                sortElement.nextSibling
1661                            );
1662                        return function() {
1663                            if (parentNode === this) {
1664                                throw new Error(
1665                                    "You can't sort elements if any one is a descendant of another."
1666                                );
1667                            }
1668
1669                            parentNode.insertBefore(this, nextSibling);
1670                            parentNode.removeChild(nextSibling);
1671                        };
1672                    });
1673
1674                    return sort.call(this, comparator).each(function(i){
1675                        placements[i].call(getSortable.call(this));
1676                    });
1677                };
1678            })();
1679        }
1680
1681/*
1682==========================================================================
1683
1684    ######## ##     ## ##    ##  ######  ######## ####  #######  ##    ##  ######
1685    ##       ##     ## ###   ## ##    ##    ##     ##  ##     ## ###   ## ##    ##
1686    ##       ##     ## ####  ## ##          ##     ##  ##     ## ####  ## ##
1687    ######   ##     ## ## ## ## ##          ##     ##  ##     ## ## ## ##  ######
1688    ##       ##     ## ##  #### ##          ##     ##  ##     ## ##  ####       ##
1689    ##       ##     ## ##   ### ##    ##    ##     ##  ##     ## ##   ### ##    ##
1690    ##        #######  ##    ##  ######     ##    ####  #######  ##    ##  ######
1691
1692==========================================================================
1693*/
1694
1695        function loadMoreResults() {
1696            $('.load_more').each(function(){
1697                let $this = $(this);
1698                if (canLoadMoreResults($this)) {
1699                    $this.trigger("click");
1700                    $load_trigger = 1;
1701                }
1702            });
1703        }
1704
1705        function canLoadMoreResults(elem) {
1706            let docViewTop = $(window).scrollTop();
1707            let docViewBottom = docViewTop + $(window).height();
1708
1709            let elemTop = $(elem).offset().top;
1710            let elemBottom = elemTop + $(elem).height();
1711
1712            return (docViewBottom >= elemTop);
1713        }
1714
1715        function leftPad(number, targetLength) {
1716            let output = number + '';
1717            while (output.length < targetLength) {
1718                output = '0' + output;
1719            }
1720            return output;
1721        }
1722
1723        // Define htmlspecialchars function to escape HTML special characters
1724        function htmlspecialchars(str) {
1725            if (typeof str !== 'string') return str;
1726            return str.replace(/&/g, '&amp;')
1727                      .replace(/</g, '&lt;')
1728                      .replace(/>/g, '&gt;')
1729                      .replace(/"/g, '&quot;')
1730                      .replace(/'/g, '&#039;');
1731        }
1732
1733    function updateSearchOptions($selectize) {
1734        $("button", $search_form).attr("disabled","disabled").html('<i class="fa fa-spinner fa-pulse fa-fw"></i>');
1735
1736        $.ajax({
1737            method: 'POST',
1738            url: cruiseappy.ajax_url,
1739            data: {
1740                action: 'PublicSearchSelectize',
1741                search: $search_form.serialize(),
1742                regional: $search_form.find("input[name='regional']:checked").val(),
1743                destination: $search_form.find("select[name='destination[]']").val(),
1744                cruiseline: $search_form.find("select[name='cruiseline[]']").val(),
1745                ship: $search_form.find("select[name='ship[]']").val(),
1746                departport: $search_form.find("select[name='departport[]']").val(),
1747                traveltype: $search_form.find("select[name='traveltype[]']").val(),
1748                searchmanager: $search_form.find("select[name='searchmanager[]']").val(),
1749                date_from: $search_form.find("input[name='date_from']").val(),
1750                date_to: $search_form.find("input[name='date_to']").val(),
1751                adults: $search_form.find("select[name='adults']").val(),
1752                children: $search_form.find("select[name='children']").val(),
1753                duration: $search_form.find("select[name='duration']").val(),
1754                children_age_1: $search_form.find("select[name='children_age_1']").val(),
1755                children_age_2: $search_form.find("select[name='children_age_2']").val(),
1756                children_age_3: $search_form.find("select[name='children_age_3']").val()
1757            },
1758            dataType: 'json',
1759            error: function() {
1760                callback();
1761            },
1762            success: function(data) {
1763                if (data.total > 0 && typeof data.results !== 'undefined') {
1764                    $.when(
1765                        $selectize.addOption(data.results),
1766
1767                        $("button", $search_form).html((cruiseappy.custom.search_button ? cruiseappy.custom.search_button.replace("%s", AddCurrency(data.total)).replace("%p", data.total == 1 ? '' : 's') : AddCurrency(data.total)+' '+(data.total == 1 ? cruiseappy.labels.cruise : cruiseappy.labels.cruises)+' &nbsp; <i class="fa fa-search" aria-hidden="true"></i>'))
1768                    ).done(function(){
1769                        $("button", $search_form).removeAttr("disabled").css("opacity", 1);
1770                    });
1771                } else {
1772                    $("button", $search_form).html((cruiseappy.custom.search_button_none ? cruiseappy.custom.search_button_none : '0 '+cruiseappy.labels.cruises+' &nbsp; <i class="fa fa-search fa-flip-horizontal" aria-hidden="true"></i>'));
1773                }
1774            }
1775        });
1776    }
1777})(this.jQuery);
1778

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.