Ruby on Rails: Search collection_check_boxes on a form - ruby-on-rails

In my RoR application I have functionality that allows a user to select contacts to send an email to. I want to add to this functionality so that a user can search the contacts.
Currently, the contacts are displayed on the views/emails/form.html.erb in checkboxes that the user can select through:
<%= f.collection_check_boxes :contact_ids, Contact.where(user_id: session[:user_id]), :id, :firstname %>
Is it possible to build on this by adding a search bar above the checkboxes that allows the user to search the checkboxes by first name?

You can have a form to work with an unobstrusive javascript.
Like
<div class="form-group">
<!-- Form outside your main form... the REMOTE flag will tell rails
to prevent the default behaviour of a form make a request
for JS response --!>
<%= form_tag contacts_path, remote: true, method: :get do %>
<%= input_tag :search %>
<%= button_tag "Search" %>
<% end %>
<div id="email-form">
<%= form_for #email, email_path do |f| %>
<!-- Many inputs relative with email omited--!>
<div class="contact-list">
</div>
<%= f.submit 'Submit' %>
<% end %>
</div>
Have an controller/action that search for your contacts and returns it for a js view...
// ContactController
def index
respond_to do |format|
format.html { #contacts = Contact.all }
format.js { #contacts = Contact.find_by(firstname: params[:search]) }
end
end
And have a view for that action/controller that manipulate the html to append the contacts to be selected
// views/contacts/index.js.erb
$(document).ready(function() {
$('#contact-list').append("<%= collection_check_boxes :email, :contact_ids, #collection, :id, :firstname %>")
})
That is a very simple example... and I don't handle repetition... if you search for the same thing twice...

Related

Ruby on Rails: Why isn't my search working?

In my RoR application I am allowing users to select contacts that they want to send an email to. The users select these contacts via checkboxes on the form. I am trying to add in search functionality so that a user can search by first name and only check boxes with contacts that match that search appear.
To do this I am trying to use this code on the view:
<div class="form-group">
<label>From Email Address</label></br>
<% #useraccounts.each do |useraccount| %>
<%= f.radio_button :account_id, useraccount.account_id, :checked => false %>
<%= f.label :account_id, useraccount.account.email, :value => "true" %><br>
<% end %>
</div>
<div class="form-group">
<%= form_tag '/emails/contact_search', :method => 'get' do %>
<p>
<%= text_field_tag :search_string, params[:search_string], :placeholder => "Search by firstname" %>
<%= submit_tag "Search", :name => nil %>
</p>
<% end %>
<label>Contacts</label></br>
<%= f.collection_check_boxes :contact_ids, #contacts, :id, :fullname %>
</div>
Where the #contacts instance variable holds the contacts returned from the search in the controller.
When a user clicks the search button, the below controller action should be invoked.
def contact_search
#email.recipients.build
#useraccounts = Useraccount.where(user_id: session[:user_id])
#contacts = Contact.contacts_search(params[:search_string])
if #contacts.empty?
flash.now[:alert] = "There are no contacts with that name."
#contacts = Contact.all
end
render :action => "new"
end
This controller action uses the contact_search method, which is in the Contact.rb model:
def self.contact_search(search_string)
self.where("firstname LIKE ?", search_string)
end
I also have the contact_search in the routes:
post 'emails/contact_search', :to => 'emails#contact_search'
get 'emails/contact_search', :to => 'emails#contact_search'
But for some reason, when a user clicks search they get a NoMethodError in Emails#create undefined method 'each' for nil:NilClass on the form. The error is as pictured.
I cannot work out why this isn't working, can someone please help?
By the erb, I guess you have a form_tag inside a form_for block... You can't do that
When you hit Submit, the action is going to the first form action... that probably is a create
It's better move your form_tag to outside your previous form block...
Seems your Modal name (Useraccount) is incorrect this must be UserAccount.
Also Please note
When we use where query with ActiveRecord modal we never get NIL object unless we have wrong Modal name.

Update Attributes of a Specific Record

Let's say I have a bunch of cards listed on my wall show action. When you interact with a card (click it for example), I want to update that card's attributes.
I'm currently doing this by getting the card's attributes with Javascript, adding them to a card form and submitting the form remotely.
I have the card's ID, but how do I tell the form which card I want to update?
What should the form and controller update action look like?
This is what I have so far
Form
<%= form_for(#card, remote: true) do |f| %>
<%= f.text_field :list_id %>
<%= f.text_field :order %>
<% end %>
Controller
def update
#card = Card.find(params[:id])
if #card.update_attributes(shared_params)
redirect_to edit_card_path(#card, format: :html)
else
render :edit
end
end
You can use the same new template for edit too. The only requirement here is the object you wanted to edit.
So, first get you edit action ready in controller as
def edit
#card = Card.find(params[:id])
end
edit/new.html.erb
<%= form_for(#card, remote: true) do |f| %>
<%= f.text_field :list_id %>
<%= f.text_field :order %>
<% end %>
In the cards show page, add a link to the edit action as
<%= link_to "Edit", edit_card_path(card.id) %>

Using a Method from Controller in Another Rails

I am using elasticsearch on my rails 4 app to search through my articles.
However, when an article is not found it redirects to a page where it alerts the user that no results are found, and allows to request a page. Instead of it saying "no results found" I want it to say "no results for ______ found" in which is takes the search bar query.
I have defined a method in the articles_controller in order to get the query but it won't show up on the page since the "no results page" uses a different controller.
What would be the best way to pull the method onto another controller or view in this case? Having trouble finding a straight forward answer for what I am trying to do. Thank you very much.
articles_controller:
def index
if params[:query].present?
#articles = Article.search(params[:query], misspellings: {edit_distance: 1})
else
#articles = Article.all
end
if #articles.blank?
return redirect_to request_path
end
get_query
end
private
def get_query
#userquery = params[:query]
end
new.html.erb (view for "no results found" page. Uses a different controller than articles page):
<body class="contactrequest">
<div class="authform" style="margin-top:15px">
<%= simple_form_for #request, :url => request_path do |f| %>
<h3 style = "text-align:center; color:red;">No results found. <%= #userquery %></h3>
<h1 style = "text-align:center; color:black;">Request a Page</h1>
<h5 style = "text-align:center; color:black; margin-bottom: 25px;">Our experts will gather the information,<br> and have your page us ASAP!</h5>
<%= f.error_notification %>
<div class="form-group">
<%= f.text_field :email, placeholder: 'Email', :autofocus => true, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.text_field :subject, placeholder: 'Item / Page Requested', class: 'form-control' %>
</div>
<div class="form-group">
<%= f.text_area :content, placeholder: 'Any additional details...', class: 'form-control', :rows => '5' %>
</div>
<%= f.submit 'Request it', :class => 'btn btn-lg btn-danger btn-block' %>
<% end %>
As you can see I've tried calling that #userquery method to display on the view page, but it doesn't show up since it's defined on a different controller. Any recommendations would be awesome.
I would suggest you render results and no results from the same controller/view. A nice clean way to do this is with partials. Your view could look something like:
<% if #articles.blank? %>
<%= render 'no_results' %>
<% else %>
<%= render 'results' %>
<% end %>
Then, you would simply create _no_results.html.erb and populate it with your current new.html.erb contents and do the same for your nominal results page (with partial _results.html.erb).

How to use carmen-rails gem in my project?

I want to use carmen-rails gem in my rails project, but in documentation at github i can't understand well how to use it , so i think : if for example i want my users have a country and state :
first : i should add 2 columns in my user model (country and state), Right ?
second : add select country and state to my user form :
<%= simple_form_for #user do |f| %>
<div class="field">
<%= f.label :country_code %><br />
<%= f.country_select :country_code, priority: %w(US CA), prompt: 'Please select a country' %>
</div>
<div class="field">
<%= f.label :state_code %><br />
<%= render partial: 'subregion_select', locals: {parent_region: f.object.country_code} %>
</div>
<% end %>
then my partial should be look like :
<div id="order_state_code_wrapper">
<% parent_region ||= params[:parent_region] %>
<% country = Carmen::Country.coded(parent_region) %>
<% if country.nil? %>
<em>Please select a country above</em>
<% elsif country.subregions? %>
<%= subregion_select(:order, :state_code, parent_region) %>
<% else %>
<%= text_field(:order, :state_code) %>
<% end %>
I'm right ?
then how to validate country and state when the form is submitted ?
finally how to change language of countries and states in the select form (to french for example ) ?
Yes and yes.
Take a look at their demo app: https://github.com/jim/carmen-demo-app/
You need to add the route to fill the states partial, then add the appropiate controller method to render the partial. Don't forget to define the partial route first and then users controller routes.
e.g. (routes.rb)
get '/users/subregion_options' => 'users#subregion_options'
resources :users
e.g. (users_controller.rb)
def subregion_options
render partial: 'subregion_select'
end
You need to add some JS to catch change event on countries select and then with the country code call the users controller method to render the states partial.
e.g. (users.js.coffee)
$ ->
$('select#user_country_code').change (event) ->
select_wrapper = $('#user_state_code_wrapper')
$('select', select_wrapper).attr('disabled', true)
country_code = $(this).val()
url = "/users/subregion_options?parent_region=#{country_code}"
select_wrapper.load(url)
You can handle validation on the user's model class as usual. The sample app includes information on changing locales.

Ajax form within a form with no layout

So I'm new to rails and having a little bit of trouble my situation is that I have a products model that has some Images attached to it. I would like on my products page to have a button to create a new image via ajax.
Inside my products _form view i have:
<%= simple_form_for(#product) do |f| %>
<%= f.error_notification %>
<div class="inputs">
<%= f.input :name %>
<%= f.input :description, :input_html => {:class => "wysihtml5 span6", :style => "height:400px;"} %>
<%= f.association :images, label_method: :name, value_method: :id %>
<h4>Upload new file</h4>
</div>
<%= link_to 'Add Image', '/images/new', :remote => true, :"data-replace" => "#image-form" %>
<div id="image-form">
</div>
<div class="actions">
<%= f.button :submit %>
</div>
<% end %>
And it does successfully Load the page via ajax.
But I would like to load it without the layout. Is this possible?
Do I need to create a new action that renders the partial form and has no layout??
So I'm assuming you have it requesting and returning html and not js? There are a couple of thoughts I have on this:
If you only ever need for this request to return from an AJAX request, then you could simply tell the controller to always render layout: false
If you would like to allow the controller to return a full page on occasion, you can either accept an argument in the get request and change the output accordingly, or you can tell the controller to:
respond_to do |format|
format.html # will render default with no block passed
format.js { render layout: false }
end
This should just work with the code in your form right now, because the :remote => true tells the controller to return js if possible, but accessing images/new from your browser will request html.
(Requesting js does not mean that you actually have to return js, as I don't in this case; it's up to you to take the proper action with what is returned. Some might consider it bad form, though, to return something other than what is technically requested.)
You can use the following in your action. Let your action is new.
def new
#your code goes here
render :layout => false
end

Resources