Files
MYSOPHAL/js/common.js
2025-08-07 13:15:31 +01:00

1196 lines
31 KiB
JavaScript

/**
* ---------------------------------------------------------------------
* GLPI - Gestionnaire Libre de Parc Informatique
* Copyright (C) 2015-2020 Teclib' and contributors.
*
* http://glpi-project.org
*
* based on GLPI - Gestionnaire Libre de Parc Informatique
* Copyright (C) 2003-2014 by the INDEPNET Development Team.
*
* ---------------------------------------------------------------------
*
* LICENSE
*
* This file is part of GLPI.
*
* GLPI is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GLPI is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GLPI. If not, see <http://www.gnu.org/licenses/>.
* ---------------------------------------------------------------------
*/
/* global L */
var timeoutglobalvar;
if (typeof(String.prototype.normalize) !== 'function') {
$.ajax({
type: "GET",
url: CFG_GLPI.root_doc + "/public/lib/unorm.js",
dataType: "script",
cache: true
});
}
/**
* modifier la propriete display d'un element
*
* @param objet
* @param statut
**/
function setdisplay(objet, statut) {
var e = objet;
if (e.style.display != statut) {
e.style.display = statut;
}
return true;
}
/**
* @param id
**/
function cleandisplay(id) {
var e = document.getElementById(id);
if (e) {
setdisplay(e,'block');
}
}
/**
* @param id
**/
function cleanhide(id) {
var e = document.getElementById(id);
if (e) {
setdisplay(e,'none');
}
}
/**
* masquer le menu actif par timeout
*
* @param idMenu
**/
function afterView(idMenu) {
setdisplay(idMenu,'none');
}
/**
* @param id
* @param idMenu
**/
function menuAff(id, idMenu) {
var m = document.getElementById(idMenu);
var item = m.getElementsByTagName('li');
var ssmenu = null;
for (var i=0; i<item.length; i++) {
if (item[i].id == id) {
ssmenu = item[i];
}
}
m = m.getElementsByTagName('ul');
if (ssmenu) {
var smenu = ssmenu.getElementsByTagName('ul');
if (smenu) {
//masquer tous les menus ouverts
for (i=0; i<m.length; i++) {
setdisplay(m[i],'none');
}
setdisplay(smenu[0],'block');
clearTimeout(timeoutglobalvar);
ssmenu.onmouseout = function() {
timeoutglobalvar = setTimeout(function() {
afterView(smenu[0]);
},300);
};
}
}
}
/**
* @param Type
* @param Id
**/
function fillidfield(Type, Id) {
window.opener.document.forms.helpdeskform.elements.items_id.value = Id;
window.opener.document.forms.helpdeskform.elements.itemtype.value = Type;
window.close();
}
/**
* marks all checkboxes inside the given element
* the given element is usaly a table or a div containing the table or tables
*
* @param container_id DOM element
**/
function markCheckboxes(container_id) {
var checkboxes = document.getElementById(container_id).getElementsByTagName('input');
for (var j = 0; j < checkboxes.length; j++) {
var checkbox = checkboxes[j];
if (checkbox && checkbox.type == 'checkbox') {
if (checkbox.disabled === false ) {
checkbox.checked = true;
}
}
}
return true;
}
/**
* marks all checkboxes inside the given element
* the given element is usaly a table or a div containing the table or tables
*
* @param container_id DOM element
**/
function unMarkCheckboxes(container_id) {
var checkboxes = document.getElementById(container_id).getElementsByTagName('input');
for (var j = 0; j < checkboxes.length; j++) {
var checkbox = checkboxes[j];
if (checkbox && checkbox.type == 'checkbox') {
checkbox.checked = false;
}
}
return true;
}
/**
* display "other" text input field in case of selecting "other" option
*
* @since 0.84
*
* @param select_object DOM select object
* @param other_option_name the name of both the option and the text input field
**/
function displayOtherSelectOptions(select_object, other_option_name) {
if (select_object.options[select_object.selectedIndex].value == other_option_name) {
document.getElementById(other_option_name).style.display = "inline";
} else {
document.getElementById(other_option_name).style.display = "none";
}
return true;
}
/**
* Check all checkboxes inside the given element as the same state as a reference one (toggle this one before)
* the given element is usaly a table or a div containing the table or tables
*
* @param reference_id DOM element
* @param container_id DOM element
**/
function checkAsCheckboxes(reference_id, container_id) {
$('#' + container_id + ' input[type="checkbox"]:enabled')
.prop('checked', $('#' + reference_id).is(':checked'));
return true;
}
/**
* Permit to use Shift key on a group of checkboxes
* Usage: $form.find('input[type="checkbox"]').shiftSelectable();
*/
$.fn.shiftSelectable = function() {
var lastChecked;
var $boxes = this;
// prevent html selection
document.onkeydown = function(e) {
var keyPressed = e.keyCode;
if (keyPressed == 16) { // shift key
$('html').addClass('unselectable');
document.onkeyup = function() {
$('html').removeClass('unselectable');
};
}
};
$($boxes).parent().click(function(evt) {
var selected_checkbox = $(this).children('input[type=checkbox]');
if (!lastChecked) {
lastChecked = selected_checkbox;
return;
}
if (evt.shiftKey) {
evt.preventDefault();
var start = $boxes.index(selected_checkbox);
var end = $boxes.index(lastChecked);
$boxes.slice(Math.min(start, end), Math.max(start, end) + 1)
.prop('checked', $(lastChecked).is(':checked'))
.trigger('change');
}
lastChecked = selected_checkbox;
});
};
/**
* safe function to hide an element with a specified id
*
* @param id id of the dive
* @param img_name name attribut of the img item
* @param img_src_close url of the close img
* @param img_src_open url of the open img
**/
function showHideDiv(id, img_name, img_src_close, img_src_open) {
var _elt = $('#' + id);
if (img_name !== '') {
var _awesome = img_src_close.match(/^fa-/);
var _deco;
var _img;
if (!_awesome) {
_img = $('img[name=' + img_name + ']');
if (_elt.is(':visible')) {
_img.attr('src', img_src_close);
} else {
_img.attr('src', img_src_open);
}
} else {
_deco = $('#'+img_name);
if (_elt.is(':visible')) {
_deco
.removeClass(img_src_open)
.addClass(img_src_close);
} else {
_deco
.removeClass(img_src_close)
.addClass(img_src_open);
}
}
}
if (_elt.is(':visible')) {
_elt.hide();
} else {
_elt.show();
}
}
/**
* safe function to hide an element with a specified id
*
* @param id
* @param img_name
* @param img_src_yes
* @param img_src_no
**/
function toogle(id, img_name, img_src_yes, img_src_no) {
if (document.getElementById) { // DOM3 = IE5, NS6
if (document.getElementById(id).value == '0') {
document.getElementById(id).value = '1';
if (img_name !== '') {
document[img_name].src=img_src_yes;
}
} else {
document.getElementById(id).value = '0';
if (img_name !== '') {
document[img_name].src=img_src_no;
}
}
}
}
/**
* @since 0.84
*
* @param tbl
* @param img_name
* @param img_src_close
* @param img_src_open
*/
function toggleTableDisplay(tbl, img_name, img_src_close, img_src_open) {
var tblRows = document.getElementById(tbl).rows;
for (var i=0; i < tblRows.length; i++) {
if (tblRows[i].className.indexOf("headerRow") == -1) {
if (tblRows[i].style.display == 'none') {
tblRows[i].style.display = "table-row";
if (img_name !== '') {
document[img_name].src = img_src_open;
}
} else {
tblRows[i].style.display = "none";
if (img_name !== '') {
document[img_name].src = img_src_close;
}
}
}
}
if (document.getElementById(tbl+'2')) {
toggleTableDisplay(tbl+'2','');
}
if (document.getElementById(tbl+'3')) {
toggleTableDisplay(tbl+'3','');
}
if (document.getElementById(tbl+'4')) {
toggleTableDisplay(tbl+'4','');
}
if (document.getElementById(tbl+'5')) {
toggleTableDisplay(tbl+'5','');
}
}
/**
* @since 0.84
*
* @param target
* @param fields
**/
function submitGetLink(target, fields) {
var myForm = document.createElement("form");
myForm.method = "post";
myForm.action = target;
for (var name in fields) {
var myInput = document.createElement("input");
myInput.setAttribute("name", name);
myInput.setAttribute("value", fields[name]);
myForm.appendChild(myInput);
}
document.body.appendChild(myForm);
myForm.submit();
document.body.removeChild(myForm);
}
/**
* @since 0.85
*
* @param id
**/
function selectAll(id) {
var element =$('#'+id);var selected = [];
element.find('option').each(function(i,e){
selected[selected.length]=$(e).attr('value');
});
element.val(selected);
element.trigger('change');
}
/**
* @since 0.85
*
* @param id
**/
function deselectAll(id) {
$('#'+id).val('').trigger('change');
}
/**
* Set all the checkbox that refere to the criterion
*
* @since 0.85
*
* @param criterion jquery criterion
* @param reference the new reference object, boolean, id ... (default toggle)
*
**/
function massiveUpdateCheckbox(criterion, reference) {
var value = null;
if (typeof(reference) == 'boolean') {
value = reference;
} else if (typeof(reference) == 'string') {
value = $('#' + reference).prop('checked');
} else if (typeof(reference) == 'object') {
value = $(reference).prop('checked');
}
if (typeof(value) == 'undefined') {
return false;
}
$(criterion).each(function() {
if (typeof(reference) == 'undefined') {
value = !$(this).prop('checked');
}
$(this).prop('checked', value);
});
return true;
}
/**
* Timeline for itiobjects
*/
var filter_timeline = function() {
$(document).on("click", '.filter_timeline li a', function(event) {
event.preventDefault();
var _this = $(this);
//hide all elements in timeline
$('.h_item').addClass('h_hidden');
//reset all elements
if (_this.data('type') == 'reset') {
$('.filter_timeline li a').removeClass('h_active');
$('.h_item').removeClass('h_hidden');
return;
}
//activate clicked element
_this.toggleClass('h_active');
//find active classname
var active_classnames = [];
$('.filter_timeline .h_active').each(function() {
active_classnames.push(".h_content."+$(this).data('type'));
});
$(active_classnames.join(', ')).each(function(){
$(this).parent().removeClass('h_hidden');
});
//show all items when no active filter
if (active_classnames.length === 0) {
$('.h_item').removeClass('h_hidden');
}
});
};
var read_more = function() {
$(document).on("click", ".long_text .read_more a, .long_text .read_more .read_more_button", function() {
$(this).parents('.long_text').removeClass('long_text');
$(this).parent('.read_more').remove();
return false;
});
};
var split_button_fct_called = false;
var split_button = function() {
if (split_button_fct_called) {
return true;
}
split_button_fct_called = true;
// unfold status list
$(document).on("click", '.x-button-drop', function() {
$(this).parents(".x-split-button").toggleClass('open');
});
$(document).on("click", '.x-split-button', function(event) {
event.stopPropagation();
});
//click on an element of status list
$(document).on("click", '.x-button-drop-menu li', function(event) {
var chosen_li = $(this);
if (event.target.children.length) {
var xBtnDrop = chosen_li.parent().siblings(".x-button-drop");
//clean old status class
xBtnDrop.attr('class','x-button x-button-drop');
//find status
var cstatus = chosen_li.data('status');
//add status to dropdown button
xBtnDrop.addClass(cstatus);
//fold status list
chosen_li.parents(".x-split-button").removeClass('open');
}
});
//fold status list on click on document
$(document).on("click", function() {
if ($('.x-split-button').hasClass('open')) {
$('.x-split-button').removeClass('open');
}
});
};
// Responsive header
if ($(window).width() <= 700) {
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('header').outerHeight();
$(window).scroll(function() {
didScroll = true;
});
setInterval(function() {
if (didScroll) {
scollHeaderResponsive();
didScroll = false;
}
}, 250);
var scollHeaderResponsive = function() {
var st = $(this).scrollTop();
// Make sure they scroll more than delta
if (Math.abs(lastScrollTop - st) <= delta) {
return;
}
if (st > lastScrollTop && st > navbarHeight) {
// Scroll Down
$('#header').removeClass('nav-down').addClass('nav-up');
} else {
// Scroll Up
if (st + $(window).height() < $(document).height()) {
$('#header').removeClass('nav-up').addClass('nav-down');
}
}
lastScrollTop = st;
};
}
var langSwitch = function(elt) {
var _url = elt.attr('href').replace(/front\/preference.+/, 'ajax/switchlang.php');
$.ajax({
url: _url,
type: 'GET',
success: function(html) {
$('#language_link')
.html(html);
$('#debugajax').remove();
}
});
};
$(function() {
if ($('html').hasClass('loginpage')) {
return;
}
$('#menu.fullmenu li').on('mouseover', function() {
var _id = $(this).data('id');
menuAff('menu' + _id, 'menu');
});
$("body").delegate('td','mouseover mouseleave', function(e) {
var col = $(this).closest('tr').children().index($(this));
var tr = $(this).closest('tr');
if (!$(this).closest('tr').hasClass('noHover')) {
if (e.type == 'mouseover') {
tr.addClass("rowHover");
// If rowspan
if (tr.has('td[rowspan]').length === 0) {
tr.prevAll('tr:has(td[rowspan]):first').find('td[rowspan]').addClass("rowHover");
}
$(this).closest('table').find('tr:not(.noHover) th:nth-child('+(col+1)+')').addClass("headHover");
} else {
tr.removeClass("rowHover");
// remove rowspan
tr.removeClass("rowHover").prevAll('tr:has(td[rowspan]):first').find('td[rowspan]').removeClass("rowHover");
$(this).closest('table').find('tr:not(.noHover) th:nth-child('+(col+1)+')').removeClass("headHover");
}
}
});
// prevent jquery ui dialog to keep focus
$.ui.dialog.prototype._focusTabbable = function() {};
//quick lang switch
$('#language_link > a').on('click', function(event) {
event.preventDefault();
langSwitch($(this));
});
// ctrl+enter in form textareas (without tinymce)
$(document).on('keydown', '#page form textarea', function(event) {
if (event.ctrlKey
&& event.keyCode == 13) {
submitparentForm($(this));
}
});
// permits to have html in dialogs title
$.widget("ui.dialog", $.extend({}, $.ui.dialog.prototype, {
_title: function(title) {
if (!this.options.title ) {
title.html("&#160;");
} else {
title.html(this.options.title);
}
}
}));
});
/**
* Trigger submit event for a parent form of passed input dom element
*
* @param Object input the dom or jquery object of input
* @return bool
*/
var submitparentForm = function(input) {
// find parent form
var form = $(input).closest('form');
// find submit button(s)
var submit = form.find('[type=submit]').filter('[name=add], [name=update]');
// trigger if only one submit button
if (submit.length == 1) {
return (submit.trigger('click') !== false);
}
return false;
};
/**
* Determines if data from drop is an image.
*
* @param {Blob} file The file
* @return {boolean} True if image, False otherwise.
*/
var isImage = function(file) {
var validimagetypes = ["image/gif", "image/jpeg","image/jpg", "image/png"];
if ($.inArray(file.type, validimagetypes) < 0) {
return false;
} else {
return true;
}
};
/**
* Return a png url reprensenting an extension
*
* @param {String} ext the extension
* @return {string} an image html tag
*/
var getExtIcon = function(ext) {
var url = CFG_GLPI.root_doc+'/pics/icones/'+ext+'-dist.png';
if (!urlExists(url)) {
url = CFG_GLPI.root_doc+'/pics/icones/defaut-dist.png';
}
return '<img src="'+url+'" title="'+ext+'">';
};
/**
* Check for existence of an url
*
* @param {String} url
* @return {Bool}
*/
var urlExists = function(url) {
var exist = false;
$.ajax({
'type': 'HEAD',
'url': url,
'async': false,
'success': function() {
exist = true;
}
});
return exist;
};
/**
* Format a size to the last possible unit (o, Kio, Mio, etc)
*
* @param {integer} size
* @return {string} The formated size
*/
var getSize = function (size) {
var bytes = ['o', 'Kio', 'Mio', 'Gio', 'Tio'];
var lastval = '';
bytes.some(function(val) {
if (size > 1024) {
size = size / 1024;
} else {
lastval = val;
return true;
}
});
return Math.round(size * 100, 2) / 100 + lastval;
};
/**
* Convert a integer index into an excel like alpha index (A, B, ..., AA, AB, ...)
* @since 9.3
* @param integer index the numeric index
* @return string excel like string index
*/
var getBijectiveIndex = function(index) {
var bij_str = "";
while (parseInt(index) > 0) {
index--;
bij_str = String.fromCharCode("A".charCodeAt(0) + ( index % 26)) + bij_str;
index /= 26;
}
return bij_str;
};
/**
* Stop propagation and navigation default for the specified event
*/
var stopEvent = function(event) {
event.preventDefault();
event.stopPropagation();
};
/**
* Back to top implementation
*/
if ($('#backtotop').length) {
var scrollTrigger = 100, // px
backToTop = function () {
var scrollTop = $(window).scrollTop();
if (scrollTop > scrollTrigger) {
$('#backtotop').show('slow');
$('#see_debug').addClass('wbttop');
} else {
$('#backtotop').hide();
$('#see_debug').removeClass('wbttop');
}
};
backToTop();
$(window).on('scroll', function () {
backToTop();
});
$('#backtotop').on('click', function (e) {
e.preventDefault();
$('html,body').animate({
scrollTop: 0
}, 700);
});
}
/**
* Returns element height, including margins
*/
function _eltRealSize(_elt) {
var _s = 0;
_s += _elt.outerHeight();
_s += parseFloat(_elt.css('margin-top').replace('px', ''));
_s += parseFloat(_elt.css('margin-bottom').replace('px', ''));
_s += parseFloat(_elt.css('padding-top').replace('px', ''));
_s += parseFloat(_elt.css('padding-bottom').replace('px', ''));
return _s;
}
var initMap = function(parent_elt, map_id, height) {
// default parameters
map_id = (typeof map_id !== 'undefined') ? map_id : 'map';
height = (typeof height !== 'undefined') ? height : '200px';
if (height == 'full') {
//full height map
var wheight = $(window).height();
var _oSize = 0;
$('#header_top, #c_menu, #c_ssmenu2, #footer, .search_page').each(function(){
_oSize += _eltRealSize($(this));
});
_oSize += parseFloat($('#page').css('padding-top').replace('px', ''));
_oSize += parseFloat($('#page').css('padding-bottom').replace('px', ''));
_oSize += parseFloat($('#page').css('margin-top').replace('px', ''));
_oSize += parseFloat($('#page').css('margin-bottom').replace('px', ''));
var newHeight = Math.floor(wheight - _oSize);
var minHeight = 300;
if ( newHeight < minHeight ) {
newHeight = minHeight;
}
height = newHeight + 'px';
}
//add map, set a default arbitrary location
parent_elt.append($('<div id="'+map_id+'" style="height: ' + height + '"></div>'));
var map = L.map(map_id, {fullscreenControl: true}).setView([43.6112422, 3.8767337], 6);
//setup tiles and © messages
L.tileLayer('https://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href=\'https://osm.org/copyright\'>OpenStreetMap</a> contributors'
}).addTo(map);
return map;
};
var showMapForLocation = function(elt) {
var _id = $(elt).data('fid');
var _items_id = $('#' + _id).val();
if (_items_id == 0) {
return;
}
var _dialog = $('<div id="location_map_dialog"/>');
_dialog.appendTo('body').dialog({
close: function() {
$(this).dialog('destroy').remove();
}
});
//add map, set a default arbitrary location
var map_elt = initMap($('#location_map_dialog'), 'location_map');
map_elt.spin(true);
$.ajax({
dataType: 'json',
method: 'POST',
url: CFG_GLPI.root_doc + '/ajax/getMapPoint.php',
data: {
itemtype: 'Location',
items_id: $('#' + _id).val()
}
}).done(function(data) {
if (data.success === false) {
_dialog.dialog('close');
$('<div>' + data.message + '</div>').dialog({
close: function() {
$(this).dialog('destroy').remove();
}
});
} else {
var _markers = [];
var _marker = L.marker([data.lat, data.lng]);
_markers.push(_marker);
var _group = L.featureGroup(_markers).addTo(map_elt);
map_elt.fitBounds(
_group.getBounds(), {
padding: [50, 50],
maxZoom: 10
}
);
}
}).always(function() {
//hide spinner
map_elt.spin(false);
});
};
var query = {};
function markMatch (text, term) {
// Find where the match is
var match = text.toUpperCase().indexOf(term.toUpperCase());
var _result = $('<span></span>');
// If there is no match, move on
if (match < 0) {
_result.append(escapeMarkupText(text));
return _result.html();
}
// Put in whatever text is before the match
_result.html(escapeMarkupText(text.substring(0, match)));
// Mark the match
var _match = $('<span class=\'select2-rendered__match\'></span>');
_match.html(escapeMarkupText(text.substring(match, match + term.length)));
// Append the matching text
_result.append(_match);
// Put in whatever is after the match
_result.append(escapeMarkupText(text.substring(match + term.length)));
return _result.html();
}
/**
* Function that renders select2 results.
*/
var templateResult = function(result) {
var _elt = $('<span></span>');
_elt.attr('title', result.title);
if (typeof query.term !== 'undefined' && typeof result.rendered_text !== 'undefined') {
_elt.html(result.rendered_text);
} else {
if (!result.text) {
return null;
}
var text = result.text;
if (!result.id) {
// If result has no id, then it is used as an optgroup and is not used for matches
_elt.html(escapeMarkupText(text));
return _elt;
}
var _term = query.term || '';
var markup = markMatch(text, _term);
if (result.level) {
var a='';
var i=result.level;
while (i>1) {
a = a+'&nbsp;&nbsp;&nbsp;';
i=i-1;
}
_elt.html(a+'&raquo;'+markup);
} else {
_elt.html(markup);
}
}
return _elt;
};
// delay function who reinit timer on each call
var typewatch = (function(){
var timer = 0;
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
/**
* Function that renders select2 selections.
*/
var templateSelection = function (selection) {
if (!("element" in selection)) {
return selection.text;
}
// Data generated by ajax containing 'selection_text'
if (Object.prototype.hasOwnProperty.call(selection, 'selection_text')) {
return selection.selection_text;
}
// Data generated with optgroups
if (selection.element.parentElement.nodeName == 'OPTGROUP') {
return selection.element.parentElement.getAttribute('label') + ' - ' + selection.text;
}
// Default text
return selection.text;
};
/**
* Returns given text without is diacritical marks.
*
* @param {string} text
*
* @return {string}
*/
var getTextWithoutDiacriticalMarks = function (text) {
// Normalizing to NFD Unicode normal form decomposes combined graphemes
// into the combination of simple ones. The "è" becomes "e + ̀`".
text = text.normalize('NFD');
// The U+0300 -> U+036F range corresponds to diacritical chars.
// They are removed to keep only chars without their diacritical mark.
return text.replace(/[\u0300-\u036f]/g, '');
};
/**
* Escape markup in text to prevent XSS.
*
* @param {string} text
*
* @return {string}
*/
var escapeMarkupText = function (text) {
if (text.indexOf('>') !== -1 || text.indexOf('<') !== -1) {
// escape text, if it contains chevrons (can already be escaped prior to this point :/)
text = jQuery.fn.select2.defaults.defaults.escapeMarkup(text);
}
return text;
};
/**
* Updates an accessible progress bar title and foreground width.
* @since 9.5.0
* @param progressid ID of the progress bar
* @return void
*/
function updateProgress(progressid) {
var progress = $("progress#progress"+progressid).first();
$("div[data-progressid='"+progressid+"']").each(function(i, item) {
var j_item = $(item);
var fg = j_item.find(".progress-fg").first();
var calcWidth = (progress.attr('value') / progress.attr('max')) * 100;
fg.width(calcWidth+'%');
if (j_item.data('append-percent') === 1) {
var new_title = (j_item.prop('title').replace(new RegExp("\\d*%$"), progress.attr('value')+'%')).trim();
progress.prop('title', new_title);
j_item.prop('title', new_title);
}
});
}
/**
* Normalize altfield value of a MultiDatePicker instance.
*
* @param input_id id of the date input field
* @param date_format dateFormat option used in MultiDatePicker instance
* (i.e. 'dd-mm-yy', 'mm-dd-yy' or 'yy-mm-dd')
*
* @return void
*/
function normalizeMultiDateAltField(input_id, date_format) {
var dates = $(input_id).val().split(', ');
var alt_dates = [];
for (var i = 0; i < dates.length; i++) {
var date_obj = $.datepicker.parseDate(date_format, dates[i]);
alt_dates.push($.datepicker.formatDate('yy-mm-dd', date_obj));
}
$(input_id).val(alt_dates.join(', '));
}
/**
* Get RGB object from an hexadecimal color code
*
* @param {*} hex
* @returns {Object} {r, g, b}
*/
function hexToRgb(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
/**
* Get luminance for a color
* https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
*
* @param {Array} rgb [r, g, b] array
* @returns {Number}
*/
function luminance(rgb) {
var a = rgb.map(function (v) {
v /= 255;
return v <= 0.03928
? v / 12.92
: Math.pow( (v + 0.055) / 1.055, 2.4 );
});
return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
}
/**
* Get contrast ratio between two colors
* https://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
*
* @param {Array} rgb1 [r, g, b] array
* @param {Array} rgb2 [r, g, b] array
* @returns {Number}
*/
function contrast(rgb1, rgb2) {
return (luminance(rgb1) + 0.05) / (luminance(rgb2) + 0.05);
}
// fullscreen api
function GoInFullscreen(element) {
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullscreen();
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen();
}
}
function GoOutFullscreen() {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
}
function getUuidV4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
/** Track input changes and warn the user of unsaved changes if they try to navigate away */
window.glpiUnsavedFormChanges = false;
$(document).ready(function() {
// Forms must have the data-track-changes attribute set to true.
// Form fields may have their data-track-changes attribute set to empty (false) to override the tracking on that input.
$(document).on('input', 'form[data-track-changes="true"] input:not([data-track-changes=""]),' +
'form[data-track-changes="true"] textarea:not([data-track-changes="false"])', function() {
window.glpiUnsavedFormChanges = true;
});
$(document).on('change', 'form[data-track-changes="true"] select:not([data-track-changes=""])', function() {
window.glpiUnsavedFormChanges = true;
});
$(window).on('beforeunload', function(e) {
if (window.glpiUnsavedFormChanges) {
e.preventDefault();
// All supported browsers will show a localized message
return '';
}
});
$(document).on('submit', 'form', function() {
window.glpiUnsavedFormChanges = false;
});
});
function onTinyMCEChange(e) {
var editor = $(e.target)[0];
if ($(editor.targetElm).data('trackChanges') !== false) {
if ($(editor.formElement).data('trackChanges') === true) {
window.glpiUnsavedFormChanges = true;
}
}
}
function relativeDate(str) {
var s = ( +new Date() - Date.parse(str) ) / 1e3,
m = s / 60,
h = m / 60,
d = h / 24,
y = d / 365.242199,
tmp;
return (tmp = Math.round(s)) === 1 ? __('just now')
: m < 1.01 ? '%s seconds ago'.replace('%s', tmp)
: (tmp = Math.round(m)) === 1 ? __('a minute ago')
: h < 1.01 ? '%s minutes ago'.replace('%s', tmp)
: (tmp = Math.round(h)) === 1 ? __('an hour ago')
: d < 1.01 ? '%s hours ago'.replace('%s', tmp)
: (tmp = Math.round(d)) === 1 ? __('yesterday')
: y < 1.01 ? '%s days ago'.replace('%s', tmp)
: (tmp = Math.round(y)) === 1 ? __('a year ago')
: '%s years ago'.replace('%s', tmp);
}