From 8bf5dedd80b4972e9f454772e0ce90b26efd8b21 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Thu, 9 Aug 2018 11:15:23 +0200 Subject: [PATCH 1/2] Ruby helpers for js.erb responses --- app/assets/stylesheets/application.scss | 3 +- app/helpers/application_helper.rb | 36 +++++++++++++++++-- .../admin/pieces_justificatives/show.js.erb | 6 ++-- app/views/admin/procedures/transfer.js.erb | 4 +-- app/views/admin/types_de_champ/show.js.erb | 8 ++--- app/views/champs/siret/index.js.erb | 13 +++---- app/views/invites/create.js.erb | 8 ++--- app/views/layouts/_flash_messages.html.haml | 5 +-- app/views/new_user/feedbacks/create.js.erb | 6 ++-- 9 files changed, 53 insertions(+), 36 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index aa4da2aa3..53796fe13 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -178,7 +178,8 @@ div.pagination { } .alert.alert-success.move-up, -.alert.alert-danger.siret { +.alert.alert-danger.siret, +.alert.sticky { position: fixed; top: 0px; left: 0; diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 46bae9be5..02b4f0144 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -7,13 +7,43 @@ module ApplicationHelper end end - def flash_class(level) + def flash_class(level, sticky = false) case level - when "notice" then "alert-success" - when "alert" then "alert-danger" + when "notice" then "alert-success#{sticky ? ' sticky' : ''}" + when "alert" then "alert-danger#{sticky ? ' sticky' : ''}" end end + def render_to_element(selector, partial:, outer: false, locals: {}) + method = outer ? 'outerHTML' : 'innerHTML' + html = escape_javascript(render partial: partial, locals: locals) + # rubocop:disable Rails/OutputSafety + raw("document.querySelector('#{selector}').#{method} = \"#{html}\";") + # rubocop:enable Rails/OutputSafety + end + + def render_flash(timeout: false, sticky: false) + if flash.any? + html = render_to_element('#flash_messages', partial: 'layouts/flash_messages', locals: { sticky: sticky }, outer: true) + flash.clear + if timeout + html += remove_element('#flash_messages', timeout: timeout, inner: true) + end + html + end + end + + def remove_element(selector, timeout: 0, inner: false) + script = "(function() {"; + script << "var el = document.querySelector('#{selector}');" + method = (inner ? "el.innerHTML = ''" : "el.parentNode.removeChild(el)") + script << "setTimeout(function() { #{method}; }, #{timeout});"; + script << "})();" + # rubocop:disable Rails/OutputSafety + raw(script); + # rubocop:enable Rails/OutputSafety + end + def current_email current_user&.email || current_gestionnaire&.email || diff --git a/app/views/admin/pieces_justificatives/show.js.erb b/app/views/admin/pieces_justificatives/show.js.erb index d89882b53..32d4bf4d3 100644 --- a/app/views/admin/pieces_justificatives/show.js.erb +++ b/app/views/admin/pieces_justificatives/show.js.erb @@ -1,4 +1,2 @@ -<% flash.each do |type, message| %> -$("#flash_message").html("
<%= sanitize(message) %>
").children().fadeOut(5000) -<% end %> -$('#piece_justificative_form').html("<%= escape_javascript(render partial: 'form', locals: { procedure: @procedure } ) %>"); +<%= render_flash(timeout: 3000, sticky: true) %> +<%= render_to_element('#piece_justificative_form', partial: 'admin/pieces_justificatives/form', locals: { procedure: @procedure }) %> diff --git a/app/views/admin/procedures/transfer.js.erb b/app/views/admin/procedures/transfer.js.erb index a23b011f9..7dbdff4fe 100644 --- a/app/views/admin/procedures/transfer.js.erb +++ b/app/views/admin/procedures/transfer.js.erb @@ -1,9 +1,7 @@ <%- if response.status == 404 %> transfer_errors_message(true); <%- else %> - $("#main-container").prepend("
"); - $("#flash_message").prepend("
<%= sanitize(flash.notice) %>
"); - <% flash.clear %> + <%= render_flash %> transfer_errors_message(false); $("#email_admin").val(''); diff --git a/app/views/admin/types_de_champ/show.js.erb b/app/views/admin/types_de_champ/show.js.erb index c76ba0c80..b0001f62f 100644 --- a/app/views/admin/types_de_champ/show.js.erb +++ b/app/views/admin/types_de_champ/show.js.erb @@ -1,5 +1,3 @@ -<% flash.each do |type, message| %> -$("#flash_message").html("
<%= sanitize(message) %>
").children().fadeOut(5000) -<% end %> -$('#liste-champ').html("<%= escape_javascript(render partial: 'admin/types_de_champ/form', locals: { procedure: @procedure, types_de_champ: @types_de_champ } ) %>"); -on_change_type_de_champ_select (); +<%= render_flash(timeout: 3000, sticky: true) %> +<%= render_to_element('#liste-champ', partial: 'admin/types_de_champ/form', locals: { procedure: @procedure, types_de_champ: @types_de_champ }) %> +on_change_type_de_champ_select(); diff --git a/app/views/champs/siret/index.js.erb b/app/views/champs/siret/index.js.erb index 4f13c1678..3b74d6a35 100644 --- a/app/views/champs/siret/index.js.erb +++ b/app/views/champs/siret/index.js.erb @@ -1,8 +1,5 @@ -(function() { - <% if @blank || @error %> - var html = "<%= escape_javascript(render partial: 'shared/champs/siret/delete_etablissement', locals: { message: @error, position: @champ.order_place, etablissement: @etablissement }) %>"; - <% else %> - var html = "<%= escape_javascript(render partial: 'shared/champs/siret/etablissement', locals: { position: @champ.order_place, etablissement: @etablissement }) %>"; - <% end %> - document.querySelector("#etablissement-for-<%= @champ.id %>").innerHTML = html; -})(); +<% if @blank || @error %> + <%= render_to_element("#etablissement-for-#{@champ.id}", partial: 'shared/champs/siret/delete_etablissement', locals: { message: @error, position: @champ.order_place, etablissement: @etablissement }) %> +<% else %> + <%= render_to_element("#etablissement-for-#{@champ.id}", partial: 'shared/champs/siret/etablissement', locals: { position: @champ.order_place, etablissement: @etablissement }) %> +<% end %> diff --git a/app/views/invites/create.js.erb b/app/views/invites/create.js.erb index 19c233149..c73db9f67 100644 --- a/app/views/invites/create.js.erb +++ b/app/views/invites/create.js.erb @@ -1,6 +1,2 @@ -var formView = "<%= escape_javascript(render partial: 'invites/form', locals: { dossier: @dossier }) %>"; -document.querySelector("#invites-form").outerHTML = formView; - -var flashMessagesView = "<%= escape_javascript(render partial: 'layouts/flash_messages') %>"; -document.querySelector("#flash_messages").outerHTML = flashMessagesView; -<% flash.clear %> +<%= render_to_element('#invites-form', partial: 'invites/form', locals: { dossier: @dossier }, outer: true) %> +<%= render_flash %> diff --git a/app/views/layouts/_flash_messages.html.haml b/app/views/layouts/_flash_messages.html.haml index 5f4b14ef3..a365b07f6 100644 --- a/app/views/layouts/_flash_messages.html.haml +++ b/app/views/layouts/_flash_messages.html.haml @@ -2,11 +2,12 @@ - if flash.any? #flash_message.center - flash.each do |key, value| + - sticky = defined?(sticky) ? sticky : false - if value.class == Array - .alert{ class: flash_class(key) } + .alert{ class: flash_class(key, sticky) } - value.each do |message| = sanitize(message) %br - else - .alert{ class: flash_class(key) } + .alert{ class: flash_class(key, sticky) } = sanitize(value) diff --git a/app/views/new_user/feedbacks/create.js.erb b/app/views/new_user/feedbacks/create.js.erb index 1e3fea19f..de4c271b3 100644 --- a/app/views/new_user/feedbacks/create.js.erb +++ b/app/views/new_user/feedbacks/create.js.erb @@ -1,4 +1,2 @@ -document.querySelector('#user-satisfaction').innerHTML = ''; -var flashMessagesView = "<%= escape_javascript(render partial: 'layouts/flash_messages') %>"; -document.querySelector("#flash_messages").outerHTML = flashMessagesView; -<% flash.clear %> \ No newline at end of file +<%= remove_element('#user-satisfaction') %> +<%= render_flash %> From ea68c75361e86e9c9ed8b9e56f10e94e2fdcedc8 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Thu, 9 Aug 2018 11:19:56 +0200 Subject: [PATCH 2/2] Use delegated events instead of local handlers --- app/assets/javascripts/old_design/admin.js | 89 +++++++++---------- .../old_design/dossiers_list_link.js | 16 ++-- app/views/admin/procedures/index.js.erb | 1 - app/views/admin/types_de_champ/show.js.erb | 1 - 4 files changed, 48 insertions(+), 59 deletions(-) diff --git a/app/assets/javascripts/old_design/admin.js b/app/assets/javascripts/old_design/admin.js index 981032ec3..5b7af468e 100644 --- a/app/assets/javascripts/old_design/admin.js +++ b/app/assets/javascripts/old_design/admin.js @@ -1,52 +1,47 @@ -$(document).on('turbolinks:load', init_admin); +$(document).on('click', '.delete', function() { + $(this).hide(); + $(this) + .closest('td') + .find('.confirm') + .show(); +}); -function init_admin(){ - destroy_action(); - on_change_type_de_champ_select(); -} +$(document).on('click', '.cancel', function() { + $(this) + .closest('td') + .find('.delete') + .show(); + $(this) + .closest('td') + .find('.confirm') + .hide(); +}); -function destroy_action(){ - $(".delete").on('click', function(){ - $(this).hide(); - $(this).closest('td').find(".confirm").show(); - }); +$(document).on('change', 'select.form-control.type-champ', function() { + var parent = $(this) + .parent() + .parent(); - $(".cancel").on('click', function(){ - $(this).closest('td').find(".delete").show(); - $(this).closest('td').find(".confirm").hide(); - }); + parent.removeClass('header-section'); + parent.children('.drop-down-list').removeClass('show-inline'); + parent.children('.pj-template').removeClass('show-inline'); - $("#liste-gestionnaire #libelle").on('click', function(){ - setTimeout(destroy_action, 500); - }); -} + $('.mandatory', parent).show(); -function on_change_type_de_champ_select (){ - $("select.form-control.type-champ").on('change', function(e){ - - parent = $(this).parent().parent(); - - parent.removeClass('header-section'); - parent.children(".drop-down-list").removeClass('show-inline'); - parent.children(".pj-template").removeClass('show-inline'); - - $('.mandatory', parent).show(); - - switch(this.value){ - case 'header_section': - parent.addClass('header-section'); - break; - case 'drop_down_list': - case 'multiple_drop_down_list': - case 'linked_drop_down_list': - parent.children(".drop-down-list").addClass('show-inline'); - break; - case 'piece_justificative': - parent.children(".pj-template").addClass('show-inline'); - break; - case 'explication': - $('.mandatory', parent).hide(); - break; - } - }); -} + switch (this.value) { + case 'header_section': + parent.addClass('header-section'); + break; + case 'drop_down_list': + case 'multiple_drop_down_list': + case 'linked_drop_down_list': + parent.children('.drop-down-list').addClass('show-inline'); + break; + case 'piece_justificative': + parent.children('.pj-template').addClass('show-inline'); + break; + case 'explication': + $('.mandatory', parent).hide(); + break; + } +}); diff --git a/app/assets/javascripts/old_design/dossiers_list_link.js b/app/assets/javascripts/old_design/dossiers_list_link.js index 18b167ace..70425251a 100644 --- a/app/assets/javascripts/old_design/dossiers_list_link.js +++ b/app/assets/javascripts/old_design/dossiers_list_link.js @@ -1,10 +1,6 @@ -$(document).on('turbolinks:load', link_init); - -function link_init() { - $('#dossiers-list tr').on('click', function(event) { - var href = $(this).data('href'); - if (href && event.target.tagName !== 'A') { - location.href = href; - } - }); -} +$(document).on('click', '#dossiers-list tr', function(event) { + var href = $(this).data('href'); + if (href && event.target.tagName !== 'A') { + location.href = href; + } +}); diff --git a/app/views/admin/procedures/index.js.erb b/app/views/admin/procedures/index.js.erb index 232965d99..b2e0bdc6a 100644 --- a/app/views/admin/procedures/index.js.erb +++ b/app/views/admin/procedures/index.js.erb @@ -1,2 +1 @@ <%= smart_listing_update :procedures %> -link_init(); \ No newline at end of file diff --git a/app/views/admin/types_de_champ/show.js.erb b/app/views/admin/types_de_champ/show.js.erb index b0001f62f..5c22f8080 100644 --- a/app/views/admin/types_de_champ/show.js.erb +++ b/app/views/admin/types_de_champ/show.js.erb @@ -1,3 +1,2 @@ <%= render_flash(timeout: 3000, sticky: true) %> <%= render_to_element('#liste-champ', partial: 'admin/types_de_champ/form', locals: { procedure: @procedure, types_de_champ: @types_de_champ }) %> -on_change_type_de_champ_select();