Replace form index ID after clone - javascript

Within a Project form, a user can clone any specific task -- this is working fine. I now need to replace the copied task's index ID (which is a time stamp) with a new time stamp. My current code only replaces a single div.
How can I replace all form input/label field IDs with a timestamp? I current do a find() and then replace.
Any ideas greatly appreciated!
$(function() {
$('form').on('click', '.clone-task', function(event) {
event.preventDefault();
var time = new Date().getTime();
var taskCopy = $(this).parents(".dupForm").clone();
$("#dupTask").append(workoutCopy);
var attributes = taskCopy.find('input').attr('name').replace(/\[\d+]/g, time);
alert(attributes);
});
});
Task Form (ruby-on-rails):
<fieldset>
<div class="field">
<b><%= f.label :name, "Major Task" %></b> |
<%= f.text_field :name, :placeholder => "task name" %>
<%= f.hidden_field :_destroy %>
<%= link_to "remove", '#', class: "remove_fields" %>
</div>
<div class="field">
<%= f.label :time_start, "Scheduled Time" %><br />
<%= f.time_select :time_start, {:ampm => true, :minute_step => 15} %>
</div>
<div class="field">
<%= f.label :task_duration, "Task Duration(mins)" %>
<%= f.number_field :task_duration, size: 3 %>
</div>
<b>Add Supporting Actions to Your Task</b>
<%= f.fields_for :activities do |builder| -%>
<%= render 'activity_fields', f: builder %>
<% end %>
</div>
<%= link_to_add_fields "Add Action", f, :activities %>
</fieldset>

jQuery attr() method allows you to use a function as argument which will act as a loop to process all matched elements.
taskCopy.find('input').attr('name', function( idx, name){
return name.replace(/\[\d+]/g, time);
});
API refrence: http://api.jquery.com/attr/

Related

Rails: How to keep at least one form section displayed in edit forms

Following railscasts #196 Nested Model Form, I was able to implement a working add/remove function to my forms.
The problem is when I remove the last form section, submit, and edit form. The form section is empty and displays the "+ Add More" link only (since I removed the others when I submitted the form?).
By default, I used #userprofile.programs.build so the form builds one program section when it is first created.
userprofiles_controller.rb
def new
#userprofile = Userprofile.new(params[:userprofile])
#userprofile.programs.build
end
_form.html.erb
<h3>Programs</h3>
<%= f.fields_for :programs do |builder| %>
<%= render 'program_fields', f: builder %>
<% end %>
<div class="field">
<%= link_to_add_fields "+ Add More", f, :programs %>
</div>
_program_fields.html.erb
<fieldset>
<%= f.select :program_name, [['A'], ['B']], { label: "Program Name: ", :include_blank => "Please select a program...", { class: "form-control" } %>
<%= f.select :program_role, [['Student'], ['Teacher']], { label: "Program Role: ", :include_blank => "Please select your role..." }, { class: "form-control" } %>
<%= f.hidden_field :_destroy %>
<%= link_to "Delete", '#', class: "remove_fields" %>
</fieldset>
Not sure how or if I need to add a condition and build in the userprofiles_controller.rb when the edit form is empty? So that if the whole section is removed, it still shows one form section by default and not just a empty section with the link to "+ Add More".
Or if there is some way so the first program section cannot be deleted. But the rest that are added has the "Delete" function?
Any insight would help, thank you!
UPDATE:
userprofiles.js.coffee
$(document).on 'click', 'form .remove_fields', (event) ->
$(this).prev('input[type=hidden]').val('1')
$(this).closest('fieldset').hide()
event.preventDefault()
Let's say you have the following HTML -- I added a couple of classes:
_form.html.erb
<div class="programs-form">
<h3>Programs</h3>
<div class="programs-fields">
<%= f.fields_for :programs do |builder| %>
<%= render 'program_fields', f: builder %>
<% end %>
</div>
<div class="field">
<%= link_to_add_fields "+ Add More", f, :programs %>
</div>
</div>
_program_fields.html.erb
<fieldset class="program">
<%= f.select :program_name, [['A'], ['B']], { label: "Program Name: ", :include_blank => "Please select a program...", { class: "form-control" } %>
<%= f.select :program_role, [['Student'], ['Teacher']], { label: "Program Role: ", :include_blank => "Please select your role..." }, { class: "form-control" } %>
<%= f.hidden_field :_destroy %>
<%= link_to "Delete", '#', class: "remove_fields" %>
</fieldset>
Then, assuming you have jQuery loaded somewhere in your app, you can run the following script:
$(function () {
$('a.remove_fields').hide();
$('.programs-fields').on('change', function (ev) {
if ($('fieldset.program').length > 1) {
$('a.remove_fields').show();
}
});
});
I haven't had the chance to set up a test environment and run this code, so please let me know if you have any problems -- I'll be more than happy to fix any bugs!

Error: ActionController::Unknown Format (for format.js)

I'm completing a project. I have a search field that accepts a url. Upon submit, my code scrapes data from a website and saves it in a variable. I want to use that data to automatically fill in form fields for the user on that same page.
Here's what I currently have in the view:
<%= provide(:title, "New Deal") %>
<h3 class="create">Step 1: <span class="text">Enter the wholesale URL and click add button to create a new deal.</span></h3>
<%= form_tag new_deal_path, id: "search-form", method: :get do %>
<p>
<%= label_tag(:search, "Enter the URL:") %>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Add Deal", name: nil, class: "scrape-trigger", remote: true %>
</p>
<% end %>
<% end %>
Here's my controller action:
def new
if params[:search]
#response = Deal.search(params[:search])
respond_to do |format|
format.js
end #currently, can't get this to work.
end
#deal = Deal.new
#deal.orders.build
#user = User.new
end
And here is the form I want to fill:
<div class="manual-deal">
<%= f.label :url %><br>
<%= f.url_field :url %><br><br>
<%= f.label :title %><br>
<%= f.text_field :title %><br><br>
<%= f.label :image %><br>
<%= f.file_field :image %><br><br>
<%= f.label :retail_price_cents %><br>
<%= f.text_field :retail_price_cents %><br><br>
<%= f.label :wholesale_price_cents %><br>
<%= f.text_field :wholesale_price_cents %><br><br>
<%= f.label :minimum_bids %><br>
<%= f.number_field :minimum_bids %><br><br>
<%= f.label :estimated_delivery %><br>
<%= f.date_field :estimated_delivery %><br><br>
<%= f.label :delivery_method %><br>
<%= f.select :delivery_method, ['USPS', 'UPS', 'FedEX', 'Shyp', 'Local Pickup'] %><br><br>
<%= f.label :description %><br>
<%= f.text_area :description %><br>
<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="<%= Rails.configuration.stripe[:publishable_key] %>"
data-description="Charge"
data-amount="<%=#deal.wholesale_price_cents%>">
</script>
<% end %>
Following the advice on another question, I created a new.js.erb file in the view where I want this to happen. I thought I could fill the fields from there using:
function ready() {
$('.scrape-trigger').on("click", function() {
$('#deal_url').val(params[:search]);
$('#deal_title').val(title);
$('#deal_image').val(image);
$('#deal_wholesale_price_cents').val(price_range);
$('#deal_description').val(description);
});
};
$(document).on('ready page:load', ready)
Not quite sure about this last part. Can someone point me in the right direction? I've been stuck on this for hours and haven't found a decent solution. I've found some other resources on Ajax, but nothing that works with what I need with this scraped data.
Cheers.
I'm assuming #response has all the information you're going to need when filling out the form. (Also note that #deal and #user will not be available to new.js.erb because they are defined after you render that file.)
This .js.erb file is rendered exactly once, exactly when it is rendered. Because of that, you don't need to worry about any $(document).on('ready page:load', ready) nonsense. You don't want this code to run when the page has loaded, you want it to run when the file is rendered. Get rid of it!
You should be left with just the .val() lines. This is a fine way to go about setting the value of things, but this file has no idea what params[:search] or title is. The only variable you passed to this file is #response. Use it!
So you should end up with something like the following:
$('#deal_url').val(#reponse.url);
$('#deal_title').val(#reponse.title);
$('#deal_image').val(#reponse.image);
$('#deal_wholesale_price_cents').val(#reponse.price_range);
$('#deal_description').val(#reponse.description);

Put html param into Rails array parameter

Ruby on Rails 4.1
The form is placing the parameters into an array when POST is done. I am making a script to auto fill the billing address the same as the shipping address. When the script runs it is assigning the values as html values.
How do you put these values into the payment array being sent?
The log where cc_name and ship_name are outside the payment array, I want them inside:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"x", "cc_name"=>"Bobby", "payment"=>{"telephone"=>"555", "email"=>"drfernandez1#yahoo.com", "address1"=>"641 W Rt 66", "address2"=>"", "city"=>"Glendora", "state"=>"CA", "postal_code"=>"91740", "country"=>"USA", "cc_type"=>"Visa", "cc_number"=>"5555555588884444", "ccv"=>"321", "expires_on(1i)"=>"2014", "expires_on(2i)"=>"9", "expires_on(3i)"=>"1", "ship_address1"=>"641 W Route 66", "ship_address2"=>"", "ship_city"=>"Glendora", "ship_state"=>"c", "ship_postal_code"=>"91740", "ship_country"=>"u", "card_holder_auth"=>"1", "charge_auth"=>"1", "name_auth"=>"David Duke", "date_auth"=>"7"}, "billingtoo"=>"on", "ship_name"=>"Bobby", "commit"=>"Send Payment"}
The form (minus clutter):
<%= form_for #payment do |f| %>
<%= render 'shared/payment_error_messages' %>
<h1>Fill in all blank areas with payment information:</h1>
<div class="col-md-5 col-md-offset-1">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Applicant Information</h3>
</div>
<div class="panel-body">
<%= f.label :cc_name, "Name as it appears on credit card:" %><br>
<%= f.text_field :cc_name, class: "input-lg", :name => "cc_name" %> <%#= #payment.errors.get(:cc_name) %>
<%= f.label :telephone, "Telephone Number:" %><br>
<%= f.text_field :telephone, class: "input-lg" %>
...
<div class="panel-body">
<input type="checkbox" name="billingtoo" onclick="FillBilling(this.form)"><em>Shipping Address is the same as the Billing Address</em>
<p>Please Note: This cannot be a P.O box address</p>
<%= f.label :ship_name, "Name:" %><br>
<%= f.text_field :ship_name, class: "input-lg", :name => "ship_name" %>
<%= f.label :ship_address1, "Address 1:" %><br>
<%= f.text_field :ship_address1, class: "input-lg" %>
...
<%= f.submit "Send Payment", class: "btn btn-lg btn-primary", id: "commit" %>
</div>
</div>
</div>
<% end %>
<br/>
<%= link_to 'Back', session[:last_page] %>
</div>
<script>
function FillBilling(f) {
if(f.billingtoo.checked == true) {
f.ship_name.value = f.cc_name.value;
}
}
</script>
You are overwriting the field's name:
:name => "cc_name"
That's the reason why it is sent outside of the array. Try removing the :name assigning:
<%= f.text_field :cc_name, class: "input-lg" %>
and
<%= f.text_field :ship_name, class: "input-lg" %>

Rails:In-place editing in edit form with submit button

I want to create my edit form such that it will display the current user information simply as text not in text filed and when user click on the text it will turn into text field and user can edit his information . Changes will be reflect in data base only when user click on submit button.
Simply it is not completely in place editing and not completely like default edit form it is mixture of the behaviour of both the features.
My form looks like following .it is not complete form these are some of the fields of form.
<%= form_for #contact, :html => { :multipart => true, :class => "contact_form"} do |f| %>
<% if #contact.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#contact.errors.count, "error") %> prohibited this contact from being saved:</h2>
<ul>
<% #contact.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :f_name, "First Name" %><br/>
<%= f.text_field :f_name %>
</div>
<div class ="field">
<%= f.label :experience, "Total years of experience "%><br/>
<%= f.select :experience, (0...30),{},{:class => 'select'} %>
</div>
<div class="field">
<%= f.label :l_name, "Last Name" %><br/>
<%= f.text_field :l_name %>
</div>
<div class = "field">
<%= f.label :primary_practice_area, "Primary practice area" %><br/>
<%= f.select :primary_practice_area , MetaPracticeArea.all.collect {|p| [ p.practice_area, p.id ] } %>
</div>
<div class = "field">
<%= f.label :phone, "Phone" %><br/>
<%= f.text_field :phone %>
</div>
<div class="actions">
<%= f.submit :class => "submit_btn" %>
</div>
<% end %>
and controller and model is default.
You can try the REST_in_place gem: https://github.com/janv/rest_in_place
Check below link for in_place_editing :
http://railscasts.com/episodes/302-in-place-editing?view=asciicast

Dynamically add & remove new but the same fields of a form any amount times

I have a form that has no nested models.
class UserProductsController
def new
#user_product = current_user.user_products.build
end
end
With jquery/javascript i want to add and remove new #user_product fields on the same form. This how it would look normally:
<%= form_for(#user_product) do |f| %>
<%= f.error_messages %>
<%= f.text_field :product %>
<%= f.text_field :address %>
<%= f.text_field :price %>
<%= f.submit %>
<% end %>
And I'm trying to achieve:
<%= form_for(#user_product) do |f| %>
<%= f.error_messages %>
<%= f.text_field :product_name %>
<%= f.text_field :address %>
<%= f.text_field :price %>
---New ID(New generated ID, could be any new number in the database)
<%= f.text_field :product_name %>
<%= f.text_field :address %>
<%= f.text_field :price %>
<%= Remove this Product %> # ajax style, this link removes this product entirely
----ID 3----
<%= f.text_field :product_name %>
<%= f.text_field :address %>
<%= f.text_field :price %>
<%= Remove this Product %>
-----Add link------
<%= Add Another Field %> # ajax style adding
<%= f.submit %>
<% end %>
Notice the new IDs that aren't preset and the one submit button so this way more then one Product can be created at a time by a User. How do i achieve the above?
Thank you.
Answer:
Using the User.rb model you can do what James said. Here is my form that works.
<%= form_for(current_user, :url => user_products_path) do |f| %>
<%= f.error_messages %>
<%= f.fields_for :user_products do |builder| %>
<%= render "user_product_fields", :f => builder %>
<% end %>
<%= link_to_add_fields "Add a UserProduct", f, :user_products %>
<%= f.submit "Create" %>
<% end %>
_user_product_fields.html.erb
<div class="fields">
<%= f.label :product, "Product" %>
<%= f.text_field :product %>
<%= f.label :address, "Address" %>
<%= f.text_field :address %>
<%= f.label :price %>
<%= f.text_field :price %>
<%= link_to_remove_fields "remove", f %>
</div>
As others have suggested (somewhat unhelpfully), use nested forms.
You need the form to be based on the current_user object with fields_for declaration for :user_products. You will need to set the url for the form to post back to the user_product controller not the user controller using url_for and you will need to adjust the user_product controllers update and create actions to make use of params[:user] instead of params[:user_product]
If you have your accepts_nested_attributes configured properly all should be good.
BTW if you follow those railscasts you will find that the javascript to add new will not work for Rails 3.x
You should use something like this for your view helpers
module ApplicationHelper
def link_to_remove_fields(name, f)
f.hidden_field(:_destroy) + link_to_function(name, "remove_fields(this)")
end
def link_to_add_fields(name, f, association)
new_object = f.object.class.reflect_on_association(association).klass.new
fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
render(association.to_s.singularize + "_fields", :f => builder)
end
link_to_function(name, "add_fields(this, '#{association}', '#{escape_javascript(fields)}')")
end
end
and something like this for your javascript in your application.js file
// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults
function remove_fields(link) {
$(link).previous("input[type=hidden]").value = "1";
$(link).up(".fields").hide();
}
function add_fields(link, association, content) {
var new_id = new Date().getTime();
var regexp = new RegExp("new_" + association, "g")
$(link).up().insert({
after: content.replace(regexp, new_id)
});
}
and obviously your form_for need to be refactored to something like this
<%= form_for(current_user, :url => user_product_path) do |f| %>
<!-- add your f.fields_for :user_products here, probably in a rendered partial -->
<%end%>
That should be enough with the rails casts to get you going
Checkout this:
http://railscasts.com/episodes/196-nested-model-form-part-1
http://railscasts.com/episodes/197-nested-model-form-part-2
You can use cocoon for this.

Categories

Resources