Project

General

Profile

Download (6.73 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * Expected dom structure:
3
 *  <div class="form-item form-type-checkbox form-item-search-areas-area-0-4f854b84-2d93-4b0d-a40d-9e05be7cbae1">
4
        <input
5
            id="edit-search-areas-area-0-4f854b84-2d93-4b0d-a40d-9e05be7cbae1"
6
            name="search[areas][area][0][4f854b84-2d93-4b0d-a40d-9e05be7cbae1]"
7
            value="4f854b84-2d93-4b0d-a40d-9e05be7cbae1"
8
            class="form-checkbox" type="checkbox">
9
        <label class="option" for="edit-search-areas-area-0-4f854b84-2d93-4b0d-a40d-9e05be7cbae1">
10
            <span class="parents">Pacific (6) &gt; Northwestern Pacific (62) &gt; </span>Marianas (MRN)
11
        </label>
12
    </div>
13
 */
14

    
15
// see also https://github.com/geetarista/jquery-plugin-template/blob/master/jquery.plugin-template.js
16

    
17
// the semi-colon before function invocation is a safety net against concatenated
18
// scripts and/or other plugins which may not be closed properly.
19
;(function($, document, window, undefined) {
20

    
21

    
22
    // Name the plugin so it's only in one place
23
    var pluginName = 'search_area_filter';
24

    
25
    // Default options for the plugin as a simple object
26
    var defaults = {
27
    };
28

    
29
    function Plugin(element, filter_text_selector, options) {
30

    
31
        this.element = element;
32
        this.text_field = $(filter_text_selector);
33
        this.form_items;
34
        this.checked_items_container;
35

    
36
        // firebug console stub (avoids errors if firebug is not active)
37
        if (typeof console === "undefined") {
38
            console = {
39
                log: function () {
40
                }
41
            };
42
        }
43

    
44
        // Merge the options given by the user with the defaults
45
        this.options = $.extend({}, defaults, options);
46

    
47
        // Attach data to the elment
48
        this.$el      = $(element);
49
        this.$el.data(name, this);
50

    
51
        this._defaults = defaults;
52

    
53
        var meta = this.$el.data(name + '-opts');
54
        this.opts = $.extend(this._defaults, options, meta);
55

    
56
        // Initialization code to get the ball rolling
57
        // If your plugin is simple, this may not be necessary and
58
        // you could place your implementation here
59
        this.init();
60
    }
61

    
62
    Plugin.prototype = {
63
        // Public functions accessible to users
64
        // Prototype methods are shared across all elements
65
        // You have access to this.options and this.element
66
        // If your plugin is complex, you can split functionality into more
67
        // methods like this one
68

    
69
        init: function () {
70
            // Plugin initializer - prepare your plugin
71

    
72
            var timer;
73

    
74
            // init
75
            var form_item_container = this.$el;
76

    
77
            form_items = form_item_container.find('.form-checkboxes').find('.form-item');
78
            // --- add container for labels of checked items
79
            checked_items_container = $('<div class="checked-items clearfix"></div>');
80
            this.text_field.before(checked_items_container);
81

    
82
            form_items.find('input:checked').each(function(){
83
                handle_item_checked($(this));
84
            });
85

    
86

    
87
            this.text_field.keyup(function () {
88
                clearTimeout(timer);
89
                timer = setTimeout(filter_elements($(this).val()), 1000);
90
            });
91

    
92
            form_items.children('input').change(function (e) {
93
                handle_item_checked($(this));
94
            });
95
        }
96
    };
97

    
98
    $.fn[pluginName] = function(options) {
99
        // Iterate through each DOM element and return it
100
        return this.each(function() {
101
            // prevent multiple instantiations
102
            if (!$.data(this, 'plugin_' + pluginName)) {
103
                $.data(this, 'plugin_' + pluginName, new Plugin(this, options));
104
            }
105
        });
106
    };
107

    
108

    
109
    var handle_item_checked = function(item){
110

    
111
        var label = item.siblings('label');
112

    
113
        console.log('input of ' + label.text() + ' changed to ' + (item.is(':checked') ? '1':'0'));
114

    
115
        if (item.is(':checked')) {
116
            checked_items_container.append('<div class="selected-item-label" data-cdm-checked="' + item.val() + '">' + label.text() + '</div>');
117
        } else {
118
            // i was trying to use  an attribute selector 'div[data-cdm-checked="' + target.val() + '"' here,
119
            // but it did not work at all,
120
            // so looping over the children seems to be the better approach
121
            checked_items_container.children().each(function(index, element){
122
                var el = $(element);
123
                if(el.attr('data-cdm-checked') == item.val()){
124
                    console.log('   removing');
125
                    el.remove();
126
                }
127
            });
128
        }
129
    };
130

    
131
    var filter_elements = function(entered_text){
132

    
133
        console.log('entered text: ' + entered_text);
134

    
135
        // --- remove all highlighting and
136
        // --- hide all form items except checked items which always must be visible
137
        form_items.each(function(){
138
            var form_item_container = $(this);
139
            if(form_item_container.children(':checked').length == 0){
140
                form_item_container.hide();
141
            }
142
            var matching_label = form_item_container.find('.child-label');
143
            matching_label.html(matching_label.text());
144
        });
145

    
146

    
147
        if(entered_text.length > 0){
148

    
149
            var matching_items = form_items.filter(function(){
150
                return $(this).text().toLowerCase().contains(entered_text.toLowerCase());
151
            });
152

    
153
            // --- highlite the matching text
154
            var rexgexp = new RegExp(entered_text, 'i');
155
            matching_items.each(function(){
156
                var matching_label = $(this).find('.child-label');
157
                var matching_snippet = matching_label.text().match(rexgexp);
158
                if(matching_snippet.length > 0){
159
                    // NOTE this will only highlite the first match in the string
160
                    matching_label.html(matching_label.text().replace(matching_snippet[0], '<span class="highlite">' + matching_snippet[0] + '</span>'));
161
                }
162
            });
163
            matching_items.show();
164

    
165
            // --- also show the options of parent areas
166
            var parent_uuids = [];
167
            matching_items.find('span.parent').each(function(){
168
                var parent_uuid = $(this).attr('data-cdm-parent');
169
                if(parent_uuids.indexOf(parent_uuid) == -1){
170
                    parent_uuids.push(parent_uuid);
171
                }
172
            });
173

    
174
            parent_uuids.forEach(function(uuid, index, array) {
175
                // form-item-search-areas-area-0-bda3f9fb-30cf-43fd-8d17-5e4d69545ed5"
176
                // TODO make the class attribute prefix configurable!
177
                $('.form-item-search-areas-area-0-' + uuid).show();
178
            });
179
        } else {
180
            form_items.show();
181
        }
182

    
183
    };
184

    
185

    
186
})(jQuery, document, window);
187

    
(13-13/15)