Trying to remove jQuery code as much as possible
This commit is contained in:
parent
cbd2e36a37
commit
07c2af9841
@ -16,15 +16,15 @@ _CONF_LISTENER_TARGET = _CONF_LISTENER_TARGET === "all" ? "*" : _CONF_LISTENER_T
|
|||||||
* Source : https://www.iconfinder.com/iconsets/glyphs
|
* Source : https://www.iconfinder.com/iconsets/glyphs
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var SVG_EDIT = '<svg style="width: 1em; height: 1em;" version="1.1" viewBox="0 0 24 24" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g class="svg_edit"><path d="m2 20c0 1.1.9 2 2 2h2.6l-4.6-4.6z"/><path d="m21.6 5.6-3.2-3.2c-.8-.8-2-.8-2.8 0l-.2.2c-.4.4-.4 1 0 1.4l4.6 4.6c.4.4 1 .4 1.4 0l.2-.2c.8-.8.8-2 0-2.8z"/><path d="m14 5.4c-.4-.4-1-.4-1.4 0l-9.1 9.1c-.5.5-.5 1.1-.1 1.5l4.6 4.6c.4.4 1 .4 1.4 0l9.1-9.1c.4-.4.4-1 0-1.4z"/></g></svg>';
|
const SVG_EDIT = '<svg style="width: 1em; height: 1em;" version="1.1" viewBox="0 0 24 24" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g class="svg_edit"><path d="m2 20c0 1.1.9 2 2 2h2.6l-4.6-4.6z"/><path d="m21.6 5.6-3.2-3.2c-.8-.8-2-.8-2.8 0l-.2.2c-.4.4-.4 1 0 1.4l4.6 4.6c.4.4 1 .4 1.4 0l.2-.2c.8-.8.8-2 0-2.8z"/><path d="m14 5.4c-.4-.4-1-.4-1.4 0l-9.1 9.1c-.5.5-.5 1.1-.1 1.5l4.6 4.6c.4.4 1 .4 1.4 0l9.1-9.1c.4-.4.4-1 0-1.4z"/></g></svg>';
|
||||||
var SVG_VALID = '<svg style="width: 1em; height: 1em; fill:white;" version="1.1" viewBox="0 0 24 24" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g id="info"/><g id="icons"><path d="M10,18c-0.5,0-1-0.2-1.4-0.6l-4-4c-0.8-0.8-0.8-2,0-2.8c0.8-0.8,2.1-0.8,2.8,0l2.6,2.6l6.6-6.6 c0.8-0.8,2-0.8,2.8,0c0.8,0.8,0.8,2,0,2.8l-8,8C11,17.8,10.5,18,10,18z" class="svg_check"/></g></svg>';
|
const SVG_VALID = '<svg style="width: 1em; height: 1em; fill:white;" version="1.1" viewBox="0 0 24 24" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g id="info"/><g id="icons"><path d="M10,18c-0.5,0-1-0.2-1.4-0.6l-4-4c-0.8-0.8-0.8-2,0-2.8c0.8-0.8,2.1-0.8,2.8,0l2.6,2.6l6.6-6.6 c0.8-0.8,2-0.8,2.8,0c0.8,0.8,0.8,2,0,2.8l-8,8C11,17.8,10.5,18,10,18z" class="svg_check"/></g></svg>';
|
||||||
var SVG_CANCEL = '<svg style="width: 1em; height: 1em;" version="1.1" viewBox="0 0 24 24" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g id="info"/><g id="icons"><path d="M14.8,12l3.6-3.6c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0L12,9.2L8.4,5.6c-0.8-0.8-2-0.8-2.8,0 c-0.8,0.8-0.8,2,0,2.8L9.2,12l-3.6,3.6c-0.8,0.8-0.8,2,0,2.8C6,18.8,6.5,19,7,19s1-0.2,1.4-0.6l3.6-3.6l3.6,3.6 C16,18.8,16.5,19,17,19s1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8L14.8,12z" class="svg_cancel"/></g></svg>';
|
const SVG_CANCEL = '<svg style="width: 1em; height: 1em;" version="1.1" viewBox="0 0 24 24" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g id="info"/><g id="icons"><path d="M14.8,12l3.6-3.6c0.8-0.8,0.8-2,0-2.8c-0.8-0.8-2-0.8-2.8,0L12,9.2L8.4,5.6c-0.8-0.8-2-0.8-2.8,0 c-0.8,0.8-0.8,2,0,2.8L9.2,12l-3.6,3.6c-0.8,0.8-0.8,2,0,2.8C6,18.8,6.5,19,7,19s1-0.2,1.4-0.6l3.6-3.6l3.6,3.6 C16,18.8,16.5,19,17,19s1-0.2,1.4-0.6c0.8-0.8,0.8-2,0-2.8L14.8,12z" class="svg_cancel"/></g></svg>';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allow inclusion from other page
|
* Allow inclusion from other page
|
||||||
* See https://github.com/Ilogeek/redmine_issue_dynamic_edit/commit/26684a2dd9b12dcc7377afd79e9fe5c142d26ebd for more info
|
* See https://github.com/Ilogeek/redmine_issue_dynamic_edit/commit/26684a2dd9b12dcc7377afd79e9fe5c142d26ebd for more info
|
||||||
*/
|
*/
|
||||||
var LOCATION_HREF = typeof custom_location_href !== 'undefined' ? custom_location_href : window.location.href;
|
let LOCATION_HREF = typeof custom_location_href !== 'undefined' ? custom_location_href : window.location.href;
|
||||||
|
|
||||||
if (_CONF_FORCE_HTTPS) {
|
if (_CONF_FORCE_HTTPS) {
|
||||||
LOCATION_HREF = LOCATION_HREF.replace(/^http:\/\//i, 'https://');
|
LOCATION_HREF = LOCATION_HREF.replace(/^http:\/\//i, 'https://');
|
||||||
@ -34,18 +34,18 @@ if (_CONF_FORCE_HTTPS) {
|
|||||||
* or if user has to hover every element to discover if (s)he can edit it
|
* or if user has to hover every element to discover if (s)he can edit it
|
||||||
*/
|
*/
|
||||||
if (_CONF_DISPLAY_EDIT_ICON === "block"){
|
if (_CONF_DISPLAY_EDIT_ICON === "block"){
|
||||||
$('body.controller-issues.action-show .issue.details').addClass('showPencils');
|
document.querySelectorAll('body.controller-issues.action-show .issue.details').forEach((elt) => elt.classList.add('showPencils'));
|
||||||
}
|
}
|
||||||
|
|
||||||
let updateCSRFToken = function(token){
|
const updateCSRFToken = function(token){
|
||||||
document.querySelectorAll('input[name="authenticity_token"]').forEach(elt => elt.value = token);
|
document.querySelectorAll('input[name="authenticity_token"]').forEach((elt) => elt.value = token);
|
||||||
document.querySelector('meta[name="csrf-token"]').setAttribute("content", token);
|
document.querySelector('meta[name="csrf-token"]').setAttribute("content", token);
|
||||||
}
|
}
|
||||||
|
|
||||||
let setCSRFTokenInput = function(token){
|
const setCSRFTokenInput = function(token){
|
||||||
document.querySelectorAll('form[method="post"]').forEach(elt => {
|
document.querySelectorAll('form[method="post"]').forEach((elt) => {
|
||||||
if(!elt.querySelectorAll('input[name="authenticity_token"]').length){
|
if(!elt.querySelectorAll('input[name="authenticity_token"]').length){
|
||||||
let input = document.createElement("input");
|
const input = document.createElement("input");
|
||||||
input.setAttribute("type", "hidden");
|
input.setAttribute("type", "hidden");
|
||||||
input.setAttribute("name", "authenticity_token");
|
input.setAttribute("name", "authenticity_token");
|
||||||
input.value = token;
|
input.value = token;
|
||||||
@ -55,50 +55,63 @@ let setCSRFTokenInput = function(token){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Generate edit block */
|
/* Generate edit block */
|
||||||
var getEditFormHTML = function(attribute){
|
const getEditFormHTML = function(attribute){
|
||||||
var formElement = $('#issue_' + attribute + "_id");
|
let formElement = document.querySelector('#issue_' + attribute + "_id");
|
||||||
formElement = formElement.length ? formElement : $('#issue_' + attribute);
|
formElement = formElement ? formElement : document.querySelector('#issue_' + attribute);
|
||||||
formElement = formElement.length ? formElement : $('#' + attribute);
|
formElement = formElement ? formElement : document.querySelector('#' + attribute);
|
||||||
|
|
||||||
// Checkbox specific case
|
// Checkbox specific case
|
||||||
var is_checkboxes = false;
|
let is_checkboxes = false;
|
||||||
let is_file = false;
|
let is_file = false;
|
||||||
let is_list = false;
|
let is_list = false;
|
||||||
let CF_ID = false;
|
let CF_ID = false;
|
||||||
if(!formElement.length && attribute.startsWith("custom_field_values_")){
|
if(!formElement && attribute.startsWith("custom_field_values_")){
|
||||||
CF_ID = attribute.split("custom_field_values_")[1];
|
CF_ID = attribute.split("custom_field_values_")[1];
|
||||||
/* Is it a checkbox block ? */
|
/* Is it a checkbox block ? */
|
||||||
formElement = $('#issue_custom_field_values_' + CF_ID);
|
formElement = document.querySelector('#issue_custom_field_values_' + CF_ID);
|
||||||
if(formElement.length){
|
if(formElement){
|
||||||
formElement = formElement.parents('.check_box_group');
|
formElement = formElement.closest('.check_box_group');
|
||||||
is_checkboxes = CF_ID;
|
is_checkboxes = CF_ID;
|
||||||
} else {
|
} else {
|
||||||
/* Is it a file block ? */
|
/* Is it a file block ? */
|
||||||
formElement = $('#issue_custom_field_values_' + CF_ID + '_blank');
|
formElement = document.querySelector('#issue_custom_field_values_' + CF_ID + '_blank');
|
||||||
if(formElement.length){
|
if(formElement){
|
||||||
formElement = formElement.parents('p');
|
formElement = formElement.closest('p');
|
||||||
formElement.find('label').remove();
|
formElement.removeChild(formElement.querySelector('label'));
|
||||||
is_file = CF_ID;
|
is_file = CF_ID;
|
||||||
} else {
|
} else {
|
||||||
/* Is it a checkbox/radio group ? */
|
/* Is it a checkbox/radio group ? */
|
||||||
formElement = $('#issue-form .cf_' + CF_ID + '.check_box_group');
|
formElement = document.querySelector('#issue-form .cf_' + CF_ID + '.check_box_group');
|
||||||
is_list = CF_ID;
|
is_list = CF_ID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(formElement.length){
|
if(formElement){
|
||||||
var clone = formElement.clone();
|
const clone = formElement.cloneNode(true);
|
||||||
if(clone.is('select') && !clone.prop('multiple')) clone.on('change', function(e){sendData($(this).serializeArray());});
|
if(clone.matches('select') && !clone.hasAttribute('multiple')) {
|
||||||
if(is_checkboxes || is_file || is_list) {
|
clone.addEventListener('change', function(e){
|
||||||
clone.prop('id', "issue_custom_field_values_" + CF_ID + "_dynamic");
|
sendData([{"name" : clone.getAttribute('name'), "value" : clone.value}]);
|
||||||
} else {
|
});
|
||||||
clone.prop('id', formElement.prop('id') + "_dynamic");
|
|
||||||
}
|
}
|
||||||
var wrapper = $("<div/>").addClass('dynamicEditField');
|
if(is_checkboxes || is_file || is_list) {
|
||||||
wrapper.append(clone);
|
clone.setAttribute('id', "issue_custom_field_values_" + CF_ID + "_dynamic");
|
||||||
if(!clone.is('select') || clone.prop('multiple')) wrapper.append("<button class='action valid'><!--✓-->" + SVG_VALID + "</button>");
|
} else {
|
||||||
wrapper.append("<button class='action refuse'><!--✕-->" + SVG_CANCEL + "</button>");
|
clone.setAttribute('id', formElement.getAttribute('id') + "_dynamic");
|
||||||
|
}
|
||||||
|
const wrapper = document.createElement('div');
|
||||||
|
wrapper.classList.add('dynamicEditField');
|
||||||
|
wrapper.insertBefore(clone, null);
|
||||||
|
if(!clone.matches('select') || clone.hasAttribute('multiple')) {
|
||||||
|
let btn_valid = document.createElement('button');
|
||||||
|
btn_valid.classList.add('action', 'valid');
|
||||||
|
btn_valid.innerHTML = SVG_VALID;
|
||||||
|
wrapper.insertBefore(btn_valid, null);
|
||||||
|
}
|
||||||
|
const btn_refuse = document.createElement('button');
|
||||||
|
btn_refuse.classList.add('action', 'refuse');
|
||||||
|
btn_refuse.innerHTML = SVG_CANCEL;
|
||||||
|
wrapper.insertBefore(btn_refuse, null);
|
||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,16 +119,23 @@ var getEditFormHTML = function(attribute){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Loop over all form attribute and clone them into details part */
|
/* Loop over all form attribute and clone them into details part */
|
||||||
var cloneEditForm = function(){
|
const cloneEditForm = function(){
|
||||||
$('.issue.details div.subject').append('<button class="refreshData">⟳</button>');
|
const btn_refresh = document.createElement('button');
|
||||||
$(".issue.details ").wrap("<form id='fakeDynamicForm'>");
|
btn_refresh.classList.add('refreshData');
|
||||||
|
btn_refresh.innerHTML = "⟳";
|
||||||
|
document.querySelector('.issue.details div.subject').insertBefore(btn_refresh, null);
|
||||||
|
|
||||||
$('div.issue.details .attribute').each(function(){
|
const wrapper = document.createElement('form');
|
||||||
var classList = $(this).attr('class').split(/\s+/);
|
wrapper.setAttribute('id', 'fakeDynamicForm');
|
||||||
|
document.querySelector('.issue.details').parentNode.insertBefore(wrapper, document.querySelector('.issue.details'));
|
||||||
|
wrapper.appendChild(document.querySelector('.issue.details'));
|
||||||
|
|
||||||
var attributes = classList.filter(function(elem) { return elem != "attribute"; });
|
document.querySelectorAll('div.issue.details .attribute').forEach(function(elt){
|
||||||
|
const classList = elt.classList.value.split(/\s+/);
|
||||||
|
|
||||||
|
let attributes = classList.filter(function(elem) { return elem != "attribute"; });
|
||||||
// Specific case : all "-" are replaced by "_" into form id
|
// Specific case : all "-" are replaced by "_" into form id
|
||||||
attributes = attributes.map(attr => attr.replaceAll('-', '_'));
|
attributes = attributes.map((attr) => attr.replaceAll('-', '_'));
|
||||||
|
|
||||||
let custom_field = false;
|
let custom_field = false;
|
||||||
attributes.forEach(function(part, index, arr) {
|
attributes.forEach(function(part, index, arr) {
|
||||||
@ -131,122 +151,160 @@ var cloneEditForm = function(){
|
|||||||
let selected_elt = custom_field ? custom_field : attributes;
|
let selected_elt = custom_field ? custom_field : attributes;
|
||||||
if(attributes && !_CONF_EXCLUDED_FIELD_ID.includes(selected_elt)){
|
if(attributes && !_CONF_EXCLUDED_FIELD_ID.includes(selected_elt)){
|
||||||
let dynamicEditField = getEditFormHTML(selected_elt);
|
let dynamicEditField = getEditFormHTML(selected_elt);
|
||||||
if(dynamicEditField) $(this).find('.value').append(" <span class='iconEdit'><!--✎-->" + SVG_EDIT + "</span>").append(dynamicEditField);
|
if(dynamicEditField){
|
||||||
|
let btn_edit = document.createElement('span');
|
||||||
|
btn_edit.classList.add('iconEdit');
|
||||||
|
btn_edit.innerHTML = SVG_EDIT;
|
||||||
|
elt.querySelector('.value').insertBefore(btn_edit, null);
|
||||||
|
elt.querySelector('.value').insertBefore(dynamicEditField, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Specific Case : Description field
|
// Specific Case : Description field
|
||||||
if(!_CONF_EXCLUDED_FIELD_ID.includes("description") && document.querySelectorAll('div.issue.details .description').length){
|
if(!_CONF_EXCLUDED_FIELD_ID.includes("description") && document.querySelectorAll('div.issue.details .description').length){
|
||||||
$('div.issue.details .description > p').first().find('strong').after(" <span class='iconEdit'><!--✎-->" + SVG_EDIT + "</span>");
|
const btn_edit = document.createElement('span');
|
||||||
var formDescription = getEditFormHTML("description");
|
btn_edit.classList.add('iconEdit');
|
||||||
formDescription.find("#issue_description_dynamic").removeAttr('data-tribute');
|
btn_edit.innerHTML = SVG_EDIT;
|
||||||
$('div.issue.details .description').append(formDescription);
|
document.querySelector('div.issue.details .description > p strong').insertAdjacentElement("afterend", btn_edit);
|
||||||
|
const formDescription = getEditFormHTML("description");
|
||||||
|
formDescription.querySelector("#issue_description_dynamic").removeAttribute('data-tribute');
|
||||||
|
document.querySelector('div.issue.details .description').insertBefore(formDescription, null);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
typeof(CKEDITOR) === "object" &&
|
typeof(CKEDITOR) === "object" &&
|
||||||
typeof(CKEDITOR.instances['issue_description'] !== "undefined") &&
|
typeof(CKEDITOR.instances['issue_description'] !== "undefined") &&
|
||||||
typeof(CKEDITOR.instances['issue_description'].getData) === typeof(Function)
|
typeof(CKEDITOR.instances['issue_description'].getData) === typeof(Function)
|
||||||
) {
|
) {
|
||||||
var cfg = CKEDITOR.instances['issue_description'].config;
|
const cfg = CKEDITOR.instances['issue_description'].config;
|
||||||
cfg.height = 100;
|
cfg.height = 100;
|
||||||
CKEDITOR.replace("issue_description_dynamic", cfg)
|
CKEDITOR.replace("issue_description_dynamic", cfg)
|
||||||
}else if (typeof(jsToolBar) === typeof(Function)) {
|
}else if (typeof(jsToolBar) === typeof(Function)) {
|
||||||
var wikiToolbar = new jsToolBar(document.getElementById('issue_description_dynamic')); wikiToolbar.draw();
|
const wikiToolbar = new jsToolBar(document.querySelector('#issue_description_dynamic')); wikiToolbar.draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specific Case : Title field
|
// Specific Case : Title field
|
||||||
if(!_CONF_EXCLUDED_FIELD_ID.includes("subject")){
|
if(!_CONF_EXCLUDED_FIELD_ID.includes("subject")){
|
||||||
$('div.issue.details div.subject h3').append(" <span class='iconEdit'><!--✎-->" + SVG_EDIT + "</span>");
|
const btn_edit = document.createElement('span');
|
||||||
var formTitle = getEditFormHTML("issue_subject");
|
btn_edit.classList.add('iconEdit');
|
||||||
$('div.issue.details div.subject').append(formTitle);
|
btn_edit.innerHTML = SVG_EDIT;
|
||||||
|
document.querySelector('div.issue.details div.subject h3').insertBefore(btn_edit, null);
|
||||||
|
const formTitle = getEditFormHTML("issue_subject");
|
||||||
|
document.querySelector('div.issue.details div.subject').insertBefore(formTitle, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform action on .value (display edit form) */
|
/* Perform action on .value (display edit form) */
|
||||||
$('body').on(_CONF_LISTENER_TYPE_VALUE,
|
document.querySelector('body').addEventListener(_CONF_LISTENER_TYPE_VALUE,
|
||||||
'div.issue.details .attributes .attribute .' + _CONF_LISTENER_TARGET + ', div.issue.details div.description > p, div.issue.details div.subject',
|
|
||||||
function(e){
|
function(e){
|
||||||
if($(e.target).closest('.dynamicEditField').length) return; /* We're already into a dynamic field, ignore */
|
let is_attribute = e.target.matches('div.issue.details .attributes .attribute .' + _CONF_LISTENER_TARGET) || e.target.closest('div.issue.details .attributes .attribute .' + _CONF_LISTENER_TARGET);
|
||||||
$('.dynamicEditField').each(function(e){ $(this).removeClass('open'); });
|
let is_description = e.target.matches('div.issue.details div.description > p') || e.target.closest('div.issue.details div.description > p');
|
||||||
if(!$(e.target).closest('a').length && !$(e.target).closest('button').length){
|
let is_subject = e.target.matches('div.issue.details div.subject') || e.target.closest('div.issue.details div.subject');
|
||||||
if($(this).parent().hasClass('description')){
|
if(is_attribute || is_description || is_subject ){
|
||||||
$(this).parent().find('.dynamicEditField').addClass('open');
|
if(e.target.closest('.dynamicEditField')) return; /* We're already into a dynamic field, ignore */
|
||||||
} else {
|
document.querySelectorAll('.dynamicEditField').forEach(function(elt){ elt.classList.remove('open'); });
|
||||||
$(this).find('.dynamicEditField').addClass('open');
|
if(!e.target.closest('a') && !e.target.closest('button')){
|
||||||
|
let selector = e.target.closest('.value');
|
||||||
|
if(is_description) selector = e.target.closest('.description');
|
||||||
|
if(is_subject) selector = e.target.closest('.subject');
|
||||||
|
selector.querySelector('.dynamicEditField').classList.add('open');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Perform action on .iconEdit (display edit form) */
|
/* Perform action on .iconEdit (display edit form) */
|
||||||
$('body').on(_CONF_LISTENER_TYPE_ICON,
|
document.querySelector('body').addEventListener(_CONF_LISTENER_TYPE_ICON, function(e){
|
||||||
'div.issue.details .iconEdit', function(e){
|
let is_attribute = e.target.matches('div.issue.details .attributes .attribute .' + _CONF_LISTENER_TARGET) || e.target.closest('div.issue.details .attributes .attribute .' + _CONF_LISTENER_TARGET);
|
||||||
$('.dynamicEditField').each(function(e){ $(this).removeClass('open'); });
|
let is_description = e.target.matches('div.issue.details div.description > p') || e.target.closest('div.issue.details div.description > p');
|
||||||
$(this).parent().find('.dynamicEditField').addClass('open');
|
let is_subject = e.target.matches('div.issue.details div.subject') || e.target.closest('div.issue.details div.subject');
|
||||||
|
if(e.target.matches('.iconEdit') || e.target.closest('.iconEdit')){
|
||||||
|
document.querySelectorAll('.dynamicEditField').forEach(function(elt){ elt.classList.remove('open'); });
|
||||||
|
let selector = e.target.closest('.value');
|
||||||
|
if(is_description) selector = e.target.closest('.description');
|
||||||
|
if(is_subject) selector = e.target.closest('.subject');
|
||||||
|
selector.querySelector('.dynamicEditField').classList.add('open');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Perform data update when clicking on valid button from edit form */
|
/* Perform data update when clicking on valid button from edit form */
|
||||||
$('body').on('click', '.dynamicEditField .action.valid', function(e){
|
document.querySelector('body').addEventListener('click', function(e){
|
||||||
|
if(e.target.matches('.dynamicEditField .action.valid') || e.target.closest('.dynamicEditField .action.valid')){
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var input = $(this).parents('.dynamicEditField').find(':input');
|
let inputs = e.target.closest('.dynamicEditField').querySelectorAll('*[name]');
|
||||||
sendData(input.serializeArray());
|
let formData = [];
|
||||||
$(this).parents('.dynamicEditField').removeClass('open');
|
let existingIndex = [];
|
||||||
|
inputs.forEach(elt => {
|
||||||
|
let not_multiple = !elt.matches('input[type="radio"]') && !elt.matches('input[type="checkbox"]');
|
||||||
|
if(elt.matches('input[type="radio"]:checked') || elt.matches('input[type="checkbox"]:checked') || not_multiple){
|
||||||
|
if(!existingIndex.includes(elt.getAttribute('name'))){
|
||||||
|
existingIndex.push(elt.getAttribute('name'));
|
||||||
|
formData.push({"name" : elt.getAttribute('name'), "value" : elt.value})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
sendData(formData);
|
||||||
|
e.target.closest('.dynamicEditField').classList.remove('open');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Hide edit form when clicking on cancel button */
|
/* Hide edit form when clicking on cancel button */
|
||||||
$('body').on('click', '.dynamicEditField .action.refuse', function(e){
|
document.querySelector('body').addEventListener('click', function(e){
|
||||||
|
if(e.target.matches('.dynamicEditField .action.refuse') || e.target.closest('.dynamicEditField .action.refuse')){
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
$(this).parents('.dynamicEditField').removeClass('open');
|
e.target.closest('.dynamicEditField').classList.remove('open');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Update whole .details block + history + form with global refresh button */
|
/* Update whole .details block + history + form with global refresh button */
|
||||||
$('body').on('click', '.refreshData', function(e){
|
document.querySelector('body').addEventListener('click', function(e){
|
||||||
|
if(e.target.matches('.refreshData') || e.target.closest('.refreshData')){
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
sendData();
|
sendData();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Listen on esc key press to close opened dialog box */
|
/* Listen on esc key press to close opened dialog box */
|
||||||
document.onkeydown = function(evt) {
|
document.onkeydown = function(evt) {
|
||||||
evt = evt || window.event;
|
evt = evt || window.event;
|
||||||
var isEscape = false;
|
let isEscape = false;
|
||||||
if ("key" in evt) {
|
if ("key" in evt) {
|
||||||
isEscape = (evt.key === "Escape" || evt.key === "Esc");
|
isEscape = (evt.key === "Escape" || evt.key === "Esc");
|
||||||
} else {
|
} else {
|
||||||
isEscape = (evt.keyCode === 27);
|
isEscape = (evt.keyCode === 27);
|
||||||
}
|
}
|
||||||
if (isEscape) {
|
if (isEscape) {
|
||||||
$('.dynamicEditField').each(function(e){ $(this).removeClass('open'); });
|
document.querySelectorAll('.dynamicEditField').forEach(function(elt){ elt.classList.remove('open'); });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let checkVersion = function(callback){
|
const checkVersion = function(callback){
|
||||||
jQuery.ajax({
|
fetch(LOCATION_HREF, {
|
||||||
type: 'GET',
|
method: 'GET',
|
||||||
url: LOCATION_HREF,
|
|
||||||
crossDomain: true,
|
crossDomain: true,
|
||||||
global: false,
|
}).then(res => res.text()).then(data => {
|
||||||
success: function(msg) {
|
const parser = new DOMParser();
|
||||||
let parsed = $.parseHTML(msg);
|
const doc = parser.parseFromString(data, 'text/html');
|
||||||
let current_version = $(parsed).find('#issue_lock_version').val();
|
const distant_version = doc.querySelector('#issue_lock_version').value;
|
||||||
|
if(distant_version !== document.querySelector('#issue_lock_version').value){
|
||||||
if(current_version !== $('#issue_lock_version').val()){
|
if(!document.querySelector('#content . conflict')){
|
||||||
if(!$('#content .conflict').length){
|
const msg = document.createElement('div');
|
||||||
$('#content').prepend(`
|
msg.classList.add('conflict');
|
||||||
<div class="conflict">
|
msg.innerHTML = `${_TXT_CONFLICT_TITLE}
|
||||||
${_TXT_CONFLICT_TITLE}
|
|
||||||
<div class="conflict-details">
|
<div class="conflict-details">
|
||||||
<div class="conflict-journal">
|
<div class="conflict-journal">
|
||||||
<p><a href='#' onClick="window.location.href=window.location.href">${_TXT_CONFLICT_LINK}</a> <strong>${_TXT_CONFLICT_TXT}</strong></p>
|
<p><a href='#' onClick="window.location.href=window.location.href">${_TXT_CONFLICT_LINK}</a> <strong>${_TXT_CONFLICT_TXT}</strong></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>`
|
||||||
</div>`);
|
document.querySelector('#content').insertBefore(msg, document.querySelector('#content').firstChild);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$('#content .conflict').remove();
|
if(document.querySelector('#content .conflict')) document.querySelector('#content .conflict').remove();
|
||||||
}
|
|
||||||
|
|
||||||
if(callback) callback(current_version);
|
|
||||||
}
|
}
|
||||||
|
if(callback) callback(distant_version);
|
||||||
|
}).catch(err => {
|
||||||
|
console.warn('Issue while trying to get version (avoiding conflict)');
|
||||||
|
console.log(err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,7 +312,9 @@ let checkVersionInterval = false;
|
|||||||
let setCheckVersionInterval = function(activate){
|
let setCheckVersionInterval = function(activate){
|
||||||
if(!_CONF_CHECK_ISSUE_UPDATE_CONFLICT) return false;
|
if(!_CONF_CHECK_ISSUE_UPDATE_CONFLICT) return false;
|
||||||
if(activate && !checkVersionInterval){
|
if(activate && !checkVersionInterval){
|
||||||
checkVersionInterval = window.setInterval(function(){ checkVersion(); }, 5000);
|
checkVersionInterval = window.setInterval(function(){
|
||||||
|
if(Document.visibilityState === "visible") checkVersion();
|
||||||
|
}, 5000);
|
||||||
} else {
|
} else {
|
||||||
clearInterval(checkVersionInterval);
|
clearInterval(checkVersionInterval);
|
||||||
checkVersionInterval = false;
|
checkVersionInterval = false;
|
||||||
@ -264,111 +324,96 @@ let setCheckVersionInterval = function(activate){
|
|||||||
setCheckVersionInterval(true);
|
setCheckVersionInterval(true);
|
||||||
|
|
||||||
/* Global function to perform AJAX call */
|
/* Global function to perform AJAX call */
|
||||||
var sendData = function(serialized_data){
|
let sendData = function(serialized_data){
|
||||||
|
|
||||||
let updateIssue = function(serialized_data){
|
let updateIssue = function(serialized_data){
|
||||||
setCheckVersionInterval(false);
|
setCheckVersionInterval(false);
|
||||||
var token = $("meta[name=csrf-token]").attr('content');
|
const token = document.querySelector("meta[name=csrf-token]").getAttribute('content');
|
||||||
var params = serialized_data || [];
|
let params = serialized_data || [];
|
||||||
params.push({name: '_method', value: "patch"});
|
params.push({name: '_method', value: "patch"});
|
||||||
params.push({name: 'authenticity_token', value: token})
|
params.push({name: 'authenticity_token', value: token});
|
||||||
|
|
||||||
jQuery.ajax({
|
let request = new XMLHttpRequest();
|
||||||
type: 'POST',
|
request.open('POST', LOCATION_HREF, true);
|
||||||
url: LOCATION_HREF,
|
let formData = new FormData();
|
||||||
data: $.param(params),
|
params.forEach(data => formData.append(data.name, data.value));
|
||||||
success: function(msg) {
|
|
||||||
/* get result page content (updated issue detail page with new status) */
|
|
||||||
$('#ajax-indicator').css('display', 'none');
|
|
||||||
|
|
||||||
var parsed = $.parseHTML(msg);
|
let callError = function(msg){
|
||||||
|
setCheckVersionInterval(true);
|
||||||
|
document.querySelector('#ajax-indicator').style.display = 'none';
|
||||||
|
|
||||||
var error = $(parsed).find("#errorExplanation");
|
/* error and no update, info logged into console */
|
||||||
if (error.length) {
|
console.groupCollapsed('%c -------- Error while updating the issue attribute dynamically -------- ', 'background: #ff0000; color: white; font-weight:900');
|
||||||
|
console.log("POST " + LOCATION_HREF);
|
||||||
|
console.log(msg);
|
||||||
|
console.groupEnd();
|
||||||
|
}
|
||||||
|
|
||||||
if ($('html').find("#errorExplanation").length == 0) {
|
request.onreadystatechange = function() {
|
||||||
$('.issue.details').before("<div id='errorExplanation'>" + error.html() + "</div>");
|
if (this.readyState == 4) {
|
||||||
|
if(this.status == 200) {
|
||||||
|
const parser = new DOMParser();
|
||||||
|
const doc = parser.parseFromString(this.responseText, 'text/html');
|
||||||
|
|
||||||
$([document.documentElement, document.body]).animate({
|
let error = doc.querySelector("#errorExplanation");
|
||||||
scrollTop: $("#errorExplanation").offset().top
|
|
||||||
}, 500);
|
if(error){
|
||||||
|
if (!document.querySelector("#errorExplanation")) {
|
||||||
|
let err_div = document.createElement('div');
|
||||||
|
err_div.setAttribute("id", "errorExplanation");
|
||||||
|
err_div.innerHTML = error.innerHTML;
|
||||||
|
document.querySelector('.issue.details').insertAdjacentElement("beforebegin", err_div);
|
||||||
|
|
||||||
|
location.href = "#";
|
||||||
|
location.href = "#errorExplanation";
|
||||||
} else {
|
} else {
|
||||||
$('html').find("#errorExplanation").html(error.html());
|
document.querySelector("#errorExplanation").innerHTML = error.innerHTML;
|
||||||
}
|
}
|
||||||
|
|
||||||
jQuery.ajax({
|
doc = fetch(LOCATION_HREF, {
|
||||||
type: 'GET',
|
method: 'GET',
|
||||||
url: LOCATION_HREF,
|
|
||||||
data: { "authenticity_token" : token },
|
|
||||||
crossDomain: true,
|
crossDomain: true,
|
||||||
async: false,
|
}).then(res => res.text()).then(data => {
|
||||||
success: function(msg) {
|
const parser = new DOMParser();
|
||||||
parsed = $.parseHTML(msg);
|
return parser.parseFromString(data, 'text/html');
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
/* removing error div if exists */
|
if(document.querySelector("#errorExplanation")) document.querySelector("#errorExplanation").remove();
|
||||||
$('html').find("#errorExplanation").remove();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we update form*/
|
document.querySelector('form#issue-form').innerHTML = doc.querySelector('form#issue-form').innerHTML;
|
||||||
$('form#issue-form').html( $(parsed).find('form#issue-form').html() );
|
document.querySelector('#all_attributes').innerHTML = doc.querySelector('#all_attributes').innerHTML;
|
||||||
|
document.querySelector('div.issue.details').innerHTML = doc.querySelector('div.issue.details').innerHTML;
|
||||||
|
document.querySelector('#tab-content-history').appendChild(doc.querySelector('#history .journal.has-details:last-child'));
|
||||||
|
document.querySelector('#issue_lock_version').value = doc.querySelector("#issue_lock_version").value;
|
||||||
|
|
||||||
/* we update issue properties edit block */
|
|
||||||
$('#all_attributes').html( $(parsed).find('#all_attributes').html() );
|
|
||||||
|
|
||||||
/* we update the details block */
|
|
||||||
$('div.issue.details').html( $(parsed).find('div.issue.details').html() );
|
|
||||||
|
|
||||||
/* we update the history list */
|
|
||||||
$('#tab-content-history').append($(parsed).find('#history .journal.has-details:last-child'));
|
|
||||||
|
|
||||||
/* Update lock version with last one */
|
|
||||||
$('#issue_lock_version').val($(parsed).find("#issue_lock_version").val());
|
|
||||||
|
|
||||||
/* we init edit fields */
|
|
||||||
cloneEditForm();
|
cloneEditForm();
|
||||||
|
|
||||||
//set datepicker fallback for input type date
|
//set datepicker fallback for input type date
|
||||||
if (
|
if (
|
||||||
$('body').find('input[type=date]').length &&
|
document.querySelector('input[type=date]') &&
|
||||||
$('body').find('input[type=date]').datepickerFallback instanceof Function &&
|
$('body').find('input[type=date]').datepickerFallback instanceof Function &&
|
||||||
typeof datepickerOptions !== 'undefined'
|
typeof datepickerOptions !== 'undefined'
|
||||||
) {
|
) {
|
||||||
$('body').find('input[type=date]').datepickerFallback(datepickerOptions);
|
$('body').find('input[type=date]').datepickerFallback(datepickerOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
setCSRFTokenInput($(parsed).find('input[name="authenticity_token"]').val());
|
setCSRFTokenInput(doc.querySelector('input[name="authenticity_token"]').value);
|
||||||
updateCSRFToken($(parsed).find('input[name="authenticity_token"]').val());
|
updateCSRFToken(doc.querySelector('input[name="authenticity_token"]').value);
|
||||||
setCheckVersionInterval(true);
|
setCheckVersionInterval(true);
|
||||||
},
|
} else {
|
||||||
error: function(xhr, msg, error) {
|
callError(this.status);
|
||||||
setCheckVersionInterval(true);
|
}
|
||||||
$('#ajax-indicator').css('display', 'none');
|
|
||||||
|
|
||||||
/* error and no update, info logged into console */
|
|
||||||
console.groupCollapsed('%c -------- Error while updating the issue attribute dynamically -------- ', 'background: #ff0000; color: white; font-weight:900');
|
|
||||||
console.log("POST " + LOCATION_HREF);
|
|
||||||
console.table(params);
|
|
||||||
console.log('%c xhr data: ', 'background: black; color: white;');
|
|
||||||
console.log(xhr);
|
|
||||||
console.log('%c msg data: ', 'background: black; color: white;');
|
|
||||||
console.log(msg);
|
|
||||||
console.log('%c error data: ', 'background: black; color: white;');;
|
|
||||||
console.log(error);
|
|
||||||
console.groupEnd();
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
request.send(formData);
|
||||||
|
}
|
||||||
|
|
||||||
if(_CONF_CHECK_ISSUE_UPDATE_CONFLICT){
|
if(_CONF_CHECK_ISSUE_UPDATE_CONFLICT){
|
||||||
checkVersion(function(current_version){
|
checkVersion(function(distant_version){
|
||||||
if(current_version == $('#issue_lock_version').val()){
|
if(distant_version == document.querySelector('#issue_lock_version').value){
|
||||||
updateIssue(serialized_data);
|
updateIssue(serialized_data);
|
||||||
} else {
|
} else {
|
||||||
$([document.documentElement, document.body]).animate({
|
|
||||||
scrollTop: $("#content .conflict").offset().top
|
|
||||||
}, 500);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -41,6 +41,7 @@ body.controller-issues.action-show div.issue.details .iconEdit {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
transition: opacity .3s ease-in;
|
transition: opacity .3s ease-in;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
margin-left: 1ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.controller-issues.action-show div.issue.details.showPencil .iconEdit,
|
body.controller-issues.action-show div.issue.details.showPencil .iconEdit,
|
||||||
@ -108,6 +109,7 @@ body.controller-issues.action-show .dynamicEditField select {
|
|||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.controller-issues.action-show .dynamicEditField select[multiple="multiple"] {
|
body.controller-issues.action-show .dynamicEditField select[multiple="multiple"] {
|
||||||
@ -143,6 +145,7 @@ body.controller-issues.action-show .dynamicEditField select {
|
|||||||
body.controller-issues.action-show .dynamicEditField .check_box_group {
|
body.controller-issues.action-show .dynamicEditField .check_box_group {
|
||||||
border: 0px !important;
|
border: 0px !important;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
width:100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MOBILE MEDIAQUERY */
|
/* MOBILE MEDIAQUERY */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user