Roo/bootstrap/MasonryBrick.js
[roojs1] / Roo / bootstrap / MasonryBrick.js
1 /*
2  * - LGPL
3  *
4  * element
5  * 
6  */
7
8 /**
9  * @class Roo.bootstrap.MasonryBrick
10  * @extends Roo.bootstrap.Component
11  * Bootstrap MasonryBrick class
12  * 
13  * @constructor
14  * Create a new MasonryBrick
15  * @param {Object} config The config object
16  */
17
18 Roo.bootstrap.MasonryBrick = function(config){
19     
20     Roo.bootstrap.MasonryBrick.superclass.constructor.call(this, config);
21     
22     Roo.bootstrap.MasonryBrick.register(this);
23     
24     this.addEvents({
25         // raw events
26         /**
27          * @event click
28          * When a MasonryBrick is clcik
29          * @param {Roo.bootstrap.MasonryBrick} this
30          * @param {Roo.EventObject} e
31          */
32         "click" : true
33     });
34 };
35
36 Roo.extend(Roo.bootstrap.MasonryBrick, Roo.bootstrap.Component,  {
37     
38     /**
39      * @cfg {String} title
40      */   
41     title : '',
42     /**
43      * @cfg {String} html
44      */   
45     html : '',
46     /**
47      * @cfg {String} bgimage
48      */   
49     bgimage : '',
50     /**
51      * @cfg {String} videourl
52      */   
53     videourl : '',
54     /**
55      * @cfg {String} cls
56      */   
57     cls : '',
58     /**
59      * @cfg {String} href
60      */   
61     href : '',
62     /**
63      * @cfg {String} size (xs|sm|md|md-left|md-right|tall|wide)
64      */   
65     size : 'xs',
66     
67     /**
68      * @cfg {String} placetitle (center|bottom)
69      */   
70     placetitle : '',
71     
72     /**
73      * @cfg {Boolean} isFitContainer defalut true
74      */   
75     isFitContainer : true, 
76     
77     /**
78      * @cfg {Boolean} preventDefault defalut false
79      */   
80     preventDefault : false, 
81     
82     /**
83      * @cfg {Boolean} inverse defalut false
84      */   
85     maskInverse : false, 
86     
87     getAutoCreate : function()
88     {
89         if(!this.isFitContainer){
90             return this.getSplitAutoCreate();
91         }
92         
93         var cls = 'masonry-brick masonry-brick-full embed-responsive';
94         
95         if(this.href.length){
96             cls += ' masonry-brick-link';
97         }
98         
99         if(this.bgimage.length){
100             cls += ' masonry-brick-image';
101         }
102         
103         if(this.maskInverse){
104             cls += ' mask-inverse';
105         }
106         
107         if(!this.html.length && !this.maskInverse && !this.videourl.length){
108             cls += ' enable-mask';
109         }
110         
111         if(this.size){
112             cls += ' masonry-' + this.size + '-brick';
113         }
114         
115         if(this.placetitle.length){
116             
117             switch (this.placetitle) {
118                 case 'center' :
119                     cls += ' masonry-center-title';
120                     break;
121                 case 'bottom' :
122                     cls += ' masonry-bottom-title';
123                     break;
124                 default:
125                     break;
126             }
127             
128         } else {
129             if(!this.html.length && !this.bgimage.length){
130                 cls += ' masonry-center-title';
131             }
132
133             if(!this.html.length && this.bgimage.length){
134                 cls += ' masonry-bottom-title';
135             }
136         }
137         
138         if(this.cls){
139             cls += ' ' + this.cls;
140         }
141         
142         var cfg = {
143             tag: (this.href.length) ? 'a' : 'div',
144             cls: cls,
145             cn: [
146                 {
147                     tag: 'div',
148                     cls: 'masonry-brick-mask'
149                 },
150                 {
151                     tag: 'div',
152                     cls: 'masonry-brick-paragraph',
153                     cn: []
154                 }
155             ]
156         };
157         
158         if(this.href.length){
159             cfg.href = this.href;
160         }
161         
162         var cn = cfg.cn[1].cn;
163         
164         if(this.title.length){
165             cn.push({
166                 tag: 'h4',
167                 cls: 'masonry-brick-title',
168                 html: this.title
169             });
170         }
171         
172         if(this.html.length){
173             cn.push({
174                 tag: 'p',
175                 cls: 'masonry-brick-text',
176                 html: this.html
177             });
178         }
179         
180         if (!this.title.length && !this.html.length) {
181             cfg.cn[1].cls += ' hide';
182         }
183         
184         if(this.bgimage.length){
185             cfg.cn.push({
186                 tag: 'img',
187                 cls: 'masonry-brick-image-view',
188                 src: this.bgimage
189             });
190         }
191         
192         if(this.videourl.length){
193             var vurl = this.videourl.replace(/https:\/\/youtu\.be/, 'https://www.youtube.com/embed/');
194             // youtube support only?
195             cfg.cn.push({
196                 tag: 'iframe',
197                 cls: 'masonry-brick-image-view embed-responsive-item',
198                 src: vurl,
199                 frameborder : 0,
200                 allowfullscreen : true
201             });
202         }
203         
204         return cfg;
205         
206     },
207     
208     getSplitAutoCreate : function()
209     {
210         var cls = 'masonry-brick masonry-brick-split';
211         
212         if(this.href.length){
213             cls += ' masonry-brick-link';
214         }
215         
216         if(this.bgimage.length){
217             cls += ' masonry-brick-image';
218         }
219         
220         if(this.size){
221             cls += ' masonry-' + this.size + '-brick';
222         }
223         
224         switch (this.placetitle) {
225             case 'center' :
226                 cls += ' masonry-center-title';
227                 break;
228             case 'bottom' :
229                 cls += ' masonry-bottom-title';
230                 break;
231             default:
232                 if(!this.bgimage.length){
233                     cls += ' masonry-center-title';
234                 }
235
236                 if(this.bgimage.length){
237                     cls += ' masonry-bottom-title';
238                 }
239                 break;
240         }
241         
242         if(this.cls){
243             cls += ' ' + this.cls;
244         }
245         
246         var cfg = {
247             tag: (this.href.length) ? 'a' : 'div',
248             cls: cls,
249             cn: [
250                 {
251                     tag: 'div',
252                     cls: 'masonry-brick-split-head',
253                     cn: [
254                         {
255                             tag: 'div',
256                             cls: 'masonry-brick-paragraph',
257                             cn: []
258                         }
259                     ]
260                 },
261                 {
262                     tag: 'div',
263                     cls: 'masonry-brick-split-body',
264                     cn: []
265                 }
266             ]
267         };
268         
269         if(this.href.length){
270             cfg.href = this.href;
271         }
272         
273         if(this.title.length){
274             cfg.cn[0].cn[0].cn.push({
275                 tag: 'h4',
276                 cls: 'masonry-brick-title',
277                 html: this.title
278             });
279         }
280         
281         if(this.html.length){
282             cfg.cn[1].cn.push({
283                 tag: 'p',
284                 cls: 'masonry-brick-text',
285                 html: this.html
286             });
287         }
288
289         if(this.bgimage.length){
290             cfg.cn[0].cn.push({
291                 tag: 'img',
292                 cls: 'masonry-brick-image-view',
293                 src: this.bgimage
294             });
295         }
296         
297         if(this.videourl.length){
298             var vurl = this.videourl.replace(/https:\/\/youtu\.be/, 'https://www.youtube.com/embed/');
299             // youtube support only?
300             cfg.cn[0].cn.cn.push({
301                 tag: 'iframe',
302                 cls: 'masonry-brick-image-view',
303                 src: vurl,
304                 frameborder : 0,
305                 allowfullscreen : true
306             });
307         }
308         
309         return cfg;
310     },
311     
312     initEvents: function() 
313     {
314         switch (this.size) {
315             case 'xs' :
316                 this.x = 1;
317                 this.y = 1;
318                 break;
319             case 'sm' :
320                 this.x = 2;
321                 this.y = 2;
322                 break;
323             case 'md' :
324             case 'md-left' :
325             case 'md-right' :
326                 this.x = 3;
327                 this.y = 3;
328                 break;
329             case 'tall' :
330                 this.x = 2;
331                 this.y = 3;
332                 break;
333             case 'wide' :
334                 this.x = 3;
335                 this.y = 2;
336                 break;
337             case 'wide-thin' :
338                 this.x = 3;
339                 this.y = 1;
340                 break;
341                         
342             default :
343                 break;
344         }
345         
346         if(Roo.isTouch){
347             this.el.on('touchstart', this.onTouchStart, this);
348             this.el.on('touchmove', this.onTouchMove, this);
349             this.el.on('touchend', this.onTouchEnd, this);
350             this.el.on('contextmenu', this.onContextMenu, this);
351         } else {
352             this.el.on('mouseenter'  ,this.enter, this);
353             this.el.on('mouseleave', this.leave, this);
354             this.el.on('click', this.onClick, this);
355         }
356         
357         if (typeof(this.parent().bricks) == 'object' && this.parent().bricks != null) {
358             this.parent().bricks.push(this);   
359         }
360         
361     },
362     
363     onClick: function(e, el)
364     {
365         var time = this.endTimer - this.startTimer;
366         // Roo.log(e.preventDefault());
367         if(Roo.isTouch){
368             if(time > 1000){
369                 e.preventDefault();
370                 return;
371             }
372         }
373         
374         if(!this.preventDefault){
375             return;
376         }
377         
378         e.preventDefault();
379         
380         if (this.activeClass != '') {
381             this.selectBrick();
382         }
383         
384         this.fireEvent('click', this, e);
385     },
386     
387     enter: function(e, el)
388     {
389         e.preventDefault();
390         
391         if(!this.isFitContainer || this.maskInverse || this.videourl.length){
392             return;
393         }
394         
395         if(this.bgimage.length && this.html.length){
396             this.el.select('.masonry-brick-paragraph', true).first().setOpacity(0.9, true);
397         }
398     },
399     
400     leave: function(e, el)
401     {
402         e.preventDefault();
403         
404         if(!this.isFitContainer || this.maskInverse  || this.videourl.length){
405             return;
406         }
407         
408         if(this.bgimage.length && this.html.length){
409             this.el.select('.masonry-brick-paragraph', true).first().setOpacity(0, true);
410         }
411     },
412     
413     onTouchStart: function(e, el)
414     {
415 //        e.preventDefault();
416         
417         this.touchmoved = false;
418         
419         if(!this.isFitContainer){
420             return;
421         }
422         
423         if(!this.bgimage.length || !this.html.length){
424             return;
425         }
426         
427         this.el.select('.masonry-brick-paragraph', true).first().setOpacity(0.9, true);
428         
429         this.timer = new Date().getTime();
430         
431     },
432     
433     onTouchMove: function(e, el)
434     {
435         this.touchmoved = true;
436     },
437     
438     onContextMenu : function(e,el)
439     {
440         e.preventDefault();
441         e.stopPropagation();
442         return false;
443     },
444     
445     onTouchEnd: function(e, el)
446     {
447 //        e.preventDefault();
448         
449         if((new Date().getTime() - this.timer > 1000) || !this.href.length || this.touchmoved){
450         
451             this.leave(e,el);
452             
453             return;
454         }
455         
456         if(!this.bgimage.length || !this.html.length){
457             
458             if(this.href.length){
459                 window.location.href = this.href;
460             }
461             
462             return;
463         }
464         
465         if(!this.isFitContainer){
466             return;
467         }
468         
469         this.el.select('.masonry-brick-paragraph', true).first().setOpacity(0, true);
470         
471         window.location.href = this.href;
472     },
473     
474     //selection on single brick only
475     selectBrick : function() {
476         
477         if (!this.parentId) {
478             return;
479         }
480         
481         var m = Roo.bootstrap.LayoutMasonry.get(this.parentId);
482         var index = m.selectedBrick.indexOf(this.id);
483         
484         if ( index > -1) {
485             m.selectedBrick.splice(index,1);
486             this.el.removeClass(this.activeClass);
487             return;
488         }
489         
490         for(var i = 0; i < m.selectedBrick.length; i++) {
491             var b = Roo.bootstrap.MasonryBrick.get(m.selectedBrick[i]);
492             b.el.removeClass(b.activeClass);
493         }
494         
495         m.selectedBrick = [];
496         
497         m.selectedBrick.push(this.id);
498         this.el.addClass(this.activeClass);
499         return;
500     },
501     
502     isSelected : function(){
503         return this.el.hasClass(this.activeClass);
504         
505     }
506 });
507
508 Roo.apply(Roo.bootstrap.MasonryBrick, {
509     
510     //groups: {},
511     groups : new Roo.util.MixedCollection(false, function(o) { return o.el.id; }),
512      /**
513     * register a Masonry Brick
514     * @param {Roo.bootstrap.MasonryBrick} the masonry brick to add
515     */
516     
517     register : function(brick)
518     {
519         //this.groups[brick.id] = brick;
520         this.groups.add(brick.id, brick);
521     },
522     /**
523     * fetch a  masonry brick based on the masonry brick ID
524     * @param {string} the masonry brick to add
525     * @returns {Roo.bootstrap.MasonryBrick} the masonry brick
526     */
527     
528     get: function(brick_id) 
529     {
530         // if (typeof(this.groups[brick_id]) == 'undefined') {
531         //     return false;
532         // }
533         // return this.groups[brick_id] ;
534         
535         if(this.groups.key(brick_id)) {
536             return this.groups.key(brick_id);
537         }
538         
539         return false;
540     }
541     
542     
543     
544 });
545
546