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 %>