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

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

Related

Rails Ransack gem slider

I want to be able to performa range search with ransack. I was hoping I could do this with a slider that has two thumbs. I'm thinking that the _in predicate would be perfect for a situation like this. However, I cannot find an example on how to appropriately configure this. Here would be some example code:
CONTROLLER `users_controller.rb:
def index
#page_title = 'Users'
#page_icon = 'store'
#q = User.search(params[:search]).ransack(params[:q])
#retailers = #q.result.order("#{sort_column} #{sort_direction}").paginate(page: params[:page], per_page: 20)
end
VIEW users/index.html.erb:
<%= search_form_for #q, url: users_path, class: 'form' do |f| %>
<div class="row">
<div class="col-sm-3">
<div class="form-group">
<%= label_tag :search %>
<%= text_field_tag :search, params[:search], class: "form-control" %>
</div>
</div>
<div class="col-sm-3">
<div class="form-group">
<%= f.label :first_name_eq, "First Name" %>
<%= f.select :first_name_eq, {include_blank: true}, {class: "chosen-select"} %>
</div>
</div>
<div class="col-sm-3">
<div class="form-group">
<%= f.label :team_eq, "Team" %>
<%= f.select :team_eq, Team.options_for_select, {include_blank: true}, {class: "chosen-select"} %>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-3">
<div class="form-group">
<%= f.label :score_in, "Score Range" %>
<%= f.search_field :score_in, {include_blank: true} %>
</div>
</div>
</div>
<div>
<%= f.submit 'Apply Filters', class: 'btn btn-outline-dark btn-md' %>
<%= link_to 'Reset Filters', users_path(q: {reset: true}), class: 'btn btn-outline-danger btn-md' %>
</div>
<% end %>
I guess where I'm lost is how to start or implement a slider w/ two thumbs that would appropriately pass the parameters when submitted. Or even if I just create a two thumbed slider from a js library, how to connect it then to ransack, or at least pass the values of the two thumbs to ransacks params. Another thing that might be helpful is if someone has an example, both in controller/view, of what the _in predicate should look like.

Rails bootstrap_checkbox not reflecting value of table - Showing all OFF

I built a form for a table with mostly boolean values. The form displays well, the bootstrap toggle works well, it saves data well, but it displays all the value as OFF when the edit page is called again.
I have tried playing with the options. Adding checked_value and unchecked_value, but it does not work.
<%= simple_form_for(#setting) do |f| %>
<div class="form-check_boxs">
<div class="row">
<div class="col-md-4">
<%= f.label :open_for_work do %>
<%= t :open_for_work %>
</div>
<div class="col-md-8">
<%= f.check_box :open_for_work, options: {}, checked_value: "true", unchecked_value: "false" %>
</div><% end %>
</div>
<div class="row">
<div class="col-md-4">
<%= f.label :turn_app_local do %>
<%= t :turn_app_local%>
</div>
<div class="col-md-8">
<%= f.check_box :turn_app_local, options: {}, checked_value: "true", unchecked_value: "false" %>
</div><% end %>
</div>
<div class="form-actions">
<%= f.button :submit, class: "btn btn-primary" %>
</div>
<% end %>
Does anyone knows how to actually use the gem 'bootstrap-switch-rails' in rails ?
NB: My site is all in Bootsrap 4, could be the reason why this does not work ?
The bootstrap issue should just affect styling and not the actual params passed through. Try:
<%= f.input :status, :as => :check_boxes, collection: [['true', 'false']] %>
Note that these will pass the strings 'true' and 'false' respectively when selected or not.

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 - Cocoon gem - Nested Forms

I am trying to make an app with Rails 4.
I use simple form gem for forms and am trying to use Cocoon gem for nested elements of the forms.
I asked this question, which explains what I'm trying to achieve in more detail: Rails - Multiple entries for a single attribute
I have a profile model and a qualifications model. The associations are:
profile.rb
has_many :qualifications
accepts_nested_attributes_for :qualifications, reject_if: :all_blank, allow_destroy: true
qualification.rb
belongs_to :profile
the profiles controller includes the qualification attributes in the strong params:
def profile_params
params[:profile].permit(:user_id, :title, :hero, :overview, :research_interest, :occupation, :external_profile,
:working_languages, :tag_list,
qualifications_attributes: [:id, :level, :title, :year_earned, :institution, :_destroy] )
end
My profile form now has:
<div class="intpol2">
Your qualifications
</div>
<%= render 'qualifications/qualification_fields', f: f %>
</div>
<div class="row">
<div class="col-md-6">
<%= link_to_add_association 'Add a qualification', f: f, partial: 'qualifications/qualification_fields' %>
</div>
My qualifications partial form is now named in my qualification views folder as _qualifications_fields.html.erb
<div class="nested-fields">
<div class="container-fluid">
<%= simple_fields_for :qualifications do |f| %>
<div class="form-inputs">
<div class="row">
<div class="col-md-6">
<%= f.input :title, :label => "Your award" %>
</div>
<div class="col-md-6">
</div>
</div>
<div class="row">
<div class="col-md-6">
<%= f.input :level, collection: [ "Bachelor's degree", "Master's degree", "Ph.D", "Post Doctoral award"] %>
</div>
<div class="col-md-6">
<%= f.input :year_earned, :label => "When did you graduate?", collection: (Date.today.year - 50)..(Date.today.year) %>
</div>
</div>
<div class="row">
<div class="col-md-6">
<!-- link_to_remove_association 'Remove this qualification', f, :f -->
</div>
</div>
</div>
<% end %>
</div>
</div>
I commented out the remove link, because as is, I get this error:
undefined method `new_record?' for nil:NilClass
I'm baffled by the way Rails reports errors- I rarely understand error messages of this style, but I gather it's something to do with there not being any qualifications to remove. Does cocoon handle this?
When I comment this out and try again, I get this error with the link to add an association:
undefined method `object' for #<Hash:0x007fe70c501ea0>
I don't know what this message means either.
So, by following the steps in the Cocoon gem docs, (with changes because I don't know how to write things in haml; and changing the form of expression to reference the form builder 'f: f' works across the rest of my forms, so Im guessing that the expression shown in the docs might be something to do with haml), I have 2 errors at this stage:
add association - undefined method object
remove association - undefined method `new_record?
I'm struggling to understand what's going on here.
TAKING JEIWAN'S SUGGESTION:
I change my profile form to:
<%= simple_form_for #profile, html: { multipart: true } do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<div class="row">
<div class="intpol2">
Your professional qualifications
</div>
<%= simple_fields_for :qualifications do |f| %>
<%= render 'qualifications/qualification_fields', f: f %>
</div>
<div class="row">
<div class="col-md-6">
<%= link_to_add_association 'Add a qualification', f, :qualifications, partial: 'qualifications/qualification_fields' %>
<% end %>
</div>
</div>
<div class="form-actions">
<%= f.button :submit, "Submit", :class => 'formsubmit' %>
</div>
<% end %>
</div>
</div>
</div>
I change my qualification fields form to:
<div class="nested-fields">
<div class="container-fluid">
<div class="form-inputs">
<div class="row">
<div class="col-md-6">
<%= f.input :title, :label => "Your award" %>
</div>
<div class="col-md-6">
</div>
</div>
<div class="row">
<div class="col-md-6">
<%= f.input :level, collection: [ "Bachelor's degree", "Master's degree", "Ph.D", "Post Doctoral award"] %>
</div>
<div class="col-md-6">
<%= f.input :year_earned, :label => "When did you graduate?", collection: (Date.today.year - 50)..(Date.today.year) %>
</div>
</div>
<div class="row">
<div class="col-md-6">
<%= link_to_remove_association 'Remove this qualification', f %>
</div>
</div>
</div>
</div>
</div>
When I save this and try again, I get this error:
undefined method `new_record?' for nil:NilClass
The error message highlights this line:
<%= link_to_remove_association 'Remove this qualification', f %>
link_to_add_association 'Add a qualification', f: f, partial: 'qualifications/qualification_fields'
f: f is incorrect here. The second parameter should be a form builder (just an object, not a hash) and the third parameter – the name of the association, i.e. :qualifications in your case. So it should look like this:
link_to_add_association 'Add a qualification', f, :qualifications, partial: 'qualifications/qualification_fields'
And here:
link_to_remove_association 'Remove this qualification', f, :f
:f is also wrong. Third parameter here is HTML options. If you don't need them, then just specify 2 parameters:
link_to_remove_association 'Remove this qualification', f
Next, _qualification_fields.html.erb shouldn't contain simple_fields_for. This partial is used to render the fields of one distinct association object. It is shown when you click 'Add a qualification' or when your parent object already has some qualifications. simple_fields_for :qualifications should be put in you profile form and contain render 'qualifications/qualifications_fields', f: f and link_to_add_association .... Consider this example: https://github.com/nathanvda/cocoon#simpleform

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

Resources