function CR_formdataappend(v1,v2) {
if (v1 == ""){return v2;};
if (v2 == ""){return v1;};
return v1+"&"+v2;
}
function CR_objectToFormData(obj) {
var formstring = "";
for(var property in obj) {
if(obj.hasOwnProperty(property)) {
// if the property is an object, but not a File,
// use recursivity.
if(typeof obj[property] === 'object') {
formstring = CR_formdataappend(formstring,CR_objectToFormData(obj[property]));
} else {
// if it's a string or a File object
formstring = CR_formdataappend(formstring,property+"="+obj[property]);
}
}
}
return formstring;
};
function CR_post(link,postdata,callback=null,callbackdata=null)
{
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
if (callback !== null)
callback(this.responseText,callbackdata);
}
};
xmlhttp.open("POST", link, true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
if (postdata && typeof postdata === 'object')
{
xmlhttp.send(CR_objectToFormData(postdata));
}
else
xmlhttp.send(postdata);
};
var cr_tables=[];
cr_tables['update_delay']=2000;
var cr_table_log=false;
var cr_modal, cr_modal_text;
function cr_cookies_get()
{
return document.cookie.split(';').map(function split(e) { var tmp = e.trim().split('='); return tmp; });
}
function cr_cookies_index(needle, cks=null)
{
if ( cks == null ) cks = cr_cookies_get();
let keys = cks.map(function primul(e) {return e[0]});
return keys.indexOf(needle);
}
function table_parse_config(name,cfg)
{
cr_tables[name]=cfg;
cr_tables[name]["columns_visible"]=new Array();
cr_tables[name]["columns_sort"]=new Array();
cr_tables[name]["columns_filter"]=new Array();
cr_tables[name]["TotalRecordCount"]=0;
cr_tables[name]["pageNo"]=1;
if (cr_tables[name]['actions']['insert'])
{
if (cr_tables[name]['insert_label'])
cr_tables[name]['insert_label']= '✚ '+cr_tables[name]['insert_label'];
else
cr_tables[name]['insert_label']= '✚ Add line';
}
if (cr_tables[name]["paging"])
{
if (isNaN(cr_tables[name]["pageSize"]))
cr_tables[name]["pageSize"]=50;
if ((!cr_tables[name]["pageSizes"]) || (cr_tables[name]["pageSizes"].constructor !== Array))
cr_tables[name]["pageSizes"]=[25,50,100,200,500,1000];
}
for(var propt in cr_tables[name]["columns"])
{
if (! cr_tables[name]["columns"][propt].hasOwnProperty("id"))
delete cr_tables[name]["columns"][propt];
else
{
if (!(cr_tables[name]["columns"][propt]["show"]===false))
cr_tables[name]["columns_visible"].push(propt);
if (cr_tables[name]["columns"][propt]["key"]===true)
cr_tables[name]["key"]=cr_tables[name]["columns"][propt]["id"];
}
}
}
function table_create(name,divid,cfg)
{
var cookies_array = cr_cookies_get();
table_parse_config(name,cfg);
cr_tables[name]['divid']=document.getElementById(divid);
cr_tables[name]['divid'].classList.add('cr_table_div');
var tbl = document.createElement('table');
cr_tables[name]['tbl']=tbl;
tbl.classList.add("cr_table");
// table header name
var th = tbl.createTHead();
var tr = th.insertRow();
var td = tr.insertCell();
if (cr_tables[name]['actions']['print'])
td.innerHTML = cr_tables[name]['title'] + "
";
else
td.innerHTML = cr_tables[name]['title'];
td.classList.add('cr_table_title');
td.setAttribute('colSpan', cr_tables[name]["columns_visible"].length);
if (cr_tables[name]['actions']['insert'])
{
var addrow=document.createElement("div");
addrow.style.float = "right"
addrow.style.cursor='copy'
addrow.innerHTML=cr_tables[name]['insert_label'];
addrow.setAttribute("onclick", "cr_click_add_row('" + name + "')");
td.appendChild(addrow);
}
// if we have filtering, need to create the modal window
if (cr_tables[name]["filtering"] && (! cr_modal))
{
cr_modal=document.createElement("div");
cr_modal.className="modal";
var cd=document.createElement("div");
cd.className="modal-content";
cr_modal.appendChild(cd);
var cls=document.createElement("span");
cls.className="close";
cls.innerHTML="×";
cls.setAttribute("onclick", "cr_close_filter_button()");
cd.appendChild(cls);
var pg=document.createElement("p");
pg.innerHTML="Filter:";
cd.appendChild(pg);
cr_modal_filterdiv = document.createElement("div");
cd.appendChild(cr_modal_filterdiv);
var okbtn = document.createElement("input");
okbtn.setAttribute("id", "cr_modal_btn");
okbtn.setAttribute("type", "button");
okbtn.setAttribute("name", "ok" );
okbtn.setAttribute("value", "Apply Filter" );
okbtn.setAttribute("onclick", "cr_close_filter_button()");
cd.appendChild(okbtn);
document.body.appendChild(cr_modal);
}
// table header columns
var tr = th.insertRow();
for(var j = 0; j < cr_tables[name]["columns_visible"].length; j++)
{
var col=cr_tables[name]["columns"][cr_tables[name]["columns_visible"][j]];
var td = tr.insertCell();
td.appendChild(document.createTextNode(col["title"]));
if (col.width)
td.style.width=col.width;
var thbtnsdiv=document.createElement("div");
//add the sorting buttons on header row
if (cr_tables[name]["sorting"] && (col["sorting"]===true))
{
var tdata="\u21F3";
if (col["sort"]=='asc')
tdata="\u21E7";
else if (col["sort"]=='desc') {
tdata="\u21E9";}
if ( (tempindex = cr_cookies_index(`cr_table_sort_${name}_${col["id"]}`,cookies_array))>-1)
tdata=cookies_array[tempindex][1];
var btsort = document.createElement("button");
btsort.name = "btnsort"+col["id"];
btsort.dataset['cid']=col["id"];
btsort.value = cr_tables[name]["columns_visible"][j];
btsort.setAttribute("onclick", "cr_click_sorting_button('" + name + "', this)");
btsort.innerHTML=tdata;
cr_tables[name]["columns_sort"].push(btsort);
thbtnsdiv.appendChild(btsort);
}
//add the filter buttons on top of header row
if (cr_tables[name]["filtering"] && (col["filter"]===true))
{
var btnfilter = document.createElement("button");
btnfilter.name = "btnfilter"+col["id"];
btnfilter.dataset['cid']=col["id"];
btnfilter.dataset['search']='';
if ( (tempindex = cr_cookies_index(`cr_table_filter_${name}_${col["id"]}`,cookies_array))>-1)
btnfilter.dataset['search']=cookies_array[tempindex][1];
btnfilter["FT"] = "IN";
if (!col["filtertype"])
col["filtertype"]="search";
if ( (col["filtertype"]=="search") || (col["filtertype"]=="date"))
{
fltr = document.createElement("input");
fltr.setAttribute("type", col["filtertype"]);
fltr.setAttribute("name", "cr_modal" );
fltr.value=btnfilter.dataset['search'];
if (btnfilter.dataset['search'] !='')
btnfilter.style.background="red";
fltr.addEventListener("keyup", function(event) {event.preventDefault(); if (event.keyCode === 13) {cr_close_filter_button();} });
btnfilter['filtru']=fltr;
btnfilter.dataset['type']=col["filtertype"];
}
if (col["filtertype"]=="checkbox")
{
fltrdiv = document.createElement("div");
for(i=0; i
";
var key=data['Records'][dr][cr_tables[name]["key"]];
//one column at a time
for(var j = 0; j < cr_tables[name]["columns_visible"].length; j++)
{
var columnid = cr_tables[name]["columns_visible"][j];
var dataid = cr_tables[name]["columns"][columnid]['id'];
var datashow = data['Records'][dr][dataid];
//if the cell is editable we need to build the object
if (cr_tables[name]["columns"][columnid]['edit']==true)
{
//if is an checkbox - create the element
if ( cr_tables[name]["columns"][columnid]['checkbox'])
{
new_tbody += `
`;
}
//if it is an object - drop down list we create the element
else if ( typeof(cr_tables[name]["columns"][columnid]['values'])=="object" )
{
var opts=cr_tables[name]["columns"][columnid]['values'];
new_tbody += `
`;
}
else
{//else we create the edit as an input string
new_tbody += `
`;
}
}
else
{//the cell is not editable so we ad it as an paragraph
new_tbody += `
';
this._allowedValues.push(option.value);
if (option.hasAttribute('selected')){ //TODO in caz de valoare implicita, trebuie procesat
selected.innerHTML = option.innerHTML;
this.value = option.id;
}
}
optionsContainer.innerHTML = options;
}
this.optionsList = this.querySelectorAll(".option");
// this.optionsList.addEventListener('click', this.handleOptionSelect.bind(this));
this.optionsList.forEach(o => {
o.addEventListener("click", () => {
selected.innerHTML = o.innerHTML;
this.value = o.id;
optionsContainer.style.display="none";
searchBox.style.display="none";
this.dispatchEvent(new CustomEvent('change', { detail: this.value }));
});
});
searchBox.optionsList = this.optionsList;
searchBox.addEventListener("keyup", function(e) {
let searchTerm=e.target.value;
searchTerm = searchTerm.toLowerCase();
e.currentTarget.optionsList.forEach(option => {
let label = option.innerText.toLowerCase();
if (label.indexOf(searchTerm) != -1) {
option.style.display = "block";
} else {
option.style.display = "none";
}
});
});
searchBox.addEventListener("focusout", function(e) {
searchBox.style.display="none";
selected.classList.remove("active");
setTimeout(() => { optionsContainer.style.display="none"; }, 500);
});
this._ajaxenable=false;
if (this.hasAttribute('data-source')) {
this._ajaxsource = this.getAttribute('data-source');
if (this.hasAttribute('data-filter')) this._ajaxfilter = this.getAttribute('data-filter'); else this._ajaxfilter = '';
this._ajaxenable=true;
};
this._allowuserinput=false;
if (this.hasAttribute('data-userinput')) {
this._allowuserinput=true;
}
}
}
window.customElements.define('enhanced-select', EnhanancedSelect);
const grid_no_links=4, points_subdivision=50;
var width, height, canvas, ctx, points, points_subdivisionY=50;
// Main
initGrid();
addListeners();
drawGrid();
function initGrid() {
canvas = document.getElementById('grid_bg');
height = window.innerHeight
width = window.innerWidth
canvas.width = width;
canvas.height = height;
ctx = canvas.getContext('2d');
points_subdivisionY=Math.round(points_subdivision*height/width);
// create points
points = [];
for(var x = 0; x < points_subdivision; x++) {
for(var y = 0; y < points_subdivisionY; y++) {
var px = x/points_subdivision + Math.random()/points_subdivision;
var py = y/points_subdivisionY + Math.random()/points_subdivisionY;
var p = {x: px, originX: px, y: py, originY: py };
points.push(p);
}
}
// for each point find the required closest pointsto draw lines
for(var i = 0; i < points.length; i++) {
var closest = [];
var p1 = points[i];
for(var j = 0; j < points.length; j++) {
var p2 = points[j]
if(!(p1 == p2)) {
var placed = false;
for(var k = 0; k < grid_no_links; k++) {
if(!placed) {
if(closest[k] == undefined) {
closest[k] = p2;
placed = true;
}
}
}
for(var k = 0; k < grid_no_links; k++) {
if(!placed) {
if(getDistance(p1, p2) < getDistance(p1, closest[k])) {
closest[k] = p2;
placed = true;
}
}
}
}
}
p1.closest = closest;
}
// assign a circle to each point
for(var i in points) {
var c = new Circle(points[i], 2+Math.random()*2, 'rgba(255,255,255,0.3)');
points[i].circle = c;
points[i].active = Math.random()/3;
points[i].circle.active = Math.random()/2;
}
}
function addListeners() {
window.addEventListener('resize', resize);
}
function resize() {
width = window.innerWidth;
height = window.innerHeight;
canvas.width = width;
canvas.height = height;
drawGrid();
}
function drawGrid() {
ctx.clearRect(0,0,width,height);
for(var i in points) {
drawLines(points[i]);
points[i].circle.draw();
}
}
function drawLines(p) {
if(!p.active) return;
for(var i in p.closest) {
ctx.beginPath();
ctx.moveTo(p.x*width, p.y*height);
ctx.lineTo(p.closest[i].x*width, p.closest[i].y*height);
ctx.strokeStyle = 'rgba(156,217,249,'+ p.active+')';
ctx.stroke();
}
}
function Circle(pos,rad,color) {
var _this = this;
// constructor
(function() {
_this.pos = pos || null;
_this.radius = rad || null;
_this.color = color || null;
})();
this.draw = function() {
if(!_this.active) return;
ctx.beginPath();
ctx.arc(_this.pos.x*width, _this.pos.y*height, _this.radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'rgba(156,217,249,'+ _this.active+')';
ctx.fill();
};
}
function getDistance(p1, p2) {
return Math.pow(p1.x - p2.x, 2) + Math.pow((p1.y - p2.y)*height/width, 2);
}
class MultiInput extends HTMLElement {
constructor() {
super();
// This is a hack :^(.
// ::slotted(input)::-webkit-calendar-picker-indicator doesn't work in any browser.
// ::slotted() with ::after doesn't work in Safari.
this.innerHTML +=
``;
this._shadowRoot = this.attachShadow({mode: 'open'});
this._shadowRoot.innerHTML =
`
`;
const input = document.createElement('input')
input.type = "hidden";
input.classList.add("hidden-input");
this.appendChild(input);
this._forminput=input;
input.value = "[]";
if (this.hasAttribute('data-name')){
input.name = this.getAttribute('data-name');
}
this._ajaxenable=false;
if (this.hasAttribute('data-source')) {
this._ajaxsource = this.getAttribute('data-source');
if (this.hasAttribute('data-filter')) this._ajaxfilter = this.getAttribute('data-filter'); else this._ajaxfilter = '';
this._ajaxenable=true;
};
this._allowuserinput=false;
if (this.hasAttribute('data-userinput')) {
this._allowuserinput=true;
}
this._datalist = this.querySelector('datalist');
this._allowedValues = [];
for (const option of this._datalist.options) {
this._allowedValues.push(option.value);
if (option.hasAttribute('selected')){
const item = document.createElement('div');
item.classList.add('item');
item.textContent = option.value;
this.insertBefore(item, this._input);
}
}
this._forminput.value = this.getValues();
this._input = this.querySelector('input');
this._input.onblur = this._handleBlur.bind(this);
this._input.oninput = this._handleInput.bind(this);
this._input.onkeydown = (event) => {
this._handleKeydown(event);
};
this._input.onkeyup = (event) => {
this._handleKeyup(event);
};
this._allowDuplicates = this.hasAttribute('allow-duplicates');
};
_ajaxcallback(data,multiinputobject){
multiinputobject._allowedValues = [];
while (multiinputobject._datalist.firstChild && !multiinputobject._datalist.firstChild.remove());
var obj = JSON.parse( data );
for( let prop in obj ){
multiinputobject._allowedValues.push(obj[prop]);
const option = document.createElement('option');
option.value = obj[prop];
multiinputobject._datalist.appendChild(option);
}
};
//called when input is 2 or more characters and we have an ajax address configured
_ajaxupdateallowedvalues() {
const xmlhttp = new XMLHttpRequest();
const callback = this._ajaxcallback;
const multiinputobject = this;
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
callback(this.responseText,multiinputobject);
}
};
xmlhttp.open("POST", this._ajaxsource, true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
var searchstring = this._ajaxfilter;
if (searchstring != '') searchstring += '=' + this._input.value
xmlhttp.send(searchstring);
};
// Called by _handleKeydown() when the value of the input is an allowed value.
_addItem(value) {
if (value =='') return;
this._input.value = '';
const item = document.createElement('div');
item.classList.add('item');
item.textContent = value;
this.insertBefore(item, this._input);
item.onclick = () => {
this._deleteItem(item);
};
// Remove value from datalist options and from _allowedValues array.
// Value is added back if an item is deleted (see _deleteItem()).
if (!this._allowDuplicates) {
for (const option of this._datalist.options) {
if (option.value === value) {
option.remove();
};
}
this._allowedValues =
this._allowedValues.filter((item) => item !== value);
}
this._forminput.value = this.getValues();
}
// Called when the × icon is tapped/clicked or
// by _handleKeydown() when Backspace is entered.
_deleteItem(item) {
const value = item.textContent;
item.remove();
// If duplicates aren't allowed, value is removed (in _addItem())
// as a datalist option and from the _allowedValues array.
// So — need to add it back here.
if (!this._allowDuplicates) {
const option = document.createElement('option');
option.value = value;
// Insert as first option seems reasonable...
this._datalist.insertBefore(option, this._datalist.firstChild);
this._allowedValues.push(value);
}
}
// Avoid stray text remaining in the input element that's not in a div.item.
_handleBlur() {
if (this._allowuserinput) {
const option = document.createElement('option');
option.value = this._input.value;
// Insert as first option seems reasonable...
this._datalist.insertBefore(option, this._datalist.firstChild);
this._allowedValues.push(this._input.value);
this._addItem(this._input.value);
}
this._input.value = '';
}
// Called when input text changes,
// either by entering text or selecting a datalist option.
_handleInput() {
// Add a div.item, but only if the current value
// of the input is an allowed value
const value = this._input.value;
if (this._allowedValues.includes(value)) {
this._addItem(value);
}
}
// Called when text is entered or keys pressed in the input element.
_handleKeydown(event) {
const itemToDelete = event.target.previousElementSibling;
const value = this._input.value;
// On Backspace, delete the div.item to the left of the input
if (value ==='' && event.key === 'Backspace' && itemToDelete) {
this._deleteItem(itemToDelete);
// Add a div.item, but only if the current value
// of the input is an allowed value
} else if (this._allowedValues.includes(value)) {
this._addItem(value);
};
}
// Called when text is entered or keys pressed in the input element.
_handleKeyup(event) {
const value = this._input.value;
if (this._ajaxenable && value.length>1) {
this._ajaxupdateallowedvalues();
}
}
// Public method for getting item values as an array.
getValues() {
const values = [];
const items = this.querySelectorAll('.item');
for (const item of items) {
values.push(item.textContent);
}
return values;
}
}
window.customElements.define('multi-input', MultiInput);