//****************************************
// CLASSE JS_datagrid
// Datagrid
// Autore: Massimiliano Cuttini
// Versione: 1.3.2 - 16 gennaio 2018 - connessione automatica al modulo di ricerca
// Versione: 1.3.1 - 24 agosto 2016 - bug fix
// Versione: 1.3.0 - 8 giugno 2016
//****************************************
// contenitore di tutti i calendario e reference
var JS_datagrid_assoc = new Array();
function JS_datagrid(div_id, opt) {
//costruzione di un ID associativo autonomo
this.ID = JS_datagrid_assoc.length;
JS_datagrid_assoc[this.ID] = this;
this.method = "GET";
this.lang = {
"result_found": "Risultati trovati",
"total_pages": "Numero di pagine",
"result_per_page": "Risultati per pagina",
"no_results": "Nessun risultato"
};
this.div_id = div_id;
this.div = document.getElementById(div_id);
this.opt = opt;
if (this.div == null) {
alert("Non posso creare la tabella " + opt.name + ": non trovo il DIV");
return false;
}
this.div.innerHTML = '
\
\
';
this.table = $('#' + this.div_id + " table").get(0);
this.tHead = this.table.tHead;
this.tBody = this.table.tBodies[0];
this.search_form = false;
//DEFAULT VALUES
this.nav = {
display : 0,
url : null,
urlupdate : false,
query : null,
orderBy : null,
page : 1,
results : 20,
range : 5,
tot_results: null,
onclick : function () {
this.nav._parent.loadData(this.nav.query, this.nav.results, this.nav.page, this.nav.orderBy);
return false;
}
};
this.dataset = null;
//OPTION
this.autoindex = (opt["autoindex"]) ? opt["autoindex"] : null;
this.data_source = (opt["data_source"]) ? opt["data_source"] : null;
this.getRowStyle = (opt["setRowClass"]) ? opt["setRowClass"] : function () {
return false;
};
if (opt["method"]) this.setMethod(opt["method"]);
if (opt["lang"]) this.setLanguage(opt["lang"]);
if (opt["columns"]) this.setColumns(opt["columns"]);
if (opt["dataset"]) this.setData(opt["dataset"]);
if (opt["nav"]) this.setNavigator(opt["nav"]);
}
JS_datagrid.prototype.setMethod = function (method) {
method = method.toUpperCase();
if (method!="GET" && method!="POST") {
alert("Metodo "+method+" non permesso");
}
this.method = method;
}
JS_datagrid.prototype.setLanguage = function (dictionary) {
for (var i in dictionary) this.lang[i] = dictionary[i];
}
JS_datagrid.prototype.setNavigator = function (nav_obj) {
for (var i in nav_obj) this.nav[i] = nav_obj[i];
if (this.nav.results) {
this.nav.tot_pages = (Math.ceil(this.nav.tot_results / this.nav.results));
}
var divnav = $('#' + this.div_id + " .datagrid_navigator_top");
if (!this.nav.display || this.nav.display == "bottom") divnav.hide(); else {
divnav.find(".datagrid_tot_results").html(this.lang.result_found+": " + this.nav["tot_results"] + "");
divnav.find(".datagrid_tot_pages").html(this.lang.total_pages+": " + this.nav["tot_pages"] + "");
divnav.find(".datagrid_nav_results").html(this.lang.result_per_page+": " + this.nav["results"] + "");
var div_a = divnav.find(" .datagrid_nav_pages").get();
for (var div_n in div_a) this.updatePageIndex(div_a[div_n]);
divnav.show();
}
var divnav = $('#' + this.div_id + " .datagrid_navigator_bottom");
if (!this.nav.display || this.nav.display == "top") divnav.hide(); else {
divnav.find(".datagrid_tot_results").html(this.lang.result_found+": " + this.nav["tot_results"] + "");
divnav.find(".datagrid_tot_pages").html(this.lang.total_pages+": " + this.nav["tot_pages"] + "");
divnav.find(".datagrid_nav_results").html(this.lang.result_per_page+": " + this.nav["results"] + "");
var div_a = divnav.find(" .datagrid_nav_pages").get();
for (var div_n in div_a) this.updatePageIndex(div_a[div_n]);
divnav.show();
}
if (this.nav.urlupdate) {
var m = this;
window.onhashchange = function() {
m.onHashChange();
};
}
};
JS_datagrid.prototype.getNavigator = function () {
return this.nav;
};
JS_datagrid.prototype.getHash = function() {
//scarichiamo il nuovo HASH
var hashObj = {};
var h = parent.location.hash.substring(1, parent.location.hash.length);
var pieces = h.split("&");
for (var i = 0; i < pieces.length; i++) {
var d = pieces[i].split("=");
hashObj[decodeURIComponent(d[0])] = (d[1]=="null") ? null : decodeURIComponent(d[1]);
}
return hashObj;
};
JS_datagrid.prototype.onHashChange = function() {
var hashObj = this.getHash();
//verifichiamo eventuali differenze
var nav = this.nav;
var query = (hashObj["query"]) ? hashObj["query"] : nav.query;
var results = (hashObj["results"]) ? hashObj["results"] : nav.results;
var page = (hashObj["page"]) ? hashObj["page"] : nav.page;
var orderBy = (hashObj["orderBy"]) ? hashObj["orderBy"] : nav.orderBy;
if (nav.query!=query || nav.results!=results || nav.page!=page || nav.orderBy!=orderBy) {
// this._debug("onhashchange: Qualcosa è cambiato");
// this._debug("query: "+nav.query+"|"+query);
// this._debug("query: "+nav.results+"|"+results);
// this._debug("query: "+nav.page+"|"+page);
// this._debug("query: "+nav.orderBy+"|"+orderBy);
this.loadData(query,results,page,orderBy);
return true;
} else {
// this._debug("onhashchange: Niente è cambiato");
return false;
}
};
JS_datagrid.prototype.loadFromSearch = function () {
if (this.search_form) {;
return this.doSearch(getFieldsInForm(this.search_form));
} else {
alert("Modulo di ricerca non impostato");
}
};
JS_datagrid.prototype.loadFromHash = function () {
if (this.search_form) {
var hashObj = this.getHash();
if (hashObj["query"]) {
setFieldsInForm(this.search_form, JSON.parse(hashObj["query"]));
}
}
var loaded = this.onHashChange();
if (!loaded) this.reloadData();
};
JS_datagrid.prototype.loadData = function (query, results, page, orderBy) {
this.removeSearchTimer();
if (this.data_source == null) {
alert("La sorgente dati non è stata definita");
return false;
}
//chiama evento
this.onGetDataStart(query, results, page, orderBy);
var querystring = "";
if (this.method=="GET") {
querystring = "q=" + encodeURIComponent(query) + "&r=" + results + "&p=" + page + "&s=" + orderBy;
} else if (this.method=="POST") {
querystring = "data=" + encodeURIComponent(JSON.stringify({"q":JSON.parse(query),"r":results,"p":page,"s":orderBy}));
} else {
alert("Il metodo specificato può essere solo GET o POST: è stato specificato "+this.method);
return false;
};
$.ajax({
url: this.data_source,
type: this.method,
data: querystring,
dataType: "html",
_parent: this,
success: function(msg) {
try {
var R = JSON.parse(msg);
if (R==null || R=="") throw "Parser JSON fallito";
} catch (err) {
this._parent._debug(err);
this._parent._debug(msg);
return false;
}
//this._parent._debug(R);
if (R.status) {
if (R.nav) {
R.nav.query = query;
this._parent.setNavigator(R.nav);
}
this._parent.setData(R.dataset);
this._parent.onGetDataSuccess(R);
if (this._parent.nav.urlupdate) {
//parent.location.replace(parent.location.pathname + "?query=" + encodeURIComponent(query) + "&page=" + page + "&results=" + results + "&orderBy=" + orderBy);
parent.location.hash = "query=" + encodeURIComponent(query) + "&page=" + page + "&results=" + results + "&orderBy=" + orderBy;
}
} else {
this._parent.onGetDataError(R);
}
return true;
},
error: function(obj) {
if (obj.readyState==0) {
_debug("Chiamata interrotta");
} else {
this._parent.onGetDataError("Errore durante lo scaricamento delle informazioni");
_debug(obj);
}
}
});
};
JS_datagrid.prototype.reloadData = function () {
this.loadData(this.nav.query, this.nav.results, this.nav.page, this.nav.orderBy);
};
JS_datagrid.prototype.onGetDataStart = function (query, results, page, orderBy) {
//user defined function
//standard behaviour
$('#' + this.div_id).fadeTo(200, 0.20);
};
JS_datagrid.prototype.onGetDataSuccess = function (R) {
//user defined function
//standard behaviour
$('#' + this.div_id).fadeTo(100, 1);
};
JS_datagrid.prototype.onGetDataError = function (R) {
//user defined function
//standard behaviour
$('#' + this.div_id).fadeTo(100, 1);
alert("Impossibile scaricare i dati per la tabella " + this.opt.name + " " + R.error);
};
JS_datagrid.prototype.setData = function (dataset) {
this.dataset = dataset;
this.rebuildIndex();
this.updateTable();
};
JS_datagrid.prototype.rebuildIndex = function () {
var new_index = new Array();
if (this.dataset != null && this.opt.autoindex != null) {
for (var c in this.dataset) {
if (this.dataset[c] != null) {
var key = this.dataset[c][this.autoindex];
new_index[String(key)] = c;
}
}
}
this.index = new_index;
};
JS_datagrid.prototype.getElementIndex = function (id) {
return this.index[String(id)];
};
JS_datagrid.prototype.getElementByID = function (id) {
return this.dataset[this.getElementIndex(id)];
};
JS_datagrid.prototype.setColumns = function (columns) {
this.columns = columns;
var result = this.checkColumnsRecursive(this.columns,1);
this.columnsReal = result[0];
this.rowSpan = result[1];
this.updateTable();
};
JS_datagrid.prototype.checkColumnsRecursive = function (columns,rowSpan) {
var c = [];
var rowSpanMax = rowSpan;
for (var l = 0; l < columns.length; l++) {
var d = columns[l];
if (d === undefined || d.groupName === undefined) {
c[c.length]=d;
continue;
}
if (d.groupName !== undefined) {
var result = this.checkColumnsRecursive(d.columns,rowSpan+1);
c = c.concat(result[0]);
if (result[1] > rowSpanMax) rowSpanMax = result[1];
}
}
return [c,rowSpanMax];
};
JS_datagrid.prototype.columnsHeaders = function (row, columns, rowSpan) {
var columns_group = [];
for (var i = 0; i < columns.length; i++) {
var d = columns[i];
var cell = row.insertCell(-1);
// CELLA SEPARATORE
if (d == undefined) {
cell.rowSpan = rowSpan;
cell.className = "separator";
continue;
}
// CELLA GRUPPO
if (d.groupName != null) {
if (rowSpan > 1) {
if (rowSpan>2) cell.rowSpan = rowSpan - 1;
cell.colSpan = d.columns.length;
cell.className = "th_label";
cell.innerHTML = d.groupName;
columns_group = columns_group.concat(d.columns);
}
continue;
}
// CELLA NORMALE
cell.rowSpan = rowSpan;
if (d.width != null) {
cell.style.width = d.width;
}
cell.className = "th_label";
if (columns[i].label == undefined) columns[i].label = this.ucwords(columns[i].field);
cell.innerHTML = d.label;
for (var s in d.labelStyle) cell.style[s] = d.labelStyle[s];
}
return columns_group;
};
JS_datagrid.prototype.updateTable = function () {
var timer = this._time();
// HEAD
var thead = this.tHead;
//PULISCI
for (var i = (thead.rows.length - 1); i >= 0; i--) thead.deleteRow(i);
//SCRIVI
var columns = this.columns;
var rowSpan = this.rowSpan;
while(rowSpan>0) {
var row = thead.insertRow(thead.rows.length);
columns = this.columnsHeaders(row, columns, rowSpan);
rowSpan--;
};
// INSERIAMO QUI IL SORTER
var row = thead.insertRow(thead.rows.length);
for (var l = 0; l < this.columnsReal.length; l++) {
if (this.columnsReal[l] == undefined) {
var cell = row.insertCell(-1);
cell.className = "separator";
continue;
}
var d = this.columnsReal[l];
var cell = row.insertCell(-1);
if (d.sortable) {
//div sortable
var div_sort_container = document.createElement("div");
div_sort_container.className = "th_container";
cell.appendChild(div_sort_container);
var div_sort = document.createElement("div");
div_sort.className = "th_sort";
div_sort_container.appendChild(div_sort);
var a_sort_asc = document.createElement("a");
var nav = {
_parent: this,
url: this.nav.url,
query: this.nav.query,
results: this.nav.results,
page: 1,
orderBy: d.field + "|ASC"
}
a_sort_asc.nav = nav;
a_sort_asc.onclick = this.nav.onclick;
a_sort_asc.href = nav.url + "#query=" + encodeURIComponent(nav.query) + "&page=" + nav.page + "&results=" + nav.results + "&orderBy=" + nav.orderBy;
a_sort_asc.className = "sort_asc";
a_sort_asc.innerHTML = "▲";
div_sort.appendChild(a_sort_asc);
var a_sort_des = document.createElement("a");
var nav = {
_parent: this,
url: this.nav.url,
query: this.nav.query,
results: this.nav.results,
page: 1,
orderBy: d.field + "|DES"
}
a_sort_des.nav = nav;
a_sort_des.onclick = this.nav.onclick;
a_sort_des.href = nav.url + "#query=" + encodeURIComponent(nav.query) + "&page=" + nav.page + "&results=" + nav.results + "&orderBy=" + nav.orderBy;
a_sort_des.className = "sort_des";
a_sort_des.innerHTML = "▼";
div_sort.appendChild(a_sort_des);
}
}
//BODY
var tbody = this.tBody;
for (var i = (tbody.rows.length - 1); i >= 0; i--) tbody.deleteRow(i);
// DATASET VUOTO
if (this.dataset == null || !this.dataset || (Array.isArray(this.dataset) && !this.dataset.length)) {
var row = tbody.insertRow(tbody.rows.length);
var cell = row.insertCell(0);
cell.colSpan = this.columnsReal.length;
cell.innerHTML = this.lang.no_results;
return true;
}
// CICLO IL DATASET
for (var i in this.dataset) {
this.insertRow(this.dataset[i]);
}
};
JS_datagrid.prototype.insertRow = function (r) {
var tbody = this.tBody;
// NEW ROW
var rowCount = tbody.rows.length;
var row = tbody.insertRow(rowCount);
var rclass = this.getRowStyle(r);
if (rclass) row.className = rclass;
if (this.autoindex!=null) row.setAttribute("name",r[this.autoindex]);
var default_style = {
textAlign: "center"
};
for (var l = 0; l < this.columnsReal.length; l++) {
var d = this.columnsReal[l];
if (d === undefined) {
var cell = row.insertCell(-1);
cell.className = "separator";
continue;
}
var cell = row.insertCell(-1);
var style = (d.style != null) ? d.style : default_style;
for (var i in style) cell.style[i] = style[i];
cell.innerHTML = (d.format != null) ? d.format(r) : r[d.field];
}
};
JS_datagrid.prototype.updatePageIndex = function (links_div) {
//config
var range = this.nav.range * 1;
var page = this.nav.page * 1;
var results = this.nav.results * 1;
var tot_results = this.nav.tot_results * 1;
var tot_pages = this.nav.tot_pages * 1;
//reset
links_div.innerHTML = "";
range -= Math.min(0, page - range + 2, tot_pages - page + range + 1);
for (var j = 1; j <= tot_pages; j++) {
var a_new = document.createElement("a");
if (
j == 1 || //prima pagina
j == tot_pages || //ultima pagina
(j > (page - range) && j < (page + range)) //pagine centrali
) {
var nav = {
_parent: this,
url: this.nav.url,
query: this.nav.query,
results: this.nav.results,
page: j,
orderBy: this.nav.orderBy
}
var a_new = document.createElement("a");
a_new.innerHTML = j;
a_new.href = nav.url + "#query=" + encodeURIComponent(nav.query) + "&page=" + nav.page + "&results=" + nav.results + "&orderBy=" + nav.orderBy;
if (j == page) a_new.className = "actual_page";
a_new.nav = nav;
a_new.onclick = this.nav.onclick;
} else {
var a_new = document.createElement("span");
a_new.innerHTML = "..";
a_new.className = "disabled_page";
if (j < page)
j = page - range;
else if (j > page)
j = tot_pages - 1;
}
links_div.appendChild(a_new);
}
};
JS_datagrid.prototype.setSearchForm = function(form_id) {
this.search_form = form_id;
var m = this;
$("#"+this.search_form+" [data-search-type=instant]").keyup(
function() {
var s = getFieldsInForm(m.search_form);
m.instantSearch(s);
}
);
$("#"+this.search_form+" [data-search-type=instant]").change(
function() {
var s = getFieldsInForm(m.search_form);
m.instantSearch(s);
}
);
$("#"+this.search_form+" [data-search-type=standard]").blur(
function() {
var s = getFieldsInForm(m.search_form);
m.doSearch(s);
}
);
$("#"+this.search_form+" [data-search-type=standard]").change(
function() {
var s = getFieldsInForm(m.search_form);
m.doSearch(s);
}
);
$("#"+this.search_form).submit(
function() {
var s = getFieldsInForm(m.search_form);
m.doSearch(s);
return false;
}
);
};
JS_datagrid.prototype.instantSearch = function(searchNewQuery) {
if (this.searchTimer) window.clearTimeout(this.searchTimer);
var m = this;
this.searchTimer = setTimeout(function() {
m.doSearch(searchNewQuery);
}, 1000);
};
JS_datagrid.prototype.doSearch = function(searchNewQuery) {
if (this.arrayCompare(searchNewQuery,this.searchLastQuery)) {
// this._debug("Ricerca saltata, i parametri non sono cambiati");
// this._debug(searchNewQuery);
// this._debug(this.searchLastQuery);
return false;
}
this.searchLastQuery = searchNewQuery;
var q = JSON.stringify(searchNewQuery);
this.loadData(q, this.nav.results, 1, this.nav.orderBy);
return true;
};
JS_datagrid.prototype.removeSearchTimer = function() {
if (this.searchTimer) window.clearTimeout(this.searchTimer);
};
JS_datagrid.prototype._debug = function(str) {
if (typeof str === "object") str = JSON.stringify(str,null,2)
if (window.console) console.log(str);
};
JS_datagrid.prototype._time = function () {
var today = new Date();
return today.getTime();
};
JS_datagrid.prototype.ucwords = function (str) {
if (!str) return;
if (str == str.toUpperCase()) return str;
return (str + '').replace(/^([a-z\u00E0-\u00FC])|\s+([a-z\u00E0-\u00FC])/g, function ($1) {
return $1.toUpperCase();
});
};
JS_datagrid.prototype.arrayCompare = function(a,b) {
//this._debug("arrayCompare");
if (!a) return false;
if (!b) return false;
if (typeof Object.keys == 'function') {
if (Object.keys(a).length != Object.keys(b).length) return false;
} else {
for (var i in b) {
if (b[i] instanceof Array && a[i] instanceof Array) {
if (!b[i].compare(a[i])) return false;
}
//this._debug("comparazione di "+i+" tra "+a[i]+" = "+b[i]);
if (a[i] != b[i]) return false;
}
}
for (var i in a) {
if (a[i] instanceof Array && b[i] instanceof Array) {
if (!a[i].compare(b[i])) return false;
}
//this._debug("comparazione di "+i+" tra "+a[i]+" = "+b[i]);
if (a[i] != b[i]) return false;
}
return true;
};