Apres pas mal de tests, l'utilisation de regex pour récupérer un

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é
This commit is contained in:
Christophe 2020-05-08 14:46:07 +02:00
parent 99a6444c39
commit 60483a2f84
4 changed files with 70 additions and 33 deletions

View file

@ -37,11 +37,14 @@ function recupJson(d) {
return [];
}
}
const orderBy = (arr, props, orders) =>
const orderBy = (arr, props, orders, champ) =>
arr.sort((a, b) =>
props.reduce((acc, prop, i) => {
if (acc === 0) {
let [p1, p2] = orders && orders[i] === 'desc' ? [b[prop], a[prop]] : [a[prop], b[prop]];
let [p1, p2] =
orders && orders[i] === 'desc'
? [b[champ][prop], a[champ][prop]]
: [a[champ][prop], b[champ][prop]];
// passe en lowercase les String
p1 = typeof p1 === 'string' ? p1.toLowerCase() : p1;
p2 = typeof p2 === 'string' ? p2.toLowerCase() : p2;
@ -102,6 +105,7 @@ let monTableau = {
triOrders: [],
triProps: [],
selectTr: [],
champ_search: 'html',
};
},
mounted() {
@ -114,7 +118,12 @@ let monTableau = {
}
return this.pagination(
this.table.filter((ligne) =>
Object.values(ligne).toString().toLowerCase().indexOf(this.search.toLowerCase()) < 0 ? false : true
Object.values(ligne[this.champ_search])
.toString()
.toLowerCase()
.indexOf(this.search.toLowerCase()) < 0
? false
: true
)
);
},
@ -148,6 +157,9 @@ let monTableau = {
Vue.set(this.table, i, data[0]);
} else {
this.table = data;
if (data[0].search) {
this.champ_search = 'search';
}
}
Vue.nextTick(function () {
console.timeEnd('Chargement de VueJs APRES Ajax');
@ -182,7 +194,7 @@ let monTableau = {
this.triProps.push(col);
this.triOrders.push(sens);
}
this.table = orderBy(this.table, this.triProps, this.triOrders);
this.table = orderBy(this.table, this.triProps, this.triOrders, this.champ_search);
},
ordreActif(col, sens) {
const i = this.triProps.indexOf(col);
@ -193,7 +205,7 @@ let monTableau = {
}
},
resetTri() {
this.table = orderBy(this.table, ['id']);
this.table = orderBy(this.table, ['id'], '', this.champ_search);
this.triOrders = [];
this.triProps = [];
},
@ -230,8 +242,8 @@ let monTableau = {
</tr>
</thead>
<tbody>
<tr v-for="l in tableau" :key="l.id" :class="selectTr.indexOf(l.id) !== -1 ? 'select' : ''" >
<td v-for="(td,name, i) in l" :key="'td_'+i" :class="[afficher_crayons(name,l.id), name]" v-html="td" @click="selectLigne(l.id,name)">
<tr v-for="l in tableau" :key="l.html.id" :class="selectTr.indexOf(l.html.id) !== -1 ? 'select' : ''" >
<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)">
</td>
</tr>
</tbody>

View file

@ -49,11 +49,11 @@ function recupJson(d) {
}
}
var orderBy = function orderBy(arr, props, orders) {
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[prop], a[prop]] : [a[prop], b[prop]],
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
@ -120,7 +120,8 @@ var monTableau = {
pages: [],
triOrders: [],
triProps: [],
selectTr: []
selectTr: [],
champ_search: 'html'
};
},
mounted: function mounted() {
@ -135,7 +136,7 @@ var monTableau = {
}
return this.pagination(this.table.filter(function (ligne) {
return Object.values(ligne).toString().toLowerCase().indexOf(_this.search.toLowerCase()) < 0 ? false : true;
return Object.values(ligne[_this.champ_search]).toString().toLowerCase().indexOf(_this.search.toLowerCase()) < 0 ? false : true;
}));
}
},
@ -176,6 +177,10 @@ var monTableau = {
Vue.set(_this2.table, i, data[0]);
} else {
_this2.table = data;
if (data[0].search) {
_this2.champ_search = 'search';
}
}
Vue.nextTick(function () {
@ -215,7 +220,7 @@ var monTableau = {
this.triOrders.push(sens);
}
this.table = orderBy(this.table, this.triProps, this.triOrders);
this.table = orderBy(this.table, this.triProps, this.triOrders, this.champ_search);
},
ordreActif: function ordreActif(col, sens) {
var i = this.triProps.indexOf(col);
@ -227,7 +232,7 @@ var monTableau = {
}
},
resetTri: function resetTri() {
this.table = orderBy(this.table, ['id']);
this.table = orderBy(this.table, ['id'], '', this.champ_search);
this.triOrders = [];
this.triProps = [];
},
@ -243,7 +248,7 @@ var monTableau = {
}
}
},
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.id\" :class=\"selectTr.indexOf(l.id) !== -1 ? 'select' : ''\" >\n\t\t\t\t\t<td v-for=\"(td,name, i) in l\" :key=\"'td_'+i\" :class=\"[afficher_crayons(name,l.id), name]\" v-html=\"td\" @click=\"selectLigne(l.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>"
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',

View file

@ -35,22 +35,42 @@
</a>
})]
{
"id": #ID_SOUSCRIPTION,
"modif" : [(#VAL{<a class="modalbox" href="[(#URL_PAGE{souscrire}|parametre_url{id_souscription,#ID_SOUSCRIPTION}|parametre_url{redirect,gamutable})]"><i class="fa fa-pencil"></i></a>}|json_encode)],
"date" : [(#DATE|affdate{d/m/Y}|json_encode)],
"statut" : [(#GET{statut}|json_encode)],
"genre" : [(#GENRE|json_encode)],
"nom_souscripteur" : [(#NOM_SOUSCRIPTEUR|json_encode)],
"prenom" : [(#PRENOM|json_encode)],
"qui": [(#VAL{<a class="mediabox" title="Détail du souscripteur" href="[(#URL_PAGE{detail_souscription}|parametre_url{id_souscription,#ID_SOUSCRIPTION}|parametre_url{detail,qui})]"><i class="fa fa-address-book"></i></a>}|json_encode)],
"nbr" : [(#NOMBRE)],
"montant_part" : [(#MONTANT_PART)],
"montant" : [(#MONTANT)],
"prix": [(#VAL{<a class="mediabox" title="Détail de la souscription" href="[(#URL_PAGE{detail_souscription}|parametre_url{id_souscription,#ID_SOUSCRIPTION}|parametre_url{detail,prix})]"><i class="fa fa-shopping-cart"></i></a>}|json_encode)],
"type" : [(#TYPE|json_encode)],
"email" : [(#VAL{<a href="mailto:#EMAIL" target="_blank">#EMAIL</a>}|json_encode)],
"telephone" : [(#TELEPHONE|json_encode)],
"ou": [(#VAL{<a class="mediabox" title="Détail des coordonnées" href="[(#URL_PAGE{detail_souscription}|parametre_url{id_souscription,#ID_SOUSCRIPTION}|parametre_url{detail,adresse})]"><i class="fa fa-address-card"></i></a>}|json_encode)]
"html": {
id": #ID_SOUSCRIPTION,
"modif" : [(#VAL{<a class="modalbox" href="[(#URL_PAGE{souscrire}|parametre_url{id_souscription,#ID_SOUSCRIPTION}|parametre_url{redirect,gamutable})]"><i class="fa fa-pencil"></i></a>}|json_encode)],
"date" : [(#DATE|affdate{d/m/Y}|json_encode)],
"statut" : [(#GET{statut}|json_encode)],
"genre" : [(#GENRE|json_encode)],
"nom_souscripteur" : [(#NOM_SOUSCRIPTEUR|json_encode)],
"prenom" : [(#PRENOM|json_encode)],
"qui": [(#VAL{<a class="mediabox" title="Détail du souscripteur" href="[(#URL_PAGE{detail_souscription}|parametre_url{id_souscription,#ID_SOUSCRIPTION}|parametre_url{detail,qui})]"><i class="fa fa-address-book"></i></a>}|json_encode)],
"nbr" : [(#NOMBRE)],
"montant_part" : [(#MONTANT_PART)],
"montant" : [(#MONTANT)],
"prix": [(#VAL{<a class="mediabox" title="Détail de la souscription" href="[(#URL_PAGE{detail_souscription}|parametre_url{id_souscription,#ID_SOUSCRIPTION}|parametre_url{detail,prix})]"><i class="fa fa-shopping-cart"></i></a>}|json_encode)],
"type" : [(#TYPE|json_encode)],
"email" : [(#VAL{<a href="mailto:#EMAIL" target="_blank">#EMAIL</a>}|json_encode)],
"telephone" : [(#TELEPHONE|json_encode)],
"ou": [(#VAL{<a class="mediabox" title="Détail des coordonnées" href="[(#URL_PAGE{detail_souscription}|parametre_url{id_souscription,#ID_SOUSCRIPTION}|parametre_url{detail,adresse})]"><i class="fa fa-address-card"></i></a>}|json_encode)]
},
search: {
id": #ID_SOUSCRIPTION,
"modif" : "",
"date" : [(#DATE|affdate{d/m/Y}|json_encode)],
"statut" : [(#GET{statut}|json_encode)],
"genre" : [(#GENRE|json_encode)],
"nom_souscripteur" : [(#NOM_SOUSCRIPTEUR|json_encode)],
"prenom" : [(#PRENOM|json_encode)],
"qui": "",
"nbr" : [(#NOMBRE)],
"montant_part" : [(#MONTANT_PART)],
"montant" : [(#MONTANT)],
"prix": "",
"type" : [(#TYPE|json_encode)],
"email" : [(#EMAIL|json_encode)],
"telephone" : [(#TELEPHONE|json_encode)],
"ou": ""
}
}
</BOUCLE_souscriptions>
]

View file

@ -1,7 +1,7 @@
<paquet
prefix="gamutable"
categorie="outil"
version="1.0.0"
version="2.0.0"
etat="dev"
compatibilite="[3.2.0-dev;3.3.*]"
logo="prive/themes/spip/images/gamutable-xx.svg"
@ -12,13 +12,13 @@
-->
<nom>GamuTable</nom>
<auteur lien='https://gamuza.fr'>tofulm</auteur>
<licence>GNU/GPL</licence>
<pipeline nom="autoriser" inclure="gamutable_autorisations.php" />
<pipeline nom="autoriser" inclure="gamutable_autorisations.php" />
</paquet>