Commit 50065ae7 by crosf32

remove jquery

parent a110532b
......@@ -25,7 +25,7 @@
color: #2c2c2c !important;
}
.doodle-table thead tr th{
.doodle-table thead tr th {
padding: 15px;
height: 70px;
font-family: "Segoe UI", "Helvetica Neue", Arial, sans-serif;
......@@ -154,11 +154,11 @@
}
.doodle-table .delete_col{
.doodle-table .delete_col {
background: #fddddd;
position: absolute;
width: 100%;
top: -74px;
top: -100%;
height: 74px;
left: 0;
opacity: 0;
......@@ -180,6 +180,16 @@
border-right: none;
}
.doodle-table #heure:hover div {
display: flex;
opacity: 1;
}
.doodle-table #date:hover div {
display: flex;
opacity: 1;
}
.doodle-table #date:hover {
background: #fdf2f2 !important;
color: #f55753;
......
(function($) {
const CLOSEIMG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABS2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxMzggNzkuMTU5ODI0LCAyMDE2LzA5LzE0LTAxOjA5OjAxICAgICAgICAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+IEmuOgAAAMpJREFUOI3Nkk0KglAQgL/3NPEKXSX62waB0F7w7y5BQRcIpU5Qd6ikDhJ6Ahcv9LUoWhmYETS7meH7ZgZGFIE7AWKgy2eRAaFsCfNkYtkSfknkFzAAvxHY8yXmcPzKzcEIe7GqFZh1xdt+hxVEj6Sq6LgeKlk3F5SXFCXA8iMQApWsKc9p8xMeHQlCACCM2jnvNzB6fSwvRG1i0BrLj9BoytOhmcCcOqhtQpkeAVBAx5nVCkQRuPrtfg3iPx4p+4LPJRABeQv4CoR3Jng1ltK2xpYAAAAASUVORK5CYII=';
const CLOSEIMG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABS2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxMzggNzkuMTU5ODI0LCAyMDE2LzA5LzE0LTAxOjA5OjAxICAgICAgICAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+IEmuOgAAAMpJREFUOI3Nkk0KglAQgL/3NPEKXSX62waB0F7w7y5BQRcIpU5Qd6ikDhJ6Ahcv9LUoWhmYETS7meH7ZgZGFIE7AWKgy2eRAaFsCfNkYtkSfknkFzAAvxHY8yXmcPzKzcEIe7GqFZh1xdt+hxVEj6Sq6LgeKlk3F5SXFCXA8iMQApWsKc9p8xMeHQlCACCM2jnvNzB6fSwvRG1i0BrLj9BoytOhmcCcOqhtQpkeAVBAx5nVCkQRuPrtfg3iPx4p+4LPJRABeQv4CoR3Jng1ltK2xpYAAAAASUVORK5CYII=';
/**
* doodle Object
* @param item
* @param config
*/
const dynamicEvent = (event_type, target_element_selector, listener_function) => {
document.addEventListener(event_type, event => {
if (event.target && event.target.matches && event.target.matches(target_element_selector)) {
(listener_function)(event);
}
});
}
let DoodleFront = function(item, config) {
this.item = item;
this.config = config;
this.json = null;
this.days = [];
this.hours = [];
this.dateFormat = this.config.outputDateFormat || 'DD/MM/YYYY';
this.outputJson = {};
this.initLoad = () => {
this.getJsonData();
if(!this.json) {
console.warn('Invalid Json data');
return;
}
let DoodleFront = function(item, config) {
this.item = item;
this.config = config;
this.json = null;
this.days = [];
this.hours = [];
this.dateFormat = this.config.outputDateFormat || 'DD/MM/YYYY';
this.outputJson = {};
this.getDays();
this.getHours();
this.createTable(config);
this.initLoad = () => {
this.getJsonData();
this.initCSS(config);
if(!this.json) {
console.warn('Invalid Json data');
return;
}
if(!config.vertical) {
document.querySelector('table').parentNode.style.overflowX = 'auto';
}
};
this.getDays();
this.getHours();
this.createTable(config);
/**
* Create Table
*/
this.createTable = (config) => {
dynamicEvent('click', 'input[type=checkbox]', this.eventInput);
if(config.vertical) {
this.item.innerHTML += `
<ul class="doodle-list">
${this.createList()}
</ul>
`;
} else {
this.item.innerHTML += `
<table class="table doodle-table frontend">
<thead>
${this.createHeaderTable()}
</thead>
<tbody>
${this.createBodyTable()}
</tbody>
</table>
`;
}
};
this.initCSS(config);
this.createList = function() { // TODO : vertical
let div = document.createElement('div');
// DAYS =>
for(let index in this.days) {
let formatDateDay = moment(this.days[index], this.dateFormat).locale('fr').format('dddd DD');
let formatDateMonth = moment(this.days[index], this.dateFormat).locale('fr').format('MMMM');
//Remet l'overflow pour le responsive en front
if(!config.vertical) {
$('table').parent().css('overflow-x', 'auto');
}
};
let date = this.days[index];
/**
* Create Table
*/
this.createTable = (config) => {
$(document).on('click', 'input[type=checkbox]', this.eventInput);
if(config.vertical) {
this.item.append(`
<ul class="doodle-list">
${this.createList()}
</ul>
`);
} else {
this.item.append(`
<table class="table doodle-table frontend">
<thead>
${this.createHeaderTable()}
</thead>
<tbody>
${this.createBodyTable()}
</tbody>
</table>
`);
}
};
this.createList = function() { // TODO : vertical
let div = $('<div>');
// DAYS =>
for(let index in this.days) {
let formatDateDay = moment(this.days[index], this.dateFormat).locale('fr').format('dddd DD');
let formatDateMonth = moment(this.days[index], this.dateFormat).locale('fr').format('MMMM');
let date = this.days[index];
div.innerHTML += '<h5><span class="date_format"><b>' + formatDateDay + '</b></span> ' + formatDateMonth + '</td>';
let $h3 = $('<h5><span class="date_format"><b>' + formatDateDay + '</b></span> ' + formatDateMonth + '</td>');
div.append($h3);
for(let index2 in this.hours) {
let $li = $('<li class="p-3">');
if(this.json[this.days[index]].includes(this.hours[index2])) {
let hour = this.hours[index2];
if (hour.indexOf(':') === -1) {
hour += 'h';
} else {
hour = hour.replace(':', 'h');
}
$li.html(this.createInputBox(this.hours[index2], date, hour));
div.append($li);
for(let index2 in this.hours) {
let $li = document.createElement('li');
$li.classList.add('p-3');
if(this.json[this.days[index]].includes(this.hours[index2])) {
let hour = this.hours[index2];
if (hour.indexOf(':') === -1) {
hour += 'h';
} else {
hour = hour.replace(':', 'h');
}
$li.innerHTML += this.createInputBox(this.hours[index2], date, hour);
div.innerHTML += $li.innerHTML;
}
}
return div.html();
}
this.initCSS = function() {
$('.empty').css('background', '#fafafa')
};
/**
* Create table header for hours
* @returns {string}
*/
this.createBodyTable = () => {
let $tbody = $('<tbody>');
let html, tbodyFinal;
return div.innerHTML;
}
for(let index in this.days) {
let $tr = $('<tr>');
let formatDateDay = moment(this.days[index], this.dateFormat).locale('fr').format('dddd DD');
let formatDateMonth = moment(this.days[index], this.dateFormat).locale('fr').format('MMMM');
html = $tr.append('<td><span class="date_format"><b>' + formatDateDay + '</b></span> ' + formatDateMonth + '</td>')
.append(this.createBodyContent(this.days[index]));
this.initCSS = function() {
document.querySelectorAll('.empty').forEach(e => e.style.background = '#fafafa');
};
tbodyFinal = $tbody.append(html);
}
/**
* Create table header for hours
* @returns {string}
*/
this.createBodyTable = () => {
let $tbody = document.createElement('tbody');
let html, tbodyFinal;
return tbodyFinal.html();
};
for(let index in this.days) {
let $tr = document.createElement('tr');
let formatDateDay = moment(this.days[index], this.dateFormat).locale('fr').format('dddd DD');
let formatDateMonth = moment(this.days[index], this.dateFormat).locale('fr').format('MMMM');
/**
* Create body content
* @param index
* @returns {string}
*/
this.createBodyContent = (index) => {
let html;
let $td = $('<td>');
for(let key in this.hours) {
if(this.json[index].includes(this.hours[key]))
html = '<td>' + this.createInputBox(this.hours[key], index) + '</td>';
else
html = '<td class="empty"></td>';
$td.append(html);
}
html = $tr.innerHTML += '<td><span class="date_format"><b>' + formatDateDay + '</b></span> ' + formatDateMonth + '</td>'
+ this.createBodyContent(this.days[index]);
return $td.html();
};
tbodyFinal = $tbody.innerHTML += html;
}
/**
* Creer l'input
* @param hour
* @param day
* @returns {string}
*/
this.createInputBox = (hour, day, name = null) => {
let dayFormat = moment(day, this.dateFormat).format('DDMMYYYY');
let html = "<label class='label_input'><input type='checkbox' data-check=" + dayFormat + '_' + hour + " /><span><i></i></span>";
if(name) {
html += "<h5>" + name + "</h5>";
}
html += "</label>"
return html;
return tbodyFinal;
};
};
/**
* Create body content
* @param index
* @returns {string}
*/
this.createBodyContent = (index) => {
let html;
let $td = document.createElement('td');
/**
* Create table header for hours
* @returns {string}
*/
this.createHeaderTable = () => {
let $tr = $('<tr>');
let thead;
let finalSortedTab = [];
// Nombre de cases vide
const NBRCASEVIDE = 1;
//Ajoute les cases vide
for (let i = 0; i < NBRCASEVIDE; i++) {
thead = $tr.append('<th></th>');
}
for(let key in this.hours) {
if(this.json[index].includes(this.hours[key]))
html = '<td>' + this.createInputBox(this.hours[key], index) + '</td>';
else
html = '<td class="empty"></td>';
// Permet de mettre un 'h' pour les heures/minutes
this.hours.forEach( (el, index) => {
if (el.indexOf(':') === -1) {
el += 'h';
} else {
el = el.replace(':', 'h');
}
$td.innerHTML = html;
}
finalSortedTab.push(el);
});
return $td.innerHTML;
};
//Ajoute les heures
for(let index in finalSortedTab) {
thead = $tr.append('<th>' + finalSortedTab[index] + '</th>');
}
/**
* Creer l'input
* @param hour
* @param day
* @returns {string}
*/
this.createInputBox = (hour, day, name = null) => {
let dayFormat = moment(day, this.dateFormat).format('DDMMYYYY');
return thead.html();
};
let html = "<label class='label_input'><input type='checkbox' data-check=" + dayFormat + '_' + hour + " /><span><i></i></span>";
if(name) {
html += "<h5>" + name + "</h5>";
}
html += "</label>"
return html;
};
/**
* Get Days
*/
this.getDays = () => {
this.days = Object.keys(this.json);
};
/**
* Create table header for hours
* @returns {string}
*/
this.createHeaderTable = () => {
let $tr = document.createElement('tr');
let thead;
let finalSortedTab = [];
/**
* Get Hours
*/
this.getHours = () => {
for(let key in this.json) {
for(let index in this.json[key]) {
if(!this.hours.includes(this.json[key][index])) {
this.hours.push(this.json[key][index]);
this.hours.sort();
}
}
}
};
// Nombre de cases vide
const NBRCASEVIDE = 1;
/**
* Get Json data
*/
this.getJsonData = () => {
let dataJson = this.item.data('json');
//Ajoute les cases vide
for (let i = 0; i < NBRCASEVIDE; i++) {
thead = $tr.innerHTML += '<th></th>';
}
if(typeof dataJson === 'object') {
this.json = dataJson;
} else if(this.isJsonString(dataJson)){
this.json = JSON.parse(dataJson);
// Permet de mettre un 'h' pour les heures/minutes
this.hours.forEach( (el, index) => {
if (el.indexOf(':') === -1) {
el += 'h';
} else {
let data = this.fileExistsAndGetData(dataJson);
if(data) {
let json = JSON.parse(data);
if (!$.isEmptyObject(json)) {
this.json = json;
}
}
el = el.replace(':', 'h');
}
};
/**
* Check if string is valid Json
* @param str
* @returns {boolean}
*/
this.isJsonString = (str) => {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
};
finalSortedTab.push(el);
});
/**
* Check if file exist and get data
* @param url
* @returns {boolean}
*/
this.fileExistsAndGetData = (url) => {
if(url){
let req = new XMLHttpRequest();
req.open('GET', url, false);
req.send();
return req.response;
} else {
return false;
}
};
//Ajoute les heures
for(let index in finalSortedTab) {
thead = $tr.innerHTML += '<th>' + finalSortedTab[index] + '</th>';
}
/**
* Generate JSON
*/
this.createJSON = () => {
let $input = $(this.config.inputSelector);
return thead.innerHTML;
};
/**
* Get Days
*/
this.getDays = () => {
this.days = Object.keys(this.json);
};
if ($input.length > 0) {
$input.val(JSON.stringify(this.outputJson));
/**
* Get Hours
*/
this.getHours = () => {
for(let key in this.json) {
for(let index in this.json[key]) {
if(!this.hours.includes(this.json[key][index])) {
this.hours.push(this.json[key][index]);
this.hours.sort();
}
}
};
}
};
/**
* Event for input
* @param e event
*/
this.eventInput = (e) => {
let data = $(e.target).data('check').split('_');
let isChecked = $(e.target).is(':checked');
if (isChecked) {
this.addInOutputObject(data);
$(e.target).parent().parent().css('background', '#e2deef');
} else {
this.removeInOutputObject(data);
$(e.target).parent().parent().css('background', '');
/**
* Get Json data
*/
this.getJsonData = () => {
let dataJson = this.item.dataset.json;
if(typeof dataJson === 'object') {
this.json = dataJson;
} else if(this.isJsonString(dataJson)) {
this.json = JSON.parse(dataJson);
} else {
let data = this.fileExistsAndGetData(dataJson);
if(data) {
let json = JSON.parse(data);
if (Object.keys(json).length > 0) {
this.json = json;
}
}
}
};
this.createJSON();
};
/**
* Check if string is valid Json
* @param str
* @returns {boolean}
*/
this.isJsonString = (str) => {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
};
/**
* Add value into json
* @param data
*/
this.addInOutputObject = (data) => {
/**
* Check if file exist and get data
* @param url
* @returns {boolean}
*/
this.fileExistsAndGetData = (url) => {
if(url){
let req = new XMLHttpRequest();
req.open('GET', url, false);
req.send();
return req.response;
} else {
return false;
}
};
let dayFormat = moment(data[0], 'DDMMYYYY').format(this.dateFormat);
/**
* Generate JSON
*/
this.createJSON = () => {
let $input = document.querySelector(this.config.inputSelector);
if (!this.outputJson[dayFormat]) {
this.outputJson[dayFormat] = [];
}
if ($input) {
$input.value = JSON.stringify(this.outputJson);
}
};
let output = this.outputJson[dayFormat];
/**
* Event for input
* @param e event
*/
this.eventInput = (e) => {
let data = e.target.dataset.check.split('_');
let isChecked = e.target.checked;
if (isChecked) {
this.addInOutputObject(data);
e.target.parentNode.style.background = '#e2deef';
} else {
this.removeInOutputObject(data);
e.target.parentNode.style.background = '';
}
if (output.indexOf(data[1]) === -1) {
output.push(data[1]);
output.sort(function(a,b) {
return moment(a, 'HH:mm') - moment(b, 'HH:mm');
});
}
};
this.createJSON();
};
/**
* Remove value from json
* @param data
*/
this.removeInOutputObject = (data) => {
let dayFormat = moment(data[0], 'DDMMYYYY').format(this.dateFormat);
/**
* Add value into json
* @param data
*/
this.addInOutputObject = (data) => {
if (this.outputJson[dayFormat]) {
let output = this.outputJson[dayFormat];
let index = output.indexOf(data[1]);
let dayFormat = moment(data[0], 'DDMMYYYY').format(this.dateFormat);
if (index !== -1) {
output.splice(index, 1);
if (!this.outputJson[dayFormat]) {
this.outputJson[dayFormat] = [];
}
if (output.length === 0) {
delete this.outputJson[dayFormat];
}
}
}
};
let output = this.outputJson[dayFormat];
/**
* Init
*/
this.initLoad();
if (output.indexOf(data[1]) === -1) {
output.push(data[1]);
output.sort(function(a,b) {
return moment(a, 'HH:mm') - moment(b, 'HH:mm');
});
}
};
/**
* For back
* @param item
* @param config
* @constructor
* Remove value from json
* @param data
*/
this.removeInOutputObject = (data) => {
let dayFormat = moment(data[0], 'DDMMYYYY').format(this.dateFormat);
let DoodleBack = function (item, config) {
this.item = item;
this.config = config;
this.json = null;
this.days = [];
this.hours = this.config.defaultHours || [];
this.dateFormat = this.config.outputDateFormat || 'DD/MM/YYYY';
this.outputJson = {};
this.init = true;
if (this.outputJson[dayFormat]) {
let output = this.outputJson[dayFormat];
let index = output.indexOf(data[1]);
this.initLoad = () => {
if (this.init) {
this.getJsonData();
if (index !== -1) {
output.splice(index, 1);
if(!this.json) {
console.warn('Invalid Json data');
return;
if (output.length === 0) {
delete this.outputJson[dayFormat];
}
}
}
};
this.getDays();
this.getHours();
/**
* Init
*/
this.initLoad();
};
let DoodleBack = function (item, config) {
this.item = item;
this.config = config;
this.json = null;
this.days = [];
this.hours = this.config.defaultHours || [];
this.dateFormat = this.config.outputDateFormat || 'DD/MM/YYYY';
this.outputJson = {};
this.init = true;
this.initLoad = () => {
if (this.init) {
this.getJsonData();
this.init = false;
if(!this.json) {
console.warn('Invalid Json data');
return;
}
this.createTable();
this.createEvents();
this.initCSS();
};
this.getDays();
this.getHours();
this.reinit = () => {
this.createJSON();
$('.doodle').html('');
$(document).off('click', 'input[type=checkbox]');
$(document).off('click', 'td a');
$(document).off('changeDate', '#addDate');
$(document).off('hide.timepicker', '#timepicker');
$(document).off('click', '#timepicker');
$(document).off('mouseenter mouseleave', '#date');
$(document).off('mouseenter mouseleave', '#heure');
this.init = false;
}
this.createTable();
this.createEvents();
this.initCSS();
};
this.initLoad();
};
this.reinit = () => {
this.createJSON();
document.querySelector('.doodle').innerHTML = '';
this.createEvents = () => {
let date = new Date();
flatpickr(document.querySelector('#myDatepicker'), {
dateFormat: 'm/d/Y',
locale: 'fr',
minDate: 'today',
enableTime: false,
onClose: this.eventAddDate
})
flatpickr(document.querySelector('#timepicker'), {
dateFormat: 'H:i',
locale: 'fr',
noCalendar: true,
enableTime: true,
onClose: this.eventAddHour
})
$(document).on('click', 'input[type=checkbox]', this.eventCheckInput);
$(document).on('click', 'td a', this.eventRemoveDate);
$(document).on('click', 'th a', this.eventRemoveHour);
$(document).on('mouseenter mouseleave', '#date', function (e) {
if (e.type === 'mouseenter') {
$(e.target).find('div').css('display', 'flex');
$(e.target).find('div').animate({
opacity : 1,
display: 'flex'
}, 250, 'linear');
} else {
if ($(e.target).is('div.delete_row') ) {
$(e.target).css('display', 'none');
$(e.target).animate({
opacity : 0,
display: 'none'
}, 200);
} else {
$(e.target).find('div').css('display', 'none');
$(e.target).find('div').animate({
opacity : 0,
display: 'none'
}, 200);
}
}
});
this.initLoad();
};
$(document).on('mouseenter mouseleave', '#heure', function (e) {
if (e.type === 'mouseenter') {
$(e.target).find('div').css('display', 'flex');
$(e.target).find('div').animate({
opacity : 1,
display: 'flex'
}, 250, 'linear');
} else {
if ($(e.target).is('div.delete_col') ) {
$(e.target).css('display', 'none');
$(e.target).animate({
opacity : 0,
display: 'none'
}, 200);
} else {
$(e.target).find('div').css('display', 'none');
$(e.target).find('div').animate({
opacity : 0,
display: 'none'
}, 200);
}
}
});
this.createEvents = () => {
let date = new Date();
flatpickr(document.querySelector('#myDatepicker'), {
dateFormat: 'm/d/Y',
locale: 'fr',
minDate: 'today',
enableTime: false,
onClose: this.eventAddDate
})
flatpickr(document.querySelector('#timepicker'), {
dateFormat: 'H:i',
locale: 'fr',
noCalendar: true,
enableTime: true,
onClose: this.eventAddHour
})
dynamicEvent('click', 'input[type=checkbox]', this.eventCheckInput);
dynamicEvent('click', 'td a, td a img', this.eventRemoveDate);
dynamicEvent('click', 'th a, th a img', this.eventRemoveHour);
};
/**
* Create Table
*/
this.createTable = () => {
this.item.append(`
<table class="table doodle-table backend">
/**
* Create Table
*/
this.createTable = () => {
this.item.innerHTML +=`
<table class="table doodle-table backend">
<thead>
${this.createHeaderTable()}
</thead>
......@@ -482,493 +418,476 @@
<tbody>
${this.createBodyTable()}
</tbody>
</table>
`);
</table>
`;
this.generateEmptyCell();
};
this.initCSS = () => {
$('input[type=checkbox]:checked').parent().parent().css('background', '#e2deef');
};
/**
* Create table header for hours
* @returns {string}
*/
this.createBodyTable = () => {
let $tbody = $('<tbody>');
let html, tbodyFinal;
this.generateEmptyCell();
};
if (!$.isEmptyObject(this.outputJson)) {
for(let index in this.days) {
let $tr = $('<tr>');
this.initCSS = () => {
document.querySelectorAll('input[type=checkbox]:checked').forEach(e => e.parentNode.parentNode.style.background = '#e2deef');
};
let formatDateDay = moment(this.days[index], this.dateFormat).locale('fr').format('dddd DD');
let formatDateMonth = moment(this.days[index], this.dateFormat).locale('fr').format('MMMM');
let formatFullDate = moment(this.days[index], this.dateFormat).locale('fr').format(this.dateFormat);
let date = this.days[index];
/**
* Create table header for hours
* @returns {string}
*/
this.createBodyTable = () => {
let $tbody = document.createElement('tbody');
let tbodyFinal;
html = $tr.append('<td id="date" data-date="' + formatFullDate +'"><span class="date_format"><b>' + formatDateDay + '</b> ' + formatDateMonth + '</span><div class="delete_row"><a href="#"><img src='+ CLOSEIMG +' /></a></div></td>')
.append(this.createBodyContent(date))
.append('<td></td>');
if (Object.keys(this.outputJson).length > 0) {
for(let index in this.days) {
let $tr = document.createElement('tr');
let formatDateDay = moment(this.days[index], this.dateFormat).locale('fr').format('dddd DD');
let formatDateMonth = moment(this.days[index], this.dateFormat).locale('fr').format('MMMM');
let formatFullDate = moment(this.days[index], this.dateFormat).locale('fr').format(this.dateFormat);
let date = this.days[index];
tbodyFinal = $tbody.append(html);
}
$tr.innerHTML += '<td id="date" data-date="' + formatFullDate +'"><span class="date_format"><b>' + formatDateDay + '</b> ' + formatDateMonth + '</span><div class="delete_row"><a href="#"><img src='+ CLOSEIMG +' /></a></div></td>'
+ this.createBodyContent(date)
+ '<td></td>';
tbodyFinal.append(`<td><div id="myDatepicker" class="input-group date" data-provide="datepicker">
<label>Date</label>
<input type="text" id="addDate" class="form-control" placeholder="jj / mm / aaaa">
<span class="input-group-addon">
<i class="fa fa-calendar"></i>
</span>
</div>
</td> `);
} else {
let $tr = $('<tr>');
html = $tr.append(`<td><div id="myDatepicker" class="input-group date" data-provide="datepicker">
<label>Date</label>
<input type="text" id="addDate" class="form-control" placeholder="jj / mm / aaaa">
<span class="input-group-addon">
<i class="fa fa-calendar"></i>
</span>
</div>
</td> `);
tbodyFinal = $tbody.append(html);
$tbody.innerHTML += $tr.innerHTML;
}
$tbody.innerHTML += `<td><div id="myDatepicker" class="input-group date" data-provide="datepicker">
<label>Date</label>
<input type="text" id="addDate" class="form-control" placeholder="jj / mm / aaaa">
<span class="input-group-addon">
<i class="fa fa-calendar"></i>
</span>
</div>
</td>`;
} else {
let $tr = document.createElement('tr');
$tr.innerHTML += `<td><div id="myDatepicker" class="input-group date" data-provide="datepicker">
<label>Date</label>
<input type="text" id="addDate" class="form-control" placeholder="jj / mm / aaaa">
<span class="input-group-addon">
<i class="fa fa-calendar"></i>
</span>
</div>
</td>`;
return tbodyFinal.html();
};
$tbody.innerHTML += $tr.innerHTML;
/**
* Create body content`
* @param index
* @returns {string}
*/
this.createBodyContent = (index) => {
let html;
let $td = $('<td>');
for(let key in this.hours) {
if(this.outputJson[index] && this.outputJson[index].includes(this.hours[key]))
html = '<td>' + this.createInputBox(this.hours[key], index, true) + '</td>';
else
html = '<td>' + this.createInputBox(this.hours[key], index, false) + '</td>';
$td.append(html);
}
tbodyFinal = $tbody.innerHTML;
}
return $td.html();
};
return $tbody.innerHTML;
};
/**
* Creer l'input
* @param hour
* @param day
* @returns {string}
*/
/**
* Create body content`
* @param index
* @returns {string}
*/
this.createBodyContent = (index) => {
let html = '';
for(let key in this.hours) {
if(this.outputJson[index] && this.outputJson[index].includes(this.hours[key]))
html += '<td>' + this.createInputBox(this.hours[key], index, true) + '</td>';
else
html += '<td>' + this.createInputBox(this.hours[key], index, false) + '</td>';
}
this.createInputBox = (hour, day, checked) => {
let dayFormat = moment(day, this.dateFormat).format('DDMMYYYY');
let isChecked = checked ? 'checked' : '';
let data = dayFormat + '_' + hour;
return html;
};
return `<label class='label_input'>
/**
* Creer l'input
* @param hour
* @param day
* @returns {string}
*/
this.createInputBox = (hour, day, checked) => {
let dayFormat = moment(day, this.dateFormat).format('DDMMYYYY');
let isChecked = checked ? 'checked' : '';
let data = dayFormat + '_' + hour;
return `<label class='label_input'>
<input type='checkbox' ${isChecked} data-check="${data}" /><span><i></i></span>
</label>`
}
</label>`
}
/**
* Create table header for hours
* @returns {string}
*/
this.createHeaderTable = () => {
let $tr = $('<tr>');
let thead;
let finalSortedTab = [];
/**
* Create table header for hours
* @returns {string}
*/
this.createHeaderTable = () => {
let $tr = document.createElement('tr');
let thead;
let finalSortedTab = [];
// Nombre de cases vide
let nbrCaseVide = 1;
// Nombre de cases vide
let nbrCaseVide = 1;
//Ajoute les cases vide
for (let i = 0; i < nbrCaseVide; i++) {
thead = $tr.append('<th></th>');
}
//Ajoute les cases vide
for (let i = 0; i < nbrCaseVide; i++) {
thead = $tr.innerHTML += '<th></th>';
}
// Permet de mettre un 'h' pour les heures/minutes
this.hours.forEach( (el, index) => {
if (el.indexOf(':') === -1) {
el += 'h';
} else {
el = el.replace(':', 'h');
}
// Permet de mettre un 'h' pour les heures/minutes
this.hours.forEach( (el, index) => {
if (el.indexOf(':') === -1) {
el += 'h';
} else {
el = el.replace(':', 'h');
}
finalSortedTab.push(el);
});
finalSortedTab.push(el);
});
//Ajoute les heures
for(let index in finalSortedTab) {
thead = $tr.append('<th id="heure"><span>' + finalSortedTab[index] + '</span><div class="delete_col"><a href="#"><img src='+ CLOSEIMG +' /></a></div></th>');
}
//Ajoute les heures
for(let index in finalSortedTab) {
thead = $tr.innerHTML += '<th id="heure"><span>' + finalSortedTab[index] + '</span><div class="delete_col"><a href="#"><img src='+ CLOSEIMG +' /></a></div></th>';
}
thead = $tr.append(`<th><div class="input-group bootstrap-timepicker timepicker">
<label>Horaire</label>
<input id="timepicker" type="text" class="form-control" data-provide="timepicker">
<span class="input-group-addon">
<i class="fa fa-clock-o"></i>
</span>
</div></th> `);
thead = $tr.innerHTML += `<th><div class="input-group bootstrap-timepicker timepicker">
<label>Horaire</label>
<input id="timepicker" type="text" class="form-control" data-provide="timepicker">
<span class="input-group-addon">
<i class="fa fa-clock-o"></i>
</span>
</div></th>`;
return thead.html();
};
return thead;
};
/**
* Generate empty cell
*/
this.generateEmptyCell = () => {
let colLength = $('table thead th#heure').length + 1;
let lastTR = $('.doodle-table tbody tr:last-child');
/**
* Generate empty cell
*/
this.generateEmptyCell = () => {
let colLength = document.querySelectorAll('table thead th#heure').length + 1;
let lastTR = document.querySelector('.doodle-table tbody tr:last-child');
if(lastTR) {
for (let i = 0; i < colLength; i++) {
$(lastTR).append('<td></td>')
lastTR.innerHTML += '<td></td>';
}
}
};
};
/**
* Get Days
*/
this.getDays = () => {
this.days = Object.keys(this.json);
};
/**
* Get Days
*/
this.getDays = () => {
this.days = Object.keys(this.json);
};
/**
* Get Hours
*/
this.getHours = () => {
for(let key in this.json) {
for(let index in this.json[key]) {
if(!this.hours.includes(this.json[key][index])) {
this.hours.push(this.json[key][index]);
this.hours.sort();
}
/**
* Get Hours
*/
this.getHours = () => {
for(let key in this.json) {
for(let index in this.json[key]) {
if(!this.hours.includes(this.json[key][index])) {
this.hours.push(this.json[key][index]);
this.hours.sort();
}
}
};
/**
* Get Json data
*/
this.getJsonData = () => {
let dataJson = $(this.config.inputSelector).val();
if(typeof dataJson === 'object') {
this.json = dataJson;
} else if(this.isJsonString(dataJson)){
this.json = JSON.parse(dataJson);
} else {
let data = this.fileExistsAndGetData(dataJson);
if(data){
let json = JSON.parse(data);
}
};
if (!$.isEmptyObject(json)) {
this.json = json;
}
/**
* Get Json data
*/
this.getJsonData = () => {
let dataJson = document.querySelector(this.config.inputSelector).value;
if(typeof dataJson === 'object') {
this.json = dataJson;
} else if(this.isJsonString(dataJson)){
this.json = JSON.parse(dataJson);
} else {
let data = this.fileExistsAndGetData(dataJson);
if(data){
let json = JSON.parse(data);
if (Object.keys(json).length > 0) {
this.json = json;
}
}
this.populateOutputJson();
};
}
this.populateOutputJson();
};
this.populateOutputJson = () => {
for (let index in this.json) {
if (this.json[index].length === 0 ) {
this.addInOutputObject(index)
}
this.populateOutputJson = () => {
for (let index in this.json) {
if (this.json[index].length === 0 ) {
this.addInOutputObject(index)
}
for (let i in this.json[index]) {
let dayFormat = moment(index, this.dateFormat).format(this.dateFormat);
for (let i in this.json[index]) {
let dayFormat = moment(index, this.dateFormat).format(this.dateFormat);
this.addInOutputObject([dayFormat, this.json[index][i]] )
}
this.addInOutputObject([dayFormat, this.json[index][i]] )
}
};
}
};
/**
* Check if string is valid Json
* @param str
* @returns {boolean}
*/
this.isJsonString = (str) => {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
};
/**
* Check if string is valid Json
* @param str
* @returns {boolean}
*/
this.isJsonString = (str) => {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
};
/**
* Check if file exist and get data
* @param url
* @returns {boolean}
*/
this.fileExistsAndGetData = (url) => {
if(url){
let req = new XMLHttpRequest();
req.open('GET', url, false);
req.send();
return req.response;
} else {
return false;
}
};
/**
* Check if file exist and get data
* @param url
* @returns {boolean}
*/
this.fileExistsAndGetData = (url) => {
if(url) {
let req = new XMLHttpRequest();
req.open('GET', url, false);
req.send();
return req.response;
} else {
return false;
}
};
/**
* Generate JSON
*/
this.createJSON = () => {
let $input = $(this.config.inputSelector);
/**
* Generate JSON
*/
this.createJSON = () => {
let $input = document.querySelector(this.config.inputSelector);
if ($input.length > 0) {
$input.val(JSON.stringify(this.outputJson));
}
};
if ($input) {
$input.value = JSON.stringify(this.outputJson);
}
};
/**
* Event for input
* @param e event
*/
this.eventCheckInput = (e) => {
let data = $(e.target).data('check').split('_');
let isChecked = $(e.target).is(':checked');
if (isChecked) {
this.addInOutputObject(data);
$(e.target).parent().parent().css('background', '#e2deef');
} else {
this.removeInOutputObject(data);
$(e.target).parent().parent().css('background', '');
}
/**
* Event for input
* @param e event
*/
this.eventCheckInput = (e) => {
let data = e.target.dataset.check.split('_');
let isChecked = e.target.checked;
if (isChecked) {
this.addInOutputObject(data);
e.target.parentNode.parentNode.style.background = '#e2deef';
} else {
this.removeInOutputObject(data);
e.target.parentNode.parentNode.style.background = '';
}
this.createJSON();
};
this.createJSON();
};
/**
* Check if key exist
* @param key
* @returns {boolean}
*/
this.keyExist = (key) => {
if (moment(key, this.dateFormat).format(this.dateFormat) === key) {
if (this.days.indexOf(key) === -1) {
return true
}
else {
console.error('La date est déjà présente dans le tableau');
return false
}
/**
* Check if key exist
* @param key
* @returns {boolean}
*/
this.keyExist = (key) => {
if (moment(key, this.dateFormat).format(this.dateFormat) === key) {
if (this.days.indexOf(key) === -1) {
return true
}
else {
console.error('La date est déjà présente dans le tableau');
return false
}
}
if (moment(key, 'HH:mm').format('HH:mm') === key || moment(key, 'HH').format('HH') === key) {
if (this.hours.indexOf(key) === -1) {
return true
}
else {
console.error('L\'heure est déjà présente dans le tableau');
return false
}
if (moment(key, 'HH:mm').format('HH:mm') === key || moment(key, 'HH').format('HH') === key) {
if (this.hours.indexOf(key) === -1) {
return true
}
};
else {
console.error('L\'heure est déjà présente dans le tableau');
return false
}
}
};
/**
* Add date
* @param e
*/
this.eventAddDate = (e, dateStr) => {
let formatDateOnSneFou = moment(dateStr).locale('fr').format(this.dateFormat);
/**
* Add date
* @param e
*/
this.eventAddDate = (e, dateStr) => {
let formatDateOnSneFou = moment(dateStr).locale('fr').format(this.dateFormat);
if (this.keyExist(formatDateOnSneFou)) {
this.days.push(formatDateOnSneFou);
this.addInOutputObject(formatDateOnSneFou);
}
if (this.keyExist(formatDateOnSneFou)) {
this.days.push(formatDateOnSneFou);
this.addInOutputObject(formatDateOnSneFou);
}
//Tri les dates
let formatDate = this.dateFormat;
this.days.sort(function(a,b) {
return moment(a, formatDate) - moment(b, formatDate);
});
//Tri les dates
let formatDate = this.dateFormat;
this.days.sort(function(a,b) {
return moment(a, formatDate) - moment(b, formatDate);
});
this.reinit();
};
this.reinit();
};
/**
* Add hour
*/
this.eventAddHour = (selectedDates, dateStr) => {
let val = dateStr;
let splitHour = val.split(':');
/**
* Add hour
*/
this.eventAddHour = (selectedDates, dateStr) => {
let val = dateStr;
let splitHour = val.split(':');
if (splitHour[0].length === 1) {
val = "0" + val;
}
if (splitHour[0].length === 1) {
val = "0" + val;
}
if (this.keyExist(val)) {
if (splitHour[1] === '00') {
if (this.keyExist(splitHour[0])) {
this.hours.push(splitHour[0]);
}
} else {
this.hours.push(val);
if (this.keyExist(val)) {
if (splitHour[1] === '00') {
if (this.keyExist(splitHour[0])) {
this.hours.push(splitHour[0]);
}
} else {
this.hours.push(val);
}
}
this.hours.sort(function(a,b) {
return moment(a, 'HH:mm') - moment(b, 'HH:mm');
});
this.hours.sort(function(a,b) {
return moment(a, 'HH:mm') - moment(b, 'HH:mm');
});
this.reinit();
};
this.reinit();
};
/**
* Remove Date
* @param e
*/
this.eventRemoveDate = (e) => {
e.preventDefault();
e.stopImmediatePropagation();
/**
* Remove Date
* @param e
*/
this.eventRemoveDate = (e) => {
e.preventDefault();
e.stopImmediatePropagation();
let date = $(e.target).parent().parent().parent().data('date');
let date = e.target.closest('#date').dataset.date;
let formatDateDay = moment(date, this.dateFormat).locale('fr').format(this.dateFormat);
let formatDateDay = moment(date, this.dateFormat).locale('fr').format(this.dateFormat);
let index = this.days.indexOf(formatDateDay);
let index = this.days.indexOf(formatDateDay);
if (index !== -1) {
this.days.splice(index, 1)
}
if (index !== -1) {
this.days.splice(index, 1)
}
delete this.outputJson[formatDateDay];
this.reinit();
};
delete this.outputJson[formatDateDay];
this.reinit();
};
/**
* Remove hour
* @param e
*/
this.eventRemoveHour = (e) => {
e.stopImmediatePropagation();
e.preventDefault();
/**
* Remove hour
* @param e
*/
this.eventRemoveHour = (e) => {
e.stopImmediatePropagation();
e.preventDefault();
let hour = $(e.target).parent().parent().parent().find('span').first().text();
hour = hour.replace('h', ':');
let hour = e.target.closest('#heure').querySelector('span').innerText;
hour = hour.replace('h', ':');
if(hour.length < 5){
hour = hour.substring(0, hour.length-1);
}
if(hour.length < 5){
hour = hour.substring(0, hour.length-1);
}
let index = this.hours.indexOf(hour);
let index = this.hours.indexOf(hour);
if (index !== -1) {
this.hours.splice(index, 1)
}
if (index !== -1) {
this.hours.splice(index, 1)
}
for(let yolo in this.outputJson) {
let pipa = this.outputJson[yolo].indexOf(hour);
for(let yolo in this.outputJson) {
let pipa = this.outputJson[yolo].indexOf(hour);
if (pipa !== -1) {
this.outputJson[yolo].splice(pipa, 1);
}
if (pipa !== -1) {
this.outputJson[yolo].splice(pipa, 1);
}
}
this.reinit();
};
/**
* Add value into json
* @param data
*/
this.addInOutputObject = (data) => {
if (typeof data === 'string') {
this.outputJson[data] = [];
} else {
let dayFormat = moment(data[0], 'DDMMYYYY').format(this.dateFormat);
this.reinit();
};
if (!this.outputJson[dayFormat]) {
this.outputJson[dayFormat] = [];
}
/**
* Add value into json
* @param data
*/
this.addInOutputObject = (data) => {
if (typeof data === 'string') {
this.outputJson[data] = [];
} else {
let output = this.outputJson[dayFormat];
let dayFormat = moment(data[0], 'DDMMYYYY').format(this.dateFormat);
if (output.indexOf(data[1]) === -1) {
output.push(data[1]);
}
if (!this.outputJson[dayFormat]) {
this.outputJson[dayFormat] = [];
}
};
/**
* Remove value from json
* @param data
*/
this.removeInOutputObject = (data) => {
let dayFormat = moment(data[0], this.dateFormat).format(this.dateFormat);
if (this.outputJson[dayFormat]) {
let output = this.outputJson[dayFormat];
let index = output.indexOf(data[1]);
let output = this.outputJson[dayFormat];
if (index !== -1) {
output.splice(index, 1);
}
if (output.indexOf(data[1]) === -1) {
output.push(data[1]);
}
};
/**
* Init
*/
this.initLoad();
}
};
/**
*
* @param options
* @returns {$.fn.Doodle}
* @constructor
* Remove value from json
* @param data
*/
$.fn.Doodle = function(options) {
moment.locale('fr')
let config = initializeConfig();
this.removeInOutputObject = (data) => {
let dayFormat = moment(data[0], this.dateFormat).format(this.dateFormat);
this.each(function() {
if (!config.editMode) {
new DoodleFront($(this), config);
}
else {
new DoodleBack($(this), config);
if (this.outputJson[dayFormat]) {
let output = this.outputJson[dayFormat];
let index = output.indexOf(data[1]);
if (index !== -1) {
output.splice(index, 1);
}
});
}
};
return this;
/**
* Init
*/
this.initLoad();
};
/**
*
*/
function initializeConfig() {
let defaultOptions = {
editMode: false,
inputSelector: '',
defaultHours: [],
outputDateFormat: ''
};
class Doodle {
constructor(el, options) {
moment.locale('fr')
let config = this.initializeConfig(options);
return $.extend({}, defaultOptions, options);
if (!config.editMode) {
new DoodleFront(el, config);
}
else {
new DoodleBack(el, config);
}
}
};
})(jQuery);
initializeConfig(options) {
let defaultOptions = {
editMode: false,
inputSelector: '',
defaultHours: [],
outputDateFormat: ''
};
return Object.assign(defaultOptions, options);
}
};
......@@ -12,11 +12,8 @@
"dayjs": "^1.8.14"
},
"devDependencies": {
"bootstrap": "4.0.0-alpha.6",
"font-awesome": "^4.7.0",
"flatpickr": "^4.6.13",
"jquery": "^3.3.1",
"moment": "^2.20.1",
"tether": "^1.4.3"
"font-awesome": "^4.7.0",
"moment": "^2.20.1"
}
}
......@@ -5,9 +5,6 @@
<title>Jumbotron Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.css">
<!-- Custom styles for this template -->
<link href="./css/starter-template.css" rel="stylesheet">
<link href="../dist/css/doodle.css" rel="stylesheet">
......@@ -18,13 +15,13 @@
</head>
<body>
<div class="container">
<div class="container">
<!-- Example row of columns -->
<div class="row">
<div class="col-md-12">
<div class="specific-doodle">
<div class="doodle table-responsive" data-json='{"29/07/2019":["11","12:15","13"],"30/07/2019":["11","12:15","13"],"31/07/2019":["11","12:15","13"],"01/08/2019":["13","12:15","11"],"02/08/2019":["11","12:15","13"]}' ></div>
<input type="hidden" id="inputVal" value='{"29/07/2019":["11","12:15","13"],"30/07/2019":["11","12:15","13"],"31/07/2019":["11","12:15","13"],"01/08/2019":["13","12:15","11"],"02/08/2019":["11","12:15","13"]}'>
<div class="doodle table-responsive" data-json='{"29/07/2019":["11","13"],"30/07/2019":["11","12:15","13"],"31/07/2019":["11","12:15","13"],"01/08/2019":["13","12:15","11"],"02/08/2019":["11","12:15","13"]}' ></div>
<input type="hidden" id="inputVal" value='{"29/07/2019":["11", "13"],"30/07/2019":["11","12:15","13"],"31/07/2019":["11","12:15","13"],"01/08/2019":["13","12:15","11"],"02/08/2019":["11","12:15","13"]}'>
</div>
<!--<div class="doodle table-responsive" data-json="json/data.json"></div>
......@@ -36,21 +33,12 @@
<footer>
<p>© Company 2017</p>
</footer>
</div> <!-- /container -->
<!-- Jquery -->
<script src="../node_modules/jquery/dist/jquery.js"></script>
<!--<script src="../node_modules/tether/dist/js/tether.js"></script>-->
<!-- Bootstrap / Boostrap datepicker / Bootstrap timepicker -->
<!--<script src="../node_modules/bootstrap/dist/js/bootstrap.js"></script>-->
<!-- Moment -->
<script src="../node_modules/moment/min/moment.min.js"></script>
<script src="../node_modules/moment/min/moment-with-locales.js"></script>
<script src="../node_modules/flatpickr/dist/flatpickr.js"></script>
<script src="../node_modules/flatpickr/dist/l10n/fr.js"></script>
<script src="../dist/js/doodle.js" type="text/javascript"></script>
<script src="../test/js/app.js" type="text/javascript"></script>
</div>
<script src="../node_modules/moment/min/moment.min.js"></script>
<script src="../node_modules/moment/min/moment-with-locales.js"></script>
<script src="../node_modules/flatpickr/dist/flatpickr.js"></script>
<script src="../node_modules/flatpickr/dist/l10n/fr.js"></script>
<script src="../dist/js/doodle.js" type="text/javascript"></script>
<script src="../test/js/app.js" type="text/javascript"></script>
</body></html>
$( document ).ready(function() {
$('.doodle').Doodle({
editMode: true,
vertical: true,
inputSelector: '#inputVal'
});
new Doodle(document.querySelector('.doodle'), {
editMode: true,
vertical: true,
inputSelector: '#inputVal'
});
......@@ -2,35 +2,20 @@
# yarn lockfile v1
bootstrap-datepicker@^1.7.1:
version "1.7.1"
resolved "https://registry.yarnpkg.com/bootstrap-datepicker/-/bootstrap-datepicker-1.7.1.tgz#4ee7faf34888dbec7834fbf9dbe7c4277e01ddaf"
dependencies:
jquery ">=1.7.1 <4.0.0"
dayjs@^1.8.14:
version "1.11.5"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.5.tgz#00e8cc627f231f9499c19b38af49f56dc0ac5e93"
integrity sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA==
bootstrap-timepicker@^0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/bootstrap-timepicker/-/bootstrap-timepicker-0.5.2.tgz#10ed9f2a2f0b8ccaefcde0fcf6a0738b919a3835"
bootstrap@4.0.0-alpha.6:
version "4.0.0-alpha.6"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.0.0-alpha.6.tgz#4f54dd33ac0deac3b28407bc2df7ec608869c9c8"
dependencies:
jquery ">=1.9.1"
tether "^1.4.0"
flatpickr@^4.6.13:
version "4.6.13"
resolved "https://registry.yarnpkg.com/flatpickr/-/flatpickr-4.6.13.tgz#8a029548187fd6e0d670908471e43abe9ad18d94"
integrity sha512-97PMG/aywoYpB4IvbvUJi0RQi8vearvU0oov1WW3k0WZPBMrTQVqekSX5CjSG/M4Q3i6A/0FKXC7RyAoAUUSPw==
font-awesome@^4.7.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133"
"jquery@>=1.7.1 <4.0.0", jquery@>=1.9.1, jquery@^3.3.1:
version "3.3.1"
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.3.1.tgz#958ce29e81c9790f31be7792df5d4d95fc57fbca"
moment@^2.20.1:
version "2.21.0"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.21.0.tgz#2a114b51d2a6ec9e6d83cf803f838a878d8a023a"
tether@^1.4.0, tether@^1.4.3:
version "1.4.3"
resolved "https://registry.yarnpkg.com/tether/-/tether-1.4.3.tgz#fd547024c47b6e5c9b87e1880f997991a9a6ad54"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment