mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-13 16:45:18 +08:00
prevent to duplicate new step [fixes SCI-1280]
This commit is contained in:
parent
18e11fde59
commit
b21923cf98
2 changed files with 624 additions and 585 deletions
|
@ -4,8 +4,11 @@
|
||||||
//= require assets
|
//= require assets
|
||||||
//= require comments
|
//= require comments
|
||||||
|
|
||||||
// Sets callbacks for toggling checkboxes
|
(function(global) {
|
||||||
function applyCheckboxCallBack() {
|
'use strict';
|
||||||
|
|
||||||
|
// Sets callbacks for toggling checkboxes
|
||||||
|
function applyCheckboxCallBack() {
|
||||||
$("[data-action='check-item']").on('click', function(e){
|
$("[data-action='check-item']").on('click', function(e){
|
||||||
var checkboxitem = $(this).find("input");
|
var checkboxitem = $(this).find("input");
|
||||||
var checked = checkboxitem.is(":checked");
|
var checked = checkboxitem.is(":checked");
|
||||||
|
@ -22,10 +25,10 @@ function applyCheckboxCallBack() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Complete mymodule
|
// Complete mymodule
|
||||||
function complete_my_module_actions() {
|
function complete_my_module_actions() {
|
||||||
var modal = $('#completed-task-modal');
|
var modal = $('#completed-task-modal');
|
||||||
|
|
||||||
modal.find('[data-action="complete"]')
|
modal.find('[data-action="complete"]')
|
||||||
|
@ -54,10 +57,10 @@ function complete_my_module_actions() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets callback for completing/uncompleting step
|
// Sets callback for completing/uncompleting step
|
||||||
function applyStepCompletedCallBack() {
|
function applyStepCompletedCallBack() {
|
||||||
// First, remove old event handlers, as we use turbolinks
|
// First, remove old event handlers, as we use turbolinks
|
||||||
$("[data-action='complete-step'], [data-action='uncomplete-step']")
|
$("[data-action='complete-step'], [data-action='uncomplete-step']")
|
||||||
.off().on('click', function(e){
|
.off().on('click', function(e){
|
||||||
|
@ -99,9 +102,9 @@ function applyStepCompletedCallBack() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyCancelCallBack() {
|
function applyCancelCallBack() {
|
||||||
//Click on cancel button
|
//Click on cancel button
|
||||||
$("[data-action='cancel-edit']")
|
$("[data-action='cancel-edit']")
|
||||||
.on("ajax:success", function(e, data) {
|
.on("ajax:success", function(e, data) {
|
||||||
|
@ -126,10 +129,10 @@ function applyCancelCallBack() {
|
||||||
.on("ajax:error", function(e, xhr, status, error) {
|
.on("ajax:error", function(e, xhr, status, error) {
|
||||||
// TODO: error handling
|
// TODO: error handling
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set callback for click on edit button
|
// Set callback for click on edit button
|
||||||
function applyEditCallBack() {
|
function applyEditCallBack() {
|
||||||
$("[data-action='edit-step']")
|
$("[data-action='edit-step']")
|
||||||
.on("ajax:success", function(e, data) {
|
.on("ajax:success", function(e, data) {
|
||||||
var $step = $(this).closest(".step");
|
var $step = $(this).closest(".step");
|
||||||
|
@ -155,10 +158,10 @@ function applyEditCallBack() {
|
||||||
$("#step_name").focus();
|
$("#step_name").focus();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set callback for click on edit button
|
// Set callback for click on edit button
|
||||||
function applyMoveStepCallBack() {
|
function applyMoveStepCallBack() {
|
||||||
$("[data-action='move-step']").off("ajax:success");
|
$("[data-action='move-step']").off("ajax:success");
|
||||||
$("[data-action='move-step']")
|
$("[data-action='move-step']")
|
||||||
.on("ajax:success", function(e, data) {
|
.on("ajax:success", function(e, data) {
|
||||||
|
@ -184,9 +187,9 @@ function applyMoveStepCallBack() {
|
||||||
$("html, body").animate({ scrollTop: $step.offset().top - window.innerHeight / 2 });
|
$("html, body").animate({ scrollTop: $step.offset().top - window.innerHeight / 2 });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyCollapseLinkCallBack() {
|
function applyCollapseLinkCallBack() {
|
||||||
$(".step-panel-collapse-link")
|
$(".step-panel-collapse-link")
|
||||||
.on("ajax:success", function() {
|
.on("ajax:success", function() {
|
||||||
var collapseIcon = $(this).find(".collapse-step-icon");
|
var collapseIcon = $(this).find(".collapse-step-icon");
|
||||||
|
@ -196,9 +199,9 @@ function applyCollapseLinkCallBack() {
|
||||||
collapseIcon.toggleClass("glyphicon-collapse-down", collapsed);
|
collapseIcon.toggleClass("glyphicon-collapse-down", collapsed);
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function formCallback($form) {
|
function formCallback($form) {
|
||||||
$form
|
$form
|
||||||
.on("fields_added.nested_form_fields", function(e, param) {
|
.on("fields_added.nested_form_fields", function(e, param) {
|
||||||
if (param.object_class == "table") {
|
if (param.object_class == "table") {
|
||||||
|
@ -228,10 +231,10 @@ function formCallback($form) {
|
||||||
}, 1000);
|
}, 1000);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init ajax success/error for edit form
|
// Init ajax success/error for edit form
|
||||||
function formEditAjax($form) {
|
function formEditAjax($form) {
|
||||||
$form
|
$form
|
||||||
.on("ajax:beforeSend", function () {
|
.on("ajax:beforeSend", function () {
|
||||||
$(".nested_step_checklists ul").each(function () {
|
$(".nested_step_checklists ul").each(function () {
|
||||||
|
@ -274,9 +277,9 @@ function formEditAjax($form) {
|
||||||
renderTable($(this));
|
renderTable($(this));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function formNewAjax($form) {
|
function formNewAjax($form) {
|
||||||
$form
|
$form
|
||||||
.on("ajax:beforeSend", function () {
|
.on("ajax:beforeSend", function () {
|
||||||
$(".nested_step_checklists ul").each(function () {
|
$(".nested_step_checklists ul").each(function () {
|
||||||
|
@ -317,9 +320,9 @@ function formNewAjax($form) {
|
||||||
TinyMCE.destroyAll();
|
TinyMCE.destroyAll();
|
||||||
SmartAnnotation.preventPropagation('.atwho-user-popover');
|
SmartAnnotation.preventPropagation('.atwho-user-popover');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleButtons(show) {
|
function toggleButtons(show) {
|
||||||
if (show) {
|
if (show) {
|
||||||
$("[data-action='new-step']").show();
|
$("[data-action='new-step']").show();
|
||||||
$("[data-action='edit-step']").show();
|
$("[data-action='edit-step']").show();
|
||||||
|
@ -338,10 +341,10 @@ function toggleButtons(show) {
|
||||||
// Also hide "no steps" label if no steps are present
|
// Also hide "no steps" label if no steps are present
|
||||||
$("[data-role='no-steps-text']").hide();
|
$("[data-role='no-steps-text']").hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates handsontable where needed
|
// Creates handsontable where needed
|
||||||
function initHandsOnTable(root) {
|
function initHandsOnTable(root) {
|
||||||
root.find("[data-role='hot-table']").each(function() {
|
root.find("[data-role='hot-table']").each(function() {
|
||||||
var $container = $(this).find("[data-role='step-hot-table']");
|
var $container = $(this).find("[data-role='step-hot-table']");
|
||||||
var contents = $(this).find('.hot-contents');
|
var contents = $(this).find('.hot-contents');
|
||||||
|
@ -371,10 +374,10 @@ function initHandsOnTable(root) {
|
||||||
hot.loadData(data.data);
|
hot.loadData(data.data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init handsontable which can be edited
|
// Init handsontable which can be edited
|
||||||
function initEditableHandsOnTable(root) {
|
function initEditableHandsOnTable(root) {
|
||||||
root.find("[data-role='editable-table']").each(function() {
|
root.find("[data-role='editable-table']").each(function() {
|
||||||
var $container = $(this).find(".hot");
|
var $container = $(this).find(".hot");
|
||||||
|
|
||||||
|
@ -415,25 +418,31 @@ function initEditableHandsOnTable(root) {
|
||||||
renderTable($(this));
|
renderTable($(this));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function applyCancelOnNew() {
|
||||||
|
$("[data-action='cancel-new']").click(function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
event.stopImmediatePropagation();
|
||||||
|
|
||||||
function applyCancelOnNew() {
|
|
||||||
$("[data-action='cancel-new']").click(function() {
|
|
||||||
var $form = $(this).closest("form");
|
var $form = $(this).closest("form");
|
||||||
$form.parent().remove();
|
$form.parent().remove().promise().done(function() {
|
||||||
|
newStepHandler();
|
||||||
|
});
|
||||||
toggleButtons(true);
|
toggleButtons(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initDeleteStep(){
|
function initDeleteStep(){
|
||||||
$("[data-action='delete-step']").on("confirm:complete", function (e, answer) {
|
$("[data-action='delete-step']").on("confirm:complete", function (e, answer) {
|
||||||
if (answer) {
|
if (answer) {
|
||||||
animateLoading();
|
animateLoading();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initCallBacks() {
|
function initCallBacks() {
|
||||||
applyCheckboxCallBack();
|
applyCheckboxCallBack();
|
||||||
applyStepCompletedCallBack();
|
applyStepCompletedCallBack();
|
||||||
applyEditCallBack();
|
applyEditCallBack();
|
||||||
|
@ -441,13 +450,13 @@ function initCallBacks() {
|
||||||
applyCollapseLinkCallBack();
|
applyCollapseLinkCallBack();
|
||||||
initDeleteStep();
|
initDeleteStep();
|
||||||
TinyMCE.highlight();
|
TinyMCE.highlight();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Correction for sorting with "Sortable.min" JS library to work correctly with
|
* Correction for sorting with "Sortable.min" JS library to work correctly with
|
||||||
* "nested_form_fields" gem.
|
* "nested_form_fields" gem.
|
||||||
*/
|
*/
|
||||||
function reorderCheckboxData(checkboxUl) {
|
function reorderCheckboxData(checkboxUl) {
|
||||||
// Make sure checkbox item insertion script is always at the bottom of "ul"
|
// Make sure checkbox item insertion script is always at the bottom of "ul"
|
||||||
// tag, otherwise item will not be inserted at bottom
|
// tag, otherwise item will not be inserted at bottom
|
||||||
if(!$(checkboxUl).children().last().is('script')) {
|
if(!$(checkboxUl).children().last().is('script')) {
|
||||||
|
@ -506,9 +515,9 @@ function reorderCheckboxData(checkboxUl) {
|
||||||
$destroyInput.attr("name", destroyName);
|
$destroyInput.attr("name", destroyName);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function enableCheckboxSorting(el) {
|
function enableCheckboxSorting(el) {
|
||||||
Sortable.create(el, {
|
Sortable.create(el, {
|
||||||
draggable: 'fieldset',
|
draggable: 'fieldset',
|
||||||
handle: '.glyphicon-chevron-right',
|
handle: '.glyphicon-chevron-right',
|
||||||
|
@ -516,9 +525,9 @@ function enableCheckboxSorting(el) {
|
||||||
reorderCheckboxData(el);
|
reorderCheckboxData(el);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initializeCheckboxSorting() {
|
function initializeCheckboxSorting() {
|
||||||
var el = $("#new-step-checklists a[data-association-path=step_checklists]");
|
var el = $("#new-step-checklists a[data-association-path=step_checklists]");
|
||||||
|
|
||||||
el.click(function () {
|
el.click(function () {
|
||||||
|
@ -529,33 +538,57 @@ function initializeCheckboxSorting() {
|
||||||
enableCheckboxSorting(list.get(0));
|
enableCheckboxSorting(list.get(0));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// New step AJAX
|
// New step AJAX
|
||||||
$("[data-action='new-step']").on("ajax:success", function(e, data) {
|
function newStepHandler() {
|
||||||
|
$("[data-action='new-step']").off().on('click', function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
event.stopImmediatePropagation();
|
||||||
|
var $btn = $(this);
|
||||||
|
$btn.off();
|
||||||
|
animateSpinner(null, true);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: $btn.data('href'),
|
||||||
|
method: 'GET',
|
||||||
|
success: function(data) {
|
||||||
var $form = $(data.html);
|
var $form = $(data.html);
|
||||||
$("#steps").append($form);
|
$('#steps').append($form).promise().done(function() {
|
||||||
|
animateSpinner(null, false);
|
||||||
// Scroll to bottom
|
// Scroll to bottom
|
||||||
$("html, body").animate({ scrollTop: $(document).height()-$(window).height() });
|
$('html, body').animate({
|
||||||
|
scrollTop: $(document).height() - $(window).height()
|
||||||
|
});
|
||||||
formCallback($form);
|
formCallback($form);
|
||||||
formNewAjax($form);
|
formNewAjax($form);
|
||||||
applyCancelOnNew();
|
applyCancelOnNew();
|
||||||
toggleButtons(false);
|
toggleButtons(false);
|
||||||
initializeCheckboxSorting();
|
initializeCheckboxSorting();
|
||||||
|
|
||||||
$("#step_name").focus();
|
$('#step_name').focus();
|
||||||
$("#new-step-main-tab a").on("shown.bs.tab", function() {
|
$('#new-step-main-tab a').on('shown.bs.tab', function() {
|
||||||
$("#step_name").focus();
|
$('#step_name').focus();
|
||||||
});
|
});
|
||||||
|
|
||||||
TinyMCE.refresh();
|
TinyMCE.refresh();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
newStepHandler();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Needed because server-side validation failure clears locations of
|
||||||
|
// files to be uploaded and checklist's items etc. Also user
|
||||||
|
// experience is improved
|
||||||
|
global.processStep = function processStep(ev, editMode) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
|
||||||
// Needed because server-side validation failure clears locations of
|
|
||||||
// files to be uploaded and checklist's items etc. Also user
|
|
||||||
// experience is improved
|
|
||||||
function processStep(ev, editMode) {
|
|
||||||
var $form = $(ev.target.form);
|
var $form = $(ev.target.form);
|
||||||
$form.clearFormErrors();
|
$form.clearFormErrors();
|
||||||
$form.removeBlankFileForms();
|
$form.removeBlankFileForms();
|
||||||
|
@ -574,11 +607,12 @@ function processStep(ev, editMode) {
|
||||||
if (filesValid && checklistsValid && nameValid && descriptionValid) {
|
if (filesValid && checklistsValid && nameValid && descriptionValid) {
|
||||||
// Local file uploading
|
// Local file uploading
|
||||||
animateSpinner();
|
animateSpinner();
|
||||||
|
newStepHandler();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Expand all steps
|
// Expand all steps
|
||||||
function expandAllSteps() {
|
function expandAllSteps() {
|
||||||
$('.step .panel-collapse').collapse('show');
|
$('.step .panel-collapse').collapse('show');
|
||||||
$(document).find("[data-role='step-hot-table']").each(function() {
|
$(document).find("[data-role='step-hot-table']").each(function() {
|
||||||
renderTable($(this));
|
renderTable($(this));
|
||||||
|
@ -587,9 +621,9 @@ function expandAllSteps() {
|
||||||
$(this).addClass("glyphicon-collapse-up");
|
$(this).addClass("glyphicon-collapse-up");
|
||||||
$(this).removeClass("glyphicon-collapse-down");
|
$(this).removeClass("glyphicon-collapse-down");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function expandStep(step) {
|
function expandStep(step) {
|
||||||
$('.panel-collapse', step).collapse('show');
|
$('.panel-collapse', step).collapse('show');
|
||||||
$(step).find("span.collapse-step-icon")
|
$(step).find("span.collapse-step-icon")
|
||||||
.addClass("glyphicon-collapse-up")
|
.addClass("glyphicon-collapse-up")
|
||||||
|
@ -597,24 +631,24 @@ function expandStep(step) {
|
||||||
$(step).find("div.step-result-hot-table").each(function() {
|
$(step).find("div.step-result-hot-table").each(function() {
|
||||||
renderTable($(this));
|
renderTable($(this));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderTable(table) {
|
function renderTable(table) {
|
||||||
$(table).handsontable("render");
|
$(table).handsontable("render");
|
||||||
// Yet another dirty hack to solve HandsOnTable problems
|
// Yet another dirty hack to solve HandsOnTable problems
|
||||||
if (parseInt($(table).css("height"), 10) < parseInt($(table).css("max-height"), 10) - 30) {
|
if (parseInt($(table).css("height"), 10) < parseInt($(table).css("max-height"), 10) - 30) {
|
||||||
$(table).find(".ht_master .wtHolder").css("height", "100%");
|
$(table).find(".ht_master .wtHolder").css("height", "100%");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function initStepsComments() {
|
function initStepsComments() {
|
||||||
Comments.initialize();
|
Comments.initialize();
|
||||||
Comments.initCommentOptions("ul.content-comments");
|
Comments.initCommentOptions("ul.content-comments");
|
||||||
Comments.initEditComments("#steps");
|
Comments.initEditComments("#steps");
|
||||||
Comments.initDeleteComments("#steps");
|
Comments.initDeleteComments("#steps");
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
// On init
|
// On init
|
||||||
initCallBacks();
|
initCallBacks();
|
||||||
initHandsOnTable($(document));
|
initHandsOnTable($(document));
|
||||||
|
@ -624,7 +658,7 @@ $(document).ready(function() {
|
||||||
initPreviewModal();
|
initPreviewModal();
|
||||||
TinyMCE.highlight();
|
TinyMCE.highlight();
|
||||||
SmartAnnotation.preventPropagation('.atwho-user-popover');
|
SmartAnnotation.preventPropagation('.atwho-user-popover');
|
||||||
|
newStepHandler();
|
||||||
$(function () {
|
$(function () {
|
||||||
|
|
||||||
$("[data-action='collapse-steps']").click(function () {
|
$("[data-action='collapse-steps']").click(function () {
|
||||||
|
@ -637,4 +671,6 @@ $(document).ready(function() {
|
||||||
|
|
||||||
$("[data-action='expand-steps']").click(expandAllSteps);
|
$("[data-action='expand-steps']").click(expandAllSteps);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
})(window);
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="pull-right" style="margin: 20px 15px 0 0;">
|
<div class="pull-right" style="margin: 20px 15px 0 0;">
|
||||||
<% if can_create_step_in_protocol(@protocol) %>
|
<% if can_create_step_in_protocol(@protocol) %>
|
||||||
<a class="btn btn-primary" data-action="new-step" href="<%= new_protocol_step_path(protocol_id: @protocol.id, format: :json) %>" data-remote="true">
|
<a href="#"
|
||||||
|
class="btn btn-primary"
|
||||||
|
data-action="new-step"
|
||||||
|
data-href="<%= new_protocol_step_path(protocol_id: @protocol.id, format: :json) %>">
|
||||||
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
|
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
|
||||||
<span class="hidden-xs"><%=t "protocols.steps.new_step" %></span>
|
<span class="hidden-xs"><%=t "protocols.steps.new_step" %></span>
|
||||||
</a>
|
</a>
|
||||||
|
|
Loading…
Add table
Reference in a new issue