UPDATE 8/18/12: Is there any way I can make the following question easier to answer?
I have the following code in a js.coffee file and it works for adding lined to a form. I want it to automatically add the first line on load though and don't know how to get it to to do that...
$('form').on 'click', '.add_fields', (event) ->
time = new Date().getTime()
regexp = new RegExp($(this).data('id'), 'g')
$(this).before($(this).data('fields').replace(regexp, time))
event.preventDefault()
(If this looks familiar, it's stolen verbatim from Ryan Bates' Railscast #196 revised)
UPDATE: I tried #Baldrick's advice with the following and still no dice:
jQuery ->
$('form').on 'click', '.add_fields', (event) ->
time = new Date().getTime()
regexp = new RegExp($(this).data('id'), 'g')
$(this).before($(this).data('fields').replace(regexp, time))
event.preventDefault()
$(document).ready '.receive-form', (event) ->
time = new Date().getTime()
regexp = new RegExp($(this).data('id'), 'g')
$(this).before($(this).data('fields').replace(regexp, time))
event.preventDefault()
UPDATE 2: Here's some more info:
My html(the important parts):
<div class="modal-body ">
<%= #company.haves.new.warehouse_transactions.new %>
<%= form_for #company do |f| %>
<div class="form-inline receive-form">
<h4>Part Details:</h4>
<%= f.fields_for :haves do |builder| %>
<%#= render 'have_fields', f: builder %>
<% end %>
<%= link_to_add_fields "+", f, :haves, :warehouse_transactions %>
</div>
</div>
have_fields:
<fieldset>
<%= f.text_field :product_title, :class => 'input-small text_field', :placeholder => "Product Title" %>
<%= f.fields_for :warehouse_transactions do |builder| %>
<%= render 'wht_fields', :f => builder %>
<% end %>
<%= f.hidden_field :_destroy %>
<%= link_to "-", '#', class: "remove_fields" %>
</fieldset>
wht_fields:
<fielset>
<%= f.number_field :quantity, :class => 'input-small number_field', :placeholder => "Quantity" %>
<%= f.text_field :cost, :class => 'input-small text_field', :placeholder => "Cost" %>
<%= f.text_field :location, :class => 'input-small text_field', :placeholder => "Location" %>
<%= f.text_field :batch, :class => 'input-small text_field', :placeholder => "Batch" %>
<%= f.select :condition, ['Condition'] + WarehouseTransaction::CONDITIONS %>
<%= f.hidden_field :_destroy %>
<%= link_to "remove", '#', class: "remove_fields" %>
</fieldset>
here also is the rails helper associated with the link_to_add_fields:
def link_to_add_fields(name, f, association, child_association = nil)
new_object = f.object.send(association).klass.new
id = new_object.object_id
new_object.send(child_association).new if child_association
fields = f.fields_for(association, new_object, child_index: id) do |builder|
render(association.to_s.singularize + "_fields", f: builder)
end
link_to(name, '#', class: "add_fields", data: {id: id, fields: fields.gsub("\n", "")})
end
I was hoping to avoid turning this question into a novel, but there it is... I hope that's enough info to get this thing working.
The code below will be executed when the page is loaded:
$(document).ready(function () {
// put here code to execute on page loading
});
If the code should be executed only on one page, put it in a javascript file that is called only by this page, or add a test in the method to execute the code only when needed.
Related
In this code I was trying to remove fileds for nested_attributes using ajax :remote => ture to avoid reloading
the whole page in browser. Although fileds in fields_for was removed from DOM and association was removed from database, the fields of the nested attributes
still exist in page source and raise ActiveRecord::RecordNotFound error when trying to send params to update action of parent model
consider the following code:
_artist_form.html.erb
<%= form_for #artist do |f| %>
<%= f.label :name %>
<%= f.text_field :name %><br/>
<%= f.label :style %>
<%= f.text_field :style %><br/>
<%= f.fields_for :songs do |song_builder|%>
<div id = 'song_<%= song_builder.object.id %>_div'>
<%= song_builder.label :title %>
<%= song_builder.text_field :title %><br/>
<%= song_builder.label :lyrics %>
<%= song_builder.text_area :lyrics %><br/>
<%= link_to 'Remove song', delete_song_path(:a_id => #artist.id, :s_id => song_builder.object.id),
:method => :delete , :remote => true %>
</div>
<% end %>
<%= f.submit 'Save' %>
<% end %>
routes.rb
Rails.application.routes.draw do
...
delete '/artists/remove_song', :to => 'artists#delete_song', :as => :delete_song
end
application_controller.rb
class ArtistsController < ApplicationController
def edit
...
end
def update
#artist = Artist.find(params[:id])
if #artist.update(artist_params) #=> error Couldn't find Song with ID=2 for Artist with ID=2
redirect_to artist_path(#artist)
else
flash[:errors] = #artist.errors.full_messages
render :edit
end
end
...
def delete_song
#song_id = params[s_id]
aritst = Artist.find(:params[a_id])
song = artist.songs.find(#song_id)
song.delete
respond_to do |format|
format.js {render 'delete_song.js.erb'}
end
end
end
delete_song.js.erb
$('#song_<%= #song_id %>_div').remove() ;
Error
Couldn't find Song with ID=2 for Artist with ID=2
how to prevent sending params of removed fields by $(...).remove() to update action?
I tried to find a solution for this error. So according to charlietfl comment, I tried to store delete status somewhere locally, then rails can delete association later. So I modified the code as following:
deleting all remote script code including delete_song.js.erb file and delete_song action and delete route. then I allowed marking nested attribute for delete in Artist model file:
accepts_nested_attributes_for :songs, :allow_destroy => true
then adding delete button in _artist_form.html.erb file as following:
<%= button_tag 'x' , :class => 'close_sign', :type => 'button', :onclick => "$('#song_#{song_builder.object.id}_destroy').val('true'); $('#song_#{song_builder.object.id}_div').hide()" %><br/>
and a hidden flied to fields_for as below:
<%= song_builder.hidden_field :_destroy, :id => "song_#{song_builder.object.id}_destroy" %>
and allowing :songs_nested_attributes => [:title, :lyrics, :_destroy] in song_params
once user remove the song field, it will be hidden and marked for destroy later
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).
I have a complex form for a survey. A survey
belongs_to :template
has_many :questions, :through => :template
has_many :answers, :through => :questions
I.e. User creates a new survey, and he must select a survey template. The survey template will create some default questions and answer fields.
<%= form_for #survey do |f| %>
<p>Select a template:</p>
<%= render #templates, :locals => {:patient => #patient }, :f => f %>
<% end %>
Then I render the _templates partial, and I still have access to the form object. From here, the idea is that a user can click on a template name, and the template questions and answers will be rendered via Ajax.
<% #templates.each do |template| %>
<div class="thumbnail">
<%= link_to template.name,
{ :controller => "surveys",
:action => "new",
:template_id => template.id,
:patient_id => nil,
:f => f,
:remote=> true },
:class=> "template", :id=> template.id %>
</div>
<% end %>
surveys#new:
respond_to :js, :html
def new
#template = Template.find(params[:template_id])
#patient = Patient.find(params[:patient_id])
end
new.js.erb:
$('#assessment').append("<%= j (render new_survey_path, :locals => {:f => f} ) %>");
new_survey_path:
<%= f.fields_for :questions do |builder| %>
<% #template.questions.where(category:"S").each do |question| %>
<p><%= question.content %></p>
<%= render 'answer_fields', :question=> question %>
<% end %>
<% end %>
But I'm having trouble passing the original |f| object from #survey to new_survey_path. The last place I can access the form object is in the templates partial.
How can I fix this?
I have a remote form which contains 3 radio button tags, each will change the DB accordingly. This works perfectly fine in chrome but when I switch to FF the radio get checked and all but the DB does not change at all.
This is the form in my view.
<%= form_tag ("deal_status"), :remote => true, :class => "deals_status" do %>
<%= hidden_field_tag 'deal_id', d.id.to_s %>
<%= radio_button_tag( :state, "won"+d.id.to_s, d.state == "won", :class => "toggle-btn-left toggle-btn", :value =>"won") %>
<%= label_tag 'state_won'+d.id.to_s, "won", :class=>"btn" %>
<%= radio_button_tag :state, "lost"+d.id.to_s, d.state == 'lost', :class => "toggle-btn-center toggle-btn",:value => "lost" %>
<%= label_tag 'state_lost'+d.id.to_s, "lost",:class=>"btn" %>
<%= radio_button_tag :state, "pending"+d.id.to_s, d.state == 'pending',:class => "toggle-btn-right toggle-btn", :value => "pending" %>
<%= label_tag 'state_pending'+d.id.to_s, "pending",:class=>"btn" %>
<% end %>
this the js that does the submitting
$("body").on("change", "form :radio", function(){
$(this).closest("form").submit();
});
and this is the controller's action :
def deal_status
deal_id = params[:deal_id]
d = Deal.find_by_id(deal_id)
d.state = params[:state]
d.save
#deal_id = deal_id
#deal = d
respond_to do |format|
format.js
end
end
I have a Rails 3.2.13 app with some Ajax on forms and links, using the remote parameter.
The problem is that i can't find in the docs how to do the same with text fields - the
remote parameter didn't work, so i think it's not supported on input objects.
I'd like to do bind 'ajax:xxx' events (like 'ajax:success') on my text_field objects.
I this even possible with UJS? If not, what my options are?
Here's some code:
<%= form_for #post, :html => {:class => 'form-horizontal'} do |f| %>
<div class = 'control-group'>
<%= f.label :title, :html => {:class => 'control-label'} %>
<%= f.text_field :title, :placeholder => 'Title', :class => 'input-xxlarge' %>
</div>
<div class = 'control-group'>
<%= f.label :body, :html => {:class => 'control-label'} %>
<%= f.text_area :body, :placeholder => 'Your post here', :class => 'input-xxlarge',
:rows => 15 %>
</div>
<div class = 'control-group'>
<%= f.label :tags, :html => {:class => 'control-label'} %>
<%= f.text_field :tags, :placeholder => 'Tags separeted by ,', :class => 'input-xxlarge',
:value => '' %>
</div>
<%= f.submit 'Create', :class => 'btn btn-primary'%>
Thanks!
I would bind a change or blur event to the input, and then make the Ajax call manually on your javascript/coffecript file.
posts.js
$('#post_title').change(function() {
// Do your stuff, instantiate variables, etc...
$.ajax({
type: post_or_get,
url: your_url,
data: your_data,
success: function(data) {
// Handle stuff after hitting the server here
},
error: function(data) {
}
});
});