378 lines
9.6 KiB
JavaScript
378 lines
9.6 KiB
JavaScript
jQuery(function () {
|
|
// pour les #URL_ACTION_AUTEUR
|
|
// il faut ajouter une class : url_action
|
|
$('#app').on('click', '.url_action', function (e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
let confirmation = $(this).data('confirm');
|
|
if (confirmation !== undefined) {
|
|
if (!confirm(confirmation)) {
|
|
return;
|
|
}
|
|
}
|
|
let url = $(this).attr('href');
|
|
let 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();
|
|
}
|
|
});
|
|
});
|
|
|
|
// lancement d'une modalbox
|
|
$('#app').on('click', '.modalbox', function (e) {
|
|
e.preventDefault();
|
|
let confirmation = $(this).data('confirm');
|
|
if (confirmation !== undefined) {
|
|
if (!confirm(confirmation)) {
|
|
return;
|
|
}
|
|
}
|
|
let url = $(this).attr('href');
|
|
url += '&var_zajax=content';
|
|
$.modalbox(url);
|
|
});
|
|
|
|
// lancement d'une médiabox
|
|
$('#app').on('click', '.mediabox', function (e) {
|
|
e.preventDefault();
|
|
let confirmation = $(this).data('confirm');
|
|
if (confirmation !== undefined) {
|
|
if (!confirm(confirmation)) {
|
|
return;
|
|
}
|
|
}
|
|
let href = $(this).attr('href');
|
|
$.fn.mediabox({ href });
|
|
});
|
|
});
|
|
function recupJson(d) {
|
|
try {
|
|
return JSON.parse(d);
|
|
} catch (e) {
|
|
return [];
|
|
}
|
|
}
|
|
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[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;
|
|
|
|
// Gestion du format de date
|
|
// transforme 03/11/2000 en 20001103
|
|
let re = /^(\d{2})\/(\d{2})\/(\d{2,4})$/;
|
|
|
|
if (typeof p1 !== 'number') {
|
|
let r1 = p1.match(re);
|
|
if (Array.isArray(r1)) {
|
|
p1 = r1[3] + r1[2] + r1[1];
|
|
}
|
|
|
|
let 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');
|
|
});
|
|
|
|
function exporterCSV(json, delimitercsv, name) {
|
|
let csv = '';
|
|
json.forEach((l) => {
|
|
csv += l.join(delimitercsv);
|
|
csv += '\r\n';
|
|
});
|
|
//Download the file as CSV
|
|
let link = document.createElement('a');
|
|
link.setAttribute('href', 'data:text/csv;charset=utf-8,%EF%BB%BF' + encodeURIComponent(csv));
|
|
link.setAttribute('download', name);
|
|
link.style.visibility = 'hidden';
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
}
|
|
|
|
let monTableau = {
|
|
props: {
|
|
tparpage: {
|
|
type: Array,
|
|
default: function () {
|
|
return [10, 20, 50, 'Tous'];
|
|
},
|
|
},
|
|
apiuri: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
objet: {
|
|
type: String,
|
|
},
|
|
champcsv: {
|
|
type: String,
|
|
},
|
|
delimitercsv: {
|
|
type: String,
|
|
},
|
|
namecsv: {
|
|
type: String,
|
|
},
|
|
},
|
|
data: function () {
|
|
return {
|
|
table: [],
|
|
header: [],
|
|
crayons: [],
|
|
search: '',
|
|
page: 1,
|
|
parPage: this.tparpage[0],
|
|
parPageSelect: this.tparpage[0],
|
|
pages: [],
|
|
triOrders: [],
|
|
triProps: [],
|
|
selectTr: [],
|
|
champ_search: 'html',
|
|
chargement: true,
|
|
};
|
|
},
|
|
mounted() {
|
|
this.chargerJson();
|
|
},
|
|
computed: {
|
|
tableau: function () {
|
|
this.setPages();
|
|
if (!this.search) {
|
|
return this.pagination(this.table);
|
|
}
|
|
return this.pagination(
|
|
this.table.filter((ligne) =>
|
|
Object.values(ligne[this.champ_search])
|
|
.toString()
|
|
.toLowerCase()
|
|
.indexOf(this.search.toLowerCase()) < 0
|
|
? false
|
|
: true
|
|
)
|
|
);
|
|
},
|
|
},
|
|
watch: {
|
|
parPageSelect(e) {
|
|
if (!parseInt(e)) {
|
|
this.parPage = this.table.length;
|
|
} else {
|
|
this.parPage = e;
|
|
}
|
|
},
|
|
table() {
|
|
let $table = [];
|
|
$table = [
|
|
...[
|
|
{
|
|
header: this.header,
|
|
crayons: this.crayons,
|
|
},
|
|
],
|
|
...this.table,
|
|
];
|
|
localStorage.setItem('gamuTable', JSON.stringify($table));
|
|
},
|
|
},
|
|
methods: {
|
|
chargerJson(id) {
|
|
let url = this.apiuri;
|
|
if (parseInt(id) > 0) {
|
|
url += '&id=' + id;
|
|
} else {
|
|
let data = localStorage.getItem('gamuTable');
|
|
data = recupJson(data);
|
|
if (data && data.length) {
|
|
let config = data.shift();
|
|
this.header = config.header;
|
|
this.crayons = config.crayons;
|
|
this.table = data;
|
|
if (data.length && data[0].search) {
|
|
this.champ_search = 'search';
|
|
}
|
|
console.log('fin chargement localStorage');
|
|
}
|
|
}
|
|
fetch(url)
|
|
.then((response) => response.json())
|
|
.then((data) => {
|
|
let config = data.shift();
|
|
this.header = config.header;
|
|
this.crayons = config.crayons;
|
|
if (parseInt(id) > 0) {
|
|
let i = this.table.findIndex((ligne) => ligne.html.id === parseInt(id));
|
|
Vue.set(this.table, i, data[0]);
|
|
} else {
|
|
this.table = data;
|
|
if (data[0].search) {
|
|
this.champ_search = 'search';
|
|
}
|
|
}
|
|
Vue.nextTick(() => {
|
|
this.chargement = false;
|
|
console.timeEnd('Chargement de VueJs APRES Ajax');
|
|
});
|
|
})
|
|
.catch((error) => console.log(error));
|
|
},
|
|
setPages() {
|
|
let nombreDePages = Math.ceil(this.table.length / this.parPage);
|
|
this.pages = [];
|
|
for (let index = 1; index <= nombreDePages; index++) {
|
|
this.pages.push(index);
|
|
}
|
|
},
|
|
pagination(tableau) {
|
|
let page = this.page;
|
|
let parPage = this.parPage;
|
|
let from = page * parPage - parPage;
|
|
let to = page * parPage;
|
|
return tableau.slice(from, to);
|
|
},
|
|
afficher_crayons(name, id) {
|
|
if (Object.keys(this.crayons).indexOf(name) !== -1) {
|
|
return `crayon ${this.crayons[name]}-${name}-${id}`;
|
|
}
|
|
},
|
|
tri(col, sens) {
|
|
const 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(col, sens) {
|
|
const i = this.triProps.indexOf(col);
|
|
if (i !== -1) {
|
|
if (this.triOrders[i] === sens) {
|
|
return 'active';
|
|
}
|
|
}
|
|
},
|
|
resetTri() {
|
|
this.table = orderBy(this.table, ['id'], '', this.champ_search);
|
|
this.triOrders = [];
|
|
this.triProps = [];
|
|
},
|
|
selectLigne(id, col) {
|
|
if (col === 'id' && parseInt(id)) {
|
|
let i = this.selectTr.indexOf(id);
|
|
if (i !== -1) {
|
|
this.selectTr.splice(i, 1);
|
|
} else {
|
|
this.selectTr.push(id);
|
|
}
|
|
}
|
|
},
|
|
exportCSV(filtrage = true) {
|
|
let $csv = [];
|
|
let $header = [];
|
|
let $tableau = [];
|
|
Object.keys(this.header).forEach((k) => $header.push(k));
|
|
$tableau = this.tableau.reduce((acc, ligne) => {
|
|
let $uneLigne = [];
|
|
Object.values(ligne[this.champcsv]).forEach((l) => $uneLigne.push(l));
|
|
return [...acc, [...$uneLigne]];
|
|
}, []);
|
|
$csv = [[...$header], ...$tableau];
|
|
//console.log($csv);
|
|
exporterCSV($csv, this.delimitercsv, this.namecsv);
|
|
},
|
|
},
|
|
template: `
|
|
<div class="gamutable">
|
|
<div class="gamutable--surTable">
|
|
<select id="parPage" v-model="parPageSelect">
|
|
<option v-for="v in tparpage" :key="v">{{v}}</option>
|
|
</select>
|
|
<input class="gamutable--rechercher" type="text" v-model="search" placeholder="Rechercher">
|
|
<button class="btn gamutable--resetOrderBy" type="button" @click.stop="resetTri()">Réinitialiser les tris des colonnes</button>
|
|
<button class="btn gamutable--exportCSV" type="button" @click.stop="exportCSV()"
|
|
title="Exporter le tableau affiché en csv"
|
|
>
|
|
<i class="fa fa-file-excel-o" aria-hidden="true"></i>
|
|
</button>
|
|
<span v-show="chargement" class="rouge">
|
|
<i class="fa fa-refresh fa-spin fa-fw rouge"></i>
|
|
Mise à jour de la base de donnée
|
|
</span>
|
|
<span v-show="!chargement" class="verte">
|
|
<i class="fa fa-check"></i>
|
|
Base de données synchronisée
|
|
</span>
|
|
</div>
|
|
<table class="table table--zebra">
|
|
<thead>
|
|
<tr>
|
|
<th v-for="(label,head,i) in header" :key="'head_'+i" :class="head">
|
|
<span v-html="label"></span>
|
|
<span class="iconeTri">
|
|
<i class="fa fa-sort-asc" :class="ordreActif(head, 'asc')" aria-hidden="true" @click.stop="tri(head,'asc')"></i>
|
|
<i class="fa fa-sort-desc":class="ordreActif(head, 'desc')" aria-hidden="true" @click.stop="tri(head,'desc')" ></i>
|
|
</span>
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<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>
|
|
</table>
|
|
<div class="gamutable--sousTable">
|
|
<div class="gamutable-nbrMax">{{table.length}} éléments</div>
|
|
<div class="gamutable--pagination">
|
|
<div class="page-item">
|
|
<button type="button" class="page-link" v-if="page != 1" @click="page=1"> Start </button>
|
|
<button type="button" class="page-link" v-if="page != 1" @click="page--"> Previous </button>
|
|
</div>
|
|
<div class="page-item">
|
|
<button type="button" class="page-link" v-for="pageNumber in pages.slice(page-1, page+5)" @click="page = pageNumber"> {{pageNumber}} </button>
|
|
</div>
|
|
<div class="page-item">
|
|
<button type="button" @click="page++" v-if="page < pages.length" class="page-link"> Next </button>
|
|
<button type="button" @click="page=pages.length" v-if="page < pages.length" class="page-link"> Last </button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>`,
|
|
};
|
|
|
|
let app = new Vue({
|
|
el: '#app',
|
|
components: { monTableau },
|
|
methods: {
|
|
rechargerJson(id) {
|
|
this.$refs.montableau.chargerJson(id);
|
|
},
|
|
},
|
|
});
|