How to use javascript functions within ajaxified partials? - ruby-on-rails

In a Rails 3.2 app I have a javascript function that is triggered by the presence of a DOM element with class "trigger". (this function adds UI elements).
This works perfectly, except in partials that are rendered by ajax calls.
For example in an index view, when the page is initially rendered the function is correctly called and the UI elements rendered.
If the user then filters or paginates or otherwise interacts with the index via ajax, the function is not called and the UI elements are not applied when the partial is re-rendered via the ajax call.
So, how can I make javascript aware of elements that are rendered via ajax calls?

I think you should use jQuery.on() method.
eg
$("#content").on("click", "input[type='checkbox']", function(event){
// do some stuff
});

Seems this question has been asked before, but I was not using the correct search terms.
In case anyone else stumbles across this, the answer is...
Adding $('.switch')['bootstrapSwitch'](); to the end of your some_action.js.erb file should do the trick....
And the full question is
bootstrap-switch functionality does not load when I re-render a partial with "respond_do"

Related

Rails ujs for partial DOM replacement?

My front-end structure is like below:
<div id='item-list'>
# List of items to be replaced every time
</div>
<form>
<submit/>
</form>
The idea is that, every time when the submit button is clicked, my JS would send AJAX request, and the server would return an HTML partial for the item-list, and in my front-end, the item-list would be replaced with the ajax return.
However, since there're also some use of UJS in my item-list, the bindings no longer works after the replacement.
I believe it's the problem that the UJS code didn't execute when the replacement happens. I want to ask how to force the execution of UJS code?
Thanks a lot
You'll need to delegate your event bindings from an element which is always going to be present on your page (typically document):
$(document).on("submit", ".element", function(){
//stuff
});
The problem you have is that Javascript only works with elements in the actual DOM. It doesn't, nor can it work with, elements which are appended after the DOM has been loaded
This means you have to bind the javascript events to elements which will always be present in the DOM, and delegate from them
--
That's the best I can do with what you've sent so far - if you give more context, I'll be able to provide a richer answer

How to call a function named coffeescript function via ajax

In a Rails 3.2 app I have a jquery function that renders a chart on a DOM element
#assets/scripts.coffee.erb
$(document).ready ->
$("#chart_container").do_some_stuff
#view
<div id="chart_container"></div>
I'm in the process of ajaxifying this view to enable the user to switch the data that is presented on the chart. The problem is that the coffeescript is not triggered via the ajax response.
If I put the function within some tags on the view, everything works fine, but this is not a very 'nice' solution.
Alternatively I know that it is possible to call functions from the view.js.erb rendered by the ajax response. Something like
#view.js.erb
$('#chart_container')['myFunction']();
But my javascript knowledge is limited, and I'm having trouble working out how to name coffeescript function correctly.
I need the function to be triggered when the document is ready. But I also need to be able to call the function manually via the ajax response. How should I set this up?
(I suspect this is a very basic javascript question, and not very well asked, but I appreciate any guidance).
You can wrap the code to a function at first
#assets/scripts.coffee.erb
$(document).ready ->
$(document).chart_action()
$.fn.chart_action = ->
$("#chart_container").do_some_stuff
Then call this function at your ajax response template
#view.js.erb
$(document).chart_action()
Upate Version
Thanks for #muistooshort's suggestion, it's better to use a custom namespace instead of polluting jQuery's, even in small usage.
So, refactor the above
# Custom functions for this app
class App
chart_action: ->
$("#chart_container").do_some_stuff
# Normal code for initializing page
app = new App
$(document).ready ->
app.char_action()
# view.js.erb
app.chart_action()

How to check div tag contains partial view?

As we know window.onload event will fire only when the page is completely loaded.
I want to perform some action when a partial view loaded completely into div tag
how to check that?
like : $('divID').__ ??
You need something like:
$('#divID').ajaxComplete(function(){
// do something
});
That is of course providing I am correct in my assumption: that you are using both AJAX to populate the DIV and also the Unobtrusive Ajax library rather than the Microsoft MVC Ajax libraries.
If the Partial is simply rendered on page load, then $(document).ready(function(){}) will serve you well.

How to bind backbone.js events to JQuery UI dialogue windows?

I'm very new to backbone.js but we're starting to use more and more JS on the front end and I wanted to use some framework to give the code structure - backbone seems to suit our needs.
So started off with a very simple test app that launches a dialogue window using jquery-ui. The problem I have is that since jquery-ui adds a wrapper DIV round the original template used by backbone, the events no longer fire.
I don't want to use the jquery-ui event model as I'd rather just use the one - how can I bind backbone's to this new structure?
It looks as though the call to _.template() is actually doing the wrapping in an extra div. The parent div with the events bound to it is being left behind appended to #well. A simple workaround is to call .parent() on the result of getting the element with the model class ID. See here for example
There's more than likely some information in the _ documentation that might shed some more light on the problem too.
OK - at the end of this project, I finally realised that I hadn't answered this. What happens is when you create a .dialog with JQueryUI, it actually detatches your original DOM element and moves it to the bottom of the DOM wrapped in it's own JQueryUI markup to turn it into a dialog.
Since the Backbone view's element has now been moved, Backbone doesn't pick up any events that fire as it's happening outside it's own "view" as far as it is concerned.
So what you have to do is reassign the view's element:
var dlg = this.$("#dialogue-properties").dialog({ ..});
this.setElement(dlg);
Where this is the view. This is done within the initialize method
You can create div wrapper in your view and modal it's content, as described here (first part of the post)
cocovan does a good job explaining the problem in his answer. However, as for the solution, the JQuery UI team actually added a method at the end of 2012 (Allow dialog to be attached to a element other than body) that takes care of this issue.
It is the appendTo(selector) method (jQuery Dialog appendTo method). So simply specify to which element you want the dialog appended.

Perodic AJAX calls

I have a page where I want to do an AJAX call and possibly render a partial every 30 seconds or so. Now, I know how to do this with jquery AJAX, doing an AJAX call and passing in the path, but it doesn't seem like the Rails way.
I say this because the result is that the main view does not show you the entire structure of the page. When you render a partial, you at least see the partial's positioning inside the document, if you render a partial via AJAX, you have to read the javascript code to know that it's there.
Is there a more unobtrusive (for lack of a better word) way to do this?
When I need to do something like this, and want the partial block to be positioned, I include a container div that I then render the AJAX call into. That was I can position the partial prior to it actually being rendered.

Resources