Initial commit
This commit is contained in:
commit
793bb6a488
182 changed files with 17153 additions and 0 deletions
424
aemo/static/js/DateTimeShortcuts.js
Normal file
424
aemo/static/js/DateTimeShortcuts.js
Normal file
|
|
@ -0,0 +1,424 @@
|
|||
/*global Calendar, findPosX, findPosY, get_format, gettext, gettext_noop, interpolate, ngettext, quickElement*/
|
||||
// Inserts shortcut buttons after all of the following:
|
||||
// <input type="text" class="vDateField">
|
||||
// <input type="text" class="vTimeField">
|
||||
'use strict';
|
||||
{
|
||||
const DateTimeShortcuts = {
|
||||
calendars: [],
|
||||
calendarInputs: [],
|
||||
clockInputs: [],
|
||||
clockHours: {
|
||||
default_: [
|
||||
[gettext_noop('Now'), -1],
|
||||
[gettext_noop('Midnight'), 0],
|
||||
[gettext_noop('6 a.m.'), 6],
|
||||
[gettext_noop('Noon'), 12],
|
||||
[gettext_noop('6 p.m.'), 18]
|
||||
]
|
||||
},
|
||||
dismissClockFunc: [],
|
||||
dismissCalendarFunc: [],
|
||||
calendarDivName1: 'calendarbox', // name of calendar <div> that gets toggled
|
||||
calendarDivName2: 'calendarin', // name of <div> that contains calendar
|
||||
calendarLinkName: 'calendarlink', // name of the link that is used to toggle
|
||||
clockDivName: 'clockbox', // name of clock <div> that gets toggled
|
||||
clockLinkName: 'clocklink', // name of the link that is used to toggle
|
||||
shortCutsClass: 'datetimeshortcuts', // class of the clock and cal shortcuts
|
||||
timezoneWarningClass: 'timezonewarning', // class of the warning for timezone mismatch
|
||||
timezoneOffset: 0,
|
||||
init: function(selector) {
|
||||
selector = selector || document;
|
||||
const serverOffset = document.body.dataset.adminUtcOffset;
|
||||
if (serverOffset) {
|
||||
const localOffset = new Date().getTimezoneOffset() * -60;
|
||||
DateTimeShortcuts.timezoneOffset = localOffset - serverOffset;
|
||||
}
|
||||
|
||||
for (const inp of selector.getElementsByTagName('input')) {
|
||||
if (inp.type === 'text' && inp.classList.contains('vTimeField')) {
|
||||
DateTimeShortcuts.addClock(inp);
|
||||
DateTimeShortcuts.addTimezoneWarning(inp);
|
||||
}
|
||||
else if (inp.type === 'text' && inp.classList.contains('vDateField')) {
|
||||
DateTimeShortcuts.addCalendar(inp);
|
||||
DateTimeShortcuts.addTimezoneWarning(inp);
|
||||
}
|
||||
}
|
||||
},
|
||||
// Return the current time while accounting for the server timezone.
|
||||
now: function() {
|
||||
const serverOffset = document.body.dataset.adminUtcOffset;
|
||||
if (serverOffset) {
|
||||
const localNow = new Date();
|
||||
const localOffset = localNow.getTimezoneOffset() * -60;
|
||||
localNow.setTime(localNow.getTime() + 1000 * (serverOffset - localOffset));
|
||||
return localNow;
|
||||
} else {
|
||||
return new Date();
|
||||
}
|
||||
},
|
||||
// Add a warning when the time zone in the browser and backend do not match.
|
||||
addTimezoneWarning: function(inp) {
|
||||
const warningClass = DateTimeShortcuts.timezoneWarningClass;
|
||||
let timezoneOffset = DateTimeShortcuts.timezoneOffset / 3600;
|
||||
|
||||
// Only warn if there is a time zone mismatch.
|
||||
if (!timezoneOffset) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if warning is already there.
|
||||
if (inp.parentNode.querySelectorAll('.' + warningClass).length) {
|
||||
return;
|
||||
}
|
||||
|
||||
let message;
|
||||
if (timezoneOffset > 0) {
|
||||
message = ngettext(
|
||||
'Note: You are %s hour ahead of server time.',
|
||||
'Note: You are %s hours ahead of server time.',
|
||||
timezoneOffset
|
||||
);
|
||||
}
|
||||
else {
|
||||
timezoneOffset *= -1;
|
||||
message = ngettext(
|
||||
'Note: You are %s hour behind server time.',
|
||||
'Note: You are %s hours behind server time.',
|
||||
timezoneOffset
|
||||
);
|
||||
}
|
||||
message = interpolate(message, [timezoneOffset]);
|
||||
|
||||
const warning = document.createElement('span');
|
||||
warning.className = warningClass;
|
||||
warning.textContent = message;
|
||||
inp.parentNode.appendChild(document.createElement('br'));
|
||||
inp.parentNode.appendChild(warning);
|
||||
},
|
||||
// Add clock widget to a given field
|
||||
addClock: function(inp) {
|
||||
const num = DateTimeShortcuts.clockInputs.length;
|
||||
DateTimeShortcuts.clockInputs[num] = inp;
|
||||
DateTimeShortcuts.dismissClockFunc[num] = function() { DateTimeShortcuts.dismissClock(num); return true; };
|
||||
|
||||
// Shortcut links (clock icon and "Now" link)
|
||||
const shortcuts_span = document.createElement('span');
|
||||
shortcuts_span.className = DateTimeShortcuts.shortCutsClass;
|
||||
inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling);
|
||||
const now_link = document.createElement('a');
|
||||
now_link.href = "#";
|
||||
now_link.textContent = gettext('Now');
|
||||
now_link.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
DateTimeShortcuts.handleClockQuicklink(num, -1);
|
||||
});
|
||||
const clock_link = document.createElement('a');
|
||||
clock_link.href = '#';
|
||||
clock_link.id = DateTimeShortcuts.clockLinkName + num;
|
||||
clock_link.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
// avoid triggering the document click handler to dismiss the clock
|
||||
e.stopPropagation();
|
||||
DateTimeShortcuts.openClock(num);
|
||||
});
|
||||
|
||||
quickElement(
|
||||
'span', clock_link, '',
|
||||
'class', 'clock-icon',
|
||||
'title', gettext('Choose a Time')
|
||||
);
|
||||
shortcuts_span.appendChild(document.createTextNode('\u00A0'));
|
||||
shortcuts_span.appendChild(now_link);
|
||||
shortcuts_span.appendChild(document.createTextNode('\u00A0|\u00A0'));
|
||||
shortcuts_span.appendChild(clock_link);
|
||||
|
||||
// Create clock link div
|
||||
//
|
||||
// Markup looks like:
|
||||
// <div id="clockbox1" class="clockbox module">
|
||||
// <h2>Choose a time</h2>
|
||||
// <ul class="timelist">
|
||||
// <li><a href="#">Now</a></li>
|
||||
// <li><a href="#">Midnight</a></li>
|
||||
// <li><a href="#">6 a.m.</a></li>
|
||||
// <li><a href="#">Noon</a></li>
|
||||
// <li><a href="#">6 p.m.</a></li>
|
||||
// </ul>
|
||||
// <p class="calendar-cancel"><a href="#">Cancel</a></p>
|
||||
// </div>
|
||||
|
||||
const clock_box = document.createElement('div');
|
||||
clock_box.style.display = 'none';
|
||||
clock_box.className = 'clockbox module';
|
||||
clock_box.id = DateTimeShortcuts.clockDivName + num;
|
||||
document.body.appendChild(clock_box);
|
||||
// cpa: Make it work with bootstrap
|
||||
clock_box.style.position = clock_box.closest('body').classList.contains('modal-open') ? 'fixed' : 'absolute';
|
||||
clock_box.addEventListener('click', function(e) { e.stopPropagation(); });
|
||||
|
||||
quickElement('h2', clock_box, gettext('Choose a time'));
|
||||
const time_list = quickElement('ul', clock_box);
|
||||
time_list.className = 'timelist';
|
||||
// The list of choices can be overridden in JavaScript like this:
|
||||
// DateTimeShortcuts.clockHours.name = [['3 a.m.', 3]];
|
||||
// where name is the name attribute of the <input>.
|
||||
const name = typeof DateTimeShortcuts.clockHours[inp.name] === 'undefined' ? 'default_' : inp.name;
|
||||
DateTimeShortcuts.clockHours[name].forEach(function(element) {
|
||||
const time_link = quickElement('a', quickElement('li', time_list), gettext(element[0]), 'href', '#');
|
||||
time_link.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
DateTimeShortcuts.handleClockQuicklink(num, element[1]);
|
||||
});
|
||||
});
|
||||
|
||||
const cancel_p = quickElement('p', clock_box);
|
||||
cancel_p.className = 'calendar-cancel';
|
||||
const cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'href', '#');
|
||||
cancel_link.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
DateTimeShortcuts.dismissClock(num);
|
||||
});
|
||||
|
||||
document.addEventListener('keyup', function(event) {
|
||||
if (event.which === 27) {
|
||||
// ESC key closes popup
|
||||
DateTimeShortcuts.dismissClock(num);
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
},
|
||||
openClock: function(num) {
|
||||
const clock_box = document.getElementById(DateTimeShortcuts.clockDivName + num);
|
||||
const clock_link = document.getElementById(DateTimeShortcuts.clockLinkName + num);
|
||||
|
||||
// Recalculate the clockbox position
|
||||
// is it left-to-right or right-to-left layout ?
|
||||
if (window.getComputedStyle(document.body).direction !== 'rtl') {
|
||||
clock_box.style.left = findPosX(clock_link) + 17 + 'px';
|
||||
}
|
||||
else {
|
||||
// since style's width is in em, it'd be tough to calculate
|
||||
// px value of it. let's use an estimated px for now
|
||||
clock_box.style.left = findPosX(clock_link) - 110 + 'px';
|
||||
}
|
||||
clock_box.style.top = Math.max(0, findPosY(clock_link) - 30) + 'px';
|
||||
|
||||
// Show the clock box
|
||||
clock_box.style.display = 'block';
|
||||
document.addEventListener('click', DateTimeShortcuts.dismissClockFunc[num]);
|
||||
},
|
||||
dismissClock: function(num) {
|
||||
document.getElementById(DateTimeShortcuts.clockDivName + num).style.display = 'none';
|
||||
document.removeEventListener('click', DateTimeShortcuts.dismissClockFunc[num]);
|
||||
},
|
||||
handleClockQuicklink: function(num, val) {
|
||||
let d;
|
||||
if (val === -1) {
|
||||
d = DateTimeShortcuts.now();
|
||||
}
|
||||
else {
|
||||
d = new Date(1970, 1, 1, val, 0, 0, 0);
|
||||
}
|
||||
DateTimeShortcuts.clockInputs[num].value = d.strftime(get_format('TIME_INPUT_FORMATS')[0]);
|
||||
DateTimeShortcuts.clockInputs[num].focus();
|
||||
DateTimeShortcuts.dismissClock(num);
|
||||
// Added by cpa:
|
||||
DateTimeShortcuts.clockInputs[num].dispatchEvent(new Event('change'));
|
||||
},
|
||||
// Add calendar widget to a given field.
|
||||
addCalendar: function(inp) {
|
||||
const num = DateTimeShortcuts.calendars.length;
|
||||
|
||||
DateTimeShortcuts.calendarInputs[num] = inp;
|
||||
DateTimeShortcuts.dismissCalendarFunc[num] = function() { DateTimeShortcuts.dismissCalendar(num); return true; };
|
||||
|
||||
// Shortcut links (calendar icon and "Today" link)
|
||||
const shortcuts_span = document.createElement('span');
|
||||
shortcuts_span.className = DateTimeShortcuts.shortCutsClass;
|
||||
inp.parentNode.insertBefore(shortcuts_span, inp.nextSibling);
|
||||
const today_link = document.createElement('a');
|
||||
today_link.href = '#';
|
||||
today_link.appendChild(document.createTextNode(gettext('Today')));
|
||||
today_link.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
DateTimeShortcuts.handleCalendarQuickLink(num, 0);
|
||||
});
|
||||
const cal_link = document.createElement('a');
|
||||
cal_link.href = '#';
|
||||
cal_link.id = DateTimeShortcuts.calendarLinkName + num;
|
||||
cal_link.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
// avoid triggering the document click handler to dismiss the calendar
|
||||
e.stopPropagation();
|
||||
DateTimeShortcuts.openCalendar(num);
|
||||
});
|
||||
quickElement(
|
||||
'span', cal_link, '',
|
||||
'class', 'date-icon',
|
||||
'title', gettext('Choose a Date')
|
||||
);
|
||||
shortcuts_span.appendChild(document.createTextNode('\u00A0'));
|
||||
// CUSTOMIZED: Today link removed.
|
||||
//shortcuts_span.appendChild(today_link);
|
||||
//shortcuts_span.appendChild(document.createTextNode('\u00A0|\u00A0'));
|
||||
shortcuts_span.appendChild(cal_link);
|
||||
|
||||
// Create calendarbox div.
|
||||
//
|
||||
// Markup looks like:
|
||||
//
|
||||
// <div id="calendarbox3" class="calendarbox module">
|
||||
// <h2>
|
||||
// <a href="#" class="link-previous">‹</a>
|
||||
// <a href="#" class="link-next">›</a> February 2003
|
||||
// </h2>
|
||||
// <div class="calendar" id="calendarin3">
|
||||
// <!-- (cal) -->
|
||||
// </div>
|
||||
// <div class="calendar-shortcuts">
|
||||
// <a href="#">Yesterday</a> | <a href="#">Today</a> | <a href="#">Tomorrow</a>
|
||||
// </div>
|
||||
// <p class="calendar-cancel"><a href="#">Cancel</a></p>
|
||||
// </div>
|
||||
const cal_box = document.createElement('div');
|
||||
cal_box.style.display = 'none';
|
||||
cal_box.className = 'calendarbox module';
|
||||
cal_box.id = DateTimeShortcuts.calendarDivName1 + num;
|
||||
document.body.appendChild(cal_box);
|
||||
// cpa: Make it work with bootstrap
|
||||
cal_box.style.position = cal_box.closest('body').classList.contains('modal-open') ? 'fixed' : 'absolute';
|
||||
cal_box.addEventListener('click', function(e) { e.stopPropagation(); });
|
||||
|
||||
// next-prev links
|
||||
const cal_nav = quickElement('div', cal_box);
|
||||
const cal_nav_prev = quickElement('a', cal_nav, '<', 'href', '#');
|
||||
cal_nav_prev.className = 'calendarnav-previous';
|
||||
cal_nav_prev.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
DateTimeShortcuts.drawPrev(num);
|
||||
});
|
||||
|
||||
const cal_nav_next = quickElement('a', cal_nav, '>', 'href', '#');
|
||||
cal_nav_next.className = 'calendarnav-next';
|
||||
cal_nav_next.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
DateTimeShortcuts.drawNext(num);
|
||||
});
|
||||
|
||||
// main box
|
||||
const cal_main = quickElement('div', cal_box, '', 'id', DateTimeShortcuts.calendarDivName2 + num);
|
||||
cal_main.className = 'calendar';
|
||||
DateTimeShortcuts.calendars[num] = new Calendar(DateTimeShortcuts.calendarDivName2 + num, DateTimeShortcuts.handleCalendarCallback(num));
|
||||
DateTimeShortcuts.calendars[num].drawCurrent();
|
||||
|
||||
// calendar shortcuts
|
||||
const shortcuts = quickElement('div', cal_box);
|
||||
shortcuts.className = 'calendar-shortcuts';
|
||||
let day_link = quickElement('a', shortcuts, gettext('Yesterday'), 'href', '#');
|
||||
day_link.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
DateTimeShortcuts.handleCalendarQuickLink(num, -1);
|
||||
});
|
||||
shortcuts.appendChild(document.createTextNode('\u00A0|\u00A0'));
|
||||
day_link = quickElement('a', shortcuts, gettext('Today'), 'href', '#');
|
||||
day_link.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
DateTimeShortcuts.handleCalendarQuickLink(num, 0);
|
||||
});
|
||||
shortcuts.appendChild(document.createTextNode('\u00A0|\u00A0'));
|
||||
day_link = quickElement('a', shortcuts, gettext('Tomorrow'), 'href', '#');
|
||||
day_link.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
DateTimeShortcuts.handleCalendarQuickLink(num, +1);
|
||||
});
|
||||
|
||||
// cancel bar
|
||||
const cancel_p = quickElement('p', cal_box);
|
||||
cancel_p.className = 'calendar-cancel';
|
||||
const cancel_link = quickElement('a', cancel_p, gettext('Cancel'), 'href', '#');
|
||||
cancel_link.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
DateTimeShortcuts.dismissCalendar(num);
|
||||
});
|
||||
document.addEventListener('keyup', function(event) {
|
||||
if (event.which === 27) {
|
||||
// ESC key closes popup
|
||||
DateTimeShortcuts.dismissCalendar(num);
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
},
|
||||
openCalendar: function(num) {
|
||||
const cal_box = document.getElementById(DateTimeShortcuts.calendarDivName1 + num);
|
||||
const cal_link = document.getElementById(DateTimeShortcuts.calendarLinkName + num);
|
||||
const inp = DateTimeShortcuts.calendarInputs[num];
|
||||
|
||||
// Determine if the current value in the input has a valid date.
|
||||
// If so, draw the calendar with that date's year and month.
|
||||
if (inp.value) {
|
||||
const format = get_format('DATE_INPUT_FORMATS')[0];
|
||||
const selected = inp.value.strptime(format);
|
||||
const year = selected.getUTCFullYear();
|
||||
const month = selected.getUTCMonth() + 1;
|
||||
const re = /\d{4}/;
|
||||
if (re.test(year.toString()) && month >= 1 && month <= 12) {
|
||||
DateTimeShortcuts.calendars[num].drawDate(month, year, selected);
|
||||
}
|
||||
}
|
||||
|
||||
// Recalculate the clockbox position
|
||||
// is it left-to-right or right-to-left layout ?
|
||||
if (window.getComputedStyle(document.body).direction !== 'rtl') {
|
||||
cal_box.style.left = findPosX(cal_link) + 17 + 'px';
|
||||
}
|
||||
else {
|
||||
// since style's width is in em, it'd be tough to calculate
|
||||
// px value of it. let's use an estimated px for now
|
||||
cal_box.style.left = findPosX(cal_link) - 180 + 'px';
|
||||
}
|
||||
cal_box.style.top = Math.max(0, findPosY(cal_link) - 75) + 'px';
|
||||
|
||||
cal_box.style.display = 'block';
|
||||
document.addEventListener('click', DateTimeShortcuts.dismissCalendarFunc[num]);
|
||||
},
|
||||
dismissCalendar: function(num) {
|
||||
document.getElementById(DateTimeShortcuts.calendarDivName1 + num).style.display = 'none';
|
||||
document.removeEventListener('click', DateTimeShortcuts.dismissCalendarFunc[num]);
|
||||
},
|
||||
drawPrev: function(num) {
|
||||
DateTimeShortcuts.calendars[num].drawPreviousMonth();
|
||||
},
|
||||
drawNext: function(num) {
|
||||
DateTimeShortcuts.calendars[num].drawNextMonth();
|
||||
},
|
||||
handleCalendarCallback: function(num) {
|
||||
let format = get_format('DATE_INPUT_FORMATS')[0];
|
||||
// the format needs to be escaped a little
|
||||
format = format.replace('\\', '\\\\')
|
||||
.replace('\r', '\\r')
|
||||
.replace('\n', '\\n')
|
||||
.replace('\t', '\\t')
|
||||
.replace("'", "\\'");
|
||||
return function(y, m, d) {
|
||||
DateTimeShortcuts.calendarInputs[num].value = new Date(y, m - 1, d).strftime(format);
|
||||
DateTimeShortcuts.calendarInputs[num].focus();
|
||||
document.getElementById(DateTimeShortcuts.calendarDivName1 + num).style.display = 'none';
|
||||
// Added by cpa:
|
||||
DateTimeShortcuts.calendarInputs[num].dispatchEvent(new Event('change'));
|
||||
};
|
||||
},
|
||||
handleCalendarQuickLink: function(num, offset) {
|
||||
const d = DateTimeShortcuts.now();
|
||||
d.setDate(d.getDate() + offset);
|
||||
DateTimeShortcuts.calendarInputs[num].value = d.strftime(get_format('DATE_INPUT_FORMATS')[0]);
|
||||
DateTimeShortcuts.calendarInputs[num].focus();
|
||||
DateTimeShortcuts.dismissCalendar(num);
|
||||
}
|
||||
};
|
||||
|
||||
// CUSTOMIZED: We call it ourselves.
|
||||
//window.addEventListener('load', DateTimeShortcuts.init);
|
||||
window.DateTimeShortcuts = DateTimeShortcuts;
|
||||
}
|
||||
1
aemo/static/js/autocomplete.min.js
vendored
Normal file
1
aemo/static/js/autocomplete.min.js
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).autocomplete=t()}(this,(function(){"use strict";return function(e){var t,n,o=document,i=o.createElement("div"),r=i.style,f=navigator.userAgent,l=-1!==f.indexOf("Firefox")&&-1!==f.indexOf("Mobile"),u=e.debounceWaitMs||0,a=e.preventSubmit||!1,s=e.disableAutoSelect||!1,d=l?"input":"keyup",c=[],p="",v=2,m=e.showOnFocus,g=0;if(void 0!==e.minLength&&(v=e.minLength),!e.input)throw new Error("input undefined");var h=e.input;function E(){n&&window.clearTimeout(n)}function w(){return!!i.parentNode}function L(){var e;g++,c=[],p="",t=void 0,(e=i.parentNode)&&e.removeChild(i)}function b(){for(;i.firstChild;)i.removeChild(i.firstChild);var n=function(e,t){var n=o.createElement("div");return n.textContent=e.label||"",n};e.render&&(n=e.render);var f=function(e,t){var n=o.createElement("div");return n.textContent=e,n};e.renderGroup&&(f=e.renderGroup);var l=o.createDocumentFragment(),u="#9?$";if(c.forEach((function(o){if(o.group&&o.group!==u){u=o.group;var i=f(o.group,p);i&&(i.className+=" group",l.appendChild(i))}var r=n(o,p);r&&(r.addEventListener("click",(function(t){e.onSelect(o,h),L(),t.preventDefault(),t.stopPropagation()})),o===t&&(r.className+=" selected"),l.appendChild(r))})),i.appendChild(l),c.length<1){if(!e.emptyMsg)return void L();var a=o.createElement("div");a.className="empty",a.textContent=e.emptyMsg,i.appendChild(a)}i.parentNode||o.body.appendChild(i),function(){if(w()){r.height="auto",r.width=h.offsetWidth+"px";var t,n=0;f(),f(),e.customize&&t&&e.customize(h,t,i,n)}function f(){var e=o.documentElement,i=e.clientTop||o.body.clientTop||0,f=e.clientLeft||o.body.clientLeft||0,l=window.pageYOffset||e.scrollTop,u=window.pageXOffset||e.scrollLeft,a=(t=h.getBoundingClientRect()).top+h.offsetHeight+l-i,s=t.left+u-f;r.top=a+"px",r.left=s+"px",(n=window.innerHeight-(t.top+h.offsetHeight))<0&&(n=0),r.top=a+"px",r.bottom="",r.left=s+"px",r.maxHeight=n+"px"}}(),function(){var e=i.getElementsByClassName("selected");if(e.length>0){var t=e[0],n=t.previousElementSibling;if(n&&-1!==n.className.indexOf("group")&&!n.previousElementSibling&&(t=n),t.offsetTop<i.scrollTop)i.scrollTop=t.offsetTop;else{var o=t.offsetTop+t.offsetHeight,r=i.scrollTop+i.offsetHeight;o>r&&(i.scrollTop+=o-r)}}}()}function y(){w()&&b()}function x(){y()}function C(e){e.target!==i?y():e.preventDefault()}function T(e){for(var t=e.which||e.keyCode||0,n=0,o=[38,13,27,39,37,16,17,18,20,91,9];n<o.length;n++){if(t===o[n])return}t>=112&&t<=123||40===t&&w()||D(0)}function N(n){var o=n.which||n.keyCode||0;if(38===o||40===o||27===o){var i=w();if(27===o)L();else{if(!i||c.length<1)return;38===o?function(){if(c.length<1)t=void 0;else if(t===c[0])t=c[c.length-1];else for(var e=c.length-1;e>0;e--)if(t===c[e]||1===e){t=c[e-1];break}}():function(){if(c.length<1&&(t=void 0),t&&t!==c[c.length-1]){for(var e=0;e<c.length-1;e++)if(t===c[e]){t=c[e+1];break}}else t=c[0]}(),b()}return n.preventDefault(),void(i&&n.stopPropagation())}13===o&&(t&&(e.onSelect(t,h),L()),a&&n.preventDefault())}function k(){m&&D(1)}function D(o){var i=++g,r=h.value;r.length>=v||1===o?(E(),n=window.setTimeout((function(){e.fetch(r,(function(e){g===i&&e&&(p=r,t=(c=e).length<1||s?void 0:c[0],b())}),o)}),0===o?u:0)):L()}function H(){setTimeout((function(){o.activeElement!==h&&L()}),200)}return i.className="autocomplete "+(e.className||""),r.position="absolute",i.addEventListener("mousedown",(function(e){e.stopPropagation(),e.preventDefault()})),i.addEventListener("focus",(function(){return h.focus()})),h.addEventListener("keydown",N),h.addEventListener(d,T),h.addEventListener("blur",H),h.addEventListener("focus",k),window.addEventListener("resize",x),o.addEventListener("scroll",C,!0),{destroy:function(){h.removeEventListener("focus",k),h.removeEventListener("keydown",N),h.removeEventListener(d,T),h.removeEventListener("blur",H),window.removeEventListener("resize",x),o.removeEventListener("scroll",C,!0),E(),L()}}}}));
|
||||
6
aemo/static/js/autosize.min.js
vendored
Normal file
6
aemo/static/js/autosize.min.js
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/*!
|
||||
autosize 4.0.2
|
||||
license: MIT
|
||||
http://www.jacklmoore.com/autosize
|
||||
*/
|
||||
!function(e,t){if("function"==typeof define&&define.amd)define(["module","exports"],t);else if("undefined"!=typeof exports)t(module,exports);else{var n={exports:{}};t(n,n.exports),e.autosize=n.exports}}(this,function(e,t){"use strict";var n,o,p="function"==typeof Map?new Map:(n=[],o=[],{has:function(e){return-1<n.indexOf(e)},get:function(e){return o[n.indexOf(e)]},set:function(e,t){-1===n.indexOf(e)&&(n.push(e),o.push(t))},delete:function(e){var t=n.indexOf(e);-1<t&&(n.splice(t,1),o.splice(t,1))}}),c=function(e){return new Event(e,{bubbles:!0})};try{new Event("test")}catch(e){c=function(e){var t=document.createEvent("Event");return t.initEvent(e,!0,!1),t}}function r(r){if(r&&r.nodeName&&"TEXTAREA"===r.nodeName&&!p.has(r)){var e,n=null,o=null,i=null,d=function(){r.clientWidth!==o&&a()},l=function(t){window.removeEventListener("resize",d,!1),r.removeEventListener("input",a,!1),r.removeEventListener("keyup",a,!1),r.removeEventListener("autosize:destroy",l,!1),r.removeEventListener("autosize:update",a,!1),Object.keys(t).forEach(function(e){r.style[e]=t[e]}),p.delete(r)}.bind(r,{height:r.style.height,resize:r.style.resize,overflowY:r.style.overflowY,overflowX:r.style.overflowX,wordWrap:r.style.wordWrap});r.addEventListener("autosize:destroy",l,!1),"onpropertychange"in r&&"oninput"in r&&r.addEventListener("keyup",a,!1),window.addEventListener("resize",d,!1),r.addEventListener("input",a,!1),r.addEventListener("autosize:update",a,!1),r.style.overflowX="hidden",r.style.wordWrap="break-word",p.set(r,{destroy:l,update:a}),"vertical"===(e=window.getComputedStyle(r,null)).resize?r.style.resize="none":"both"===e.resize&&(r.style.resize="horizontal"),n="content-box"===e.boxSizing?-(parseFloat(e.paddingTop)+parseFloat(e.paddingBottom)):parseFloat(e.borderTopWidth)+parseFloat(e.borderBottomWidth),isNaN(n)&&(n=0),a()}function s(e){var t=r.style.width;r.style.width="0px",r.offsetWidth,r.style.width=t,r.style.overflowY=e}function u(){if(0!==r.scrollHeight){var e=function(e){for(var t=[];e&&e.parentNode&&e.parentNode instanceof Element;)e.parentNode.scrollTop&&t.push({node:e.parentNode,scrollTop:e.parentNode.scrollTop}),e=e.parentNode;return t}(r),t=document.documentElement&&document.documentElement.scrollTop;r.style.height="",r.style.height=r.scrollHeight+n+"px",o=r.clientWidth,e.forEach(function(e){e.node.scrollTop=e.scrollTop}),t&&(document.documentElement.scrollTop=t)}}function a(){u();var e=Math.round(parseFloat(r.style.height)),t=window.getComputedStyle(r,null),n="content-box"===t.boxSizing?Math.round(parseFloat(t.height)):r.offsetHeight;if(n<e?"hidden"===t.overflowY&&(s("scroll"),u(),n="content-box"===t.boxSizing?Math.round(parseFloat(window.getComputedStyle(r,null).height)):r.offsetHeight):"hidden"!==t.overflowY&&(s("hidden"),u(),n="content-box"===t.boxSizing?Math.round(parseFloat(window.getComputedStyle(r,null).height)):r.offsetHeight),i!==n){i=n;var o=c("autosize:resized");try{r.dispatchEvent(o)}catch(e){}}}}function i(e){var t=p.get(e);t&&t.destroy()}function d(e){var t=p.get(e);t&&t.update()}var l=null;"undefined"==typeof window||"function"!=typeof window.getComputedStyle?((l=function(e){return e}).destroy=function(e){return e},l.update=function(e){return e}):((l=function(e,t){return e&&Array.prototype.forEach.call(e.length?e:[e],function(e){return r(e)}),e}).destroy=function(e){return e&&Array.prototype.forEach.call(e.length?e:[e],i),e},l.update=function(e){return e&&Array.prototype.forEach.call(e.length?e:[e],d),e}),t.default=l,e.exports=t.default});
|
||||
241
aemo/static/js/main.js
Normal file
241
aemo/static/js/main.js
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
function htmlToElem(html) {
|
||||
let temp = document.createElement('template');
|
||||
html = html.trim(); // Never return a space text node as a result
|
||||
temp.innerHTML = html;
|
||||
return temp.content.firstChild;
|
||||
}
|
||||
|
||||
function dateFormat(input) {
|
||||
if (input) {
|
||||
var dt = new Date(input);
|
||||
return dt.toLocaleDateString("fr-CH");
|
||||
}
|
||||
return '-';
|
||||
}
|
||||
|
||||
var changed = false;
|
||||
|
||||
function check_changed(ev) {
|
||||
if (changed) {
|
||||
alert("Vos données n'ont pas été sauvegardées !");
|
||||
ev.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function toggle_read_more(ev) {
|
||||
ev.preventDefault();
|
||||
const link = ev.target;
|
||||
link.innerHTML = (link.innerHTML == 'Afficher la suite') ? 'Réduire' : 'Afficher la suite';
|
||||
link.parentNode.querySelector('.long').classList.toggle('hidden');
|
||||
link.parentNode.querySelector('.short').classList.toggle('hidden');
|
||||
}
|
||||
|
||||
function showImage(ev) {
|
||||
var modal = document.getElementById('imgModal'); /* Present in base.html */
|
||||
var imgTag = document.getElementById("img01");
|
||||
var captionText = document.getElementById("caption");
|
||||
ev.preventDefault();
|
||||
modal.style.display = "block";
|
||||
imgTag.src = this.href;
|
||||
captionText.innerHTML = this.textContent;
|
||||
}
|
||||
|
||||
function setConfirmHandlers(section) {
|
||||
if (typeof section === 'undefined') section = document;
|
||||
const selector = section.querySelectorAll(".btn-danger, .confirm");
|
||||
selector.forEach(button => {
|
||||
button.addEventListener('click', ev => {
|
||||
if (button.dataset.confirm) {
|
||||
ev.preventDefault();
|
||||
if (!confirm(button.dataset.confirm)) {
|
||||
return false;
|
||||
} else {
|
||||
if (button.getAttribute('formaction')) button.form.action = button.formAction;
|
||||
button.form.submit();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function openFormInModal(url) {
|
||||
const popup = document.querySelector('#popup0');
|
||||
|
||||
function setupForm() {
|
||||
DateTimeShortcuts.init(popup);
|
||||
setConfirmHandlers(popup);
|
||||
document.querySelectorAll("#popup0 form").forEach((form) => {
|
||||
form.addEventListener('submit', (ev) => {
|
||||
ev.preventDefault();
|
||||
const form = ev.target;
|
||||
const formData = new FormData(form);
|
||||
// GET/POST with fetch
|
||||
let url = form.action;
|
||||
let params = {method: form.method};
|
||||
if (form.method == 'post') {
|
||||
params['body'] = formData;
|
||||
}
|
||||
fetch(url, params).then(res => {
|
||||
if (res.redirected) {
|
||||
window.location.reload(true);
|
||||
return '';
|
||||
}
|
||||
return res.text();
|
||||
}).then(html => {
|
||||
if (html) {
|
||||
// Redisplay form with errors or display confirm page
|
||||
popup.querySelector('.modal-body').innerHTML = html;
|
||||
setupForm();
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
alert("Désolé, une erreur s'est produite");
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return fetch(url).then(res => res.text()).then(html => {
|
||||
const modal = new bootstrap.Modal(popup);
|
||||
popup.querySelector('.modal-body').innerHTML = html;
|
||||
modal.show();
|
||||
setupForm();
|
||||
return popup;
|
||||
});
|
||||
}
|
||||
|
||||
function resetForm(ev) {
|
||||
const form = ev.target.closest('form');
|
||||
Array.from(form.elements).forEach(el => { el.value = ''; });
|
||||
form.submit();
|
||||
}
|
||||
|
||||
function submitFilterForm(form) {
|
||||
let action = form.action || '.';
|
||||
const formData = new FormData(form);
|
||||
action += '?' + new URLSearchParams(formData).toString();
|
||||
fetch(action, {
|
||||
method: 'get',
|
||||
headers: {'X-Requested-With': 'Fetch'}
|
||||
}).then(response => { return response.text(); }).then(output => {
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(output, "text/html");
|
||||
const tableBody = doc.querySelector('.table-sortable tbody');
|
||||
document.querySelector('.table-sortable tbody').replaceWith(tableBody);
|
||||
const pagination = doc.querySelector('#pagination');
|
||||
document.querySelector('#pagination').replaceWith(pagination);
|
||||
});
|
||||
}
|
||||
|
||||
function sortColumn(ev) {
|
||||
const header = ev.target;
|
||||
const form = document.querySelector('.selection_form');
|
||||
const desc = header.classList.contains('asc');
|
||||
form.elements['sort_by'].value = (desc ? '-' : '') + header.dataset.col;
|
||||
submitFilterForm(form);
|
||||
// Reset colums classes
|
||||
Array.from(header.parentNode.children).forEach(head => {
|
||||
head.classList.remove('desc');
|
||||
head.classList.remove('asc');
|
||||
});
|
||||
header.classList.add(desc ? 'desc': 'asc');
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
if (typeof DateTimeShortcuts !== 'undefined') {
|
||||
DateTimeShortcuts.init();
|
||||
}
|
||||
autosize(document.querySelectorAll('textarea'));
|
||||
$("form").not(".selection_form").not("[method='get']").change(function() {
|
||||
changed = true;
|
||||
});
|
||||
$("#menu_crne, #aemo_buttons, #aemo_print_buttons").click
|
||||
(check_changed);
|
||||
setConfirmHandlers();
|
||||
$("table.sortable").each(function(idx) {
|
||||
new Tablesort(this);
|
||||
});
|
||||
$(".table-sortable th").click(sortColumn);
|
||||
$('a.read_more').click(toggle_read_more);
|
||||
|
||||
// Attachment images
|
||||
$('a.image').click(showImage);
|
||||
$('#modalClose').click(function(ev) {$(this).closest('div').hide(); });
|
||||
|
||||
$('input[name=dh_debut_1]').change(function(){
|
||||
var dateFin = $('input[name=dh_fin_0]');
|
||||
if (dateFin.val() == '') {
|
||||
// Copier date de début vers date de fin
|
||||
dateFin.val($('input[name=dh_debut_0]').val());
|
||||
}
|
||||
var heureFin = $('input[name=dh_fin_1]');
|
||||
if (heureFin.val() == '') {
|
||||
// Mettre heure de fin 1 heure après heure de début
|
||||
var dh = $('input[name=dh_debut_1]').val().split(":");
|
||||
h = parseInt(dh[0]) + 1;
|
||||
heureFin.val(h.toString() + ":" + dh[1]);
|
||||
}
|
||||
});
|
||||
|
||||
document.querySelectorAll('.immediate-submit').forEach(immediate => {
|
||||
//immediate.addEventListener('click', immediateSubmit);
|
||||
// With screen readers, users don't click but change the radio value
|
||||
immediate.addEventListener('change', (ev) => {
|
||||
ev.target.form.submit()
|
||||
});
|
||||
});
|
||||
|
||||
$(".js-add, .js-edit").click(function(e) {
|
||||
const url = this.dataset.url || this.href;
|
||||
e.preventDefault();
|
||||
openFormInModal(url);
|
||||
return false;
|
||||
});
|
||||
|
||||
// Activation des tooltips
|
||||
const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
|
||||
tooltipTriggerList.map((el) => new bootstrap.Tooltip(el));
|
||||
|
||||
$('#reset-button').click(resetForm);
|
||||
});
|
||||
|
||||
function debounce(func, timeout=300) {
|
||||
let timer;
|
||||
return (...args) => {
|
||||
if (timeout <= 0) func.apply(this, args);
|
||||
else {
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(() => { func.apply(this, args); }, timeout);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async function archiveFamilies(ev) {
|
||||
const btn = ev.target;
|
||||
const archiveUrl = btn.dataset.archiveurl;
|
||||
const counterSpan = document.querySelector('#archive-counter');
|
||||
const totalSpan = document.querySelector('#archive-total');
|
||||
|
||||
bootstrap.Modal.getInstance(document.getElementById('archiveModal')).hide();
|
||||
document.getElementById('archive-message').removeAttribute('hidden');
|
||||
const resp = await fetch(btn.dataset.getarchivableurl);
|
||||
const data = await resp.json();
|
||||
let compteur = 0;
|
||||
totalSpan.textContent = data.length;
|
||||
const formData = new FormData();
|
||||
formData.append('csrfmiddlewaretoken', document.querySelector('[name=csrfmiddlewaretoken]').value);
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const archResp = await fetch(
|
||||
archiveUrl.replace('999', data[i]),
|
||||
{method: 'POST', headers: {'X-Requested-With': 'Fetch'}, body: formData}
|
||||
);
|
||||
const jsonResp = await archResp.json();
|
||||
compteur += 1;
|
||||
counterSpan.textContent = compteur;
|
||||
}
|
||||
const messageP = document.querySelector("#archive-message p");
|
||||
messageP.textContent = `${compteur} dossiers ont été archivés avec succès.`;
|
||||
messageP.classList.remove('alert-danger');
|
||||
messageP.classList.add('alert-success');
|
||||
}
|
||||
6
aemo/static/js/sorts/tablesort.date.min.js
vendored
Normal file
6
aemo/static/js/sorts/tablesort.date.min.js
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/*!
|
||||
* tablesort v5.1.0 (2020-01-22)
|
||||
* http://tristen.ca/tablesort/demo/
|
||||
* Copyright (c) 2020 ; Licensed MIT
|
||||
*/
|
||||
!function(){var a=function(a){return a=a.replace(/\-/g,"/"),a=a.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{2,4})/,"$3-$2-$1"),new Date(a).getTime()||-1};Tablesort.extend("date",function(b){return(-1!==b.search(/(Mon|Tue|Wed|Thu|Fri|Sat|Sun)\.?\,?\s*/i)||-1!==b.search(/\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2,4}/)||-1!==b.search(/(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)/i))&&!isNaN(a(b))},function(b,c){return b=b.toLowerCase(),c=c.toLowerCase(),a(c)-a(b)})}();
|
||||
6
aemo/static/js/sorts/tablesort.number.min.js
vendored
Normal file
6
aemo/static/js/sorts/tablesort.number.min.js
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/*!
|
||||
* tablesort v5.1.0 (2020-01-22)
|
||||
* http://tristen.ca/tablesort/demo/
|
||||
* Copyright (c) 2020 ; Licensed MIT
|
||||
*/
|
||||
!function(){var a=function(a){return a.replace(/[^\-?0-9.]/g,"")},b=function(a,b){return a=parseFloat(a),b=parseFloat(b),a=isNaN(a)?0:a,b=isNaN(b)?0:b,a-b};Tablesort.extend("number",function(a){return a.match(/^[-+]?[£\x24Û¢´€]?\d+\s*([,\.]\d{0,2})/)||a.match(/^[-+]?\d+\s*([,\.]\d{0,2})?[£\x24Û¢´€]/)||a.match(/^[-+]?(\d)*-?([,\.]){0,1}-?(\d)+([E,e][\-+][\d]+)?%?$/)},function(c,d){return c=a(c),d=a(d),b(d,c)})}();
|
||||
6
aemo/static/js/tablesort.min.js
vendored
Normal file
6
aemo/static/js/tablesort.min.js
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
/*!
|
||||
* tablesort v5.1.0 (2020-01-22)
|
||||
* http://tristen.ca/tablesort/demo/
|
||||
* Copyright (c) 2020 ; Licensed MIT
|
||||
*/
|
||||
!function(){function a(b,c){if(!(this instanceof a))return new a(b,c);if(!b||"TABLE"!==b.tagName)throw new Error("Element must be a table");this.init(b,c||{})}var b=[],c=function(a){var b;return window.CustomEvent&&"function"==typeof window.CustomEvent?b=new CustomEvent(a):(b=document.createEvent("CustomEvent"),b.initCustomEvent(a,!1,!1,void 0)),b},d=function(a){return a.getAttribute("data-sort")||a.textContent||a.innerText||""},e=function(a,b){return a=a.trim().toLowerCase(),b=b.trim().toLowerCase(),a===b?0:a<b?1:-1},f=function(a,b){return[].slice.call(a).find(function(a){return a.getAttribute("data-sort-column-key")===b})},g=function(a,b){return function(c,d){var e=a(c.td,d.td);return 0===e?b?d.index-c.index:c.index-d.index:e}};a.extend=function(a,c,d){if("function"!=typeof c||"function"!=typeof d)throw new Error("Pattern and sort must be a function");b.push({name:a,pattern:c,sort:d})},a.prototype={init:function(a,b){var c,d,e,f,g=this;if(g.table=a,g.thead=!1,g.options=b,a.rows&&a.rows.length>0)if(a.tHead&&a.tHead.rows.length>0){for(e=0;e<a.tHead.rows.length;e++)if("thead"===a.tHead.rows[e].getAttribute("data-sort-method")){c=a.tHead.rows[e];break}c||(c=a.tHead.rows[a.tHead.rows.length-1]),g.thead=!0}else c=a.rows[0];if(c){var h=function(){g.current&&g.current!==this&&g.current.removeAttribute("aria-sort"),g.current=this,g.sortTable(this)};for(e=0;e<c.cells.length;e++)f=c.cells[e],f.setAttribute("role","columnheader"),"none"!==f.getAttribute("data-sort-method")&&(f.tabindex=0,f.addEventListener("click",h,!1),null!==f.getAttribute("data-sort-default")&&(d=f));d&&(g.current=d,g.sortTable(d))}},sortTable:function(a,h){var i=this,j=a.getAttribute("data-sort-column-key"),k=a.cellIndex,l=e,m="",n=[],o=i.thead?0:1,p=a.getAttribute("data-sort-method"),q=a.getAttribute("aria-sort");if(i.table.dispatchEvent(c("beforeSort")),h||(q="ascending"===q?"descending":"descending"===q?"ascending":i.options.descending?"descending":"ascending",a.setAttribute("aria-sort",q)),!(i.table.rows.length<2)){if(!p){for(var r;n.length<3&&o<i.table.tBodies[0].rows.length;)r=j?f(i.table.tBodies[0].rows[o].cells,j):i.table.tBodies[0].rows[o].cells[k],m=r?d(r):"",m=m.trim(),m.length>0&&n.push(m),o++;if(!n)return}for(o=0;o<b.length;o++)if(m=b[o],p){if(m.name===p){l=m.sort;break}}else if(n.every(m.pattern)){l=m.sort;break}for(i.col=k,o=0;o<i.table.tBodies.length;o++){var s,t=[],u={},v=0,w=0;if(!(i.table.tBodies[o].rows.length<2)){for(s=0;s<i.table.tBodies[o].rows.length;s++){var r;m=i.table.tBodies[o].rows[s],"none"===m.getAttribute("data-sort-method")?u[v]=m:(r=j?f(m.cells,j):m.cells[i.col],t.push({tr:m,td:r?d(r):"",index:v})),v++}for("descending"===q?t.sort(g(l,!0)):(t.sort(g(l,!1)),t.reverse()),s=0;s<v;s++)u[s]?(m=u[s],w++):m=t[s-w].tr,i.table.tBodies[o].appendChild(m)}}i.table.dispatchEvent(c("afterSort"))}},refresh:function(){void 0!==this.current&&this.sortTable(this.current,!0)}},"undefined"!=typeof module&&module.exports?module.exports=a:window.Tablesort=a}();
|
||||
Loading…
Add table
Add a link
Reference in a new issue