data-search="toto" n'est pas jouable, gros pb de performance sur un gros tableau. les regex OUI mais si pas beaucoup ;-) Il semble indispensable de pouvoir gerer finemement les elements que l'on veut rechercher, dans etre polué par les balises html. Notre json, pour la partie corps du tableau, on ajoute un subdivision : "html" : { mes champs}, comme cela, on peut ajouter une nouvelle cle : "search" : {la valeur des champs qui seront recherchés et filtrés}. Cela alourdit un peu le html, et seulement son poids. La partie html/js est toujours aussi rapide, et meme plus si on utilise cette nouvelle cle. ATTENTION : cela casse la compatibilité
263 lines
No EOL
9.2 KiB
JavaScript
263 lines
No EOL
9.2 KiB
JavaScript
"use strict";
|
|
|
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
|
|
|
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
|
|
|
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
|
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
|
|
jQuery(function () {
|
|
$('#app').on('click', '.url_action', function (e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
var url = $(this).attr('href');
|
|
var id = $(this).data('id');
|
|
console.time('Chargement de VueJs APRES Ajax');
|
|
$.ajax({
|
|
url: url,
|
|
async: true
|
|
}).done(function () {
|
|
if (parseInt(id) > 0) {
|
|
app.rechargerJson(id);
|
|
} else {
|
|
app.rechargerJson();
|
|
}
|
|
});
|
|
});
|
|
$('#app').on('click', '.modalbox', function (e) {
|
|
e.preventDefault();
|
|
var url = $(this).attr('href');
|
|
url += '&var_zajax=content';
|
|
$.modalbox(url);
|
|
});
|
|
$('#app').on('click', '.mediabox', function (e) {
|
|
e.preventDefault();
|
|
var href = $(this).attr('href');
|
|
$.fn.mediabox({
|
|
href: href
|
|
});
|
|
});
|
|
});
|
|
|
|
function recupJson(d) {
|
|
try {
|
|
return JSON.parse(d);
|
|
} catch (e) {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
var orderBy = function orderBy(arr, props, orders, champ) {
|
|
return arr.sort(function (a, b) {
|
|
return props.reduce(function (acc, prop, i) {
|
|
if (acc === 0) {
|
|
var _ref = orders && orders[i] === 'desc' ? [b[champ][prop], a[champ][prop]] : [a[champ][prop], b[champ][prop]],
|
|
_ref2 = _slicedToArray(_ref, 2),
|
|
p1 = _ref2[0],
|
|
p2 = _ref2[1]; // passe en lowercase les String
|
|
|
|
|
|
p1 = typeof p1 === 'string' ? p1.toLowerCase() : p1;
|
|
p2 = typeof p2 === 'string' ? p2.toLowerCase() : p2; // Gestion du format de date
|
|
// transforme 03/11/2000 en 20001103
|
|
|
|
var re = /^(\d{2})\/(\d{2})\/(\d{2,4})$/;
|
|
|
|
if (typeof p1 !== 'number') {
|
|
var r1 = p1.match(re);
|
|
|
|
if (Array.isArray(r1)) {
|
|
p1 = r1[3] + r1[2] + r1[1];
|
|
}
|
|
|
|
var r2 = p2.match(re);
|
|
|
|
if (Array.isArray(r2)) {
|
|
p2 = r2[3] + r2[2] + r2[1];
|
|
}
|
|
}
|
|
|
|
acc = p1 > p2 ? 1 : p1 < p2 ? -1 : 0;
|
|
}
|
|
|
|
return acc;
|
|
}, 0);
|
|
});
|
|
};
|
|
|
|
console.time('Chargement de VueJS AVANT Ajax');
|
|
console.time('Chargement de VueJs APRES Ajax');
|
|
Vue.nextTick(function () {
|
|
console.timeEnd('Chargement de VueJS AVANT Ajax');
|
|
});
|
|
var monTableau = {
|
|
props: {
|
|
tparpage: {
|
|
type: Array,
|
|
default: function _default() {
|
|
return [10, 20, 50, 'Tous'];
|
|
}
|
|
},
|
|
apiuri: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
objet: {
|
|
type: String
|
|
}
|
|
},
|
|
data: function data() {
|
|
return {
|
|
table: [],
|
|
header: [],
|
|
crayons: [],
|
|
search: '',
|
|
page: 1,
|
|
parPage: this.tparpage[0],
|
|
parPageSelect: this.tparpage[0],
|
|
pages: [],
|
|
triOrders: [],
|
|
triProps: [],
|
|
selectTr: [],
|
|
champ_search: 'html'
|
|
};
|
|
},
|
|
mounted: function mounted() {
|
|
this.chargerJson();
|
|
},
|
|
computed: {
|
|
tableau: function tableau() {
|
|
var _this = this;
|
|
|
|
if (!this.search) {
|
|
return this.pagination(this.table);
|
|
}
|
|
|
|
return this.pagination(this.table.filter(function (ligne) {
|
|
return Object.values(ligne[_this.champ_search]).toString().toLowerCase().indexOf(_this.search.toLowerCase()) < 0 ? false : true;
|
|
}));
|
|
}
|
|
},
|
|
watch: {
|
|
tableau: function tableau() {
|
|
this.setPages();
|
|
},
|
|
parPageSelect: function parPageSelect(e) {
|
|
if (!parseInt(e)) {
|
|
this.parPage = this.table.length;
|
|
} else {
|
|
this.parPage = e;
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
chargerJson: function chargerJson(id) {
|
|
var _this2 = this;
|
|
|
|
var url = this.apiuri;
|
|
|
|
if (parseInt(id) > 0) {
|
|
url += '&id=' + id;
|
|
}
|
|
|
|
fetch(url).then(function (response) {
|
|
return response.json();
|
|
}).then(function (data) {
|
|
var config = data.shift();
|
|
_this2.header = config.header;
|
|
_this2.crayons = config.crayons;
|
|
|
|
if (parseInt(id) > 0) {
|
|
var i = _this2.table.findIndex(function (ligne) {
|
|
return ligne.id === parseInt(id);
|
|
});
|
|
|
|
Vue.set(_this2.table, i, data[0]);
|
|
} else {
|
|
_this2.table = data;
|
|
|
|
if (data[0].search) {
|
|
_this2.champ_search = 'search';
|
|
}
|
|
}
|
|
|
|
Vue.nextTick(function () {
|
|
console.timeEnd('Chargement de VueJs APRES Ajax');
|
|
});
|
|
}).catch(function (error) {
|
|
return console.log(error);
|
|
});
|
|
},
|
|
setPages: function setPages() {
|
|
var nombreDePages = Math.ceil(this.table.length / this.parPage);
|
|
this.pages = [];
|
|
|
|
for (var index = 1; index <= nombreDePages; index++) {
|
|
this.pages.push(index);
|
|
}
|
|
},
|
|
pagination: function pagination(tableau) {
|
|
var page = this.page;
|
|
var parPage = this.parPage;
|
|
var from = page * parPage - parPage;
|
|
var to = page * parPage;
|
|
return tableau.slice(from, to);
|
|
},
|
|
afficher_crayons: function afficher_crayons(name, id) {
|
|
if (Object.keys(this.crayons).indexOf(name) !== -1) {
|
|
return "crayon ".concat(this.crayons[name], "-").concat(name, "-").concat(id);
|
|
}
|
|
},
|
|
tri: function tri(col, sens) {
|
|
var i = this.triProps.indexOf(col);
|
|
|
|
if (i !== -1) {
|
|
this.triOrders[i] = sens;
|
|
} else {
|
|
this.triProps.push(col);
|
|
this.triOrders.push(sens);
|
|
}
|
|
|
|
this.table = orderBy(this.table, this.triProps, this.triOrders, this.champ_search);
|
|
},
|
|
ordreActif: function ordreActif(col, sens) {
|
|
var i = this.triProps.indexOf(col);
|
|
|
|
if (i !== -1) {
|
|
if (this.triOrders[i] === sens) {
|
|
return 'active';
|
|
}
|
|
}
|
|
},
|
|
resetTri: function resetTri() {
|
|
this.table = orderBy(this.table, ['id'], '', this.champ_search);
|
|
this.triOrders = [];
|
|
this.triProps = [];
|
|
},
|
|
selectLigne: function selectLigne(id, col) {
|
|
if (col === 'id' && parseInt(id)) {
|
|
var i = this.selectTr.indexOf(id);
|
|
|
|
if (i !== -1) {
|
|
this.selectTr.splice(i, 1);
|
|
} else {
|
|
this.selectTr.push(id);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
template: "\n\t<div class=\"gamutable\">\n\t\t<div class=\"gamutable--surTable\">\n\t\t\t<select id=\"parPage\" v-model=\"parPageSelect\">\n\t\t\t\t<option v-for=\"v in tparpage\" :key=\"v\">{{v}}</option>\n\t\t\t</select>\n\t\t\t<input class=\"gamutable--rechercher\" type=\"text\" v-model=\"search\" placeholder=\"Rechercher\">\n\t\t\t<button class=\"btn gamutable--resetOrderBy\" type=\"button\" @click.stop=\"resetTri()\">R\xE9initialiser les tris des colonnes</button>\n\t\t</div>\n\t\t<table class=\"table table--zebra\">\n\t\t\t<thead>\n\t\t\t\t<tr>\n\t\t\t\t\t<th v-for=\"(label,head,i) in header\" :key=\"'head_'+i\" :class=\"head\">\n\t\t\t\t\t\t<span v-html=\"label\"></span>\n\t\t\t\t\t\t<span class=\"iconeTri\">\n\t\t\t\t\t\t\t<i class=\"fa fa-sort-asc\" :class=\"ordreActif(head, 'asc')\" aria-hidden=\"true\" @click.stop=\"tri(head,'asc')\"></i>\n\t\t\t\t\t\t\t<i class=\"fa fa-sort-desc\":class=\"ordreActif(head, 'desc')\" aria-hidden=\"true\" @click.stop=\"tri(head,'desc')\" ></i>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</th>\n\t\t\t\t</tr>\n\t\t\t</thead>\n\t\t\t<tbody>\n\t\t\t\t<tr v-for=\"l in tableau\" :key=\"l.html.id\" :class=\"selectTr.indexOf(l.html.id) !== -1 ? 'select' : ''\" >\n\t\t\t\t\t<td v-for=\"(td,name, i) in l.html\" :key=\"'td_'+i\" :class=\"[afficher_crayons(name,l.html.id), name]\" v-html=\"td\" @click=\"selectLigne(l.html.id,name)\">\n\t\t\t\t\t</td>\n\t\t\t\t</tr>\n\t\t\t</tbody>\n\t\t</table>\n\t\t<div class=\"gamutable--sousTable\">\n\t\t\t<div class=\"gamutable-nbrMax\">{{table.length}} \xE9l\xE9ments</div>\n\t\t\t<div class=\"gamutable--pagination\">\n\t\t\t\t<div class=\"page-item\">\n\t\t\t\t\t<button type=\"button\" class=\"page-link\" v-if=\"page != 1\" @click=\"page=1\"> Start </button>\n\t\t\t\t\t<button type=\"button\" class=\"page-link\" v-if=\"page != 1\" @click=\"page--\"> Previous </button>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"page-item\">\n\t\t\t\t\t<button type=\"button\" class=\"page-link\" v-for=\"pageNumber in pages.slice(page-1, page+5)\" @click=\"page = pageNumber\"> {{pageNumber}} </button>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"page-item\">\n\t\t\t\t\t<button type=\"button\" @click=\"page++\" v-if=\"page < pages.length\" class=\"page-link\"> Next </button>\n\t\t\t\t\t<button type=\"button\" @click=\"page=pages.length\" v-if=\"page < pages.length\" class=\"page-link\"> Last </button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</div>"
|
|
};
|
|
var app = new Vue({
|
|
el: '#app',
|
|
components: {
|
|
monTableau: monTableau
|
|
},
|
|
methods: {
|
|
rechargerJson: function rechargerJson(id) {
|
|
this.$refs.montableau.chargerJson(id);
|
|
}
|
|
}
|
|
}); |