trying to iterate 3d array | undefined method `each' for nil:NilClass - ruby-on-rails

what i'm making wrong?
The first 7 lines from the Array i can iterate but when i'm trying to open the another dimension than i receive an error.
My Code
require 'rest-client'
class ApiController < ApplicationController
def listings
url = 'https://api.coinmarketcap.com/v2/ticker/'
response = RestClient.get(url)
#jsonData = JSON.parse(response)
end
end
api_controller works
<h1>LISTING </h1>
<% #jsonData["data"].each do |coin| %>
<%coin.each do |id| %>
Name: <%= id["name"] %> <br />
Symbol: <% id["symbol"] %><br />
Website_slug: <% id["website_slug"] %><br />
Rank: <% id["rank"] %><br />
Circulating_supply: <% id["circulating_supply"] %><br />
total_supply: <% id["total_supply"] %><br />
max_supply: <% id["max_supply"] %><br />
till here it works
begin here it not works
<%id["quotes"].each do |quotes| %>
<%quotes.each do |usd| %>
Price: <% usd["price"] %><br />
Volume24h: <%= usd["volume_24h"] %><br />
Market_cap: <%= usd["market_cap"] %><br />
Change_1he: <%= usd["pricpercent_change_1he"] %><br />
Change_24h: <%= usd["percent_change_24h"] %><br />
Change_7d: <%= usd["percent_change_7d"] %><br />
<%end%>
<%end%>
<%end%>
<%end%>
{"1"=>{"id"=>1, "name"=>"Bitcoin", "symbol"=>"BTC", "website_slug"=>"bitcoin", "rank"=>1, "circulating_supply"=>17298850.0, "total_supply"=>17298850.0, "max_supply"=>21000000.0, "quotes"=>{"USD"=>{"price"=>6592.56514166, "volume_24h"=>3990509859.95985, "market_cap"=>114043795501.0, "percent_change_1h"=>-0.31, "percent_change_24h"=>-0.36, "percent_change_7d"=>-0.61}}, "last_updated"=>1538393012}, "1027"=>{"id"=>1027, "name"=>"Ethereum", "symbol"=>"ETH", "website_slug"=>"ethereum", "rank"=>2, "circulating_supply"=>102298658.0, "total_supply"=>102298658.0, "max_supply"=>nil, "quotes"=>{"USD"=>{"price"=>229.147840966, "volume_24h"=>1701049487.13546, "market_cap"=>23441516679.0, "percent_change_1h"=>-0.8, "percent_change_24h"=>-2.56, "percent_change_7d"=>-2.44}}, "last_updated"=>1538393021}, "52"=>{"id"=>52, "name"=>"XRP", "symbol"=>"XRP", "website_slug"=>"ripple", "rank"=>3, "circulating_supply"=>39870907279.0, "total_supply"=>99991836919.0, "max_supply"=>100000000000.0, "quotes"=>{"USD"=>{"price"=>0.5790784377, "volume_24h"=>1229031882.79177, "market_cap"=>23088382697.0, "percent_change_1h"=>-1.6, "percent_change_24h"=>-4.58, "percent_change_7d"=>7.96}}, "last_updated"=>1538393043}, "1831"=>{"id"=>1831, "name"=>"Bitcoin Cash", "symbol"=>"BCH", "website_slug"=>"bitcoin-cash", "rank"=>4, "circulating_supply"=>17378475.0, "total_supply"=>17378475.0, "max_supply"=>21000000.0, "quotes"=>{"USD"=>{"price"=>532.361000338, "volume_24h"=>480935803.85542, "market_cap"=>9251622335.0, "percent_change_1h"=>-0.78, "percent_change_24h"=>-1.57, "percent_change_7d"=>13.15}}, "last_updated"=>1538393013}, "1765"=>{"id"=>1765, "name"=>"EOS", "symbol"=>"EOS", "website_slug"=>"eos", "rank"=>5, "circulating_supply"=>906245118.0, "total_supply"=>1006245120.0, "max_supply"=>nil, "quotes"=>{"USD"=>{"price"=>5.6494577239, "volume_24h"=>822687391.374753, "market_cap"=>5119793479.0, "percent_change_1h"=>-0.53, "percent_change_24h"=>-3.01, "percent_change_7d"=>-1.66}}, "last_updated"=>1538393011}, "512"=>{"id"=>512, "name"=>"Stellar", "symbol"=>"XLM", "website_slug"=>"stellar", "rank"=>6, "circulating_supply"=>18789958255.0, "total_supply"=>104323820467.0, "max_supply"=>nil, "quotes"=>{"USD"=>{"price"=>0.261922298, "volume_24h"=>67633971.9905846, "market_cap"=>4921509046.0, "percent_change_1h"=>0.14, "percent_change_24h"=>1.03, "percent_change_7d"=>-0.49}}, "last_updated"=>1538392997}, "2"=>{"id"=>2, "name"=>"Litecoin", "symbol"=>"LTC", "website_slug"=>"litecoin", "rank"=>7, "circulating_supply"=>58532552.0, "total_supply"=>58532552.0, "max_supply"=>84000000.0, "quotes"=>{"USD"=>{"price"=>60.7806370254, "volume_24h"=>461333051.026648, "market_cap"=>3557645805.0, "percent_change_1h"=>-0.07, "percent_change_24h"=>-1.17, "percent_change_7d"=>4.09}},

You could try this code and feedback please :)
<h1>LISTING </h1>
<% #jsonData.fetch('data', {}).each do |id, coin| %>
Name: <%= coin['name'] %> <br />
Symbol: <%= coin['symbol'] %> <br />
Website_slug: <%= coin['website_slug'] %> <br />
Rank: <%= coin['rank'] %> <br />
Circulating_supply: <%= coin['circulating_supply'] %> <br />
total_supply: <%= coin['total_supply'] %> <br />
max_supply: <%= coin['max_supply'] %> <br />
Price: <%= coin.dig('quotes', 'USD', 'price') %> <br />
Volume24h: <%= coin.dig('quotes', 'USD', 'volume_24h') %> <br />
Market_cap: <%= coin.dig('quotes', 'USD', 'market_cap') %> <br />
Change_1he: <%= coin.dig('quotes', 'USD', 'pricpercent_change_1he') %> <br />
Change_24h: <%= coin.dig('quotes', 'USD', 'percent_change_24h') %> <br />
Change_7d: <%= coin.dig('quotes', 'USD', 'percent_change_7d') %> <br />
<%end%>
<%end%>
This is a sample of your JSON:
{
"data":{
"1":{
"id":1,
"name":"Bitcoin",
"symbol":"BTC",
"website_slug":"bitcoin",
"rank":1,
"circulating_supply":17298850.0,
"total_supply":17298850.0,
"max_supply":21000000.0,
"quotes":{
"USD":{
"price":6592.56514166,
"volume_24h":3990509859.95985,
"market_cap":114043795501.0,
"percent_change_1h":-0.31,
"percent_change_24h":-0.36,
"percent_change_7d":-0.61
}
},
"last_updated":1538393012
},
"1027":{
"id":1027,
"name":"Ethereum",
"symbol":"ETH",
"website_slug":"ethereum",
"rank":2,
"circulating_supply":102298658.0,
"total_supply":102298658.0,
"max_supply":null,
"quotes":{
"USD":{
"price":229.147840966,
"volume_24h":1701049487.13546,
"market_cap":23441516679.0,
"percent_change_1h":-0.8,
"percent_change_24h":-2.56,
"percent_change_7d":-2.44
}
},
"last_updated":1538393021
},
"52":{
"id":52,
"name":"XRP",
"symbol":"XRP",
"website_slug":"ripple",
"rank":3,
"circulating_supply":39870907279.0,
"total_supply":99991836919.0,
"max_supply":100000000000.0,
"quotes":{
"USD":{
"price":0.5790784377,
"volume_24h":1229031882.79177,
"market_cap":23088382697.0,
"percent_change_1h":-1.6,
"percent_change_24h":-4.58,
"percent_change_7d":7.96
}
},
"last_updated":1538393043
},
"1831":{
"id":1831,
"name":"Bitcoin Cash",
"symbol":"BCH",
"website_slug":"bitcoin-cash",
"rank":4,
"circulating_supply":17378475.0,
"total_supply":17378475.0,
"max_supply":21000000.0,
"quotes":{
"USD":{
"price":532.361000338,
"volume_24h":480935803.85542,
"market_cap":9251622335.0,
"percent_change_1h":-0.78,
"percent_change_24h":-1.57,
"percent_change_7d":13.15
}
},
"last_updated":1538393013
},
"1765":{
"id":1765,
"name":"EOS",
"symbol":"EOS",
"website_slug":"eos",
"rank":5,
"circulating_supply":906245118.0,
"total_supply":1006245120.0,
"max_supply":null,
"quotes":{
"USD":{
"price":5.6494577239,
"volume_24h":822687391.374753,
"market_cap":5119793479.0,
"percent_change_1h":-0.53,
"percent_change_24h":-3.01,
"percent_change_7d":-1.66
}
},
"last_updated":1538393011
},
"512":{
"id":512,
"name":"Stellar",
"symbol":"XLM",
"website_slug":"stellar",
"rank":6,
"circulating_supply":18789958255.0,
"total_supply":104323820467.0,
"max_supply":null,
"quotes":{
"USD":{
"price":0.261922298,
"volume_24h":67633971.9905846,
"market_cap":4921509046.0,
"percent_change_1h":0.14,
"percent_change_24h":1.03,
"percent_change_7d":-0.49
}
},
"last_updated":1538392997
},
"2":{
"id":2,
"name":"Litecoin",
"symbol":"LTC",
"website_slug":"litecoin",
"rank":7,
"circulating_supply":58532552.0,
"total_supply":58532552.0,
"max_supply":84000000.0,
"quotes":{
"USD":{
"price":60.7806370254,
"volume_24h":461333051.026648,
"market_cap":3557645805.0,
"percent_change_1h":-0.07,
"percent_change_24h":-1.17,
"percent_change_7d":4.09
}
}
}
}
}
Following this json you can see that there are no arrays [] it just a nested hashes {} so no need for all of your loops. For ex. to get the price you need to do something like: #jsonData['data']['1']['quotes']['USD']['price']
This path ['data']['1']['quotes']['USD']['price'] is all static, which means it will be the same for every coin. the only dynamic/changing part is ['1']. Sometimes it will be ['1'], ['1027'], ['52'], etc.
So in my code you can see that I access all of the data staticly but only for the IDs I had to loop over it but this loop will be over key => value because as mentioned before we are dealing with hashes not arrays.
So when I did <% #jsonData.fetch('data', {}).each do |id, coin| %>:
id has the value of '1'.
coin has the structure of the coin (you can staticlly retrieve any piece of data like coin.dig('quotes', 'USD', 'price') for ex.
What you where doing:
<% #jsonData.['data'].each do |coin| %>:
coin will be ['1', 'structure of the coin here']
when you do coin['name'] this will return nil but won't fail. At this point you thought it's working but it is not.

Related

What would the rails helper tag equivalent be of this select?

I have been struggling to convert this to some sort of rails helper select. Can anyone help with this?
<%= form_with(model: scheduleevent, class: "contents", data: { controller: 'nested-form', nested_form_wrapper_selector_value: '.nested-form-wrapper' }) do |form| %>
... schedtimerange_form start ...
<%= select_tag "days[]",options_for_select(Date::DAYNAMES.zip((1..7))), id:"days[]", multiple: true, class: 'multis' %>
<% end %>
The select tag is within a nested attribute partial called schedtimerange_form that is called like this:
<template data-nested-form-target="template">
<%= form.fields_for :schedtimeranges, Schedtimerange.new, child_index: 'NEW_RECORD' do |schedtimerange| %>
<%= render "schedtimerange_form", form: schedtimerange %>
<% end %>
</template>
<%= form.fields_for :schedtimeranges do |schedtimerange| %>
<%= render "schedtimerange_form", form: schedtimerange %>
<% end %>
Schedtimerange_form:
<div data-new-record="<%= form.object.new_record? %>">
<div class="w-full">
<div data-controller="select">
<%= select_tag "days[]",options_for_select(Date::DAYNAMES.zip((1..7))), id:"days[]", multiple: true, class: 'multis' %> </div>
</div>
<div>
<div class="w-full mb-2">
<label class="form_label"><%= t("scheduling_events_new_lbl_starttime") %> </label>
<div class="pr-4"><%= form.text_field :start_time, data: { controller: "flatpickr", flatpickr_enable_time: true, flatpickr_no_calendar: true,
flatpickr_date_format: "h:i K" }, class: 'form_control', placeholder: "#{t("scheduling_events_new_lbl_starttime")}" %> </div>
</div>
<div class="w-full mb-4">
<label class="form_label"><%= t("scheduling_events_new_lbl_endtime") %> </label>
<div class="pr-4"><%= form.text_field :end_time, data: { controller: "flatpickr", flatpickr_enable_time: true, flatpickr_no_calendar: true, flatpickr_date_format: "h:i K" }, class: 'form_control', placeholder: "#{t("scheduling_events_new_lbl_endtime")}" %> </div>
</div>
<div class="w-full">
<button type="button" class="font-medium text-red-600 dark:text-red-500 hover:underline" data-action="nested-form#remove">Remove Times</button>
</div>
</div><%= form.hidden_field :_destroy %>
</div>
<%= select_tag "days[]",options_for_select(Date::DAYNAMES.zip((1..7))), id:"days[]" %>

How to create a form with dependent fields? (RoR)

I am wondering how to create a form that displays field dependent on the fields selected beforehand. For example: if Coffee is selected as a drink, only then do I want to allow sugar and milk amounts to be input.
Here is my form:
<%= simple_form_for(#order) do |f| %>
<%= f.error_notification %>
<div class="field">
Drink: <%= f.select :drink, ['Coffee', 'Orange Juice', 'Tea'], id: 'extended_list' %><br />
</div>
Coffee Type: <%= f.select :coffee_type, ['Espresso', 'Cappuccino', 'Filter', 'Greek', 'Frappe', 'Latte'] %><br />
Sugar Amount: <%= f.select :sugar_amount, ((1..5).map {|i| [i,i] } << ["None",nil]) %><br />
Milk Amount: <%= f.select :milk_amount, ((1..5).map {|i| [i,i] } << ["None",nil]) %><br />
<% end %>
<%= f.button :submit, class: "button is-info" %>
<% end %>
First you need to wrap the fields you'd like to hide in a div. Add a distinct id to each of them.
For example, if you want to hide coffee_type, you can add the id "js-coffee-type" to it.
Also, add a class (for instance, d-none, as used by Bootstrap) so we can hide it using CSS.
<%= simple_form_for(#order) do |f| %>
<div class="field">
Drink: <%= f.select :drink, ['Coffee', 'Orange Juice', 'Tea'], id: 'extended_list' %><br />
</div>
<div id="js-coffee-type" class="d-none">Coffee Type: <%= f.select :coffee_type, ['Espresso', 'Cappuccino', 'Filter', 'Greek', 'Frappe', 'Latte'] %></div>
<div>Sugar Amount: <%= f.select :sugar_amount, ((1..5).map {|i| [i,i] } << ["None",nil]) %></div>
<div>Milk Amount: <%= f.select :milk_amount, ((1..5).map {|i| [i,i] } << ["None",nil]) %></div>
<%= f.button :submit, class: "button is-info" %>
<% end %>
In the same file, you can write the CSS code that hides this field.
<style>
.d-none { display: none; }
</style>
Now you can write the JS code to toggle the class depending on the first field.
<script>
$("#extended_list").change(function() {
var drink = $("#extended_list").val();
if (drink == "Coffee") {
$("#js-coffee-type").removeClass("d-none");
} else {
$("#js-coffee-type").addClass("d-none");
}
});
</script>
These are not best practices but they should do the work.

Rails - Drop down list with 'other' that allows creation of new model object

I currently have a rather complicated _request_form for creating new Requests in my website. Currently, when creating a request, employees must choose their name from a dropdown menu like so:
<%= f.collection_select :name, Employee.all(:order => 'name'), :name, :name %>
This selects puts the right Employee in the Request. However, on the off chance the employee isn't in database I'd like an other option in the collection_select that spawns two textboxes (for Employee name and email), and upon form submission makes the new Employee.
I assume this requires some sort of fancy Ajax, but my limited Rails knowledge doesn't extend that far!
Edit:
Here's my full view:
<%= javascript_include_tag :defaults, "nested_form" %>
<div class="request_form">
<% if !#request.errors.empty? %>
<div class="alert alert-error">
<ul>
<% #request.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="well">
<%= nested_form_for #request, html: { multipart: true } do |f| %>
<%= f.label :title %><br />
<%= f.text_field :title %><br /><br />
<%= f.label :name, 'Submitted By' %><br />
<%= f.select :name, Employee.sorted_employees_list.map { |value| [ value, value ] }, :id => "employee_box" %><br />
<div id="new_employee_data">
</div>
<%= f.label :description %><br />
<%= f.text_area :description %><br /><br />
<%= f.label :attachment_uploader, 'Attachments' %><%= f.file_field :attachment_uploader, :multiple => true, name: "data_files[attachment_uploader][]" %><br />
<% unless #request.data_files.empty? %>
<%= f.label :attachment_uploader, 'Current Attachments:' %><br />
<% end %>
<%= f.fields_for :data_files do |attachment| %>
<% if !attachment.object.new_record? %>
<%= attachment.label :attachment_uploader, 'Delete: ' + attachment.object.attachment_uploader_url.split("/").last %>
<%= attachment.check_box :_destroy %>
<% end %>
<% end %>
</div>
</div>
<script>
$(document).ready(function(){
$('#employee_box').append("<option>Other</option>");
});
$('#employee_box').change(function() {
if( $('#employee_box').val() === 'other' ) {
$('#new_employee_data').append("<input type='text' id='employee_name' placeholder='Employee Name'> <br/> <br /></input><input type='email' id='employee_email' placeholder='Employee Email'> </input>");
}else {
$('#employee_name').remove();
$('#employee_email').remove();
}
});
</script>
This includes #Kirti's suggestion. However, I can't seem to make it work!
Popup dialog is good choice, I think!
1) Add to your Gemfile, and run bundle:
gem 'jquery-ui-rails'
2) Activate jquery-ui javascript (application.js):
//= require jquery.ui.dialog
3) Link jquery-ui stylesheets (application.css):
*= require jquery.ui.dialog
4) Prepare data for select (employees_controller.rb)
def new
#prices = Price.all.map{|p| [p.price, p.id] }
#prices << ['Create New', 'new_id']
end
5) Display select component on view (employees/new.html.erb):
<%= select_tag :employee, options_for_select(#employees) %>
<div id="new_employee_dialog">
<label for="name" type="text">Employee name:</label>
<input name="name" type="text"/>
<label for="email" type="text">Employee email:</label>
<input name="email" type="email"/>
</div>
6) This javascript work with dialog window and send ajax request (assets/javascripts/employees.js.coffee):
$ ->
$("#new_employee_dialog").dialog
modal: true
width: 400
height: 300
autoOpen: false
draggable: false
dialogClass: "without-header"
buttons: [
text: "Cancel"
click: ->
$(this).dialog "close"
,
text: "Ok"
click: ->
modalForm = $(this)
$.post "/users/form_create",
employee_name: $(modalForm).find("input[name='name']").val()
employee_email: $(modalForm).find("input[name='email']").val()
, (data, status) ->
if data['status'] == 'ok'
modalForm.dialog "close"
alert "Ok"
else
alert "Oops"
]
$('#employee').change ->
selected_employee_id = jQuery("#employee").val()
console.log('selected id: ' + selected_employee_id )
if selected_employee_id == 'new_id'
$("#new_employee_dialog").dialog("open");
7) Create method to catch ajax request on server-side (employees_controller.rb):
def form_create
employee_name = params[:employee_name]
employee_email = params[:employee_email]
# create new user..
respond_to do |format|
format.json { render :json => {status: 'ok'} }
end
end
8) Add it to routes.rb:
post 'users/form_create' => 'users#form_create'
Add an empty div tag(placeholder) where you want to spawn the two input fields:
<div id="new_employee_data">
</div>
Add the following jQuery at the bottom of the view:
<script>
$(document).ready(function(){
$('#request_name').append("<option value='other'>Other</option>");
});
$('#request_name').change(function() {
if( $('#request_name').val() === 'other' ) {
$('#new_employee_data').append("<input type='text' id='employee_name' placeholder='Employee Name'> <br/> <br /></input><input type='email' id='employee_email' placeholder='Employee Email'> </input>");
}else {
$('#employee_name').remove();
$('#employee_email').remove();
}
});
</script>
where,
replace #request_name with the id generated for your collection_select.
You will also need to add code for creating the new employee in the action which is executed at form submission.
NOTE: I am no expert in AJAX but you could adapt the above jQuery and take it from there.

Rails nested forms , hide remove button for first element

Hi i hava a Rails app that uses nested forms, so for example on a section you can add, as many links as you want.. also i have this other code for citizen as some user have two citizens.
My problem here is that at least you need to enter 1 citizen.. this i can make it with jquery validate, im already running that.. The problem is the Delete button that Rails insert for each field.. So i can literaly delete all fields in the form
Is there a way so just the fields added by user have the delete button.. and not all of them?
Is there any documentation about this.. i cant found it.
Here is my code in view..
<div id="nacionalidad">
<%= f.fields_for :citizens do |citizen_form| %>
<div>
<%= citizen_form.label :citizen, t('generales.citizen') %>
<%= citizen_form.select :country_id , Country.all.collect {|p| [ t("generales."+p.iso), p.id ] }, { :include_blank => true } , { :class => 'pca33' } %>
<div id="delerr"><%= citizen_form.link_to_remove t('generales.delete') %></div>
</div>
<% end %>
<%= f.link_to_add t('generales.add'), :citizens %>
</div>
The model citizen.rb
class Citizen < ActiveRecord::Base
attr_accessible :country_id
belongs_to :player
end
Thanks
Here is the full view code. Everything is working just 2 issues:
1) The delete button is present always even for first item, need to remove this delete btn for 1st item
2) If i select a country for citizen, it adds a second option, is there a way to avoid this.. and Only add the new field if the user clics on this.. add button..
Thanks!!!
Full View Code
<!-- Información personal y de contacto -->
<div id="wrapper_signup">
<%= link_to image_tag("espanol/logo.jpg", :border => 0), root_path , :class => 'logoo' %>
<div id="loggeddiv">
<%= link_to "#{current_user.email}", '#' %> |
<%= link_to (t ('generales.salir')), destroy_user_session_path, :method => :delete %>
</div>
<div id="navsteps" >
</div>
<div id="signupdiv">
<%= nested_form_for #player, :url => wizard_path do |f| %>
<div id="nombre">
<%= f.label :name %>
<%= f.text_field :name , :value => "#{current_user.name}"%>
</div>
<div id="apellidos">
<%= f.label :lastname %>
<%= f.text_field :lastname, :value => "#{current_user.lastname}" %>
</div>
<div id="cumple">
<%= f.label :birthday %>
<%= f.date_select :birthday, :start_year => 1950, :include_blank => true %>
</div>
<div id="altura">
<%= f.label :height %>
<%= f.select :height, Player::HEIGHT.each {|h| [ h, h ] } , :include_blank => true %> <%= f.select :height_measure, Player::HEIGHT_MEASURE.each {|h| [ h, h ] } %>
<%= f.select :inches, Player::INCH.each {|h| [ h, h ] }, {}, :style => (#player.inches.present? && #player.height_measure == 'pies' ? 'display: inline ' : 'display: none') %>
<%= f.label :inches, :id => 'inch_label', :style => (#player.inches.present? && #player.height_measure == 'pies' ? 'display: inline ' : 'display: none') %>
</div>
<div id="peso">
<%= f.label :weight %>
<%= f.select :weight, Player::WEIGHT.each {|w| [ w, w ] }, :include_blank => true %> <%= f.select :weight_measure, Player::WEIGHT_MEASURE.each {|h| [ h, h ] } %>
</div>
<div id="ciudad">
<%= f.label :city %>
<%= f.text_field :city %>
</div>
<div id="cnatal" >
<%= f.label :birthplace %>
<%= f.text_field :birthplace %>
</div>
<div id="nacionalidad">
<%= f.fields_for :citizens do |citizen_form| %>
<div>
<%= citizen_form.label :citizen, t('generales.citizen') %>
<%= citizen_form.select :country_id , Country.all.collect {|p| [ t("generales."+p.iso), p.id ] }, { :include_blank => true } , { :class => 'pca33' } %>
<div id="delerr"><%= citizen_form.link_to_remove t('generales.delete') %></div>
</div>
<% end %>
<%= f.link_to_add t('generales.add'), :citizens %>
</div>
<div id="idiomlen">
<%= f.label :languages %>
<% for language in Language.find(:all) %>
<div class="idiomlenbox"><%= check_box_tag "player[language_ids][]", language.id, #player.languages.include?(language) %>
<%= t("languages.#{language.name}") %></div>
<% end %>
<div id="idiomlenotro">
<%= f.label :other_languages %><br>
<%= f.text_field :other_languages %>
</div>
</div>
<div id="cargafoto">
<button type="button" class="photo-button" onclick="document.getElementById('files').click();"><p> <%= t('generales.photo') %> </p></button>
<div id="upload-wrap">
<%= f.file_field :avatar , id: "files" %>
</div>
<div class="thumbperwrap">
<output id="list">
<div class="wraptocenter"><span></span>
<% if #player.avatar.present? %>
<%= image_tag #player.avatar.url(:profile), :class => "thumbper" %>
<% else %>
<img src="../assets/espanol/playersample.png" class="thumbper">
<% end %>
</div>
</output>
</div>
</div>
<script>
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
document.getElementById('list').innerHTML = "";
var span = document.createElement('span');
span.innerHTML = ['<div class="wraptocenter"><span></span><img class="thumbper" src="', e.target.result,
'" title="', escape(theFile.name), '"/></div>'].join('');
document.getElementById('list').insertBefore(span, null);
};
})(f);
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
<div id="videosyt">
<%= f.fields_for :links do |link| %>
<div id="videosytin">
<%= link.label :url %>
<%= link.text_field :url %>
<%= link.link_to_remove t('generales.delete') %>
</div>
<% end %>
<%= f.link_to_add t('generales.add'), :links %>
</div>
<div id="direc">
<%= f.label :cp %>
<%= f.text_field :cp %>
</div>
<div id="telef">
<%= f.label :phone %>
<%= f.text_field :phone %>
</div>
<div id="celu">
<%= f.label :cellphone %>
<%= f.text_field :cellphone %>
</div>
<div id="webpp">
<%= f.label :web_page %>
<%= f.text_field :web_page %>
</div>
<div id="next11">
<%= f.submit t('generales.next'), :class => 'siggreenc' %>
</div>
<% end %>
</div>
</div>
<%= javascript_tag do %>
$('#player_height_measure').on('change', function() {
if (this.value == 'pies') {
$('#player_inches').css('display', 'inline');
$('#inch_label').css('display', 'inline');
} else {
$('#player_inches').css('display', 'none');
$('#inch_label').css('display', 'none');
}
});
<% end %>
<style type="text/css">
#commentForm { width: 500px; }
#commentForm label { width: 250px; }
#commentForm label.error, #commentForm input.submit { margin-left: 253px; }
#signupForm { width: 670px; }
#signupForm label.error {
margin-left: 10px;
width: auto;
display: inline;
}
#newsletter_topics label.error {
display: none;
margin-left: 103px;
}
</style>
<%= javascript_tag do %>
window.onload = function() {
// validate signup form on keyup and submit
$(".edit_player").validate({ // initialize the plugin
errorElement: 'div'});
$("#player_name").rules("add", { required: true, minlength:2, messages: { required: "<%= t('generales.camporequerido') %>", minlength: "Mínimo 2 caracteres"}});
$("#player_lastname").rules("add", { required: true, minlength:2, messages: { required: "<%= t('generales.camporequerido') %>", minlength: "uh minlength?"}});
$("#player_birthday_1i").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_birthday_2i").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_birthday_3i").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_height").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_weight").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_city").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_birthplace").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_citizen").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_phone").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#player_cellphone").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
$("#files").rules("add", { required: true, messages: { required: "<%= t('generales.camporequerido') %>"}});
};
jQuery.extend(jQuery.validator.messages, {
required: "<%= t('generales.camporequerido') %>",
remote: "Please fix this field.",
email: "Ingresa un correo electrónico válido.",
url: "Please enter a valid URL.",
date: "Please enter a valid date.",
dateISO: "Please enter a valid date (ISO).",
number: "Please enter a valid number.",
digits: "Please enter only digits.",
creditcard: "Please enter a valid credit card number.",
equalTo: "Please enter the same value again.",
accept: "Please enter a value with a valid extension.",
maxlength: jQuery.validator.format("Please enter no more than {0} characters."),
minlength: jQuery.validator.format("Please enter at least {0} characters."),
rangelength: jQuery.validator.format("Please enter a value between {0} and {1} characters long."),
range: jQuery.validator.format("Please enter a value between {0} and {1}."),
max: jQuery.validator.format("Please enter a value less than or equal to {0}."),
min: jQuery.validator.format("Please enter a value greater than or equal to {0}.")
});
<% end %>
You can use jquery first selector to remove the first delete button based on the id or classname of the parent div (which you aren't currently setting)
<div class="citizens_update">
<%= citizen_form.label :citizen, t('generales.citizen') %>
<%= citizen_form.select :country_id , Country.all.collect {|p| [ t("generales."+p.iso), p.id ] }, { :include_blank => true } , { :class => 'pca33' } %>
<div id="delerr"><%= citizen_form.link_to_remove t('generales.delete') %></div>
</div>
And then use jquery to find the first instance of delerr in the citizens_update div and remove it
$(".citizens_update").find("#delerr:first").remove
http://jsfiddle.net/tiri/ayTrw/

Rails: How do I re-render a partial view on a page?

I have a webpage with a partial view that has a button and displays some information. When the user clicks the button in this partial view, I need to be able to update that partial view from the controller within the action that gets called. Specifically, there is a string that I want to update. Here is my code so far, but it's not working..
partial view (_printLabel.rhtml)
<% if #printAsinEnabled %>
<%= check_box_tag(:needPrint, :needPrint, false,
:onchange => "if (this.checked) $('printLabelAction').show(); else $('printLabelAction').hide();") %>
<%=_('Need to print label?')%><br /><br />
<div id="printLabelAction" class="action" style="display:none;">
<% onPrintLabelClick = generateAjaxRequest(
{:controller => #controller.controller_name,
:action => 'processPrintLabelRequest',
:creturnWipItemId => creturnWipItemId,
:barcode => collectedItemData.fnsku,
:title => asinInfo["title"]},
["parameters: Form.serializeElements([$('printerAddress'),$('printerRemote_true'),$('printerRemote_false')])"]) %>
<%=_('Printing')%>: <%= collectedItemData.fnsku %> <br /> <br />
<%= radio_button_tag(:printerRemote, :false, !session[:printRemote]) %>
<label for="printerRemote_false"><%=_('Local Printer')%></label> <br />
<%= radio_button_tag(:printerRemote, :true, session[:printRemote]) %>
<label for="printerRemote_true"><%=_('Remote Printer')%> - <%=_('Printer Address')%>:</label>
<%= text_field_tag(:printerAddress, session[:printerAddress],
:onchange => onPrintLabelClick,
:onclick => "$('printerRemote_true').checked = true")%> <br />
<div style="text-align:right;">
<%= button_to_function(_("Print Label"), onPrintLabelClick) %>
</div>
<%=_('Error?')%>: <%= errorMessage %> <br /> <br />
</div>
Here is the div where it gets rendered originally:
<div id="Block_asinSummary" class="block">
...
...
<td height="200px" width ="70%">
<%= link_to asinInfo["title"], asinInfo["link"], :target => "_blank" %><br/><br/>
<% if !asinInfo["clothingSize"].nil? %>
<b><%= _('Size')%>:&nbsp</b> <%= asinInfo["clothingSize"]%><br>
<% end %>
<font size='1'>
<% sku = collectedItemData.displaySku %>
<% if sku != collectedItemData.asin%>
<b>SKU:</b> <%= sku %><br>
<% else %>
<b>ASIN:</b> <%= collectedItemData.asin %>
<% end %>
<%= render(:partial => 'printLabel', :locals => { :creturnWipItemId => creturnWipItemId, :collectedItemData => collectedItemData, :asinInfo => asinInfo, :errorMessage => "HI" })%>
</font>
</td>
</tr>
</table>
...
...
<% end %>
And here is the controller code that is supposed to update "errorMessage" with a new string when clicked:
render(:partial => 'printLabel', :layout => false, :locals => { :creturnWipItemId => creturnWipItemId, :collectedItemData => #collectedItemData, :asinInfo => asinInfo, :errorMessage => "Bye" })
I am not seeing any errors from this, but the errorMessage string is not updating from "HI" to "Bye".
You can't call render partial from your controller. Instead, render the template and pass a different error message to the partial using an instance variable.

Resources