FCLT#59401 Single page als gebouwdashboard - prototype Facilitor 2020 Work In Progress
svn path=/Website/trunk/; revision=44743
This commit is contained in:
905
APPL/Consoles/console.js
Normal file
905
APPL/Consoles/console.js
Normal file
@@ -0,0 +1,905 @@
|
||||
/*
|
||||
$Revision$
|
||||
$Id$
|
||||
|
||||
File: console.js
|
||||
|
||||
Description: Generic include file for consoles for Facilitor
|
||||
|
||||
|
||||
*/
|
||||
|
||||
var targets = {},
|
||||
models = {},
|
||||
day_in_ms = 86400000,
|
||||
language = "EN",
|
||||
windowObjectReference;
|
||||
|
||||
|
||||
/* Configuration parameters, eventually to be defined elsewhere */
|
||||
const api_locations_filter = "";
|
||||
const api_buildings_filter = "&buildingfunction=^81"; // exclude de Vervallen gebouwen
|
||||
const api_disciplinetypes_filter = "";
|
||||
const api_issuedisciplines_filter = "";
|
||||
const api_issuetypes_filter = "";
|
||||
const api_contracts_filter = "";
|
||||
const api_floors_filter = "";
|
||||
const api_issues_filter = "&issuetype=^2801"; // exclude de Tolkdiensten
|
||||
const api_orders_filter = "";
|
||||
const api_reportsx_filter = "&id=2246"; // test this one
|
||||
const api_reports_filter = "&melding_gebouwcode=ALKW2&scf_pivot=1"; // test-only
|
||||
|
||||
|
||||
/* System constants */
|
||||
var dataTables_i18n = {
|
||||
NL: {
|
||||
"sProcessing": "Bezig...",
|
||||
"sLengthMenu": "_MENU_ resultaten weergeven",
|
||||
"sZeroRecords": "Geen resultaten gevonden",
|
||||
"sInfo": "_START_ tot _END_ van _TOTAL_ resultaten",
|
||||
"sInfoEmpty": "Geen resultaten om weer te geven",
|
||||
"sInfoFiltered": " (gefilterd uit _MAX_ resultaten)",
|
||||
"sInfoPostFix": "",
|
||||
"sSearch": "Zoeken:",
|
||||
"sEmptyTable": "Geen resultaten aanwezig in de tabel",
|
||||
"sInfoThousands": ".",
|
||||
"sLoadingRecords": "Een moment geduld aub - bezig met laden...",
|
||||
"oPaginate": {
|
||||
"sFirst": "Eerste",
|
||||
"sLast": "Laatste",
|
||||
"sNext": "Volgende",
|
||||
"sPrevious": "Vorige"
|
||||
},
|
||||
"oAria": {
|
||||
"sSortAscending": ": activeer om kolom oplopend te sorteren",
|
||||
"sSortDescending": ": activeer om kolom aflopend te sorteren"
|
||||
}
|
||||
},
|
||||
DE: {
|
||||
"sEmptyTable": "Keine Daten in der Tabelle vorhanden",
|
||||
"sInfo": "_START_ bis _END_ von _TOTAL_ Einträgen",
|
||||
"sInfoEmpty": "Keine Daten vorhanden",
|
||||
"sInfoFiltered": "(gefiltert von _MAX_ Einträgen)",
|
||||
"sInfoPostFix": "",
|
||||
"sInfoThousands": ".",
|
||||
"sLengthMenu": "_MENU_ Einträge anzeigen",
|
||||
"sLoadingRecords": "Wird geladen ..",
|
||||
"sProcessing": "Bitte warten ..",
|
||||
"sSearch": "Suchen",
|
||||
"sZeroRecords": "Keine Einträge vorhanden",
|
||||
"oPaginate": {
|
||||
"sFirst": "Erste",
|
||||
"sPrevious": "Zurück",
|
||||
"sNext": "Nächste",
|
||||
"sLast": "Letzte"
|
||||
},
|
||||
"oAria": {
|
||||
"sSortAscending": ": aktivieren, um Spalte aufsteigend zu sortieren",
|
||||
"sSortDescending": ": aktivieren, um Spalte absteigend zu sortieren"
|
||||
},
|
||||
"select": {
|
||||
"rows": {
|
||||
"_": "%d Zeilen ausgewählt",
|
||||
"0": "",
|
||||
"1": "1 Zeile ausgewählt"
|
||||
}
|
||||
},
|
||||
"buttons": {
|
||||
"print": "Drucken",
|
||||
"colvis": "Spalten",
|
||||
"copy": "Kopieren",
|
||||
"copyTitle": "In Zwischenablage kopieren",
|
||||
"copyKeys": "Taste <i>ctrl</i> oder <i>\u2318</i> + <i>C</i> um Tabelle<br>in Zwischenspeicher zu kopieren.<br><br>Um abzubrechen die Nachricht anklicken oder Escape drücken.",
|
||||
"copySuccess": {
|
||||
"_": "%d Zeilen kopiert",
|
||||
"1": "1 Zeile kopiert"
|
||||
},
|
||||
"pageLength": {
|
||||
"-1": "Zeige alle Zeilen",
|
||||
"_": "Zeige %d Zeilen"
|
||||
}
|
||||
}
|
||||
},
|
||||
EN: {
|
||||
"sEmptyTable": "No data available in table",
|
||||
"sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
|
||||
"sInfoEmpty": "Showing 0 to 0 of 0 entries",
|
||||
"sInfoFiltered": "(filtered from _MAX_ total entries)",
|
||||
"sInfoPostFix": "",
|
||||
"sInfoThousands": ",",
|
||||
"sLengthMenu": "Show _MENU_ entries",
|
||||
"sLoadingRecords": "Loading...",
|
||||
"sProcessing": "Processing...",
|
||||
"sSearch": "Search:",
|
||||
"sZeroRecords": "No matching records found",
|
||||
"oPaginate": {
|
||||
"sFirst": "First",
|
||||
"sLast": "Last",
|
||||
"sNext": "Next",
|
||||
"sPrevious": "Previous"
|
||||
},
|
||||
"oAria": {
|
||||
"sSortAscending": ": activate to sort column ascending",
|
||||
"sSortDescending": ": activate to sort column descending"
|
||||
}
|
||||
},
|
||||
FR: {
|
||||
"sEmptyTable": "Aucune donnée disponible dans le tableau",
|
||||
"sInfo": "Affichage de l'élément _START_ à _END_ sur _TOTAL_ éléments",
|
||||
"sInfoEmpty": "Affichage de l'élément 0 à 0 sur 0 élément",
|
||||
"sInfoFiltered": "(filtré à partir de _MAX_ éléments au total)",
|
||||
"sInfoPostFix": "",
|
||||
"sInfoThousands": ",",
|
||||
"sLengthMenu": "Afficher _MENU_ éléments",
|
||||
"sLoadingRecords": "Chargement...",
|
||||
"sProcessing": "Traitement...",
|
||||
"sSearch": "Rechercher :",
|
||||
"sZeroRecords": "Aucun élément correspondant trouvé",
|
||||
"oPaginate": {
|
||||
"sFirst": "Premier",
|
||||
"sLast": "Dernier",
|
||||
"sNext": "Suivant",
|
||||
"sPrevious": "Précédent"
|
||||
},
|
||||
"oAria": {
|
||||
"sSortAscending": ": activer pour trier la colonne par ordre croissant",
|
||||
"sSortDescending": ": activer pour trier la colonne par ordre décroissant"
|
||||
},
|
||||
"select": {
|
||||
"rows": {
|
||||
"_": "%d lignes sélectionnées",
|
||||
"0": "Aucune ligne sélectionnée",
|
||||
"1": "1 ligne sélectionnée"
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
var lcl = {
|
||||
NL: {
|
||||
"title_show_about": "Over",
|
||||
"title_show_user": "Gebruiker",
|
||||
"title_list_locations": "Locaties",
|
||||
"title_show_location": "Locatie",
|
||||
"title_list_contracts": "Contracten",
|
||||
"title_show_contract": "Contract",
|
||||
"title_list_buildings": "Gebouwen",
|
||||
"title_show_building": "Gebouw",
|
||||
"title_filter_floors": "Verdiepingen",
|
||||
"title_filter_disciplinetypes": "Vakgroeptypen",
|
||||
"title_filter_issuedisciplines": "Vakgroepen",
|
||||
"title_filter_issuetypes": "Standaardmeldingen",
|
||||
"title_list_issues": "Meldingen",
|
||||
"title_show_issue": "Melding",
|
||||
"title_show_issue_object": "Object",
|
||||
"title_list_issue_orders": "Opdrachten",
|
||||
"title_show_order": "Opdracht"
|
||||
},
|
||||
DE: {
|
||||
"title_show_about": "Betrifft",
|
||||
"title_show_user": "Gebraucher",
|
||||
"title_list_locations": "Standorte",
|
||||
"title_show_location": "Standort",
|
||||
"title_list_contracts": "Verträge",
|
||||
"title_show_contract": "Vertrag",
|
||||
"title_list_buildings": "Gebäude",
|
||||
"title_show_building": "Gebäude",
|
||||
"title_filter_floors": "Stockwerke",
|
||||
"title_filter_disciplinetypes": "Innendiensttypen",
|
||||
"title_filter_issuedisciplines": "Innendienste",
|
||||
"title_filter_issuetypes": "Standard Meldungen",
|
||||
"title_list_issues": "Meldungen",
|
||||
"title_show_issue": "Meldung",
|
||||
"title_show_issue_object": "Object",
|
||||
"title_list_issue_orders": "Aufträge",
|
||||
"title_show_order": "Auftrag"
|
||||
},
|
||||
EN: {
|
||||
"title_show_about": "About",
|
||||
"title_show_user": "User",
|
||||
"title_list_locations": "Locations",
|
||||
"title_show_location": "Location",
|
||||
"title_list_contracts": "Contracts",
|
||||
"title_show_contract": "Contract",
|
||||
"title_list_buildings": "Buildings",
|
||||
"title_show_building": "Building",
|
||||
"title_filter_floors": "Floors",
|
||||
"title_filter_disciplinetypes": "Discipline types",
|
||||
"title_filter_issuedisciplines": "Disciplines",
|
||||
"title_filter_issuetypes": "Issue types",
|
||||
"title_list_issues": "Issues",
|
||||
"title_show_issue": "Issue",
|
||||
"title_show_issue_object": "Object",
|
||||
"title_list_issue_orders": "Orders",
|
||||
"title_show_order": "Order"
|
||||
},
|
||||
FR: {
|
||||
"title_show_about": "A propos",
|
||||
"title_show_user": "Utilisateur",
|
||||
"title_list_locations": "Emplacements",
|
||||
"title_show_location": "Emplacement",
|
||||
"title_list_contracts": "Contracts",
|
||||
"title_show_contract": "Contract",
|
||||
"title_list_buildings": "Immeubles",
|
||||
"title_show_building": "Immeuble",
|
||||
"title_filter_floors": "étages",
|
||||
"title_filter_disciplinetypes": "Types de départements",
|
||||
"title_filter_issuedisciplines": "Départements",
|
||||
"title_filter_issuetypes": "Appel standard",
|
||||
"title_list_issues": "Appels",
|
||||
"title_show_issue": "Appel",
|
||||
"title_show_issue_object": "équipement",
|
||||
"title_list_issue_orders": "Missions",
|
||||
"title_show_order": "Mission"
|
||||
}
|
||||
};
|
||||
|
||||
/* global functions */
|
||||
|
||||
// return the data of a single object or of a row object (e.g. obj.data["issue"] or obj.data["issues"][row])
|
||||
function rowInfo(obj, row) {
|
||||
"use strict";
|
||||
return (obj.single ? obj.data[obj.table] : obj.data[obj.table][row]);
|
||||
}
|
||||
|
||||
// return the value of a column
|
||||
function dataInfo(obj, row, column) {
|
||||
"use strict";
|
||||
return rowInfo(obj, row)[column];
|
||||
}
|
||||
|
||||
// return a formatted column value according to the column_type
|
||||
function typeFormat(parms) {
|
||||
"use strict";
|
||||
switch (parms.column_type) {
|
||||
case "datetime":
|
||||
if (parms.single) {
|
||||
// return the datevalue in case of a single object column
|
||||
return new Date(parms.value);
|
||||
}
|
||||
return new Intl.DateTimeFormat(undefined, {
|
||||
dateStyle: 'medium',
|
||||
timeStyle: 'short',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
}).format(new Date(parms.value));
|
||||
break;
|
||||
case "date":
|
||||
if (parms.single) {
|
||||
// return the datevalue in case of a single object column
|
||||
return new Date(parms.value);
|
||||
}
|
||||
return new Intl.DateTimeFormat(undefined, {
|
||||
dateStyle: 'medium'
|
||||
}).format(new Date(parms.value));
|
||||
break;
|
||||
case "integer":
|
||||
return parseInt(parms.value, 10);
|
||||
break;
|
||||
case "number":
|
||||
// return safe number
|
||||
return $.fn.dataTable.render.number().display(parms.value);
|
||||
break;
|
||||
default:
|
||||
// return safe text
|
||||
return $.fn.dataTable.render.text().display(parms.value);
|
||||
}
|
||||
}
|
||||
|
||||
// return label of the column
|
||||
function columnType(obj, column) {
|
||||
"use strict";
|
||||
// determine column_type from [ targets[target].columns[column].type ] or from [ models[model].field[column].type ] or from fallback value "text"
|
||||
return (obj.columns[column].type || (models[obj.url].fields[column] && models[obj.url].fields[column].type) || "text");
|
||||
}
|
||||
|
||||
// return label of the column
|
||||
function columnLabel(obj, column) {
|
||||
"use strict";
|
||||
// determine label from [ models[model].field[column].label ] or else from [ target.columns[column].label ] or else from [ column name ]
|
||||
return ((models[obj.url].fields[column] && models[obj.url].fields[column].label) || obj.columns[column].label || column);
|
||||
}
|
||||
|
||||
// return value of the column (single value or [column].name value)
|
||||
function columnValue(data) {
|
||||
"use strict";
|
||||
// determine whether the value is an object with a { name: value }
|
||||
return (data && typeof data.name !== "undefined" ? data.name || "" : data || "");
|
||||
}
|
||||
|
||||
// return the formatted column value, independent of single object or row object
|
||||
function dataFormat(obj, row, column) {
|
||||
"use strict";
|
||||
// get column value (as single value or as { id: xx, name: yy })
|
||||
var data = dataInfo(obj, row, column);
|
||||
return typeFormat({
|
||||
value: columnValue(data),
|
||||
column_type: columnType(obj, column),
|
||||
single: obj.single
|
||||
});
|
||||
}
|
||||
|
||||
// return combined server-data and targets[target]/models[model][column] information object
|
||||
function columnInfo(obj, row, column) {
|
||||
"use strict";
|
||||
var data, column_label, column_data, column_type, column_valuemin, column_valuemax, column_recid;
|
||||
// get column value (as single value or as { id: xx, name: yy })
|
||||
data = dataInfo(obj, row, column);
|
||||
// get column label
|
||||
column_label = columnLabel(obj, column);
|
||||
// get formatted column value
|
||||
column_data = dataFormat(obj, row, column);
|
||||
// get column_type
|
||||
column_type = columnType(obj, column);
|
||||
// determine minimum value (only for use in a progressbar)
|
||||
column_valuemin = (obj.columns[column].valuemin || 0);
|
||||
// determine maximum value (only for use in a progressbar)
|
||||
column_valuemax = (obj.columns[column].valuemax || 100);
|
||||
// determine record id in case the column is a foreign table value
|
||||
column_recid = (data && typeof data.id !== "undefined" ? parseInt(data.id, 10) : false);
|
||||
return {
|
||||
data: data,
|
||||
column_label: column_label,
|
||||
column_data: column_data,
|
||||
column_type: column_type,
|
||||
column_valuemin: column_valuemin,
|
||||
column_valuemax: column_valuemax,
|
||||
column_recid: column_recid
|
||||
};
|
||||
}
|
||||
|
||||
// return the column [ data-order ] value, used for ordering DataTable rows ([ date ] or [ datetime ] serial number only)
|
||||
function dataOrder(obj, row, column) {
|
||||
"use strict";
|
||||
var column_type = columnType(obj, column),
|
||||
value, data = dataInfo(obj, row, column);
|
||||
if (obj.single) {
|
||||
value = "";
|
||||
} else {
|
||||
value = columnValue(data);
|
||||
}
|
||||
switch (column_type) {
|
||||
case "datetime":
|
||||
case "date":
|
||||
return new Date(value).getTime();
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// return DataTable settings based on targets[target]columns
|
||||
function tColumnDefs(obj) {
|
||||
"use strict";
|
||||
var defs = {
|
||||
language: dataTables_i18n[language],
|
||||
columnDefs: []
|
||||
},
|
||||
index = 0;
|
||||
$.each(obj.columns, function(key, value) {
|
||||
if (key !== "id") {
|
||||
if (value.hidden) {
|
||||
defs.columnDefs.push({
|
||||
targets: [index],
|
||||
visible: false,
|
||||
searchable: true
|
||||
});
|
||||
}
|
||||
index++;
|
||||
}
|
||||
});
|
||||
console.log(defs);
|
||||
return defs;
|
||||
}
|
||||
|
||||
// return tableHeader row
|
||||
function theadColumns(obj) {
|
||||
"use strict";
|
||||
var thead = "",
|
||||
column;
|
||||
for (column in obj.columns) {
|
||||
if (column !== "id") {
|
||||
thead += '<th>' + $.fn.dataTable.render.text().display(columnLabel(obj, column)) + '</th>';
|
||||
}
|
||||
}
|
||||
return thead;
|
||||
}
|
||||
|
||||
// return tableBody rows
|
||||
function tbodyData(obj) {
|
||||
"use strict";
|
||||
var tbody = "",
|
||||
row, column, order, col_info;
|
||||
for (row = 0; row < obj.data[obj.table].length; row += 1) {
|
||||
tbody += '<tr recid=' + obj.data[obj.table][row].id + '>';
|
||||
for (column in obj.columns) {
|
||||
if (column !== "id") {
|
||||
col_info = columnInfo(obj, row, column);
|
||||
tbody += '<td name="' + column + '"' +
|
||||
(col_info.column_recid ? 'recid="' + col_info.column_recid + '"' : '') +
|
||||
((order = dataOrder(obj, row, column)) ? 'data-order="' + order + '"' : '') +
|
||||
'>' +
|
||||
col_info.column_data +
|
||||
'</td>';
|
||||
}
|
||||
}
|
||||
tbody += '</tr>';
|
||||
}
|
||||
return tbody;
|
||||
}
|
||||
|
||||
// return formdata (single record form)
|
||||
function formData(obj) {
|
||||
"use strict";
|
||||
var target_selector = targets[obj.target].selector;
|
||||
var formbody = "",
|
||||
column, column_id, col_info, field, type, date, time;
|
||||
for (column in obj.columns) {
|
||||
if (column !== "id" && !(targets[obj.target].columns[column].hidden || false)) {
|
||||
column_id = target_selector + "-" + column;
|
||||
col_info = columnInfo(obj, undefined, column);
|
||||
col_info.column_id = column_id;
|
||||
col_info.single = obj.single;
|
||||
formbody +=
|
||||
'<div class="form-group form-group-sm pb-0 mb-0 form-row">' +
|
||||
'<label for="' + column_id + '" class="col-sm-4 col-form-label text-nowrap">' + col_info.column_label + '</label>' +
|
||||
new Field(col_info).render() +
|
||||
'</div>';
|
||||
}
|
||||
}
|
||||
return formbody;
|
||||
}
|
||||
|
||||
// return filterdata (buttons for filtering DataTable data)
|
||||
function filterData(obj) {
|
||||
"use strict";
|
||||
// var container_selector = targets[obj.target].selector;
|
||||
var formbody = "",
|
||||
row, column, column_id, col_info, field,
|
||||
btn_size_class = targets[obj.target].btn_size_class || settings.btn_size_class,
|
||||
btn_has_icon = targets[obj.target].btn_has_icon;
|
||||
for (row = 0; row < obj.data[obj.table].length; row += 1) {
|
||||
formbody += '<button type="button" class="btn text-center ' + btn_size_class + ' ' + settings.btn_text_class + ' ' + settings.btn_class + '" recid=' + obj.data[obj.table][row].id + '>' +
|
||||
'<div class="">' + (btn_has_icon ? '<i class="fa fa-tag fa-lg"></i>' : "") + '</div>';
|
||||
for (column in obj.columns) {
|
||||
if (column !== "id") {
|
||||
col_info = columnInfo(obj, row, column);
|
||||
formbody += '<div name="' + column + '"' +
|
||||
((targets[obj.target].columns[column].hidden || false) ? "hidden" : '') +
|
||||
(col_info.column_recid ? ' recid=' + col_info.column_recid : '') + '>' +
|
||||
((targets[obj.target].columns[column].hidden || false) ? '' : col_info.column_data) +
|
||||
'</div>';
|
||||
}
|
||||
}
|
||||
formbody += '</button>';
|
||||
}
|
||||
return formbody;
|
||||
}
|
||||
|
||||
// populate the target (datatable, form or filter)
|
||||
function populate(obj) {
|
||||
"use strict";
|
||||
// the model needs to be present (loaded) for correct workings, except for reports (graphs)
|
||||
if (targets[obj.target].report || models[obj.url].id) {
|
||||
var $this = $("#" + targets[obj.target].selector),
|
||||
h2;
|
||||
obj.columns = obj.columns || targets[obj.target].columns;
|
||||
console.log("populate: " + obj.target);
|
||||
obj.table = obj.single || obj.url;
|
||||
h2 = '<h2 name="formtitle">' + (lcl[language][targets[obj.target].title] || obj.table) + '</h2>';
|
||||
obj.single = obj.single || false;
|
||||
// render single record form html
|
||||
if (obj.single) {
|
||||
var fdata = formData(obj);
|
||||
$this.html(h2 + '<form id="' + targets[obj.target].selector + '-form">' + fdata + '</form>' + new Customfields(obj).render());
|
||||
// render buttons from rows for filter form html
|
||||
} else if (targets[obj.target].filter) {
|
||||
var fdata = filterData(obj);
|
||||
$this.html(h2 + '<form id="' + targets[obj.target].selector + '-form" class="form-inline">' + fdata + '</form>');
|
||||
// render h2 header only for report
|
||||
} else if (targets[obj.target].report) {
|
||||
$this.html(h2);
|
||||
// render table html
|
||||
} else {
|
||||
var $this, thead, tbody, table;
|
||||
thead = '<thead class="thead-dark">' + theadColumns(obj) + '</thead>';
|
||||
tbody = '<tbody>' + tbodyData(obj) + '</tbody>';
|
||||
table = '<table class="table table-sm table-striped table-hover" name="' + obj.target + '">' + thead + tbody + '</table>';
|
||||
$this.html(h2 + table);
|
||||
}
|
||||
// set trigger(s) if available
|
||||
if (targets[obj.target].trigger) {
|
||||
$(targets[obj.target].trigger_selector, $this).off().on(targets[obj.target].events, targets[obj.target].trigger);
|
||||
}
|
||||
// run ready function if available
|
||||
if (targets[obj.target].ready) {
|
||||
targets[obj.target].ready(obj);
|
||||
}
|
||||
} else {
|
||||
console.log("model " + obj.url + "not yet present!");
|
||||
// retry the populate until the model is present
|
||||
setTimeout(function() {
|
||||
populate(obj);
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
// save the model definition in models
|
||||
function setModel(obj) {
|
||||
"use strict";
|
||||
if (obj.model) {
|
||||
models[obj.model] = obj.data;
|
||||
obj.data.fields.forEach(function(field) {
|
||||
models[obj.model].fields[field.id] = field;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// get api2 data through ajax
|
||||
function api2(obj) {
|
||||
"use strict";
|
||||
if (obj.target) {
|
||||
obj.filter = (Object.keys(targets[obj.target].columns).length ? (obj.filter ? obj.filter + "&" : "?") + "fields=" + Object.keys(targets[obj.target].columns).join(",") : obj.filter || "");
|
||||
}
|
||||
var ajaxHdl = $.ajax({
|
||||
url: settings.facilitor_url + "api2/" + obj.url + (obj.filter || ""),
|
||||
dataType: "json",
|
||||
success: function(data, textStatus, jqXHR) {
|
||||
console.log("Ajax success start: " + (obj.target || obj.model));
|
||||
obj.data = data;
|
||||
if (obj.model) {
|
||||
setModel(obj);
|
||||
} else {
|
||||
populate(obj);
|
||||
}
|
||||
console.log(data);
|
||||
console.log("Ajax success stop: " + (obj.target || obj.model));
|
||||
},
|
||||
complete: function(jqXHR, textStatus) {
|
||||
console.log("Ajax complete: " + (obj.target || obj.model));
|
||||
}
|
||||
});
|
||||
console.log({
|
||||
target: (obj.target || "model_" + obj.model),
|
||||
ajaxHdl: ajaxHdl
|
||||
});
|
||||
}
|
||||
|
||||
// google maps initialisation
|
||||
var map, marker, geocoder, panorama;
|
||||
|
||||
// google maps interface to set a location and a marker
|
||||
function codeAddress(address) {
|
||||
"use strict";
|
||||
geocoder.geocode({
|
||||
'address': address
|
||||
}, function(results, status) {
|
||||
if (status == 'OK') {
|
||||
map.setCenter(results[0].geometry.location);
|
||||
marker = new google.maps.Marker({
|
||||
map: map,
|
||||
position: results[0].geometry.location
|
||||
});
|
||||
panorama.setPosition(results[0].geometry.location);
|
||||
panorama.addListener('position_changed', function() {
|
||||
if (!panorama.getVisible()) {
|
||||
panorama.setVisible(true);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
alert('Geocode was not successful for the following reason: ' + status);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// google maps initialisation and first location set to Facilitor
|
||||
function initAutocomplete(selector) {
|
||||
"use strict";
|
||||
// The location of Facilitor
|
||||
var facilitor = {
|
||||
lat: 52.216670,
|
||||
lng: 6.946060
|
||||
};
|
||||
// map part
|
||||
map = new google.maps.Map(
|
||||
document.getElementById(selector), {
|
||||
zoom: 13,
|
||||
center: facilitor,
|
||||
mapTypeId: 'roadmap'
|
||||
});
|
||||
marker = new google.maps.Marker({
|
||||
map: map,
|
||||
position: facilitor
|
||||
});
|
||||
// streetview part
|
||||
panorama = new google.maps.StreetViewPanorama(
|
||||
document.getElementById('building-view'), {
|
||||
position: facilitor,
|
||||
panControl: false,
|
||||
addressControl: false,
|
||||
pov: {
|
||||
heading: 34,
|
||||
pitch: 20
|
||||
}
|
||||
});
|
||||
map.setStreetView(panorama);
|
||||
geocoder = geocoder || new google.maps.Geocoder();
|
||||
$("#" + selector).closest(".row").attr("hidden", false);
|
||||
}
|
||||
|
||||
/* settings and functions from refactoring of targets object */
|
||||
var settings = {
|
||||
facilitor_url: "../../",
|
||||
btn_class: "btn-light",
|
||||
btn_text_class: "text-primary",
|
||||
btn_selected_class: "btn-success",
|
||||
btn_partial_class: "btn-success",
|
||||
btn_size_class: "col-sm-3",
|
||||
btn_has_icon: true
|
||||
};
|
||||
// set partial, full or no class on parent button dependent on the number of selected child buttons
|
||||
function setParentSelectedClass(parms) {
|
||||
"use strict";
|
||||
var selected = $("button." + settings.btn_selected_class + " div[name=" + parms.name + "][recid=" + parms.value + "]", parms.context).length;
|
||||
var present = $("button div[name=" + parms.name + "][recid=" + parms.value + "]", parms.context).length;
|
||||
// reset classes to default
|
||||
var button = $("button[recid=" + parms.value + "]", parms.parent)
|
||||
.removeClass(settings.btn_selected_class + ' ' + settings.btn_partial_class)
|
||||
.addClass(settings.btn_class)
|
||||
.addClass(settings.btn_text_class);
|
||||
// all childs are selected
|
||||
if (present == selected) {
|
||||
$("button[recid=" + parms.value + "]", parms.parent)
|
||||
.addClass(settings.btn_selected_class)
|
||||
.removeClass(settings.btn_class + ' ' + settings.btn_text_class);
|
||||
// part of the childs are selected
|
||||
} else if (selected > 0) {
|
||||
$("button[recid=" + parms.value + "]", parms.parent)
|
||||
.addClass(settings.btn_selected_class + ' ' + settings.btn_partial_class)
|
||||
.removeClass(settings.btn_class + ' ' + settings.btn_text_class);
|
||||
}
|
||||
return button;
|
||||
}
|
||||
// set full or no class on child buttons dependent on the parent button
|
||||
function setChildSelectedClass(parms) {
|
||||
"use strict";
|
||||
var items = $("button div[name=" + parms.name + "][recid=" + parms.$this.attr("recid") + "]", parms.context);
|
||||
items
|
||||
.each(
|
||||
function() {
|
||||
$(this).closest("button")
|
||||
.removeClass(settings.btn_partial_class)
|
||||
.toggleClass(settings.btn_selected_class, parms.$this.hasClass(settings.btn_selected_class))
|
||||
.toggleClass(settings.btn_class, !parms.$this.hasClass(settings.btn_selected_class))
|
||||
.toggleClass(settings.btn_text_class, !parms.$this.hasClass(settings.btn_selected_class));
|
||||
}
|
||||
);
|
||||
return items;
|
||||
}
|
||||
// save recid's of selected buttons in [ context ]
|
||||
function saveSelectedbuttonIds(parms) {
|
||||
"use strict";
|
||||
targets[parms.target].selected_ids = [];
|
||||
$("button." + settings.btn_selected_class, parms.context).each(function() {
|
||||
targets[parms.target].selected_ids.push($(this).attr("recid"));
|
||||
});
|
||||
}
|
||||
// save recid's used in table
|
||||
function saveUsedtabledataIds(parms) {
|
||||
"use strict";
|
||||
var index, recid, key_count = {};
|
||||
targets[parms.target].selected_ids = [];
|
||||
$("td[name=" + parms.name + "]", parms.context).each(function() {
|
||||
recid = $(this).attr("recid");
|
||||
key_count[recid] = key_count[recid] ? key_count[recid] + 1 : 1;
|
||||
index = targets[parms.target].selected_ids.indexOf(recid);
|
||||
if (index === -1) {
|
||||
targets[parms.target].selected_ids.push(recid);
|
||||
}
|
||||
});
|
||||
return key_count;
|
||||
}
|
||||
// set classes for button dependent on button_selected_class
|
||||
function setButtonClasses(parms) {
|
||||
"use strict";
|
||||
parms.$this.removeClass(settings.btn_selected_class == settings.btn_partial_class ? "" : settings.btn_partial_class)
|
||||
.toggleClass(settings.btn_selected_class)
|
||||
.toggleClass(settings.btn_class, !parms.$this.hasClass(settings.btn_selected_class))
|
||||
.toggleClass(settings.btn_text_class, !parms.$this.hasClass(settings.btn_selected_class));
|
||||
}
|
||||
// reset classes for all buttons
|
||||
function resetAllButtonClasses(parms) {
|
||||
"use strict";
|
||||
$("button", parms.context)
|
||||
.removeClass(settings.btn_partial_class + ' ' + settings.btn_selected_class)
|
||||
.addClass(settings.btn_class + ' ' + settings.btn_text_class);
|
||||
}
|
||||
// set hidden attr for buttons dependent on button_selected_class
|
||||
function setButtonHidden(parms) {
|
||||
"use strict";
|
||||
$("button", parms.context)
|
||||
.attr("hidden", function() {
|
||||
$(this).attr("hidden", !$(this).hasClass(settings.btn_selected_class))
|
||||
});
|
||||
}
|
||||
// autoselect first row in case there is only 1 result
|
||||
function autoselectRow(parms) {
|
||||
"use strict";
|
||||
// select (click) the first row if there is only 1 result
|
||||
if ($("tbody tr", "#" + targets[parms.target].selector).length == 1) {
|
||||
$("tbody tr:first", "#" + targets[parms.target].selector).click();
|
||||
}
|
||||
}
|
||||
// redraw the table and select first row in case there is only 1 result
|
||||
function redrawTable(parms) {
|
||||
"use strict";
|
||||
targets[parms.target].data_table.draw();
|
||||
autoselectRow(parms);
|
||||
}
|
||||
|
||||
/* Objects to be used in this dashboard */
|
||||
|
||||
// Object with render function to return rendered field (without label)
|
||||
function Field(parms) {
|
||||
"use strict";
|
||||
var self = this,
|
||||
date, time;
|
||||
// prefix a string with a zero when string length < length to be used ( hour/minute/day/month fields )
|
||||
var prefixZero = function(str, len) {
|
||||
return ("0" + str).slice(-len);
|
||||
};
|
||||
this.single = parms.single;
|
||||
this.column_name = parms.column_name;
|
||||
this.column_type = parms.column_type;
|
||||
this.column_id = parms.column_id;
|
||||
this.column_data = typeFormat({
|
||||
value: (parms.column_data || ""),
|
||||
column_type: parms.column_type,
|
||||
single: parms.single
|
||||
});
|
||||
this.column_valuemin = parms.column_valuemin;
|
||||
this.column_valuemax = parms.column_valuemax;
|
||||
this.render = function() {
|
||||
switch (self.column_type) {
|
||||
case "progressbar":
|
||||
return '<div class="col-sm-8 progress" style="height: 2rem;">' +
|
||||
'<div class="progress-bar progress-bar-info form-control form-control-sm" role="progressbar" id="' + self.column_id + '" style="width: ' + Math.round(1 / self.column_valuemax * self.column_data * 100) + '%;" aria-valuenow="' + self.column_data + '" aria-valuemin="' + self.column_valuemin + '" aria-valuemax="' + self.column_valuemax + '"></div>' +
|
||||
'</div>';
|
||||
break;
|
||||
case "check":
|
||||
return '<div class="form-check">' +
|
||||
'<input type="checkbox" class="form-control form-control-sm form-check-input" id="' + self.column_id + '" name=' + self.column_name + (self.column_data == 1 ? ' checked' : '') + ' disabled>' +
|
||||
'</div>';
|
||||
break;
|
||||
case "textarea":
|
||||
return '<div class="col-sm-8">' +
|
||||
'<textarea class="sm-textarea form-control form-control-sm" id="' + self.column_id + '" readonly>' + self.column_data + '</textarea>' +
|
||||
'</div>';
|
||||
break;
|
||||
case "date":
|
||||
date = self.column_data == "" ? "" : self.column_data.getFullYear().toString() + "-" + prefixZero((self.column_data.getMonth() + 1).toString(), 2) + "-" + prefixZero(self.column_data.getDate().toString(), 2);
|
||||
return '<div class="col-sm-8">' +
|
||||
'<input type="date" class="form-control form-control-sm" id="' + self.column_id + '" name=' + self.column_name + '" value="' + date + '" readonly>' +
|
||||
'</div>';
|
||||
break;
|
||||
case "datetime":
|
||||
time = self.column_data == "" ? "" : prefixZero(self.column_data.getHours().toString(), 2) + ":" + prefixZero(self.column_data.getMinutes().toString(), 2);
|
||||
date = self.column_data == "" ? "" : self.column_data.getFullYear().toString() + "-" + prefixZero((self.column_data.getMonth() + 1).toString(), 2) + "-" + prefixZero(self.column_data.getDate().toString(), 2);
|
||||
return '<div class="col-sm-5">' +
|
||||
'<input type="date" class="form-control form-control-sm" id="' + self.column_id + '" name=' + self.column_name + '" value="' + date + '" readonly>' +
|
||||
'</div>' +
|
||||
'<div class="col-sm-3">' +
|
||||
'<input type="time" class="form-control form-control-sm" id="' + self.column_id + '_time" name=' + self.column_name + '_time" value="' + time + '" readonly>' +
|
||||
'</div>';
|
||||
break;
|
||||
case "time":
|
||||
time = self.column_data == "" ? "" : prefixZero(self.column_data.getHours().toString(), 2) + ":" + prefixZero(self.column_data.getMinutes().toString(), 2);
|
||||
return '<div class="col-sm-3">' +
|
||||
'<input type="time" class="form-control form-control-sm" id="' + self.column_id + '_time" name=' + self.column_name + '_time" value="' + time + '" readonly>' +
|
||||
'</div>';
|
||||
break;
|
||||
default:
|
||||
return '<div class="col-sm-8">' +
|
||||
'<input type="' + self.column_type + '" class="form-control form-control-sm" id="' + self.column_id + '" name=' + self.column_name + '" value="' + self.column_data + '" readonly>' +
|
||||
'</div>';
|
||||
break
|
||||
}
|
||||
}
|
||||
console.log(self);
|
||||
}
|
||||
|
||||
// Object with render function to return rendered label and customfield
|
||||
function Customfield(parms) {
|
||||
"use strict";
|
||||
var self = this;
|
||||
this.single = parms.single;
|
||||
this.column_name = parms.column_name;
|
||||
this.custom_field = parms.custom_field;
|
||||
this.selector = parms.selector;
|
||||
this.column_id = parms.selector + "-" + self.custom_field.propertyid;
|
||||
// translate customfield-type to model field-type
|
||||
this.custom_field_type = function() {
|
||||
switch (self.custom_field.type) {
|
||||
case "V":
|
||||
return "check";
|
||||
case "D":
|
||||
return "date";
|
||||
case "T":
|
||||
return "time";
|
||||
case "N":
|
||||
return "number";
|
||||
default:
|
||||
return "text";
|
||||
}
|
||||
}
|
||||
this.render = function() {
|
||||
return '<div class="form-group form-group-sm pb-0 mb-0 form-row">' +
|
||||
'<label for="' + self.column_id + '" class="col-sm-4 col-form-label text-nowrap">' + self.custom_field.label + '</label>' +
|
||||
new Field({
|
||||
single: self.single,
|
||||
column_name: self.column_name,
|
||||
column_id: self.column_id,
|
||||
column_type: self.custom_field_type(),
|
||||
column_data: self.custom_field.value
|
||||
}).render() +
|
||||
'</div>';
|
||||
}
|
||||
console.log(self);
|
||||
}
|
||||
|
||||
// Object with render function to return all rendered rendered customfields including labels
|
||||
function Customfields(parms) {
|
||||
"use strict";
|
||||
var self = this,
|
||||
custom_field;
|
||||
// sort customfields on sequence
|
||||
this.custom_fields = (parms.data[parms.table].custom_fields ? parms.data[parms.table].custom_fields.sort(function(a, b) {
|
||||
return (a.sequence > b.sequence ? 1 : -1)
|
||||
}) : []);
|
||||
this.single = parms.single;
|
||||
this.target = parms.target;
|
||||
this.table = parms.table;
|
||||
this.render = function() {
|
||||
var fields = "",
|
||||
custom_field;
|
||||
if (targets[self.target].show_custom_fields && self.custom_fields.length) {
|
||||
for (custom_field in self.custom_fields) {
|
||||
// only customfields other than type Q, L or M
|
||||
if (["Q", "L", "M"].indexOf(self.custom_fields[custom_field].type) == -1 && (targets[self.target].show_custom_field_when_empty || self.custom_fields[custom_field].value != null)) {
|
||||
fields += new Customfield({
|
||||
single: self.single,
|
||||
column_name: custom_field,
|
||||
selector: targets[self.target].selector,
|
||||
custom_field: self.custom_fields[custom_field]
|
||||
}).render();
|
||||
}
|
||||
}
|
||||
}
|
||||
return '<div name="custom-fields">' + fields + '</div>';
|
||||
}
|
||||
console.log(self);
|
||||
}
|
||||
|
||||
// Object base for targets
|
||||
function Target(parms) {
|
||||
"use strict";
|
||||
var self = this;
|
||||
var choose = function(first_choice, fallback_choice) {
|
||||
return (typeof first_choice != "undefined" ? first_choice : fallback_choice);
|
||||
};
|
||||
this.title = parms.title || "";
|
||||
this.selector = parms.selector;
|
||||
this.mode = parms.mode;
|
||||
this.columns = choose(parms.columns, {});
|
||||
this.events = choose(parms.events, "click");
|
||||
this.trigger = parms.trigger || false;
|
||||
this.ready = parms.ready || false;
|
||||
this.filter = parms.filter || false;
|
||||
this.report = parms.report || false;
|
||||
this.trigger_selector = (this.filter ? "button" : "table tbody tr");
|
||||
this.iconcolumn = parms.iconcolumn || false;
|
||||
this.btn_size_class = choose(parms.btn_size_class, settings.btn_size_class);
|
||||
this.btn_has_icon = choose(parms.btn_has_icon, true);
|
||||
this.show_custom_fields = parms.show_custom_fields || false;
|
||||
this.show_custom_field_when_empty = parms.show_custom_field_when_empty || false;
|
||||
console.log(self);
|
||||
}
|
||||
Reference in New Issue
Block a user