1function structcombolookup_change_narrowby(select, disableChild) {
2    var $narowingSelect = jQuery(select),
3        id = $narowingSelect.data('childId'),
4        option = $narowingSelect.children("option:selected").val(),
5        $targetSelect = jQuery(document.getElementById(id)); // id may contain special chars
6
7    //show all
8    $targetSelect.find("option").show();
9    if (option === '') {
10        $targetSelect.find("option").removeAttr("selected");
11        $targetSelect.find("option").first().attr("selected", "selected");
12        if (disableChild) $targetSelect.attr('disabled', 'disabled');
13    } else {
14        if (disableChild) $targetSelect.removeAttr('disabled');
15        $targetSelect.find("option[data-parent!='"+option+"']").hide();
16    }
17}
18
19jQuery(function($) {
20    return function () {
21        $.widget( "custom.structcombolookup", {
22            _create: function() {
23                this.wrapper = $( "<span>" )
24                    .addClass( "custom-structcombolookup" )
25                    .insertAfter( this.element );
26
27                this.element.hide();
28                this._createAutocomplete();
29                this._createShowAllButton();
30            },
31
32            _createAutocomplete: function() {
33                var selected = this.element.children( ":selected" ),
34                    value = selected.val() ? selected.text() : "";
35
36                this.input = $( "<input>" )
37                    .appendTo( this.wrapper )
38                    .val( value )
39                    .attr( "title", "" )
40                    .addClass( "custom-structcombolookup-input ui-widget ui-widget-content ui-state-default ui-corner-left" )
41                    .autocomplete({
42                        delay: 0,
43                        minLength: 0,
44                        source: $.proxy( this, "_source" )
45                    })
46                    .tooltip({
47                        classes: {
48                            "ui-tooltip": "ui-state-highlight"
49                        }
50                    });
51
52                this._on( this.input, {
53                    autocompleteselect: function( event, ui ) {
54                        ui.item.option.selected = true;
55                        this._trigger( "select", event, {
56                            item: ui.item.option
57                        });
58                    },
59
60                    autocompletechange: "_removeIfInvalid"
61                });
62            },
63
64            _createShowAllButton: function() {
65                var input = this.input,
66                    wasOpen = false;
67
68                $( "<a>" )
69                    .attr( "tabIndex", -1 )
70                    .attr( "title", "Show All Items" )
71                    .tooltip()
72                    .appendTo( this.wrapper )
73                    .button({
74                        icons: {
75                            primary: "ui-icon-triangle-1-s"
76                        },
77                        text: false
78                    })
79                    .removeClass( "ui-corner-all" )
80                    .addClass( "custom-structcombolookup-toggle ui-corner-right" )
81                    .on( "mousedown", function() {
82                        wasOpen = input.autocomplete( "widget" ).is( ":visible" );
83                    })
84                    .on( "click", function() {
85                        input.trigger( "focus" );
86
87                        // Close if already visible
88                        if ( wasOpen ) {
89                            return;
90                        }
91
92                        // Pass empty string as value to search for, displaying all results
93                        input.autocomplete( "search", "" );
94                    });
95            },
96
97            _source: function( request, response ) {
98                var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
99                response( this.element.children( "option" ).map(function() {
100                    var text = $( this ).text();
101                    if ( this.value && ( !request.term || matcher.test(text) ) )
102                        return {
103                            label: text,
104                            value: text,
105                            option: this
106                        };
107                }) );
108            },
109
110            _removeIfInvalid: function( event, ui ) {
111
112                // Selected an item, nothing to do
113                if ( ui.item ) {
114                    return;
115                }
116
117                // Search for a match (case-insensitive)
118                var value = this.input.val(),
119                    valueLowerCase = value.toLowerCase(),
120                    valid = false;
121                this.element.children( "option" ).each(function() {
122                    if ( $( this ).text().toLowerCase() === valueLowerCase ) {
123                        this.selected = valid = true;
124                        return false;
125                    }
126                });
127
128                // Found a match, nothing to do
129                if ( valid ) {
130                    return;
131                }
132
133                // Remove invalid value
134                this.input
135                    .val( "" )
136                    .attr( "title", value + " didn't match any item" )
137                    .tooltip( "open" );
138                this.element.val( "" );
139                this._delay(function() {
140                    this.input.tooltip( "close" ).attr( "title", "" );
141                }, 2500 );
142                this.input.autocomplete( "instance" ).term = "";
143            },
144
145            _destroy: function() {
146                this.wrapper.remove();
147                this.element.show();
148            }
149        });
150
151        $( ".struct_combolookup" ).structcombolookup();
152    };
153}(jQuery));
154