I've lost in thought. I have a checkbox that I want to use to transfer a corresponding object to another scope on my page. Moreover, I want only to transfer one field of this checked object. I had used earlier Ajax by creating a .json file and then I responded to it in my controller. In my case input checkbox doesn't seem to have a remote: true option.
views/tasks/_index.html
<h3>Tasks database</h3>
<table>
<% #tasks.each do |task| %>
<tr class='tasks' id="task_<%= task.id %>">
#Some stuff
<td>
<input type="checkbox" class='check' data-id="<%= task.id %>" >
</td>
</tr>
<% end %>
</table>
<h3>Completed</h3>
<div class="complete-tasks">
</div>
Hence, I'm trying to accomplish that using an event via javascript.
So far I've managed to write some javascript code that moving my entire object.
application.js
$(document).on('ready page:load', function () {
$('.check').on('change', function(){
if ($(this).is(':checked')) {
id = $(this).attr('data-id');
task = $(this).closest("tr");
$('.complete-tasks').last().after(task);
}
});
})
But I want to relocate only one 'title' field using Ajax. Can someone please explain me how to accomplish that? I suspect I need to pass in some id's in checkbox and to define $.ajax.
models/task.rb
class Task < ActiveRecord::Base
scope :complete, -> { where(complete: true) }
scope :incomplete, -> { where(complete: nil) }
belongs_to :user
end
All you have to do is make the request to the url and then move the table row/title cell.
$(document).on('ready page:load', function () {
$('.check').on('change', function(){
if ($(this).is(':checked')) {
id = $(this).attr('data-id');
//Url is the site you want to hit.
var jqXHR = $.ajax(url);
var element = this;
jqXHR.done(function(data){
//Ajax finish here.
task = $(element).closest("tr");
$('.complete-tasks').last().after(task);
});
}
});
});
Edit: Fixed context use.
Check the jQuery documentation on how to set up the jqXHR properly:
http://api.jquery.com/jquery.ajax/
Related
In react, I could easily re-render a view by passing results from controller. I wish not to use React at this stage and was wondering if it's possible with JQuery?
I have few objects on page, and when clicked, I should see its content. Click the other object, I see its content etc. Sense? I was inspired by this dribbble.
I may not be doing this the right way but this is what I have:
Controller:
def index
selected_contract = params[:selected_contract] || current_user.contracts.last.id
#contracts = current_user.contracts.order(created_at: :desc).all
#selected_contract = current_user.contracts.find_by(id: selected_contract)
end
View:
<% #contracts.each do |contract| %>
<button class="ui button test" id="<%=contract.id%>"><%=contract.name%></button>
<% end %>
......................................
When clicked, show its content
....................................
<%= #selected_contract.name %>
JS:
$( ".ui.button.test" ).click(function(e) {
let { id } = this
console.log(id)
$.ajax({
url: `/url/${id}`,
type: 'POST',
success: function(result) {
//$('#listview').redraw()
console.log('success')
}
});
});
Routes are set properly so I get the params in the controller just fine. Is there a re-render a view, just like rerender a prop in React for jquery? Am I doing this the correct way?
If you are using jquery listview this should work.
$( "#listview" ).listview( "refresh" );
Reference
https://api.jquerymobile.com/listview/#method-refresh
or since its rails you can reload or render the partial view in your server side as well.
I appreciate that there may be many answers out there but if there are i cant quite interpret them to suit my needs..I am looking to update a records attribute in my model using ajax.
In my case the attribute selected: true
In my scenario i am clicking on an element and looking to update that elements record in the model
<ul class="components">
<% #component.each do |c| %>
<li id="<%= c.component_name %>" data-id="<%= c.id %>" data-remote="true"><%= c.component_name %></li>
<% end %>
</ul>
jQuery
$('#Literacy, #Numeracy').on('click', function(){
var component_name = $(this).text();
var component_id = $(this).data('id');
data_send = { id: component_id }
$.ajax({
method: 'put',
url: '/components/selected_component',
data: data_send,
success: function(data) {
console.log(data)
}
});
});
Controller
def selected_component
#component = Component.find(params[:id])
#component.update_attributes(selected: true)
end
Maybe im looking at this incorrectly but how can i get the id via the click event (stored as component_id) into my selected_component method
Im missing a few bits here but struggling with what today
At the moment I am getting an error
Missing template components/selected_component
but i dont want to render that page after successful update, I just want to stay on the same page
EDIT
to solve my issue i just had to add this to my format.js
{ render nothing: true }
A missing template error corresponds to not having a view that knows what to do when it gets a JavaScript request.
In your views/components/, just make an selected_components.js.erb file and that should clear the error you're getting.
I'm trying to implement an ajax voting system for a model "Things", where if a user votes on Thing then a new Thing appears in the old one's place, which he can then vote on, and so on. This takes place on the Thing view itself.
I'm pretty sure this exact code was working a week ago, but now it mysteriously broke. Now, the Thing is replaced upon the first vote, but after that, voting no longer brings forth a new Thing:
views/things/show.html.erb
<div id="randajax">
<%= link_to image_tag("UpArrowGray.jpg", class: "rand_up_vote"), upvoterandom_thing_path(#rand.id), remote: true, method: :get %>
<script type="text/javascript">
function reload_script() {
$(".rand_up_vote").click(function () {
$.get( "<%= upvoterandom_thing_path(:id => #rand.id) %>", function( data ) {
$('#randajax').html(data);
reload_script();
});
});
}
reload_script();
</script>
</div>
controllers/things_controller.rb
def upvoterandom
#thing = Thing.find(params[:id])
UpVote.create!
#rand = Thing.all.first
render text: "<a data-method=\'get\' data-remote=\'true\' href=\'" + upvoterandom_thing_path(#rand.id) + "\'><img alt=\'Upvote\' class=\'rand_upp_vote\' src=\'/assets/UpArrowGray.jpg\' /></a>".html_safe
end
Apparently the issue is that an item created with ajax can't execute javascript. The web console shows that the upvoterandom_thing_path is getting executed, but nothing happens to the randajax div. I tried giving the Thing created from the original javascript a differenc class with different javascript and that didn't work either, although a seperate item ("THIS_WORKS") with the same class executed the same javascript normally:
views/things/show.html.erb
<%= link_to "THIS_WORKS", "#", class: "TEST_TEST", remote: true %>
<div id="randajax">
<%= link_to image_tag("UpArrowGray.jpg", class: "rand_up_vote"), upvoterandom_thing_path(#rand.id), remote: true, method: :get %>
<script type="text/javascript">
function reload_script() {
$(".rand_up_vote").click(function () {
$.get( "<%= upvoterandom_thing_path(:id => #rand.id) %>", function( data ) {
$('#randajax').html(data);
reload_script();
});
});
}
reload_script();
</script>
<script type="text/javascript">
$(".TEST_TEST").click(function () {
$('#randajax').html("TEST");
});
</script>
</div>
controllers/things_controller.rb
def upvoterandom
#thing = Thing.find(params[:id])
UpVote.create!
#rand = Thing.all.first
render text: "<a data-method=\'get\' data-remote=\'true\' href=\'" + upvoterandom_thing_path(#rand.id) + "\'><img alt=\'Upvote\' class=\'rand_up_vote\' src=\'/assets/UpArrowGray.jpg\' /></a>".html_safe
end
Can anyone explain why this is happening or how I can fix this?
When you set it up, you do this in your javascript:
$(".rand_up_vote").click(function () {
...
This sets up the click event on the elements. When one of the elements is replaced, or a new one is added, it hasn't had this event added to it, so it won't work like the others.
To fix this, you need to add this same event to the new element, OR remove the event from all elements and then add it to all elements (if you don't remove it first you risk firing the same event twice on a click or whatever).
EDIT with a proposed solution.
The simplest way is to add an onclick attribute to your elements, to run the reload_script() function. Change this so that it doesn't add an onclick to the events. I was about to start editing your code and i noticed that the reload_script function calls itself at the end of the anonymous function you're adding as the onclick event: this means that when you click on a .rand_up_vote element, it will do the AJAX get, replace the html, and then add another onclick to all the elements. This is definitely not right - was this an earlier attempt to fix this problem?
You probably just need something like this:
<div id="randajax">
<%= link_to image_tag("UpArrowGray.jpg", class: "rand_up_vote"), upvoterandom_thing_path(#rand.id), remote: true, method: :get %>
<script type="text/javascript">
function reload_script() {
$.get( "<%= upvoterandom_thing_path(:id => #rand.id) %>", function( data ) {
$('#randajax').html(data);
});
}
</script>
</div>
now edit the html so that each .rand_up_vote element has an onclick="reload_script()" attribute.
I have a profile page where I render all of the user's lists using a partial:
users/show.html.erb
<%= render #lists %>
For each list I show how many wishes are associated:
lists/_list.html.erb
<p class="muted" id="wishes_count"><%= pluralize(list.wishes.count, "wish") %></p>
I'm using drag and drop to allow the user to move wishes from one list to another using jQuery sortable.
Right now, I'm using the following code:
wishes.js.erb
$(document).ready(function(){
$('.user_list_wishes').sortable({
connectWith: ".user_list_wishes",
items: ".user_list_wish",
placeholder: "sortable_placeholder",
update: function(e, ui)
{
if (this === ui.item.parent()[0])
{
item_id = ui.item.data('item-id');
list_id = $(this).data('list-id');
position = ui.item.index();
$.ajax({
type: 'POST',
url: $(this).data('update-url'),
dataType: 'json',
data: { id: item_id, wish: { row_order_position: position, list_id: list_id } }
}),
$("#wishes_count").html('<%= pluralize(list.wishes.count, "wish") %>')
}
}
})
})
This line of code:
$("#wishes_count").html('<%= pluralize(list.wishes.count, "wish") %>')
makes my application throw a NoMethodError undefined method 'wishes' for nil:NilClass
I believe it has something to do with how I render lists and reference them individually in my javascript?
Any suggestions on how to solve this problem is much appreciated!
You must handle the scenario where list is null using the following condition:
$("#wishes_count").html('<%= pluralize(list ? list.wishes.count : 0, "wish") %>')
I think the problem could be in your render call - according to the documentation:
If you have an instance of a model to render into a partial, you can use a shorthand syntax:
<%= render #customer %>
Assuming that the #customer instance variable contains an instance of the Customer model, this will use _customer.html.erb to render it and will pass the local variable customer into the partial which will refer to the #customer instance variable in the parent view.
So check that this is the case - do you have a partial called _lists.html.erb and a parent variable called list?
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.