Rails how to render two different modals for destroy action - javascript

I want to add confirmation modal when bank manager has to delete bank_employee without clients bank_employee.users = nil. If bank_employee has clients I want to render different modal - destroy_confirmation_modal. How to do it in a proper way? Where should I put if condition?
code snipped of
edit.html.erb
<div class="row">
<div class="col-sm-12 col-md-12 col-xs-12 text-center bank-employee__button-wrapper bank-employees-users-registration__registrations-submit--wrapper">
<%= t('.delete') %>
<%= f.submit t('.submit'), id: "formSubmit", class: "bank-employee__button bank-employee__button-submit"%>
</div>
</div>
<% end %> // this `end` comes from `form_for`
<%= button_to "", bank_employee_path(#bank_employee), method: :delete, form: {id: "bankEmployeeDestroyForm" }, class: "bank-employee__button-destroy" %>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 text-center">
<%= link_to bank_employees_path do %>
<span class="bank-employee__back-button">
<%= image_tag "icon_back.svg", alt: "Back icon", class: ""%>
<%= t('.back') %>
</span>
<% end %>
</div>
</div>
</div>
<%= render "destroy_confirmation_modal" %>
I don't think I should update my controller method but maybe I'm wrong?
controller.rb
def destroy
authorize current_bank_employee
#bank_employee = find_bank_employee(params[:id])
if #bank_employee.users.any? && associated_bank_employees.present?
reassign_users_and_notify_bank_employee
elsif #bank_employee.users.any?
render :edit
else
#bank_employee.destroy
render :destroy_notice, locals: { old_bank_employee: #bank_employee, assigned: false }
end
end
EDIT
my routes.rb
resources :bank_employees, except: [:show], concerns: [:with_datatable] do
member do
get :confirm
end
end
rails routes showed me this path as confirm_bank_employee so I've changed if condition as follow
<% if #bank_employee.users.empty? %>
<%= button_to "", confirm_bank_employee_path(#bank_employee), form: {id: "bankEmployeeDestroyForm" }, class: "bank-employee__button-destroy", remote: true %>
<% else %>
<%= button_to "", bank_employee_path(#bank_employee), method: :delete, form: {id: "bankEmployeeDestroyForm" }, class: "bank-employee__button-destroy" %>
<% end %>

You need a different approach.
<% if #bank_employee.clients.empty? %>
<%= button_to "", bank_employee_confirm_path(#bank_employee), form: {id: "bankEmployeeDestroyForm" }, class: "bank-employee__button-destroy", remote: true %>
<% else %>
<%= button_to "", bank_employee_path(#bank_employee), method: :delete, form: {id: "bankEmployeeDestroyForm" }, class: "bank-employee__button-destroy" %>
<% end %>
now you need two things:
inside routes.rb create a collection for your blank_employee_confirm_path:
whatever setup you have, i assume you have some kind of blank_employees resources path:
resources :blank_employees do
member do
get :confirm
end
end
now, inside your controller you need to add the method confirm:
def confirm
## do whatever you want do to here
render :js
end
this will then head over to confirm.js
create a confirm.js.erb file inside your blank_employees view folder. To confirm this is working, you can add a console.log('it works') in it.
Once you have confirmed that it is working you can add the javascript code to the confirm.js.erb file:
$('#modal-body').html('<%= escape_javascript(render :partial => 'shared/your_confirmation_modal'%>');
with this setup, you need in your edit.html.erb file a <div id="modal-body"></div> that will take the modal. Also notice that in my example the confirmation modal is stored in "views/shared/_your_confirmation_modal.html". Change the path to your setup or create the exact path in order to make this work!
Notice that the "confirm" path is for the blank_employees that have no clients. The button will be only rendered when there is no client. All the other logic you had before for the blank_employees with clients stay the same. You don't need to change there anything. If you had any logic inside there for blank_employees without any clients, move the code to the confirm method.
One more thing: Make sure to add to your destroy method a render :js as well, and inside destroy.js.erb add the same kind of logic like inside confirm.js.erb, beside that you want to render the modal for blank_employees with clients. Your destroy.js.erb file should look something like this:
$('#modal-destroy').html('<%= escape_javascript(render :partial => 'shared/your_destroy_modal'%>');
Very important: Just like with the first modal, add a <div id="modal-destroy"></div> to your edit.html.erb file, otherwise it wont render the modal.
If something is unclear, let me know!
Greetings!

Related

Rails - How to submit a form without changing the page and updating the view?

Hello all !
Im using rails and in the steps I would like the user to (on the same page) :
Enter his address
Filling the form
Submit the form
Click to submit
Update the view to show the address
The view updated
Should I use Stimulis or Ajax? I don’t quite understand which would be more useful!
Because i try to use simply JS but it’s was not DRY and not really simple:
// file.js
document.querySelector(".form").addEventListener('submit', function () {
adress_form = document.querySelector(".adress_form");
adress_form.style.display="none";
document.location.reload();
display_adress = document.querySelector(".display_adress");
display_adress.style.display = "block";
});
#file.html.erb
<div class="display_adress">
<% if current_user.line1? && current_user.postal_code? && current_user.city? %>
<p>Mon adresse actuel : <%= current_user.line1 %>, <%= current_user.city %> <%= current_user.postal_code %></p>
<% end %>
</div>
<div class="address_form">
<%= simple_form_for(current_user, remote: true, html: { id: "addddd"}) do |f| %>
<%= f.input :line1, label: 'Mon adresse' %>
<%= f.input :city, label: 'Ville' %>
<%= f.input :postal_code, label: 'Code Postal' %>
<%= f.submit %>
<% end %>
</div>
To resume, i want the user to enter his address on the form, to submit, to update my database and to update the view with the new address the user submitted
Thanks for helping!
You can respond in the controller javascript. For example:
file.html.erb
<%= simple_form_for(current_user, remote: true, format: :js, html: { id: "addddd"}) do |f| %>
users_controller.rb
def create
# do your business logic
render 'create
end
users/create.js.erb
document.getElementById("formId").innerText = "Othe html text or you can call render(*)"

How to send [:commit] param with remote: true form_for

I have a form and I need to have 2 submit buttons. This seems like the only way I can think to do to accomplish what I want.
The goal is to use one form to send to one method and then possibly redirect to another method depending on the params passed because the functions will be different.
Form:
<%= form_for(:mass, url: mass_product_variant_category_path, method: :get, remote: true) do |mass| %>
<%= mass.submit "Update All", name: "All", class: "btn btn-light" %>
<%= mass.submit "Update Files", name: "Files", class: "btn btn-light" %>
<% #Stuff.each do |variant| %>
<%= check_box_tag 'store_variant_ids[]', variant.id %>
<% end %>
...
<% end %>
I tried: <%= submit_tag "Submit", name: "All" %>, also not working.
The html:
<input type="submit" name="File" value="Update Files" class="btn btn-light" data-disable-with="Update Files">
Controller:
def mass_product_variant_category
#stuff = Stuff.where(store_variant_id: params[:store_variant_ids])
if params[:commit] == "File"
redirect_to edit_multiple_stuffs_path(stuffs: #stuffs)
else
respond_to do |format|
format.js
end
end
end
The params that get passed are:
{..."mass" => {hidden_field: "int"}, "other_attributes" => ["int"]...}
This is due to using remote: true, but not sure why or how.
How can I pass through a param based on the submit form?
I've read other SO posts on this, but there are very few and none seem to have a good or any accepted answers. I also cannot use hidden_fields due to needing a redirect based on submit button used.
Is there a "Rails" way to do this without needing to add javascript or is that my only option?
I solved this by using a hidden_field_tag within the form that gets filled in based on the submit button used through an onclick. I can then check the hidden_fields param in the controller.
The "name" attribute maps to the name in the params hash. For this case you should do something like:
if params["File"]
# Something
elsif params["All"]
# Other thing
else
# Default
end

Rails Edit action not updating and not work properly using Ajax

I am trying to do two things:
With Ajax render Edit form when a user clicks on Edit link/button
Then after editing and they click on Update link/button, hide the form.
...but unfortunately, it didn't behave that way. It perfectly renders the form through Ajax but...
it renders the form on all of the rows.
after edit and you click update it doesn't hide the form.
Below is the code:
controller
before_action :set_clock_entry, only: [:edit, :update]
def edit
end
def update
respond_to do |format|
if #clock_entry.update(clock_entry_params)
format.js { flash.now[:notice] = 'Clock entry was successfully updated.' }
format.html { redirect_to #clock_entry, notice: 'Clock entry was successfully updated.' }
format.json { render :show, status: :ok, location: #clock_entry }
else
format.html { render :edit }
format.json { render json: #clock_entry.errors, status: :unprocessable_entity }
end
end
end
edit.html.erb
<h1>Editing Clock Entry</h1>
<%= render 'form', clock_entry: #clock_entry %>
<%= link_to 'Back', clock_entries_path %>
_form.html.erb
<%= simple_form_for clock_entry, remote: true do |f| %> # I am setting remote: true here
<%= f.error_notification %>
<%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
<div class="form-inputs">
<%= f.input :purpose %>
</div>
<div class="form-actions">
<%= f.button :submit, class: 'btn btn-primary btn-block btn-lg' %>
</div>
<% end %>
edit.js.erb
$('#edit-clock-entry a').hide().parent().append("<%= j render 'form', clock_entry: #clock_entry %>")
html edit link
<tr>
<td>
<div id="edit-clock-entry">
<%= link_to 'Edit', edit_clock_entry_path(clock_entry), remote: true %>
</div>
</td>
</tr>
This is the image - it renders on all ids
I give it all/dedicate it to #bkunzi01's comment under the post to the problem/question and that is what helped me solved it. So this is how I eventually solved it:
Error 1:
So according to what was suggested as I mentioned earlier, I had to redefine my edit.js.erb file to handle unique id of the edit in the row. So my edit.js.erb becomes:
$('#edit-clock-entry-<%= #clock_entry.id %> a').hide().parent().append("<%= j render 'form', clock_entry: #clock_entry %>")
Error 2:
I did not create update action with ajax and that made it behaved the way it behaved. So I created a file called update.js.erb to handle what happens when users hit the update button. So my update.js.erb becomes:
$('.refresh').bind('ajax:success', function () {
$(this).hide().parent();
})
So this is what I have now shown in the image
Log also shows the right record was updated
This fixed it for me.

JQuery submit for rails form not working

The info:
I have two models: link and campaign in show.html.erb for link I have the following two forms:
<%= form_for #link, method: :delete, remote: true, id: "delete" do |f| %>
<%= f.submit :"Submit", id: "linksubmit" %>
<% end %>
<%= form_for :campaign, url: campaigns_path do |x| %>
<%= x.hidden_field :title, value: #link.title %>
<%= x.hidden_field :name, value: #link.name %>
<%= x.hidden_field :link, value: #link.link %>
<%= x.hidden_field :description, value: #link.description %>
<%= x.hidden_field :owner, value: current_user.try(:email) %>
<%= x.hidden_field :date, value: Date.today.to_s %>
<%= x.submit :Start, id: "campaignsubmit" %>
<% end %>
When I click the submit buttons on their own, they do their job, which is either destroy the link or make a new campaign I need both to submit at the same time. I tried to do that with some JQuery. This is what I have.
$('document').ready(function() {
$('button#campaignsubmit').click(function() {
$('form#delete').submit();
});
});
Doesn't work. I ran some tests, and I know the JQuery is functioning fine, just not with this function. Any help?
The issue is in this line $('document').ready(function() {. It should be $(document).ready(function() {. The binding is never getting called, so it won't bind, and thus won't work.
Edit: Side note... you can remove the tag names, since IDs are unique per page (or at least are supposed to be).

Sidebar and Main page persistence - Rails

I am using a sidebar that searches and generates a list (within the sidebar) I want the main page to remain unchanged when searching with the sidebar. I believe this requires some JS, but I know nothing about JS.
my navbar is in a div _navbar.html.erb
main page is basically any other page being generated
here is my code: https://github.com/nrkfeller/ratingapplication
You need to use AJAX with rails. Here is how it may work for you:
Add a :remote => true to your form and :'data-update-target' => 'update-container' to specify where you want the search results to go. You might want to avoid using the courses_path, but use form_tag({:controller => courses, :action => 'search'} to directly state where you want the form to be submitted.
<%= form_tag courses_path, method: :get, :remote => true ,class: "navbar- form navbar-right", :'data-update-target' => 'update-container' , role: "search" do %>
<p>
<%= text_field_tag :search, params[:search], class: "form-control" %>
<%= submit_tag "Search",:disable_with => 'Please wait...', name: nil, class: "btn btn-default" %>
</p>
<% end %>
Add this to your sidebar. This is where the partial with the results will come:
<div id="update-container"></div>
Add the javascript`` to put it where it is supposed to be when the request finishes:
<script>
$(function() {
$('form[data-update-target]').on('ajax:success', function(evt, data) {
var target = $(this).data('update-target');
$('#' + target).html(data);
});
});
Add a partial named _search_results.html.erb <- this is where your results go.
<!-- arbitrary code -->
<%= #results.each do |result| %>
<%= result %>
In your controller:
def search
#results= #your search code
render :partial => 'search_results', :content_type => 'text/html'
end
This is will get the functionality you wanted. Beware, this is more of a pesudocode than an exact implementation of what you want to do. You have to fill in the gaps.
I hope I was helpful!

Categories

Resources