I have 3 tabs and on 3rd tab click I'm loading data into the 3rd tab, but once the data is loaded and i click the 3rd tab it loads data twice i.e send request 2 times and when I click the tab 3rd time it doubles the request and send 4 requests and so on.
My Code:
// Separate Ajax call for coach stylish view Data
$(document).on( "click", '.ajaxTab' , function( e ){
e.preventDefault();
var $this = $(this),
loadUrl = $this.attr('data-href'),
target = $this.attr('data-target');
$.get(loadUrl, function(data) {
$(target).html(data);
});
$this.tab('show');
return false;
});
Tab link:
<li><a class="ajaxTab" data-toggle="tabAjax" href="#"
data-href="<?php echo $this->CxHelper->Route('eb-admin-get-coach-stylish-view') ?>?userId={{userId}}"
data-target="#coach-view-stylish-ajax"
rel="tooltip">Coach View (Stylised)</a>
</li>
Use one instead of on. [http://api.jquery.com/one/][1]
$(document).one( "click", '.ajaxTab' , function( e ){
e.preventDefault();
var $this = $(this),
loadUrl = $this.attr('data-href'),
target = $this.attr('data-target');
$.get(loadUrl, function(data) {
$(target).html(data);
});
$this.tab('show');
return false;
});
[1]: http://api.jquery.com/one/
jQuery off method to remove existing click event handler http://api.jquery.com/off/
$(document).off().on( "click", '.ajaxTab' , function( e ){
e.preventDefault();
var $this = $(this),
loadUrl = $this.attr('data-href'),
target = $this.attr('data-target');
$.get(loadUrl, function(data) {
$(target).html(data);
});
$this.tab('show');
return false;
});
Perhaps the click is being called in an incremental value, i usually see that when i set click listeners in an ajax success method.
you might want to unbind events from the .ajaxTab
$(document).on( "click", '.ajaxTab' , function( e ){
$('.ajaxTab').unbind();
.........//the other logic
});
unbind removes click listeners from the element
Related
I am loading data from URL inside a TAB div, data loads successfully on first request/click but on 2nd request/click it goes to the target link and doesn't populate the target DIV.
Anchor:
<li><a data-toggle="tabAjax" href="http://site.cx/admin/get-coach-stylish-view?userId={{userId}}" id="ajax_tab" class="media_node active span" data-target="#coach-view-stylish-ajax" rel="tooltip">Coach View (Stylised)</a></li>
Div to populate with DATA:
<!-- Coach View Stylised -->
<div id="coach-view-stylish-ajax">
</div>
<!-- Coach View Stylised End -->
JS:
<script>
$('[data-toggle="tabAjax"]').click(function(e) {
e.preventDefault();
var $this = $(this),
loadUrl = $this.attr('href'),
target = $this.attr('data-target');
$.get(loadUrl, function(data) {
$(target).html(data);
});
$this.tab('show');
return false;
});
</script>
1- try to put a debugger in your code, and check that the code is being called on 2nd click. If not, then you need to rebind the click event.
2- You can try this way
<li><a data-toggle="tabAjax" href="#" data-href="http://site.cx/admin/get-coach-stylish-view?userId={{userId}}" id="ajax_tab" class="media_node active span" data-target="#coach-view-stylish-ajax" rel="tooltip">Coach View (Stylised)</a></li>
make href="#" and store url in data-href="..."
and in your javascript
<script>
$('[data-toggle="tabAjax"]').click(function(e) {
e.preventDefault();
var $this = $(this),
loadUrl = $this.attr('data-href'), //change href to data-href
target = $this.attr('data-target');
$.get(loadUrl, function(data) {
$(target).html(data);
});
$this.tab('show');
return false;
});
</script>
I am generating a list of entries from a JSON feed. I want to click a div and bring up the edit modal. I'm having some issues getting the relatedTarget from the click event. It's returned as undefined.
Is there another way of passing data to the modal?
$.getJSON('api/v1/module', function(data){
$.each(data, function(i, learning) {
var $div = $('<div>')
.append(
$('<p>').text(learning.title),
$('<p>').text(learning.lastupdated)
)
.addClass('panel panel-default')
.attr('data-title', learning.title)
.appendTo('.module-list')
.on('click', function(){
$('#edit-module').modal({
show: true
})
})
});
})
$('#edit-module').on('show.bs.modal', function (event) {
var button = $(event.relatedTarget) // Button that triggered the modal
var recipient = button.data('title') // Extract info from data-* attributes
// If necessary, you could initiate an AJAX request here (and then do the updating in a callback).
// Update the modal's content. We'll use jQuery here, but you could use a data binding library or other methods instead.
var modal = $(this)
modal.find('.modal-body input').val(recipient)
console.log( event.relatedTarget )
console.log( event )
console.log( button )
console.log( JSON.stringify(button) )
})
From the Boostrap docs:
If caused by a click, the clicked element is available as the
relatedTarget property of the event.
But here the display is caused by modal(), not the initial click.
To have the click trigger the display as described in the docs, you need to call the modal using Boostrap's data-toggle. Add those data attributes, and remove your .on() handler:
$.getJSON('api/v1/module', function(data){
$.each(data, function(i, learning) {
var $div = $('<div>')
...
.attr('data-title', learning.title)
.attr("data-toggle", "modal")
.attr("data-target", "#edit-module")
.appendTo('.module-list')
});
})
Use event delegation for your dynamically-created .panel elements.
Direct and delegated events: http://api.jquery.com/on/
Event handlers are bound only to the currently selected elements; they must exist at the time your code makes the call to .on(). To ensure the elements are present and can be selected, place scripts after the elements in the HTML markup or perform event binding inside a document ready handler. Alternatively, use delegated events to attach event handlers.
$(function() {
$('.module-list').on('click', '.panel', function(){
$('#edit-module').modal({
show: true
})
})
});
$.getJSON('api/v1/module', function(data){
$.each(data, function(i, learning) {
var $div = $('<div>')
.append(
$('<p>').text(learning.title),
$('<p>').text(learning.lastupdated)
)
.addClass('panel panel-default')
.attr('data-title', learning.title)
.appendTo('.module-list')
});
})
$('#edit-module').on('show.bs.modal', function (event) {
var button = $(event.relatedTarget) // Button that triggered the modal
var recipient = button.data('title') // Extract info from data-* attributes
// If necessary, you could initiate an AJAX request here (and then do the updating in a callback).
// Update the modal's content. We'll use jQuery here, but you could use a data binding library or other methods instead.
var modal = $(this)
modal.find('.modal-body input').val(recipient)
console.log( event.relatedTarget )
console.log( event )
console.log( button )
console.log( JSON.stringify(button) )
})
I am copying an element and adding it to a a list of elements. First, I get some HTML using an ajax call:
var setButtonClick = function (url, btn) {
$.ajax(url, $('form').serialize(), 'Html').then(function (data) {
$(btn).parent().find(sel.addListItem).on('click', function () {
addListItem(data, this, btn);
});
addListItem(data, btn, btn);
});
}
addListItem looks like this:
var addListItem = function (data, context, btn) {
var $template = $(data);
// stuff not related removed for brevity
$(btn).before($template);
}
I then have a remove function using a delegate:
$(sel.editableList).delegate(sel.removeListItem, 'click', function () {
// fires once for every element with the sel.removeListItem selector
}
I need the click event to fire once for the clicked element only. I can get a basic version of delegate working by inserting content like this:
$( "body" ).delegate( "p", "click", function() {
$( this ).after( "<p>Another paragraph!</p>" );
});
Therefore, I'm thinking it may be because I'm inserting a copy of the element or is it the same element I'm adding over and over? I've also tried to use clone to create a new element before inserting like:
var $template = $(data).clone();
Can anyone show me where I am going wrong with this please?
The problem is that every time your ajax is called you attach a click event handler to the elements. It gets called repeatedly, because you add it to the elements that already existed and had this handler attached.
The solution for your problem is to detach previously attached handlers with off() function.
var setButtonClick = function (url, btn) {
$.ajax(url, $('form').serialize(), 'Html').then(function (data) {
$(btn).parent().find(sel.addListItem)
.off('click')
.on('click', function () {
addListItem(data, this, btn);
});
addListItem(data, btn, btn);
});
}
#
In the future you may want to attach different click event handlers or may want to turn off specific handlers, for that you could use namespaces.
$(elem).on('event.namespace', function(){});
$(elem).off('event.namespace');
That way you could have multiple click event handlers on one element. This would be the code if you have more than one click event handlers
var setButtonClick = function (url, btn) {
$.ajax(url, $('form').serialize(), 'Html').then(function (data) {
$(btn).parent().find(sel.addListItem)
.off('click.addItem')
.on('click.addItem', function () {
addListItem(data, this, btn);
});
addListItem(data, btn, btn);
});
}
#
And here's the example.
$('.btn').on('click.ns1', function(){
alert('Hey');
});
$('.btn').on('click.ns2', function(){
alert('How you doin?');
});
// Comment me out to see the difference
$('.btn').off('click.ns2');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="btn">Click me</button>
Can you please tell me how how to get click event of row element of jstree ?
I make a demo of jstree in my fiddle .it is made in panel .you have to press "open panel " button to check panel
I want to click event of jstree element to get it id on click ?
For preparation of tree I have to press "add test case button" many times and then press "open panel" button.
here is my fiddle
http://jsfiddle.net/ZLe2R/6/
function addMenuItemsOfTestSuit(id){
var menuid = "menu_" + id;
var ref = $('#tree').jstree(true);
alert('thank')
ref.create_node("#", {"id" : menuid, "text" : id});
ref.deselect_all();
}
Use this event listener:
$('#tree').on("select_node.jstree", function (e, data) { alert("node_id: " + data.node.id); });
Look jsTree API events for a list of events.
EDIT: created a fiddle: http://jsfiddle.net/y7ar9/4/
You can use
$(document).on('click', '.jstree-anchor', function(e) {...});
You may want to move your click handler to its own function and get the id from the anchor's parent:
$(document).on('click', '.jstree-anchor', function(e) {
var anchorId = $(this).parent().attr('id');
var clickId = anchorId.substring(anchorId.indexOf('_') + 1, anchorId.length);
onMenuItemClick(clickId, e);
});
$(document).on('click', '.clickTestCaseRow', function (e) {
onMenuItemClick(this.id, e);
});
function onMenuItemClick(clickId, e) {
hideDisplayView();
displayNewView(clickId);
e.stopPropagation();
}
Here is a fiddle.
Personally I like event 'activate_node' instead. if you do a postback on node selection change and the page is reloaded and the node is still selected it will not cause another event to fire causing an endless postback loop.
$('#jstree').on('activate_node.jstree', function (e, data) {
if (data == undefined || data.node == undefined || data.node.id == undefined)
return;
alert('clicked node: ' + data.node.id);
});
I need to send a request on click of button but callback is not received on firing of click event of the button.
Following is code snippet:
$(document).ready(function () {
var counter = 0;
$("#trail").click(function () {
$("#dialog").dialog();
if (counter < 1) {
$("#searchboxdiv").after('<input type="text" id="searchbox">');
$("#searchbox").after('<input type="button" id="searchbutton" value="search">');
counter++;
}
});
$("#searchbutton").click(function () {
var dataToSend = null;
$.ajax({
data: dataToSend,
url: "FormHandler",
success: function (result) {},
beforeSend: function () {
dataToSend = $("#searchbox").val();
}
});
});
$("#searchboxdiv").on('click', "#searchbutton", function(){
var data = null;
});
});
I added the textbox in the dialog box dynamically and on click of button in dialog box, callback is not received
Your options:
Use event delegation. Bind the click to immediate static parent like this :
$("#searchboxdiv").on('click', "#searchbutton", function(){ });
Or, bind it to the document.
$(document).on('click', "#searchbutton", function(){ });
Or, move the existing click after counter++;, ie., inside $("#trail")'s click handler.
For more info, see on()
Use event delegation (for dynamically added #searchbutton)
$('#searchboxdiv').on('click',"#searchbutton",function(){
http://learn.jquery.com/events/event-delegation/