Receive Carrierwave URL through javascript - javascript

Is there a way to grab the Model.image_url through sql or javascript?
I have a select that when changed, I want the <img src=> to change dynamically.
With other situations I have done the following to change the background color of a div container:
<%= f.grouped_collection_select :color_id, #other_model, :colors, :title, :id, :title, include_blank: "Select Color" %>
<div id="div" style="background-color:<%= "#{model.color.hex}" %>;">
...
</div>
**javascript**
var colors = <%= Color.pluck(:id, :hex).to_h.to_json.html_safe %>;
document.getElementById("model_color_id").addEventListener("change", function(){
document.getElementById("div" %>").style.backgroundColor = colors[this.value];
}, false);
For getting the carrierwave imgae, I tried a similar approach:
var product_mock = <%= Item.pluck(:id, :image).to_h.to_json.html_safe %>;
document.getElementById("model_item_id").addEventListener("change", function(){
document.getElementById("item").src = product_mock[this.value];
}, false);
but this isn't grabbing the *.url' or *_url
Tried a way like this for onchange:
$('#shop_product_item_id').on('change', function(){
let item_id = $(this).val(); #tried with and without these 2 lines and with var
console.log(item_id); #tried with and without these 2 lines
var image = <%= Item.find(1).image_url %>;
document.getElementById("id").src = image;
});
There is an id:1
nothing prints to console but the following error:
Uncaught TypeError: e.unique is not a function
Is there a way to grab this from carrierwave thorugh sql or even ruby within the javascript?

You can change your code Item.pluck(:id, :image).to_h.to_json.html_safe to Item.all.map{|item| [item.id, item.image_url]}.to_h.to_json.html_safe . But as others said in comments better to get items through Ajax request not just store them in html.

Related

How to access changing instance variables (due to a loop) in JavaScript

I am trying to use AJAX to append images to a div container. My photos have a URL field, and so I tried to create an instance variable to then throw inside a div tag like <div id="individual-photo" data-url="<%= #photo_url %>">.
This didn't work, because it assigned one value for that instance variable and when I called it in my .js var url = $("#individual-photo").data("url");, it gave me the same image for all future photos.
I found that solution in another StackOverflow and I think that would work if I wasn't working with a div generated through a loop.. so my question is, seeing as how I am using a loop.. how do I communicate this information to my .js file?
This is the code in my index.html.erb
<div id="sidescrolling-container">
<% if #page > 1 %>
<%= link_to "PREV", (next_path(#link - 2) + "/#individual-photo") %>
<% end %>
<% #pics.each do |photo| %>
<% #pic_id = photo.id%>
<% #photo_url = Photo.where(id: #pic_id)[0].url %>
<div id="individual-photo" data-url="<%= #photo_url %>">
<img src="<%= photo.url %>" height='250px' width="250px">
<span id="photo-title"><%= photo.title %></span>
</div>
<% end %>
<% if #page < #page_max %>
<%= link_to "NEXT", (next_path(#link) + "/#individual-photo"), id: "next_button" %>
<% end %>
</div>
and my .js
var images = $.get("photos/" + page, function(data){
var info = $("#individual-photo", data).each(function(){
var title = $("#photo-title", this).text();
var url = $("#individual-photo").data("url");
$("#sidescrolling-container").append(
'<div id="individual-photo"><img src="'+url+'" height="250px" width="250px"><span id="photo-title">'+title+'</span></div>'
)
})
})
If there's a better way to go about this I'd love to know more! Just no gem solutions please, I don't want to use gems for this part of my code.
$("#individual-photo") references every individual photo in your complete DOM, $("#individual-photo").data() always references the data properties of the first element in this selection. Therefore, you always get the the first url.
It should be
var images = $.get("photos/" + page, function(data){
$("#individual-photo", data).each(function(){
var title = $("#photo-title", this).text();
var url = $(this).data("url");
$("#sidescrolling-container").append(
'<div id="individual-photo"><img src="'+url+'" height="250px" width="250px"><span id="photo-title">'+title+'</span></div>'
)
})
})

Rails: Making each choice in a form select field render relevant input in another form field

Noob here so I apologize ahead of time for sounding like an amateur. I'm trying to code an e-commerce site. Customers will order posters from images uploaded to the site and get to choose the size of poster (h x w) they want depending on the dimensions of the original image. I have a form for creating a new order and one of the fields is a select field with the poster size options. When they select a size, I want a price to automatically update in a separate field in the form so they know before submitting the form what the price will be.
The strategy I've been trying is to add jQuery onclick code in the select field choices. Here's what I have for the form (just showing the first choice in the select field for brevity):
<%= form_for(#order) do |f| %>
<div id="order_form">
<div class="field">
<%= f.label(:size) %><br>
<%= f.select(:size, [link_to("#{#image.dimensions['width']/120} * #{#image.dimensions['height']/120}", '#', :onclick => "showPrice('#{#image.dimensions['width']/120} * #{#image.dimensions['height']/120}'); return true;"), ... ]) %>
</div>
<div class="field">
<%= f.label(:price) %><br>
<%= f.text_field :price, :id => 'price' %>
</div>
</div>
And in assets>javascripts>application.js my jQuery code is:
function showPrice(size) {
$("#price").html("$" + size * 0.08);
}
It's not working and I don’t know if what I’m trying to do won’t work or if I'm just doing it wrong.
Thanks in advance for any help.
Here's the solution I came up with finally... I changed my goal a little, instead of trying to make it so when the user selects the size it will automatically update the price field I just made a separate paragraph (not a form field). Here's what it looks like:
<div id="order_form">
<p id='price'><%= '$' + :size.to_int * 0.8 %></p>
<div class="field">
<%= f.label(:size) %><br>
<%= f.select :size, ["#{#image.dimensions['width']/120} X # {#image.dimensions['height']/120}", "#{#image.dimensions['width']/140} X #{#image.dimensions['height']/140}", "#{#image.dimensions['width']/160} X #{#image.dimensions['height']/160}", "#{#image.dimensions['width']/180} X #{#image.dimensions['height']/180}", "#{#image.dimensions['width']/200} X #{#image.dimensions['height']/200}", "#{#image.dimensions['width']/220} X #{#image.dimensions['height']/220}"], {}, :oninput => "showPrice(this)" %>
</div>
</div>
and here's my jQuery function:
function showPrice(size) {
var Amt = $(size).val();
var arr = Amt.split(" ");
var newerAmt = Math.round( arr[0] * arr[2] * 0.8);
$("#price").html('Price: $' + newerAmt);
}
This works except it's not automatically showing the price when the page with the form loads with the default size... any advice on that would be great...
~~~~~~~~~
OK I finally figured that last part out. I referred to another thread on here and it led me to this solution so sorry for the resubmit but here it is:
To get JavaScript to recognize the ruby symbol :size I added this div in that same file:
<%= content_tag :div, class: "size_information", data: {size: #size} do %>
<% end %>
It isn't visible in the browser but it contains the data we need for JS.
Then in the JS function on that same page I referred to that data and then was able to use it as a variable:
<%= javascript_tag do %>
$(document).ready(function() {
var size = $('.size_information').data('size');
var arr = size.split(" ");
var newerAmt = Math.round( arr[0] * arr[2] * 0.8);
$("#price").html('Price: $' + newerAmt);
})
<% end %>
I would try something like this.
$('select#size').change( function () {
var amount = $('select#size').val();
var newAmt = amount * 0.08
$('#price').val('$' + newAmt);
})
Try breaking down the parts of the code to see which is working and which are not.
For example start with something simple like this
$('select#size').change(function () {
var amount = $('select#size').val();
console.log(amount)
//checking to see if .change function works
//and if you are able to collect the value of
//whats inside 'select#size'
})
If this works then maybe you can consider doing the next line
var newAmt = amount * 0.08
console.log(newAmt)
If this works then next would be to try checking to see if you are successfully calling on the #price field.
var price = $('#price').val();
console.log(price)
So if thats working then maybe you can try placing values into #price first
$('#price').val('its working!')
If all of them are working, combining the whole code should work too. Hope this helps!

how do i access the document dom object in ejs?

I am trying show a list of participants when the user clicks on the button.But each time i end up with an error ""document is not defined".(Please don't give me jquery!!).
<% var bt = document.getElementById("bt");
bt.addEventListener('onclick',function(){
var chatbox = document.getElementsByClassName('parti');
var msg = document.createElement('div');
msg.setAttribute('class', 'participants');
msg.textContent('Participant \n\n\n'); %>
<%= chatbox.appendChild(msg); %>
<% }); %>
Change this line:
bt.addEventListener('onclick',function(){
With this:
bt.addEventListener('click',function(){
When we use addEventListener we don't need to use prefix 'on' for even name.
Also, you have used getElementsByClassName and for this you need to iterate over array, so use:
<%= chatbox[0].appendChild(msg); %>

Rails 4 / Ruby 2: Local variable (FormBuilder) for partial is lost through dynamic update

I have this form that renders a partial for selecting a person's task.
new.html.slim:
= form_for(#person) do |f|
= f.text_field :name
= f.fields_for :assignment do |a|
= a.collection_select :project_id, Project.order(:name), :id, :name
div id="task_list"
= render 'shared/_task_select', a: a
= f.submit 'Save'
shared/_task_select.html.slim:
= a.collection_select :task_id, #tasks, :id, :name
Changing the project triggers a javascript that runs a "create_tasklist"-method in the PersonsController.
new.js:
$(document).ready(function() {
$('#person_assignment_attributes_project_id').change(function() {
var selection = $('#person_assignment_attributes_project_id').val();
$.ajax({
url: "/create_tasklist",
data: {
project_id : selection
},
dataType: "script"
});
});
});
The "create_tasklist"-method triggers a javascript that updates the partial:
create_tasklist.js.erb:
$("#task_list").html("<%= escape_javascript(render 'shared/task_list', a: a) %>");
Now this raises the error:
undefined local variable or method `a' for #<#<Class:0x42cd770>:0x4213ef0>
The same form works well when editing existing persons - until changing the project. Thus, FormBuilder "a" loses its definition through the javascript actions. I have to use a partial here because I want to do more stuff with it in a later stage. Any ideas how to get that variable to keep its defintion?
Edit 1:
I already tried adding this below the third line of new.html.slim:
javascript:
var a = "#{a}";
and then adding: a: a in the "data" declaration of new.js.
Edit 2:
With this the FormBuilder seems to pass through until the "create_tasklist"-method, but I do not know how to access it properly there. If I declare ´#a = params[:a]´ in the "create_tasklist"-method and then use (in create_tasklist.js.erb):
$("#task_list").html("<%= escape_javascript(render 'shared/task_list', a: #a) %>");
I recieve the error:
undefined method `collection_select' for "#<ActionView::Helpers::FormBuilder:0x4760400>":String
So the FormBuilder has become a string but a least it "got through" somehow. How can I leave it intact and is a more efficent way to achieve this?

Rails, Send id to URL via Javascript

I have a collection select, and I am trying to refresh the page, and pass the org_id to the URL when the user chooses from the collection select. The collection_select looks like this...
<div id="org-select">
<%= collection_select :org, :id, Org.all, :id, :name %>
</div>
In application.js I have...
$(document).ready(function(){
$("#org-select").on("change","select",function(){
val = $(this).children('option:selected').val();
window.location = '/sessions?org_id='+ val;
});
});
When the user chooses a new org from my coll_select, I am getting a page refresh. However, my URL looks like..
http://localhost:3000/sessions?org_id=2
The org_id ($this.val()) is getting set to 2 each time. It is not being updated when I choose a new org from my drop down. The page is updating, but the id is set to 2 each time.
Here is the rendered HTML...
<div id="sessions">
<div id="org-select">
<select id="org_id" name="org[id]"><option value="1">Lumbees</option>
<option value="2">Tuskarora</option></select>
</div>
The issue I am seeing now is that the page defaults to 'Lumbees' being selected in my dropdown, and even when I choose another value, the page redirects back to 'Lumbees'. Any ideas? Obviously there is a redirect somewhere, however there is nothing in app/views/sessions/index.html.erb that I can find.
what is your collection select id,i guess it org_id or write some custom id ,you are making request on change of div which is incorrect.
<div id="org-select">
<%= collection_select :org, :id, Org.all, :id, :name,{},{:id=>"org_id"} %>
</div>
$("#org_id").on("change", function(){
window.location = '/sessions?org_id='+ $(this).val()
});
Your are trying to pick an value from the div element which should not work.
If you listen on the select element insted it should work better.
$(document).ready(function(){
$("#org-select select").on("change", function(){
window.location = '/sessions?org_id='+ $(this).val()
});
});
And if it still don't work you cud also try to be more precise with the selected value like below.
$(document).ready(function(){
$("#org-select select").on("change", function(){
window.location = '/sessions?org_id='+ $(this).find(':selected').val()
});
});
try next:
UPDATED
$(document).ready(function(){
$("#org-select").on("change","select",function(){
val = $(this).children('option:selected').val();
window.location = '/sessions?org_id='+ val;
});
});
The issue with the page refresh was in the collection select...here is all the code...
app.js
$(document).ready(function(){
$("#org-select select").on("change",function(){
val = $(this).val();
window.location = '/sessions?org_id='+ val;
});
});
index.html.erb
<%= collection_select :org, :id, Org.all, :id, :name, {:selected => params[:org_id]} %>
I needed to specify an object to be selected by default.

Categories

Resources