Ruby remote partial being rendered twice - ruby-on-rails

I've spent this afternoon moving code around, trying different things, etc but am unable to solve my (probably simple) problem. I have a button on my index layout that displays a partial form in a modal dialogue to a) create new entries or b) edit existing ones. I'm using the materialize, simple form and client side validation gems.
When I click the button for a new entry the modal appears twice, which looks a bit rubbish but more importantly when I try to save an entry two POST requests are made.
Obviously, I just want the form partial to be rendered once... but I can't work out why its happening twice.
Thanks all for your help, let me know if you need any more than what I have provided below.
This is the button code in the index.html.erb layout
<div class="fixed-action-btn">
<%= link_to "<i class='material-icons'>add</i>".html_safe,
new_patient_path, :remote => true, :id => 'new_patient_link',
:class => "btn-floating btn-large red" %>
</div>
Which then loads the javascript in new.js.erb
$('#modal_partial').html('<%= escape_javascript(render('form')) %>');
That subsequently renders the _form.html.erb partial into the following div (which is stored in a shared/_footer.html.erb partial and sits at the bottom of the index page.
<div id="form_modal_wrap">
<div id="modal_partial" class="modal modal-fixed-footer">
</div>
</div>
And the _form.html.erb partial:
<div id="edit_patient_modal" class="";>
<%= simple_form_for #patient, validate: true, remote: true do |f| %>
<div class="modal-content" style="padding: 0px;">
<h4 class="col s12" style="margin: 0px; padding: 10px 25px;">New Patient</h4>
<%= f.error_notification %>
<div class="row">
<div class="col s12" style="padding: 0px;">
<ul class="tabs" style="padding: 0px;">
<li class="tab col"><a class="active" href="#demographics">Demographics</a></li>
<li class="tab col"><a class="active" href="#admission">Admission</a></li>
<li class="tab col">Presentation</li>
<li class="tab col">Jobs</li>
<li class="tab col">Results</li>
</ul>
</div>
<div id="demographics" class="col s12" style="padding: 20px;">
<%= f.input :nhs, :label => "NHS" %>
<%= f.input :fname, :label => "Firstname" %>
<%= f.input :lname, :label => "Lastname", validate: { presence: true, uniqueness: false } %>
<%= f.input :dob, :label => "DOB", as: :date, start_year: Date.today.year - 110,
end_year: Date.today.year - 12,
order: [:day, :month, :year] %>
<%= f.input :mrn, :label => "MRN" %>
</div>
<div id="admission" class="col s12" style="padding:20px;" >
<%= f.association :location %>
<%= f.input :bed, :label => "Bed" %>
<%= f.association :team, input_html: { multiple: true } %>
</div>
<div id="presentation" class="col s12" style="padding:20px;">
<%= f.input :dx, :label => "Dx" %>
<%= f.input :pmh, :label => "PMH" %>
</div>
<div id="jobs" class="col s12" style="padding:20px">
<p>This job list is shared between all teams.</p>
<%= f.input :jobs, :label => "Jobs" %>
</div>
<div id="results" class="col s12" style="padding:20px;">
<table>
<tr>
<th>Group</th>
<th>Result</th>
<th>Date</th>
</tr>
<% #patient.results.each do |result| %>
<tr>
<td>
<%= Investigation.find(result.investigation_id).group %>
</td>
<td>
<%= Investigation.find(result.investigation_id).short %>
<%= result.value %>
</td>
<td>
<%= result.date %>
</td>
</tr>
<% end %>
</table>
</div>
</div>
</div>
<div class="modal-footer">
<a id="modal_close" href="#!" class="modal-close waves-effect waves-pink btn-flat">Cancel</a>
<%= f.button :submit, :class => "waves-effect btn" %>
</div>
<% end -%>
The following javascript is in the bottom of the _form.html.erb partial:
$(document).ready(function(){
$('#modal_partial .tabs').tabs();
$('#modal_partial select').formSelect();
$('#modal_partial').modal();
$('#modal_partial').modal('open');
$('form').enableClientSideValidations();
});
$("#modal_close").on("click", function(e) {
e.preventDefault();
$('#modal_partial').modal('close');
});
</script>

So I worked out what I'd done in the end...
in application.js I had added both of the following:
//= require jquery_ujs
//= require rails-ujs
By removing either one of these the modals only appeared once. After reading the documentation I only need rails-ujs as it performs the same functions as jquery_ujs, but without having a dependency upon jquery. It does not mean that you can't still have jquery as an independent requirement (as I still do).
So the solution was to delete the line //= require jquery-ujs and just have the following:
//= require rails-ujs
Thanks lacostenycoder for you help

The only way to debug this is to check EVERY part of your code which loads javascript including your layouts. Something is causing the form to duplicate, but it's impossible to debug without seeing all of the code.

Related

How to add in multiple options for checkbox in Ruby on Rails?

This is likely a super easy answer for a Ruby on Rails expert. I have a form and need to add in a checkbox that has multiple items. I've been messing with the following code for a lot longer than I'd like to admit:
<%= form_for :lead, url: something, html: {id: 'product-form'} do |f|%>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<%= f.label :product%>
<%= f.check_box :product, {multiple:true}, "option", "option2", :class => 'form-control'%>
</div>
</div>
</div>
<% end %>
With this code I get the error "wrong number of arguments (5 for 1..4)".
Basically I just want someone to be able to pick multiple options. I've also tried the following:
<div class="row">
<div class="col-md-12">
<div class="form-group">
<%= f.label :product%>
<%= f.check_box :option1, "Option1" :class => 'form-control'%>
<%= f.check_box :option2, "Option2", :class => 'form-control'%>
</div>
</div>
</div>
And I get the delightful "undefined method `merge' for "Option1":String". What am I missing to put the values in associated with the label?
I use Rails 5.1.6 and this is how I achieved adding multiple options for checkbox. I also placed it in a dropdown.
In the migration file:
t.string :skills
In my controller "tasks_controller.rb":
def task_params
params.require(:task).permit(:work_type, :title, :post, {skills: []})
end
In my model "task.rb" I did:
validates :skills, presence: true
serialize :skills, JSON
I created a module mobilephones_data.rb in directory "app/model/concerns/" which holds all the options of the checkbox as an array that can be edited easily.
In app/model/concerns/mobilephones_data.rb I wrote:
module Mobilenphones_Data
Activities = [
'Amazon Kindle', 'Blackberry', 'iPad', 'iPhone', 'Mobile Phone', 'Nokia',
'Palm', 'Samsung'
]
end
This will put all data from module's array into the checkbox drop-down as checkbox options. In My form I did:
<div class="card">
<a class="card-link card-header" data-toggle="collapse" href="#collapseOne">
Mobile Phones
</a>
<div id="collapseOne" class="collapse" data-parent="#accordion">
<div class="card-body">
<% Mobilenphones_Data::Activities.each do |activity| %>
<div id="skill_list" class="col-lg-3 col-md-4 col-sm-12 col-12">
<%= f.check_box :skills, { multiple: true }, activity, false %>
<%= activity %>
</div>
<% end %>
</div>
</div>
</div> <!--bottom-->
</div>
In my view "show.html.erb":
<% #name_of_model.skills.each do |skill| %>
<%= skill %>
<% end %>
For posterity sake:
<div class="row">
<div class="col-md-12">
<div class="form-group">
<%= f.label "Select a Product" %><br />
<%= f.check_box(:option) %>
<%= f.label(:mug, "Option") %><br />
<%= f.check_box(:option2) %>
<%= f.label(:mousepad, "Option2") %>
</div>
</div>
</div>

Rails materialize-sass form with autocomplete and cocoon gem nested resource

I am using materialize-sass gem on a form. Using autocomplete feature to get Vendor names. other fields on the form are item names and quantity which are a nested resource. For this I am using cocoon gem
For some reason the very first time the page loads, all seems to work fine. But adding more fields does not seem to be working. I tried using drop down select and that does not show the list of items. I replaced it with another autocomplete and the main field does show however the auto complete feature does not work. Any idea what may be wrong?
Please see my code below.
purchase_orders _forms.html.erb
<div class="col s12">
<%= simple_form_for(#purchase_order) do |f| %>
<%= f.error_notification %>
<div class="row">
<div class="col s6">
<%= f.input :vendor_name, input_html: { class: 'vendor_name autocomplete' } %>
</div>
</div>
<section class="show-section">
<div class="row">
<div class="col l12"><h4>Item List</h4></div>
<div class="col s12">
<%= f.simple_fields_for :purchase_order_details do |purchase_order_detail| %>
<%= render 'purchase_order_detail_fields', :f => purchase_order_detail %>
<div class="links">
<%= link_to_add_association 'Add More', f, :purchase_order_details %>
</div>
<% end %>
</div>
</div>
</section>
<%= f.button :submit %>
<% end %>
</div>
_purchase_order_detail_fields.html.erb
<div class="nested-fields">
<div class="row">
<div class="col l6">
<%#= f.input(:item_id, collection: Ingredient.is_active, label_method: :title, value_method: :id) %>
<%= f.input :item_name, input_html: { class: 'item_name autocomplete' } %>
</div>
<div class="col l5">
<%= f.input :item_quantity %>
</div>
<div class="col l1">
<%= link_to_remove_association "delete", f, :class => "material-icons teal-text text-lighten-1" %>
</div>
<%#= f.hidden_field :item_type , :value=> params[:category_id] %>
</div>
</div>
Checking out the demo-project they use, and more specifically the init.js they use I notice two things: if you are using turbolinks you will have to do the same, and when using cocoon you will have to do something like:
$('form').on('cocoon:before-insert', function(e, insertedItem) {
$(insertedItem).find('select').material_select();
})
This is the coffee script I used to be able to populate the autocompelte
$.ajax
url: '/packing_materials/by_name.json'
dataType: 'json'
success: (my_res) ->
$ ->
$('input.packing_material_name.autocomplete').autocomplete data: my_res
$(document).on 'cocoon:before-insert', ->
$.ajax
url: '/packing_materials/by_name.json'
dataType: 'json'
success: (my_res) ->
$ ->
$('input.packing_material_name.autocomplete').autocomplete data: my_res

file_field upload button appearing multiple times on edit form

I have this code in my _form.html.erb file:
<%= f.fields_for :request_attachments do |ra| %>
<div class="row westmontTextMuseo3" id="uploader">
<div class="col-xs-12">
<label class="btn btn-info"> Upload Files
<%= ra.file_field :request_attachment_file, :multiple => true, name: "request_attachments[file][]", :style => "display: none", type: "file" %>
<%= ra.hidden_field :file_cache %>
</label>
<%= link_to(ra.object.file.url.to_s.split('/')[-1], ra.object.file.url) %>
</div>
</div>
<% end %>
I can see why the Upload Files button appears. It seems like I want it outside the scope of the nested form, but I don't know how to do that.
My goal is to place the button once after it has provided links to each of the already attached files.
Any help would be great, thanks.
Edit: Other code to see if we can get it to work.
<%= f.fields_for :request_attachments do |ra| %>
<%= link_to(ra.object.file.url.to_s.split('/')[-1], ra.object.file.url) %>
<% end %>
<div class="row westmontTextMuseo3" id="uploader">
<div class="col-xs-12">
<label class="btn btn-info"> Upload Files
<%= #request.request_attachments.file_field :request_attachment_file, :multiple => true, name: "request_attachments[file][]", :style => "display: none", type: "file" %>
<%= #request.request_attachments.hidden_field :file_cache %>
</label>
</div>
</div>
But this fails with an undefined method file_field' for #<RequestAttachment...
This seemed to have worked
<%= f.fields_for :request_attachments do |ra| %>
<div class="row">
<div class="col-xs-12">
<%= link_to(ra.object.file.url.to_s.split('/')[-1], ra.object.file.url) %>
</div>
</div>
<% end %>
<div class="row westmontTextMuseo3" id="uploader">
<div class="col-xs-12">
<label class="btn btn-info"> Upload Files
<%= file_field_tag :request_attachment_file, :multiple => true, name: "request_attachments[file][]", :style => "display: none", type: "file" %>
<%= hidden_field_tag :file_cache %>
</label>
</div>
</div>
I assumed since the attributes were nested it wouldn't work, but it did work.

Trying to initiate a variable on page load Angularjs

I am trying to initiate a variable showName when the page loads. It worked fine when I did it using just angular but when I implemented it with rails(with embedded ruby tags) I am not able to hide the text field and save button as my variable gets undefined. I have tried couple of ways and ended with no result.
Here is my code. Any help is really appreciated. Thanks.
Edit.html.erb:
<div class="row" ng-controller="EditUserCtrl">
<div class="col-md-6 col-md-offset-3" id="editForm">
<%= form_for(#user) do |f| %>
<h1 id="editHeader">Account Information </h1>
<%= render 'shared/error_messages' %>
<div class="form-group">
<%= f.label :name, "Full Name:" %><br>
<div class="row">
<div class="col-sm-7">
<div ng-hide="showName">
<%= f.label :name, #user.name , id:"editFields" %>
</div>
<%= f.text_field :name, { :'ng-show' => 'showName'}%>
</div>
<div class="col-sm-5" ng-show="showName">
<%= f.button "Save", :action => "update_name" , :method => :put, class: "btn btn-primary", :'ng-click' => "clicked()", id:"editAccount" %>
</div>
<div class="col-sm-5" ng-hide="showName">
<i id="nav-cart-count" class="glyphicon glyphicon-edit"></i> Edit
</div>
</div>
</div>
<% end %>
</div>
Use ng-init to initialize the variable
<div class="row" ng-controller="EditUserCtrl" ng-init="showName = true">

Rails Bootstrap Modal fields do not get focused on clicking jquery-ui conflict

I have a Rails app using Bootstrap. I'm creating a modal to enter labor against a workorder. The modal shows up fine.
But, if you left click on a field to enter data, it does nothing. Yet, if you right click, you can enter data. Plus the dropdown selector doesn't work. Also the calendar selector shows up only if you right click. The save & close buttons, and the checkbox work fine.
Here is a pic from the browser:
The modal code:
<a data-toggle="modal" href="#eventform-<%= workorder.id %>">
<i class="icon-time"></i>
<%= render :partial => "eventform", locals: {workorder: workorder} %>
</a>
The `_eventform.html.erb:
<div id="eventform-<%= workorder.id %>" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="eventformLabel" aria-hidden="true">
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h4 id="eventformLabel">Add Labor -
Employee: <%= current_user.employee.employee_full_name %>
- Workorder: <%= Workorder.find(workorder.id).wonum %>
</h4>
</div>
<div class="modal-body">
<%= simple_form_for Event.new do |f| %>
<%= f.hidden_field :employee_id, :value => current_user.employee.id %>
<%= f.hidden_field :workorder_id, :value => workorder.id %>
<%= f.hidden_field :maxsynch, :value => "N" %>
<%= f.hidden_field :all_day, :value => true %>
<div class="span3">
<%= f.association :actcode, :label_method => :act_desc, :label => 'Activity', :include_blank => true %>
<%= f.input :hours, :label => 'Hours' %>
</div>
<div class="span3">
<%= f.input :title, :label => 'Work Performed' %>
<%= f.input :starts_at, :as => :string, :label => 'Date', :input_html => {:class => 'datepicker', :value => Date.today.to_s} %>
<%= f.input :overtime, :label => 'Overtime' %>
</div>
<div class="modal-footer">
<%= f.submit 'Save', :class => 'btn btn-mini btn-primary' %>
<a class="btn btn-mini" data-dismiss="modal" href="#">Close</a>
</div>
<% end %>
</div>
</div>
Thanks for the help!
UPDATE1
If I remove //= require jquery.ui.all from application.js, then the fields work. But, then I loose jquery.ui functionality.
UDPATE2
The problem goes away if I remove 'gem fullcalendar'

Resources