I want to display a modal window with an error message, when the user has entered something invalid in a form, but render another action if everything is OK. However, when I try to display the modal window with
render :js => "jQuery.facebox(#{...})"
only the actual JavaScript called is displayed:
try {
jQuery.facebox(...)
} catch (e) { alert('RJS error:\n\n' + e.toString());
alert('jQuery.facebox(\"<div class=\'error\'>Error</div>\")');
throw e;
}
Have you tried putting the code in a partial? So instead of
render :js => "jQuery.facebox(#{...})"
try
render :partial => "my_facebox_popup"
Then inside of your _my_facebox_popup.html.erb partial put your code:
<script type = "text/javascript">
...
</script>
debug any errors you get with firebug.
Try this
render :update do|page|
page << "jQuery.facebox(#{...})"
end
Maybe you should specify in the jQuery call the dataType of the response you're waiting for.
E.g.:
$.ajax({
url: "/controller/action/id",
success: function(){
$(this).addClass("done");
},
dataType: 'script'
});
Related
From file soul.html.erb , partial view called at the time of page load
<%= render 'contact_options_soul_d' %>
In file contact_options_soul_d.html.erb partial view looks like this -
<div id="contact-option">
<div id= 'un-authenticated' data-access-api-result = <%= #valid_ticket %> %></div>
</div>
On click of a button a Rest call happens in controller and partial view is called from partial_create.js.erb
def partial_create
respond_to do |format|
format.js
end
return
end
File partial_create.js.erb
$('#contact-option').html('<%= escape_javascript(render :partial => 'rhythm/contact_options_soul_d') %>')
My Question is - partial view is called , breakpoint hits and new value of #valid_ticket also gets updated, but view is not getting updated as webpage still looks same even after updation.(View remains same when checked in browser inspect)
Please help!!!
This is not an answer to exactly the way you're doing it, but you could always render it in the controller and return that on "respond_to", then on Ajax success use the returned value to substitute the html:
def partial_create
html = (render_to_string partial: 'rhythm/contact_options_soul_d', locals: { if_you_need: variables_in_partial })
respond_to do |format|
format.json { render json: { new_html: html, success: true } }
end
return
end
then on your JS code (this with jQuery):
function soul_searching(parameters) {
$.ajax({
url: "YOUR/POST/ROUTE",
type: "POST",
dataType: "json",
data: {
any_parameters: 'you_need_to_pass_to_controller'
},
success: function(data) {
$('#contact-option').html(data['new_html']);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
//DO SOMETHING
}
});
}
You need to prepend partials with an underscore. For example:
_contact_options_soul_d.html.erb
Note: You only need to do this to the file name. You can still call the partial with
<%= render partial: 'contact_options_soul_d.html.erb' %>
Also make sure you're referencing the path if the partial is in a separate folder.
I'm working in a simple increment fonction who is not working. In my console I have this error "NetworkError: 404 Not Found - ..../test/increment_nbr" and I'm not able to fix it.
Html:
<button id="incr">AJAX2</button>
<script>
$("#incr").on("click", function(e) {
e.preventDefault();
$.ajax({
url: "/test/increment_nbr",
dataType: "json",
type: "POST",
success: function(data) {
}
});
})
</script>
My controller:
respond_to :html, :json
def increment_nbr
#user = User.find(params[:id])
#user.increment! :nbr_set
render json: { nbr: #user.nbr_set }.to_json
end
Routes:
resources :test do
member do
put :increment_nbr
post :increment_nbr
end
end
Your routing is incorrect - you've defined your two increment_nbr routes as member routes, meaning they operate on an instance of your parent test route and would generate URLs like /test/2/increment_nbr.
See http://guides.rubyonrails.org/routing.html#adding-more-restful-actions for more information
I'm trying to update the content of "mydiv" without refreshing the entire index page.
#mydata is given by mycontroller. I need to recalculate it every n seconds and pass it to "mydiv"
With "link_to" it works!
index.html.erb
<%=
link_to('refresh', '/mycontroller/index', :remote => true)
%>
<div id="mydiv">
<%=
#mydata
%>
</div>
index.js.erb
$('#mydiv').html('<%= escape_javascript(#mydata) %>')
Now I need to refresh the content of "mydiv" automatically every n seconds (so without click on the link). I have tried solutions from:
First Link
Second Link
but no luck.
In my application.js I have writed this:
function executeQuery() {
$.ajax({
//url: '/index',
success: function(data) {
$('#mydiv').html(data)
}
});
setTimeout(executeQuery, 500);
}
$(document).ready(function() {
setTimeout(executeQuery, 500);
});
For who is facing my same problem, I solved it by replacing
$('#mydiv').html(data)
with
$('#mydiv').load('/mycontroller/index #mydiv')
Use setInterval() instead of using setTimeout().
Ref: https://www.w3schools.com/jsref/met_win_setinterval.asp
function executeQuery() {
$.ajax({
type: 'GET',
url: 'example.com/url/', // Provide your response URL here.
success: function(data) {
$('#mydiv').html(data);
}
});
}
setInterval(executeQuery(), (n * 1000)); // Replace 'n' with how many seconds you want.
This code will run the executeQuery() method in every 'n' seconds interval. So that your requirement is accomplished.
Set layout to false in the action and just pass on the relevent content, not the entire page
def action1
<your code here>
end
def action2
<your code here>
render :layout => false
end
Your view for action2 should have content pertaining only to #mydiv.
A better solution would be to use a single action and change render options based on type of request. (Ajax or non ajax)
I have an ajax call to fetch information from Flickr API which returns JSON data. I want to display values from JSON data in my view. I do this by editing some innerHTML with jQuery. The problem I am having is that the data is undefined, so it looks like a scoping problem.
photo.js
jQuery(function() {
$('#<%=p[:id]%>').click(function (e) {
//ajax call to fetch photo info
var fetch_id = '<%=p[:id]%>';
var fetch_secret = '<%=p[:secret]%>';
$.ajax({
type: 'GET',
url: '/photos/fetch_info',
dataType: 'json',
data: { 'id' : fetch_id, 'secret' : fetch_secret },
success: function(data){
console.log(data) //returns Object
console.log(data.title) //returns appropriate title
//edit innerHTML of basic_modal
$('.basic_modal').html(
"<div id='modal_image'><%= escape_javascript(image_tag p[:url]) %></div><div id='photo_title'><%=data.title %></div>"
);
//load modal
$('.basic_modal').modal({
overlayClose:true
});
} //end success: function(result)
});
When I print data.title to console, I get the appropriate title. However, when I try to edit HTML and render <%=data.title %>, I get an undefined variable/method error.
Any tip on how I can display the data in my modal in the view?
Here is my controller:
def fetch_info
#info = flickr.photos.getInfo(:photo_id => params[:id], :secret=> params[:secret])
respond_to do |format|
format.json { render :json => #info }
end
end
var result = jQuery.parseJSON(data);
You donot need to do this, Because datatype:JSON already parse the data
$('.basic_modal').html(
"<div id='modal_image'><%= escape_javascript(image_tag p[:url]) %>
</div><div id='photo_title'><%="+data.title+" %></div>"
);
this might help you
I'm in the process of migrating from Prototype to jQuery and moving all JS outside of the view files. All is going fairly well with one exception. Here's what I'm trying to do, and the problem I'm having. I have a diary where users can update records in-line in the page like so:
user clicks 'edit' link to edit an entry in the diary
a get request is performed via jQuery and an edit form is displayed allowing the user to modify the record
user updates the record, the form disappears and the updated record is shown in place of the form
All of that works so far. The problem arises when:
user updates a record
user clicks 'edit' to update another record
in this case, the edit form is shown twice!
In firebug I get a status code 200 when the form shows, and then moments later, another edit form shows again with a status code of 304
I only want the form to show once, not twice. The form shows twice only after I update a record, otherwise everything works fine. Here's the code, any ideas? I think this might have to do with the fact that in food_item_update.js I call the editDiaryEntry() after a record is updated, but if I don't call that function and try and update the record after it's been modified, then it just spits up the .js.erb response on the screen. That's also why I have the editDiaryEntry() in the add_food.js.erb file. Any help would be greatly appreciated.
diary.js
jQuery(document).ready(function() {
postFoodEntry();
editDiaryEntry();
initDatePicker();
});
function postFoodEntry() {
jQuery('form#add_entry').submit(function(e) {
e.preventDefault();
jQuery.post(this.action, jQuery(this).serialize(), null, "script");
// return this
});
}
function editDiaryEntry() {
jQuery('.edit_link').click(function(e) {
e.preventDefault();
// This should look to see if one version of this is open...
if (jQuery('#edit_container_' + this.id).length == 0 ) {
jQuery.get('/diary/entry/edit', {id: this.id}, null, "script");
}
});
}
function closeEdit () {
jQuery('.close_edit').click(function(e) {
e.preventDefault();
jQuery('.entry_edit_container').remove();
jQuery("#entry_" + this.id).show();
});
}
function updateDiaryEntry() {
jQuery('.edit_entry_form').submit(function(e) {
e.preventDefault();
jQuery.post(this.action, $(this).serialize(), null, "script");
});
}
function initDatePicker() {
jQuery("#date, #edit_date").datepicker();
};
add_food.js.erb
jQuery("#entry_alert").show();
jQuery('#add_entry')[ 0 ].reset();
jQuery('#diary_entries').html("<%= escape_javascript(render :partial => 'members/diary/diary_entries', :object => #diary, :locals => {:record_counter => 0, :date_header => 0, :edit_mode => #diary_edit}, :layout => false ) %>");
jQuery('#entry_alert').html("<%= escape_javascript(render :partial => 'members/diary/entry_alert', :locals => {:type => #type, :message => #alert_message}) %>");
jQuery('#entry_alert').show();
setTimeout(function() { jQuery('#entry_alert').fadeOut('slow'); }, 5000);
editDiaryEntry();
food_item_edit.js.erb
jQuery("#entry_<%= #entry.id %>").hide();
jQuery("#entry_<%= #entry.id %>").after("<%= escape_javascript(render :partial => 'members/diary/food_item_edit', :locals => {:user_food_profile => #entry}) %>");
closeEdit();
updateDiaryEntry();
initDatePicker();
food_item_update.js
jQuery("#entry_<%= #entry.id %>").replaceWith("<%= escape_javascript(render :partial => 'members/diary/food_item', :locals => {:entry => #entry, :total_calories => 0}) %>");
jQuery('.entry_edit_container').remove();
editDiaryEntry();
Maybe you should be using the live function instead of binding to the click once. I am not sure if it will help but it will sure alleviate the need to bind the click event again after updating the page.