parsing a comma in ruby for loop - ruby-on-rails

So I'm looping through a object for loop in my ruby on rails app
currently this is the code:
<%overlays.by_time.each do |overlay| %>
{
"content": "<a href=''><img src='<%= overlay.imageurl %>'></a>",
start: <%=overlay.starttime %>,
end: <%=overlay.starttime %> + <%= overlay.duration %>,
style: {<%=raw theme.contact_us_overlay_style %>},
click_url: '<%= overlay.linkurl %>'
},
<%end>
the problem is the comma, which preventing my videojs player from running. I need the comma for next preceding overlay content, but i don't need it on the last one, which is the problem that causing it. How do i remove it on the last object iteration?

You have several possibilities. A quick (but not very elegant) one is to check whether the item is the latest one.
You can use for example each_with_index:
<% overlays.by_time.each_with_index do |overlay, index| %>
{
"content": "<a href=''><img src='<%= overlay.imageurl %>'></a>",
start: <%=overlay.starttime %>,
end: <%=overlay.starttime %> + <%= overlay.duration %>,
style: {<%=raw theme.contact_us_overlay_style %>},
click_url: '<%= overlay.linkurl %>'
}<%= "," unless index == (overlays.length - 1) %>
<% end %>
A better alternative, since you are essentially producing a string output, would be to generate (may be using an helper) the string output for each overlay as item into an array, then use join(",") to concatenate the array values into a single string.
This code should not be part of an ERB template, but may be a function or helper.
def json_for_overlays(overlays)
overlays.by_time.map do |overlay, index|
<<-JS
{
content: <img src="#{overlay.imageurl}">,
start: #{overlay.starttime},
end: #{overlay.starttime} + #{overlay.duration},
style: {#{raw(theme.contact_us_overlay_style)}},
click_url: '#{overlay.linkurl}'
}
JS
end.join(",")
end

You can look it this another way. Put the comma before each item. Then you just need to suppress the comma for the 0th index.
<% overlays.by_time.each_with_index do |overlay, index| %>
<%= "," unless index == 0 %>
{
"content": "<a href=''><img src='<%= overlay.imageurl %>'></a>",
start: <%=overlay.starttime %>,
end: <%=overlay.starttime %> + <%= overlay.duration %>,
style: {<%=raw theme.contact_us_overlay_style %>},
click_url: '<%= overlay.linkurl %>'
}
<% end %>

Related

getting params from form_tag for datetime_local_field

so i am working with google calendar apis in rails.
<%= form_tag new_event_url do %>
<div>
Subject :
<%= text_field_tag (:subject) %>
</div> <br>
<div>
Date And Time :
<%= datetime_local_field(:user, :event_date) %>
</div><br>
i need to grab parameter from the datetime_local_field.
controller code:
#subject = params[:subject]
#date = params[:user_event_date]
event = Google::Apis::CalendarV3::Event.new({
start: {
date_time: #date.to_datetime.rfc3339
},
end: {
date_time: #date.to_datetime.rfc3339
},
summary: #subject,
})
the subject part is good, but can't get the date_time
how to access that?
datetime_local_field creates a nested input:
#date = params[:user][:event_date]
Next time just look at the log or do params.inspect.

Add character counter in simple_form in Ruby on Rails

I use the simple_form gem and I want a simple character counter on a text field. I was told, this might work:
add this to the form:
<%= f.input :body, id: "body-field" %>
<span id="body-count">0 characters</span>
and javascript:
$("#body-field").on("keyup", function(){
length = $(this).val().length;
$("#body-count").html(length);
});
I got this information from here (Attention: It is full of advertisement): http://www.sohua.xyz/questions-full/4320915/how-do-i-implement-a-basic-character-counter-in-a-simple-form
I did this, but nothing happens. Here is my actual code chapters/new.html.erb:
<%= simple_form_for([#book, #book.chapters.build]) do |f| %>
<%= f.input :chaptertitle %>
Mininmum amount of characters: <%= #book.min_length %> Maximum amount of characters: <%= #book.max_length %>
<%= f.input :chaptercontent, id: "body-field" %>
<span id="body-count">0 characters</span>
<%= f.input :author %>
<%= f.button :submit %>
<% end %>
<script>
$("#body-field").on("keyup", function(){
length = $(this).val().length;
$("#body-count").html(length);
});
</script>
Can you give me any advice, how to get it work?
You need to wrap your code in jquery document ready function:
$(function() {
$("#body-field").on("keyup", function(){
var length = $(this).val().length;
$("#body-count").html(length);
});
});
Why don't you use an existing library instead?
https://github.com/dtisgodsson/jquery-character-counter
You might want to use either js or coffee-script, I am providing a coffee script example below:
Add this piece of code to your chapters.coffee file:
ready = ->
totalChars = 100
#Total characters allowed
countTextBox = $('#body-field')
# Remaining chars count will be displayed here
charsCountEl = $('#countchars')
#initial value of countchars element
charsCountEl.text totalChars
#user releases a key on the keyboard
countTextBox.keyup ->
#get chars count in Text field
thisChars = #value.replace(/{.*}/g, '').length
if thisChars > totalChars
# total extra chars to delete
CharsToDel = thisChars - totalChars
#remove excess chars from text field
#value = #value.substring(0, #value.length - CharsToDel)
else
#count remaining chars
charsCountEl.text totalChars - thisChars
return
return
$(document).ready ready
$(document).on 'page:load', ready
# Loads javascript while loading page
Add this line to your form right below to the Text input field.
var ready;
var charsCountEl, countTextBox, totalChars;
totalChars = 100;
countTextBox = $('#body-field');
charsCountEl = $('#countchars');
charsCountEl.text(totalChars);
countTextBox.keyup(function() {
var CharsToDel, thisChars;
thisChars = this.value.replace(/{.*}/g, '').length;
if (thisChars > totalChars) {
CharsToDel = thisChars - totalChars;
this.value = this.value.substring(0, this.value.length - CharsToDel);
} else {
charsCountEl.text(totalChars - thisChars);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="text" id="body-field" />
<span id="countchars"></span>
If your file under javascript/ folder doesn't have extestion .coffee the please rename it to chapters.coffee if it does then thats it.
PS: here is the javascript version of the same http://pastebin.com/LZb1DAC4.
Reference: https://stackoverflow.com/a/24629105/2545197
This solution won't be as good as Abhinay's solution, but it works for me:
(Please note, I'm an amateur, this code may be horrendous)
Javascript code:
<script>
$(document).ready(function(){
var choosingbar = function( event ){
$(event.target).parents(".counting").children(".count").text($(event.target).val().length);
};
$(".counting textarea").keyup(choosingbar);
});
</script>
new.html.erb code:
<%= simple_form_for([#book, #book.chapters.build]) do |f| %>
<%= f.input :chaptertitle %>
Mininmum amount of characters: <%= #book.min_length %> Maximum amount of characters: <%= #book.max_length %>
<div class="counting" ><%= f.input :chaptercontent %>Characters: <span class="count"></span></div><br>
<%= f.input :author %>
<%= f.button :submit %>
<% end %>

json generated by rails can't be recognized by react

I have a react componente like this
var Task = React.createClass({
render: function () {
return (
<div className="task" id={ this.props.task.uid }>
<div className="header">
<span>task #{ this.props.task.uid }</span>
</div>
</div>
)
}
});
and when a task is created, I add this task to the task list inside an create.js.erb
<% if #task.errors.any? %>
$("#error-alert").removeClass('hidden')
<% else %>
$('#task-modal').modal('hide')
$('#tasks-list').prepend(React.renderToString(Task({ task: '<%= #task.to_react %>' })))
<% end %>
turns out that when the task component is prepended, he is prepended empty (just a box, without any text).
I tried <%= #task.to_react.to_json.html_safe %> and also had no success
My Task#to_react method:
def to_react
{
role: role,
need: need,
result: result,
uid: uid
}
end
Not that familiar with rails but unless it's doing some magic here you're embedding the object in a string.
Try
task: <%= ... %>
Instead of:
task: '<%= ... %>'

Rails display value based on key in deep array of hashes

This is the array of hashes received as parsed_response from an API response which was XML, using Httparty.
Difficult and confusing to traverse inside and get the value.
"flights"=>{
"flight"=>{
"segments"=>{
"segment"=>[ (this has square brackets)
{
"index"=>"3",
"departure_airport"=>"DEL",
"arrival_airport"=>"CCU",
"departure_date_time"=>"2014-07-07T13:20:00",
"arrival_date_time"=>"2014-07-07T15:35:00",
"flight_number"=>"20",
"airline"=>"AI",
"operating_airline"=>"AI",
"stops"=>"0",
"equipment"=>"320",
"duration"=>"8100"
},
{
"index"=>"4",
"departure_airport"=>"CCU",
"arrival_airport"=>"BLR",
"departure_date_time"=>"2014-07-07T18:10:00",
"arrival_date_time"=>"2014-07-07T20:40:00",
"flight_number"=>"771",
"airline"=>"AI",
"operating_airline"=>"AI",
"stops"=>"0",
"equipment"=>"319",
"duration"=>"9000"
}
]
}
}
},
To display above hash values I did
<% h["flights"]["flight"]["segments"]["segment"].each do |o,p| %>
<% if o.class == Hash %>
<strong><%= o['airline'] %></strong>
<%= o['arrival_airport'] %> - <%= o['arrival_date_time'] %><br>
<% else %>
<%= o %>
<% end %>
<% end %>
(NOTE: Simply placing o['airline'] after loop would give can't convert String into Integer)
The else statement is to parse the below type of response.
"flights"=>{
"flight"=>{
"segments"=>{
"segment"=>{ (no square brackets)
"index"=>"3",
"departure_airport"=>"DEL",
"arrival_airport"=>"CCU",
"departure_date_time"=>"2014-07-07T13:20:00",
"arrival_date_time"=>"2014-07-07T15:35:00",
"flight_number"=>"20",
"airline"=>"AI",
"operating_airline"=>"AI",
"stops"=>"0",
"equipment"=>"320",
"duration"=>"8100"
}
}
}
},
So having <%= o %> after else statment, will give
["index", "7"] ["departure_airport", "DEL"] ["arrival_airport", "BLR"] ["departure_date_time", "2014-07-10T07:10:00"] ["arrival_date_time", "2014-07-10T09:50:00"] ["flight_number", "807"] ["airline", "9W"] ["operating_airline", "9W"] ["stops", "0"] ["equipment", "738"] ["duration", "9600"]
But having <% elsif o=="departure_airport" %> <%= p %> <% end %> in-place of else statement, will give the value associated with the key.
To get a single value using the key, this is fine. But it really gets messy to put all those key in the above format to get their values.
There should be a better way to parse it, but just cant figure out how will I deduce a use case where ['segment'] would give the result appropriately, based on if it is again a hash or it is just a key.
Thanks.
The solution here would be to wrap the Hash into an Array before looping it.
controller
#segments_array = Array.wrap(h["flights"]["flight"]["segments"]["segment"])
view
<% #segments_array.each do |segment| %>
<strong><%= segment['airline'] %></strong>
<%= segment['arrival_airport'] %> - <%= segment['arrival_date_time'] %><br>
...
<% end %>
[h["flights"]["flight"]["segments"]["segment"]].flatten.each do |segment|
puts "#{segment['arrival_airport']} - #{segment['arrival_date_time']}"
end
HTH

how would I add inline html to this erb image tag?

I want to add this html data tag inline
data-zoom-image="<% image_tag(step.i_connection.image.image.url(:large) %>"
to this erb tag, but am unsure how I would go about this. Any ideas?
<%= image_tag(step.i_connection.image.image.url(:medium), id: "iconnection#{n}") %>
You pass it in like data: { zoom_image: "large/image1.jpg" } and the data attribute gets converted to data-zoom-image="large/image1.jpg".
Try:
<%= image_tag(step.i_connection.image.image.url(:medium), id: "iconnection#{n}", data: { zoom_image: "large/image1.jpg" }) %>
Update:
I think you want to output the result of:
<% image_tag(step.i_connection.image.image.url(:large)) %> instead of just interpreting it.
Try:
data: { zoom_image: "#{ image_tag(step.i_connection.image.image.url(:large)) }" }

Resources