Skip to content

Commit 57aa4b5

Browse files
authored
Merge pull request jbaysolutions#421 from insighio/master
Support initial responsive layouts and breakpoint change event
2 parents 6d756de + db5b494 commit 57aa4b5

File tree

7 files changed

+227
-3
lines changed

7 files changed

+227
-3
lines changed

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,16 @@ Include the browser-ready bundle (download from [releases](https://github.com/jb
175175

176176
The value must be an `Array` of `Object` items. Each item must have `i`, `x`, `y`, `w` and `h` properties. Please refer to the documentation for `GridItem` below for more information.
177177

178+
* **responsiveLayouts**
179+
180+
* type: `Object`
181+
* required: `false`
182+
* default : `{}`
183+
184+
This is the initial layouts of the grid per breakpoint if `responsive` is set to `true`.
185+
The keys of the `Object` are breakpoint names and each value is an `Array` of `Object` items as defined by `layout` prop. eg:{ lg:[layout items], md:[layout items] }.
186+
Setting the prop after the creation of the GridLayout has no effect.
187+
178188
* **colNum**
179189

180190
* type: `Number`
@@ -469,6 +479,7 @@ Working example [here](https://jbaysolutions.github.io/vue-grid-layout/examples/
469479
@layout-mounted="layoutMountedEvent"
470480
@layout-ready="layoutReadyEvent"
471481
@layout-updated="layoutUpdatedEvent"
482+
@breakpoint-changed="breakpointChangedEvent"
472483
>
473484

474485
<grid-item v-for="item in layout"
@@ -626,6 +637,24 @@ Working example [here](https://jbaysolutions.github.io/vue-grid-layout/examples/
626637
},
627638
```
628639

640+
* **breakpointChangedEvent**
641+
642+
Breakpoint Changed event
643+
644+
Every time the breakpoint value changes due to window resize
645+
646+
```javascript
647+
/**
648+
*
649+
* @param newBreakpoint the breakpoint name
650+
* @param newLayout the chosen layout for the breakpoint
651+
*
652+
*/
653+
breakpointChangedEvent: function(newBreakpoint, newLayout){
654+
console.log("BREAKPOINT CHANGED breakpoint=", newBreakpoint, ", layout: ", newLayout );
655+
},
656+
```
657+
629658

630659
## Contribute
631660

examples/06-responsive.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ <h1>Vue Grid Layout Example 6 - Responsive</h1>
1414
<br/>
1515
<a href="05-mirrored.html">Previous example: Mirrored grid layout</a>
1616
<br/>
17-
<a href="07-prevent-collision.html">Next example: Responsive</a>
17+
<a href="07-prevent-collision.html">Next example: Prevent collision</a>
1818

1919
<div id="app" style="width: 100%;">
2020
<!--<pre>{{ $data | json }}</pre>-->

examples/07-prevent-collision.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ <h1>Vue Grid Layout Example 8 - Prevent Collision</h1>
1313
<a href="https://github.com/jbaysolutions/vue-grid-layout">View project on Github</a>
1414
<br/>
1515
<a href="06-responsive.html">Previous example: Responsive</a>
16+
<br/>
17+
<a href="08-responsive-predefined-layouts.html">Next example: Responsive - predefined layouts</a>
1618

1719
<div id="app" style="width: 100%;">
1820
<!--<pre>{{ $data | json }}</pre>-->
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Vue Grid Layout Example 1 - Basic Responsive</title>
6+
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
7+
<link rel="stylesheet" href="app.css">
8+
<!--<link rel="stylesheet" href="../dist/vue-grid-layout.css">-->
9+
</head>
10+
<body>
11+
<h1>Vue Grid Layout Example 6 - Responsive</h1>
12+
13+
<a href="https://github.com/jbaysolutions/vue-grid-layout">View project on Github</a>
14+
<br/>
15+
<a href="07-prevent-collision.html">Previous example: Prevent collision</a>
16+
17+
<div id="app" style="width: 100%;">
18+
<!--<pre>{{ $data | json }}</pre>-->
19+
<div>
20+
<div class="layoutJSON">
21+
Displayed as <code>[x, y, w, h]</code>:
22+
<div class="columns">
23+
<div class="layoutItem" v-for="item in layout">
24+
<b>{{item.i}}</b>: [{{item.x}}, {{item.y}}, {{item.w}}, {{item.h}}]
25+
</div>
26+
</div>
27+
</div>
28+
</div>
29+
<div id="content">
30+
<!--<button @click="decreaseWidth">Decrease Width</button>
31+
<button @click="increaseWidth">Increase Width</button>
32+
<button @click="addItem">Add an item</button>-->
33+
<input type="checkbox" v-model="draggable"/> Draggable
34+
<input type="checkbox" v-model="resizable"/> Resizable
35+
<input type="checkbox" v-model="responsive"/> Responsive
36+
<br/>
37+
<grid-layout :layout.sync="layout"
38+
:responsive-layouts="layouts"
39+
:col-num="12"
40+
:row-height="30"
41+
:is-draggable="draggable"
42+
:is-resizable="resizable"
43+
:vertical-compact="true"
44+
:use-css-transforms="true"
45+
:responsive="responsive"
46+
@breakpoint-changed="breakpointChangedEvent"
47+
>
48+
<grid-item v-for="item in layout"
49+
:x="item.x"
50+
:y="item.y"
51+
:w="item.w"
52+
:h="item.h"
53+
:i="item.i"
54+
>
55+
<span class="text">{{item.i}}</span>
56+
</grid-item>
57+
</grid-layout>
58+
</div>
59+
60+
</div>
61+
<script src="vue.min.js"></script>
62+
<script src="../dist/vue-grid-layout.umd.min.js"></script>
63+
<script src="08-responsive-predefined-layouts.js"></script>
64+
</body>
65+
</html>
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
var testLayouts = {
2+
md: [
3+
{"x":0, "y":0, "w":2, "h":2, "i":"0"},
4+
{"x":2, "y":0, "w":2, "h":4, "i":"1"},
5+
{"x":4, "y":0, "w":2, "h":5, "i":"2"},
6+
{"x":6, "y":0, "w":2, "h":3, "i":"3"},
7+
{"x":2, "y":4, "w":2, "h":3, "i":"4"},
8+
{"x":4, "y":5, "w":2, "h":3, "i":"5"},
9+
{"x":0, "y":2, "w":2, "h":5, "i":"6"},
10+
{"x":2, "y":7, "w":2, "h":5, "i":"7"},
11+
{"x":4, "y":8, "w":2, "h":5, "i":"8"},
12+
{"x":6, "y":3, "w":2, "h":4, "i":"9"},
13+
{"x":0, "y":7, "w":2, "h":4, "i":"10"},
14+
{"x":2, "y":19, "w":2, "h":4, "i":"11"},
15+
{"x":0, "y":14, "w":2, "h":5, "i":"12"},
16+
{"x":2, "y":14, "w":2, "h":5, "i":"13"},
17+
{"x":4, "y":13, "w":2, "h":4, "i":"14"},
18+
{"x":6, "y":7, "w":2, "h":4, "i":"15"},
19+
{"x":0, "y":19, "w":2, "h":5, "i":"16"},
20+
{"x":8, "y":0, "w":2, "h":2, "i":"17"},
21+
{"x":0, "y":11, "w":2, "h":3, "i":"18"},
22+
{"x":2, "y":12, "w":2, "h":2, "i":"19"}
23+
],
24+
lg: [
25+
{"x":0,"y":0,"w":2,"h":2,"i":"0"},
26+
{"x":2,"y":0,"w":2,"h":4,"i":"1"},
27+
{"x":4,"y":0,"w":2,"h":5,"i":"2"},
28+
{"x":6,"y":0,"w":2,"h":3,"i":"3"},
29+
{"x":8,"y":0,"w":2,"h":3,"i":"4"},
30+
{"x":10,"y":0,"w":2,"h":3,"i":"5"},
31+
{"x":0,"y":5,"w":2,"h":5,"i":"6"},
32+
{"x":2,"y":5,"w":2,"h":5,"i":"7"},
33+
{"x":4,"y":5,"w":2,"h":5,"i":"8"},
34+
{"x":6,"y":4,"w":2,"h":4,"i":"9"},
35+
{"x":8,"y":4,"w":2,"h":4,"i":"10"},
36+
{"x":10,"y":4,"w":2,"h":4,"i":"11"},
37+
{"x":0,"y":10,"w":2,"h":5,"i":"12"},
38+
{"x":2,"y":10,"w":2,"h":5,"i":"13"},
39+
{"x":4,"y":8,"w":2,"h":4,"i":"14"},
40+
{"x":6,"y":8,"w":2,"h":4,"i":"15"},
41+
{"x":8,"y":10,"w":2,"h":5,"i":"16"},
42+
{"x":10,"y":4,"w":2,"h":2,"i":"17"},
43+
{"x":0,"y":9,"w":2,"h":3,"i":"18"},
44+
{"x":2,"y":6,"w":2,"h":2,"i":"19"}
45+
],
46+
};
47+
48+
// var GridLayout = VueGridLayout.GridLayout;
49+
// var GridItem = VueGridLayout.GridItem;
50+
51+
new Vue({
52+
el: '#app',
53+
// components: {
54+
// "GridLayout": GridLayout,
55+
// "GridItem": GridItem
56+
// },
57+
data: {
58+
layouts: testLayouts,
59+
layout: testLayouts["lg"],
60+
draggable: true,
61+
resizable: true,
62+
responsive: true,
63+
index: 0
64+
},
65+
/*
66+
mounted: function () {
67+
this.index = this.layout.length;
68+
},
69+
methods: {
70+
increaseWidth: function(item) {
71+
var width = document.getElementById("content").offsetWidth;
72+
width += 20;
73+
document.getElementById("content").style.width = width+"px";
74+
},
75+
decreaseWidth: function(item) {
76+
77+
var width = document.getElementById("content").offsetWidth;
78+
width -= 20;
79+
document.getElementById("content").style.width = width+"px";
80+
},
81+
removeItem: function(item) {
82+
//console.log("### REMOVE " + item.i);
83+
this.layout.splice(this.layout.indexOf(item), 1);
84+
},
85+
addItem: function() {
86+
var self = this;
87+
//console.log("### LENGTH: " + this.layout.length);
88+
var item = {"x":0,"y":0,"w":2,"h":2,"i":this.index+"", whatever: "bbb"};
89+
this.index++;
90+
this.layout.push(item);
91+
},
92+
breakpointChangedEvent: function(newBreakpoint, newLayout){
93+
console.log("BREAKPOINT CHANGED breakpoint=", newBreakpoint, ", layout: ", newLayout );
94+
}
95+
}
96+
*/
97+
});
98+
99+
/*
100+
function generateLayout() {
101+
return _.map(_.range(0, 25), function (item, i) {
102+
var y = Math.ceil(Math.random() * 4) + 1;
103+
return {
104+
x: _.random(0, 5) * 2 % 12,
105+
y: Math.floor(i / 6) * y,
106+
w: 2,
107+
h: y,
108+
i: i.toString(),
109+
static: Math.random() < 0.05
110+
};
111+
});
112+
}*/
113+
114+
115+

src/App.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
@layout-mounted="layoutMountedEvent"
5151
@layout-ready="layoutReadyEvent"
5252
@layout-updated="layoutUpdatedEvent"
53+
@breakpoint-changed="breakpointChangedEvent"
5354
>
5455
<grid-item v-for="item in layout" :key="item.i"
5556
:static="item.static"
@@ -225,6 +226,9 @@
225226
layoutUpdatedEvent: function(newLayout){
226227
console.log("Updated layout: ", newLayout)
227228
},
229+
breakpointChangedEvent: function(newBreakpoint, newLayout){
230+
console.log("breakpoint changed breakpoint=", newBreakpoint, ", layout: ", newLayout );
231+
}
228232
229233
},
230234
}

src/components/GridLayout.vue

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@
8989
type: Boolean,
9090
default: false
9191
},
92+
responsiveLayouts: {
93+
type: Object,
94+
default: function() {
95+
return {};
96+
}
97+
},
9298
breakpoints:{
9399
type: Object,
94100
default: function(){return{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }}
@@ -381,7 +387,6 @@
381387
382388
// finds or generates new layouts for set breakpoints
383389
responsiveGridLayout(){
384-
385390
let newBreakpoint = getBreakpointFromWidth(this.breakpoints, this.width);
386391
let newCols = getColsFromBreakpoint(newBreakpoint, this.cols);
387392
@@ -403,6 +408,10 @@
403408
// Store the new layout.
404409
this.layouts[newBreakpoint] = layout;
405410
411+
if (this.lastBreakpoint !== newBreakpoint) {
412+
this.$emit('breakpoint-changed', newBreakpoint, layout);
413+
}
414+
406415
// new prop sync
407416
this.$emit('update:layout', layout);
408417
@@ -413,7 +422,7 @@
413422
// clear all responsive layouts
414423
initResponsiveFeatures(){
415424
// clear layouts
416-
this.layouts = {};
425+
this.layouts = Object.assign({}, this.responsiveLayouts);
417426
},
418427
419428
// find difference in layouts

0 commit comments

Comments
 (0)