Project

General

Profile

1
/*! UIkit 2.27.5 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */
2
(function(addon) {
3

    
4
    var component;
5

    
6
    if (window.UIkit2) {
7
        component = addon(UIkit2);
8
    }
9

    
10
    if (typeof define == 'function' && define.amd) {
11
        define('uikit-grid', ['uikit'], function(){
12
            return component || addon(UIkit2);
13
        });
14
    }
15

    
16
})(function(UI){
17

    
18
    "use strict";
19

    
20
    UI.component('grid', {
21

    
22
        defaults: {
23
            colwidth  : 'auto',
24
            animation : true,
25
            duration  : 300,
26
            gutter    : 0,
27
            controls  : false,
28
            filter    : false,
29
            origin    : UI.langdirection
30
        },
31

    
32
        boot:  function() {
33

    
34
            // init code
35
            UI.ready(function(context) {
36

    
37
                UI.$('[data-uk-grid]', context).each(function(){
38

    
39
                    var ele = UI.$(this);
40

    
41
                    if(!ele.data('grid')) {
42
                        UI.grid(ele, UI.Utils.options(ele.attr('data-uk-grid')));
43
                    }
44
                });
45
            });
46
        },
47

    
48
        init: function() {
49

    
50
            var $this = this, gutter = String(this.options.gutter).trim().split(' ');
51

    
52
            this.gutterv  = parseInt(gutter[0], 10);
53
            this.gutterh  = parseInt((gutter[1] || gutter[0]), 10);
54

    
55
            // make sure parent element has the right position property
56
            this.element.css({'position': 'relative'});
57

    
58
            this.controls = null;
59
            this.origin   = this.options.origin;
60

    
61
            if (this.options.controls) {
62

    
63
                this.controls = UI.$(this.options.controls);
64

    
65
                // filter
66
                this.controls.on('click', '[data-uk-filter]', function(e){
67
                    e.preventDefault();
68
                    $this.filter(UI.$(this).attr('data-uk-filter'));
69
                });
70

    
71
                // sort
72
                this.controls.on('click', '[data-uk-sort]', function(e){
73
                    e.preventDefault();
74
                    var cmd = UI.$(this).attr('data-uk-sort').split(':');
75
                    $this.sort(cmd[0], cmd[1]);
76
                });
77
            }
78

    
79
            UI.$win.on('load resize orientationchange', UI.Utils.debounce(function(){
80

    
81
                if ($this.currentfilter) {
82
                    $this.filter($this.currentfilter);
83
                } else {
84
                    this.update();
85
                }
86

    
87
            }.bind(this), 100));
88

    
89
            this.on('display.uk.check', function(){
90
                if ($this.element.is(':visible'))  $this.update();
91
            });
92

    
93
            UI.domObserve(this.element, function(e) {
94
                $this.update();
95
            });
96

    
97
            if (this.options.filter !== false) {
98
                this.filter(this.options.filter);
99
            } else {
100
                this.update();
101
            }
102
        },
103

    
104
        _prepareElements: function() {
105

    
106
            var children = this.element.children().not('[data-grid-prepared]'), css;
107

    
108
            // exit if no already prepared elements found
109
            if (!children.length) {
110
                return;
111
            }
112

    
113
            css = {
114
                position  : 'absolute',
115
                boxSizing : 'border-box',
116
                width     : this.options.colwidth == 'auto' ? '' : this.options.colwidth
117
            };
118

    
119
            if (this.options.gutter) {
120

    
121
                css['padding-'+this.origin] = this.gutterh;
122
                css['padding-bottom'] = this.gutterv;
123

    
124
                this.element.css('margin-'+this.origin, this.gutterh * -1);
125
            }
126

    
127
            children.attr('data-grid-prepared', 'true').css(css);
128
        },
129

    
130
        update: function(elements) {
131

    
132
            var $this = this;
133

    
134
            this._prepareElements();
135

    
136
            elements = elements || this.element.children(':visible');
137

    
138
            var children  = elements,
139
                maxwidth  = this.element.width() + (2*this.gutterh) + 2,
140
                left      = 0,
141
                top       = 0,
142
                positions = [],
143

    
144
                item, width, height, pos, posi, i, z, max, size;
145

    
146
            this.trigger('beforeupdate.uk.grid', [children]);
147

    
148
            children.each(function(index){
149

    
150
                item   = UI.$(this);
151
                size   = this.getBoundingClientRect();
152
                width  = size.width;
153
                height = size.height;
154
                left   = 0;
155
                top    = 0;
156

    
157
                for (i=0,max=positions.length;i<max;i++) {
158

    
159
                    pos = positions[i];
160

    
161
                    if (left <= pos.aX) { left = pos.aX; }
162
                    if (maxwidth < (left + width)) { left = 0; }
163
                    if (top <= pos.aY) { top = pos.aY; }
164
                }
165

    
166
                posi = {
167
                    ele    : item,
168
                    top    : top,
169
                    width  : width,
170
                    height : height,
171
                    aY     : (top  + height),
172
                    aX     : (left + width)
173
                };
174

    
175
                posi[$this.origin] = left;
176

    
177
                positions.push(posi);
178
            });
179

    
180
            var posPrev, maxHeight = 0, positionto;
181

    
182
            // fix top
183
            for (i=0,max=positions.length;i<max;i++) {
184

    
185
                pos = positions[i];
186
                top = 0;
187

    
188
                for (z=0;z<i;z++) {
189

    
190
                    posPrev = positions[z];
191

    
192
                    // (posPrev.left + 1) fixex 1px bug when using % based widths
193
                    if (pos[this.origin] < posPrev.aX && (posPrev[this.origin] +1) < pos.aX) {
194
                        top = posPrev.aY;
195
                    }
196
                }
197

    
198
                pos.top = top;
199
                pos.aY  = top + pos.height;
200

    
201
                maxHeight = Math.max(maxHeight, pos.aY);
202
            }
203

    
204
            maxHeight = maxHeight - this.gutterv;
205

    
206
            if (this.options.animation) {
207

    
208
                this.element.stop().animate({'height': maxHeight}, 100);
209

    
210
                positions.forEach(function(pos){
211

    
212
                    positionto = {"top": pos.top, opacity: 1};
213
                    positionto[$this.origin] = pos[$this.origin];
214

    
215
                    pos.ele.stop().animate(positionto, this.options.duration);
216
                }.bind(this));
217

    
218
            } else {
219

    
220
                this.element.css('height', maxHeight);
221

    
222
                positions.forEach(function(pos){
223
                    positionto = {"top": pos.top, opacity: 1};
224
                    positionto[$this.origin] = pos[$this.origin];
225
                    pos.ele.css(positionto);
226
                }.bind(this));
227
            }
228

    
229
            // make sure to trigger possible scrollpies etc.
230
            setTimeout(function() {
231
                UI.$doc.trigger('scrolling.uk.document');
232
            }, 2 * this.options.duration * (this.options.animation ? 1:0));
233

    
234
            this.trigger('afterupdate.uk.grid', [children]);
235
        },
236

    
237
        filter: function(filter) {
238

    
239
            this.currentfilter = filter;
240

    
241
            filter = filter || [];
242

    
243
            if (typeof(filter) === 'number') {
244
                filter = filter.toString();
245
            }
246

    
247
            if (typeof(filter) === 'string') {
248
                filter = filter.split(/,/).map(function(item){ return item.trim(); });
249
            }
250

    
251
            var $this = this, children = this.element.children(), elements = {"visible": [], "hidden": []}, visible, hidden;
252

    
253
            children.each(function(index){
254

    
255
                var ele = UI.$(this), f = ele.attr('data-uk-filter'), infilter = filter.length ? false : true;
256

    
257
                if (f) {
258

    
259
                    f = f.split(/,/).map(function(item){ return item.trim(); });
260

    
261
                    filter.forEach(function(item){
262
                        if (f.indexOf(item) > -1) infilter = true;
263
                    });
264
                }
265

    
266
                elements[infilter ? "visible":"hidden"].push(ele);
267
            });
268

    
269
            // convert to jQuery collections
270
            elements.hidden  = UI.$(elements.hidden).map(function () {return this[0];});
271
            elements.visible = UI.$(elements.visible).map(function () {return this[0];});
272

    
273
            elements.hidden.attr('aria-hidden', 'true').filter(':visible').fadeOut(this.options.duration);
274
            elements.visible.attr('aria-hidden', 'false').filter(':hidden').css('opacity', 0).show();
275

    
276
            $this.update(elements.visible);
277

    
278
            if (this.controls && this.controls.length) {
279
                this.controls.find('[data-uk-filter]').removeClass('uk-active').filter('[data-uk-filter="'+filter+'"]').addClass('uk-active');
280
            }
281
        },
282

    
283
        sort: function(by, order){
284

    
285
            order = order || 1;
286

    
287
            // covert from string (asc|desc) to number
288
            if (typeof(order) === 'string') {
289
                order = order.toLowerCase() == 'desc' ? -1 : 1;
290
            }
291

    
292
            var elements = this.element.children();
293

    
294
            elements.sort(function(a, b){
295

    
296
                a = UI.$(a);
297
                b = UI.$(b);
298

    
299
                return (b.data(by) || '') < (a.data(by) || '') ? order : (order*-1);
300

    
301
            }).appendTo(this.element);
302

    
303
            this.update(elements.filter(':visible'));
304

    
305
            if (this.controls && this.controls.length) {
306
                this.controls.find('[data-uk-sort]').removeClass('uk-active').filter('[data-uk-sort="'+by+':'+(order == -1 ? 'desc':'asc')+'"]').addClass('uk-active');
307
            }
308
        }
309
    });
310

    
311
});
(13-13/46)