Open suits-at opened 6 years ago
it would be awesome!
I've started something like this, but it hides all columns and doesnt recalculate table width for some reason:
mounted() {
window.addEventListener('resize', this.handleResize)
}
methods: {
handleResize() {
let i = this.fields.length - 1
if (dataTableWidth < browserWidth) {
return
} else {
for (i; i > 0; i--) {
if (dataTableWidth < browserWidth) return
this.fields[i].visible = false
this.$refs.vuetable.normalizeFields()
console.log('hidding', this.fields[i])
}
}
}
}
DataTables has more comprehensive spec. It might be doable in v2.1 where the support for Row component has been implemented (the same idea as an extension in DataTables).
I think this should not be a standard feature as not everybody will want to use it. Please do not expect it to be implemented so soon as I can only do so much with the spare time I have.
@Georgeek I had a look at your code and found a problem. You are looping over all elements, and set every field to visible = false. Your condition if (dataTableWidth < browserWidth) return
never comes true, if you change the viewport just once and therefore the dataTableWidth does no change during your loop. Because of that, all items were set to visible = false
at once.
Another way would be to use this.fields[this.$refs.vuetable.countVisibleFields-1].visible = false;
instead of using a for-loop to hide only one column at once. This works fine if you resize your browser window manually, but it does not work if you open the table on a samll device. Hope this helps improving your code so you might find a working solution for your needs. :)
@suits-at thank you for reply. It didnt work because at some circumstances it fires only once, despite the 'addEventListener' event. I've tried recursion as well and store col counter...
I've solved in another way (which i dont like and its temporary)
// methods
// if window resize horizontaly
windowResize() {
let width = window.innerWidth
if (width !== this.screenWidth) {
this.handleResize(this.fieldsLength);
this.screenWidth = width;
};
},
// hiding cells
showHideColumn(colNum, show = false) {
for (let i = 0; i < row.length; i++ ) {
let col = row[i].cells[colNum]
col.style.display = show ? '': 'none'
}
if (!show) {
this.fieldsLength = colNum - 1
} else if (show && colNum < this.fields.length - 1) {
this.fieldsLength = colNum + 1
} else {
return this.fieldsLength
}
},
// fires on resize, stores in array columns brakepoints (to restore it next time)
handleResize(col = this.fields.length - 1) {
let browserWidth
let tableCont = this.$refs.testtable
let dataTableRect = tableCont.children[0].getBoundingClientRect()
let dataTableOffset = dataTableRect.x
let dataTableWidth = dataTableRect.width
browserWidth = window.innerWidth - dataTableOffset - 20
if (dataTableWidth < browserWidth) {
if (!this.dtBreakpoints.length) return
for(let i = 0; i < this.dtBreakpoints.length; i++) {
if (this.dtBreakpoints[i].width < browserWidth) {
this.showHideColumn(this.dtBreakpoints[i].col, true)
this.dtBreakpoints.shift()
}
}
return
}
if (col > 0) {
let breakpoint = { col: col, width: dataTableWidth}
this.showHideColumn(col, false)
this.dtBreakpoints.unshift(breakpoint)
this.handleResize(col - 1)
}
Didnt mention mounted() where i add 'addEventListener' and resize initially
rewrote handleResize and deleted showHideColumn. Almost work as i wanted :)
handleResize(col = this.fields.length - 1) {
let browserWidth
let tableCont = this.$refs.vuetable
let dataTableRect = tableCont.$el.getBoundingClientRect()
let dataTableOffset = dataTableRect.x
let dataTableWidth = dataTableRect.width
browserWidth = window.innerWidth - dataTableOffset
if (dataTableWidth < browserWidth) {
if (!this.dtBreakpoints.length) return
for(let i = 0; i < this.dtBreakpoints.length; i++) {
if (this.dtBreakpoints[i].width < browserWidth) {
this.$nextTick()
.then(() => this.fields[this.dtBreakpoints[i].col].visible = true)
.then(() => this.$refs.vuetable.normalizeFields())
.then(() => this.dtBreakpoints.shift())
}
}
return
}
if (col > 0) {
let breakpoint = { col: col, width: dataTableWidth + 20}
this.dtBreakpoints.unshift(breakpoint)
this.$nextTick()
.then(() => this.fields[col].visible = false)
.then(() => this.$refs.vuetable.normalizeFields())
.then(() => this.handleResize(col - 1))
}
},
aslo need to take into account that resize works only on browser width on pc. To make it works on tablet and phone we need to check display orientation and screen width
mounted() {
// js resize mounted
this.fieldsLength = this.fields.length - 1
window.addEventListener('optimizedResize', this.windowResize)
window.addEventListener('orientationchange', this.onOrientationChange)
}
methods: {
onOrientationChange() {
this.$refs.vuetable.reload()
},
onDtLoaded() {
this.handleOrientation(this.fields.length - 1)
}
}
vuetable(ref="vuetable"
// omitted settings
@vuetable:loaded="onDtLoaded"
handleOrientation is almost the same as handleResize (need to refactor)
handleOrientation(col = this.fields.length - 1) {
let tableCont = this.$refs.vuetable
let dataTableRect = tableCont.$el.getBoundingClientRect()
let dataTableOffset = dataTableRect.x
let dataTableWidth = dataTableRect.right // было width
let matchMedia = (window.matchMedia('(max-device-width: 1400px) and (orientation: landscape)').matches || window.matchMedia('(max-device-width: 1400px) and (orientation: portrait)').matches)
let browserWidth = matchMedia ? screen.width - 50 : window.innerWidth
if (dataTableWidth < browserWidth) return
if (col > 1 && col < this.fields.length) {
let breakpoint = { col: col, width: dataTableWidth + 20}
this.$nextTick()
.then(() => this.fields[col].visible = false)
.then(() => this.$refs.vuetable.normalizeFields())
.then(() => this.dtBreakpoints.unshift(breakpoint))
.then(() => this.decrementFieldsLenght(col))
.then(() => {
if (dataTableWidth > browserWidth) {
this.handleOrientation(this.fieldsLength)
}
})
}
}
hi Georgeek thanks for your effort could you share full code implementation at codepen or jsfiddle ? tip: 1 - dont forget to add
data () {
return {
fieldsLength:'',
dtBreakpoints:[]
}
},
2- "optimizedResize" is not working at opera browser. i used "resize" instead. window.addEventListener('resize', this.windowResize)
As mentioned in #356 I would like to use vuetable-2, but I also need responsiveness. In my opinion the approach from the DataTables extension "responsive" gives the best user experience possible. (Demo) Only the data which fits on the screen is shown, everything als automatically gets hidden inside a detail-row (depentend on the viewport). By clicking the green "+", the hidden data of the clicked row gets visible. As vuetable-2 already has detail-rows included, and using this aproach to make table responsive by default would also be framework independent, I thought this might be a good option for including responsive behaviour to vuetables-2. What do you think @ratiw?