Jquery not applying after html is replaced - ajax

I have some jquery functions that I call from the $(document).eady() function like the following :
<script type="text/javascript">
$(document).ready(function(){
$('.table_task_type tr').mouseover(function(){
$(this).addClass("hover");
});
$('.table_task_type tr').mouseleave(function(){
$(this).removeClass("hover");
});
$('input:checkbox').click(function() {
$(this).parent().parent().toggleClass('checked');
});
});
</script>
The thing is that I replace part of the html on some user action. I do it like :
$("#my_table").empty();
$("#my_table").html(data);
The jquery events are fired the first time the page is loaded, but as soon as the html of my table is replaced it doesn't work anymore.
Any workaround to that ?

use jquery live method
example:
$('.table_task_type tr').live('mouseover',function(){
$(this).addClass("hover");
});

You should use the .on() method as the previous posters have suggested. What you want to do is put the binding on a parent element of the container that is being refreshed.
<div id="content">
<div id="my_table">
<table>
<tr class="table_task_type">
<td>foo</td>
<td>bar</td>
<td>baz</td>
</tr>
</table>
</div>
</div>
$(function() {
$('#content').on('hover', '.table_task_type',
function() {
$(this).toggleClass('.rollover');
},
function() {
$(this).toggleClass('.rollover');
});
});
The listener is bound to the parent container of the one you are re-populating. Since the parent container (#content) is not re-populated, the binding won't break. It's also faster because the click event only has to bubble up one node in the DOM as opposed to bubbling all the way up to document.

Related

What's the best way to add the same ajax function to a list of comments?

Source code is like this:
<div>
<h4>comment content</h4>
<a id="delcmt_{{ comment.id }}">delete this comment</a>
</div>
......
<div>
<h4>comment content</h4>
<a id="delcmt_{{ comment.id }}">delete this comment</a>
</div>
I what to add ajax function to each of the "delete this comment" link:
<script type=text/javascript>
$(function() {
$('a#delcmt_id').bind('click', function() {
$.get($SCRIPT_ROOT + '/del_comment', {
}, function(data) {
$("#result").value(data.result);
});
return false;
});
});
</script>
What I can come out is using a loop to copy the upper ajax function for each comment, that must be very ugly. Any good ideas?
Try adding a class and select it with jquery add an event handler. You have to use the 'on' event because the elements you wish attach behavior to might be dynamic and load after document ready.
#*Render all this with razor, or angular or knockout*#
<div>
<h4>comment content</h4>
<span style="cursor: pointer;" id="1" data-rowid="1" class="delete-me-class">delete this comment</span>
</div>
<div>
<h4>comment content</h4>
<span style="cursor: pointer;" id="2" data-rowid="2" class="delete-me-class">delete this comment</span>
</div>
<script>
$(function () {
$('body').on('click', '.delete-me-class', function () {//http://api.jquery.com/on/ on is the latest 'live' binding for elements that may not exists when DOM is ready.
var rowId = $(this).data('rowid');
//TODO Use rowId for your delete ajax, or your element Id if you wish.
alert('You clicked on the delete link with the row ID of ' + rowId);
});
});
</script>
Here is a working Fiddle

Loading another page with jquery-Ajax

I am loading another html page from an index page, then I would like to get an element from that loaded page, but the page seems not loaded yet since the element resulted to null, even if there is a function call back with in the ajax load function:
$(document).ready(function() {
$('#btnEdit').click(function(){
$('#contents').load("abcd.html",showNewcontents())
function showNewcontents() {
alert("" + document.getElementById("make").value);
}
return false;
});
});
in body:
<body>
CLICK ME
<div id="contents"></div>
</body>
in abcd.html:
<div id="contents">
<form>
<input type="hidden" id="make" name="make" value="make">
</form>
</div>
Any clue as to how to modify this to get the element?
load expects to receive a function as an argument.
showNewcontents() calls a function.
You are passing the return value of the call to showNewcontents, not the showNewcontents function.
Remove the ().

Ajax back to previous page

I have a form inserted by jQuery Ajax to a page's div (say, 'content') and when the user finishes filling the form and hits 'submit' button, the result will be shown for further verification. The html and ajax code are as follows:
HTML:
<form id="userForm" action="..." method="post">
...
...
</form>
Ajax:
$(document).ready(function() {
$('#userForm').ajaxForm({
success: function(returnData) {
$('#content').html(returnData);
}
});
});
The 'returnData' is the filled form (without input fields) for further confirmation. Now, how do I implement a 'back' button such that the user may go back and modify the previously entered data?
I am working on Google App Engine with Python. Thanks.
I wouldn't replace the form with new HTML.
I would rather hide the form with display: none and add the new HTML for viewing alongside. If you want to go back, then you can just hide the "viewing div" and show again the form, without the need to refill any input elements.
Something along these lines should work
HTML:
<div id="content">
<div id="user-form-container">
<form id="userForm" ...>...</form>
</div>
<div id="viewing-container"></div>
</div>
CSS:
#viewing-container {
display: none;
}
The viewing part contains some sort of back-button, which hides the viewing area and shows the form again
jQ:
$(document).ready(function() {
$('#userForm').ajaxForm({
success: function(returnData) {
$('#viewing-container').html(returnData);
$('#user-form-container').hide();
$('#viewing-container').show();
$('#viewing-container #back-button').click(function() {
$('#user-form-container').show();
$('#viewing-container').hide();
});
}
});
});

Events not working when using Mustache with Backbone.js

So I am making a test app using RequireJs, Mustache and Backbone.js. I had some success with rendering the collection of models with the Mustache template. But my Mustache template has a button and when I try to bind click event on the button in the view, the button click doesn't invoke the callback function. I am really stuck, can someone tell me where I am not doing right?
Here is my code:
ItemView.js:
define(['jquery', 'backbone', 'underscore', 'mustache', '../../atm/model/item'], function ($, Backbone, _, Mustache, Item) {
var ItemView = Backbone.View.extend({
initialize: function() {
},
tagName: 'li',
events: {
'click .button': 'showPriceChange'
},
render: function() {
var template = $('#template-atm').html();
var itemObj = this.model.toJSON();
itemObj['cid'] = this.model.cid;
var rendering = Mustache.to_html(template, itemObj);
this.el = rendering;
return this;
},
showPriceChange: function(event) {
alert('Changing...');
$('#' + elemId).empty();
$('#' + elemId).append(document.createTextNode('Changed'));
},
});
return ItemView;
});
atm.html:
<!DOCTYPE html>
<html>
<head>
<title>Elevator</title>
<script data-main="scripts/main" src="scripts/require-jquery.js"></script>
<style type="text/css">
</style>
</head>
<body>
<h1>Vending Machine</h1>
<div id="atm-items">
</div>
<script id="template-atm" type="html/template">
<li>
<p>Item: {{name}}</p>
<label for="price-{{cid}}">Price:</label>
<input id="price-{{cid}}" type="text" value="{{price}}"/>
<button class="button">Change</button>
<p id="status-{{name}}-{{cid}}">- -</p>
</li>
</script>
</body>
</html>
You're replacing the view's el inside render:
render: function() {
//...
this.el = rendering;
//...
}
When you do that, you're losing the jQuery delegate that is attached to this.el, that delegate handler (which Backbone adds) is responsible for the event routing.
Usually, you add things to this.el rather than replacing this.el. If your template looked like this:
<script id="template-atm" type="html/template">
<p>Item: {{name}}</p>
<label for="price-{{cid}}">Price:</label>
<input id="price-{{cid}}" type="text" value="{{price}}"/>
<button class="button">Change</button>
<p id="status-{{name}}-{{cid}}">- -</p>
</script>
then you would this.$el.append(rendering) in your view's render; this would give you an <li> in this.el since you've set your view's tagName to li.
Alternatively, if you really need to keep the <li> in the template, you could use setElement to replace this.el, this.$el, and take care of the event delegation:
this.setElement(rendering);
Presumably you're wrapping all these <li>s in a <ul>, <ol>, or <menu> somewhere else; if you're not then you're producing invalid HTML and the browser might try to correct it for you, the corrections might cause you trouble elsewhere as your HTML structure might not be what your selectors think it is.

Fancybox 2 fails to show AJAX content ("The requested content cannot be loaded.")

I have this fairly basic code within a $(document).ready listener:
$('#contact-us-button').fancybox({
padding: 20,
beforeLoad: function () {
$("#slideshow").data('nivoslider').stop();
},
afterClose: function () {
$("#slideshow").data('nivoslider').start();
}
});
$('.get-a-quote').fancybox({
padding: 20,
beforeLoad: function () {
$("#slideshow").data('nivoslider').stop();
},
afterClose: function () {
$("#slideshow").data('nivoslider').start();
}
});
Whereas the HTML:
<a id="contact-us-button" href="impianto/get-a-quote-form.php"></a>
[...]
<div class="product">
<h1>Ferrari California</h1>
<a href="dettaglio.php?id=7">
<img src="images/showcase/ferrari-california-showcase.jpg" />
</a>
<a class="get-a-quote" href="impianto/get-a-quote-form.php?id=7"></a>
</div>
Fancybox binds correctly but shows that message in place of my form. There are no conflicts among class names and IDs. Any ideas? Please note that Fancybox 1.3.4 behaves correctly with about the same code (different options).
Try adding the fancybox.ajax class to your links like
<a id="contact-us-button" class="fancybox.ajax" href="impianto/get-a-quote-form.php"></a>
and
<a class="get-a-quote fancybox.ajax" href="impianto/get-a-quote-form.php?id=7"></a>
Try using the property 'type' : 'iframe' if you want it to show another web page's content inside it like a window to the other page.
Something like this in your < head > tag:
<script type="text/javascript">
$(document).ready(function() {
$(".fancybox").fancybox({
'type' : 'iframe'
});
});
</script>
Also it might be obvious but if not... With this specific javascript enabling "fancybox" class links as popup links, your link to fire a popup would have class set as matching the class name in the javascript above, something like:
Link

Resources