Update div id in jquery so script can only run once - javascript

I currently have a script that I am using in my website. The goal of the script is when the user clicks the link, the javascript function will fire. This function is based off of the div id. At the end of the function I use jquery to change said div id. However, when the user clicks the link again the function still fires, even though the id has changed. What am I doing wrong? How can I get the script to only execute the first time the link is clicked?
$("#down").click(function(){
var id = $("#down").attr("class");
$.ajax({
type: "POST",
url: "vote.php",
data: "side=down&id=" + id,
success: function(){ alert("lul worked"); }
});
$('.' + id + '#down').attr('id', 'down_stay');
});
Now that you all have answered, what is the better choice, using "one" or using "unbind"?

Don't use click, use on. Or in your case, one:
$('#down').one('click', function() {
// function only fires once and then is unbound.
});

Use $("#down").one("click", function(){}); instead to make it fire only once.

Use unbind() instead.
replace
$('.' + id + '#down').attr('id', 'down_stay');
with
$( this ).unbind( 'click' );

Try using one
$("#down").one('click', function(){
The DOM events are attached to the elements and not to the attributes.
So even if you change the attributes of the element it does not mean it is a different element.
The event will only be removed if that particular element will be removed from the DOM..

Related

Updating a single divs contents and not every div with that class

I have the following HTML:
<a class="btn test-btn test-btn-1">
<span>Content 1</span>
</a>
This is used multiple times on the page. The 1 at the end of the test-btn- is generated dynamically so it could be 1 or it could be 200.
When the button is clicked some AJAX runs and a class gets added to the a tag called test-btn-clicked. When it's all finished I want to update the content within the span to say something different.
Now I've tried a few ways but everytime it keeps updating the content of every button and not just the one I have clicked.
Can anyone suggest a way to do this?
You need to target the current clicked element only, however you wont be able to access $(this) in ajax call as the context will be changed from clicked element to ajax call. You should define the current elements context before ajax call and then use it to update the clicked element. something like this:
$('.test-btn').click(function(){
var that = this;
$.ajax( { url: '#',success: function (result) {
$(that).find('span').text("new span text here");
});
});
Assuming this is the function that triggers the ajax call:
$('.btn').on('click', function() {
var that = $(this);
that.addClass('test-btn-clicked');
$.ajax({
url: "test.html"
}).done(function(data) {
that.find('span').html(data);
});
});
you need to do use this like
$('.test-btn').click(function(){ //
// your code
$(this).find('span').text('some text');
});

dynamic selectors added when a function is performed

I am echoing some php lines with some class id and need to be able to use them with jquery .click as the selector. Is there a way to do this?? The property is not loaded with everthing else, it is added later on by php.
play.js-
$(".link").click( function(){
/* var l = ""
$.post('input_commands/move_to.php',{l:l}, function(data) {
text=data;
elem = $("#placeholder");
//delay=100;
addTextByDelay(text,elem,delay);
}); */
alert("omg whyyyyy");
});
get_locations.php -
if($array_loc['loc_north']>0){echo "<a class='link' id='location_north'>Go north to ".$array_loc_north['loc_name']."</a> <br>";}
You need to use a delegated event because your elements are added to the DOM dynamically (or after the event handler is created).
$(document).on('click', '.link', function(){
console.log("clicked");
});
In the above, the event is delegated to the document and so all clicks will be checked against the .link selector, even if the target is an element that didn't exist when the event was delegated.
in order to bind an event to a dynamic element (one that was added after first DOM load),
replace:
$(".link").click( function(){
with:
$(document).on('click', '.link', function(){
hope that helps.
If it's added dynamically using ajax you might want to call that selector and append the .click() on the callback.
$.ajax({
url: '...',
success: function(response) {
// do stuff with response (assume that .link will be appended)
$(".link").click( function(){
//stuff when click link
}
}
});
Otherwise, you can output the links with the onclick attribute and define a custom function:
if($array_loc['loc_north']>0){echo "<a class='link' id='location_north' onclick='customFunction(this)'>Go north to ".$array_loc_north['loc_name']."</a> <br>";}
and in the JS:
function customFunction(element) {
//do stuff here after the link was clicked
//element variable passed as parameter contains the link element clicked
}
PS: If there are multiple elements it's not ok to specify constant value for "id" attribute because it should be unique.

Jquery .on not observing new elements that are added after load

I have the following jQuery code which watches for an ajax request and then shows / hides a spinner image when the request starts / ends.
This works fine on page load. However if I update part of the page with a new ajax link, this code no longer catches the ajax:before. Does anyone know if there is a solution to this without having to call unbind() and then re-call the code again?
$("*[data-spinner]").on('ajax:before', function(e) {
$('#' + $(e.target).data('spinner')).show();
});
$("*[data-spinner]").on('ajax:complete', function(e) {
$('#' + $(e.target).data('spinner')).hide();
});
Did you tried like
$("body").on("'ajax:before", "*[data-spinner]", function(){
$('#' + $(e.target).data('spinner')).show();
});
$("body").on('ajax:complete', "*[data-spinner]", function(e) {
$('#' + $(e.target).data('spinner')).hide();
});
$(document).on('ajax:before', '*[data-spinner]', function(e) {
$('#' + $(e.target).data('spinner')).show();
});
This is because jQuery binds its functions to the DOM on the pageload. If you try to bind your "data-spinner" that is not there yet jQuery will not find it and wont bind it.
However if you bind on document it can be found and we pass your '*[data-spinner]' as a 2nd parameter since its just a filter. jQuery will watch it only when you click something inside "document" so it will always be up-to-dated.
It should be something like
$(document).on("ajax:before", "*[data-spinner]", function(){
//...
});
Or you can use the parent element instead of document and it's better/faster, i.e.
$('#parent_element').on("ajax:before", "*[data-spinner]", function(){
//...
});
The prototype is
.on( events [, selector ] [, data ], handler(eventObject) )
Read more on jQuery website.

DataTable can't get id element after page change

I am trying to make ajax call on focus for every text input, I can make is in first page( when document ready) but when I change page , javascript can't parse inputs because it wasn't created when document is ready. How can I fix it ?
jQuery(document).ready( function(){
jQuery('[id^=urun_sirasi-]').focus(function(){
event.preventDefault();
var urun_sirasi=jQuery(this).data('sira');
console.log(urun_sirasi);
jQuery('#urun_sirasi-'+urun_sirasi).bind('keyup',function(e)
{
console.log(jQuery("#urun_sirasi-"+urun_sirasi).val());
jQuery.ajax({
url:'../ajax.php',
data:'process=siralama&urun_id='+urun_sirasi+'&urun_sirasi='+jQuery.trim(jQuery("#urun_sirasi-"+urun_sirasi).val()),
success:function(e){
// e -> 1 ve ya0 geliyor.
console.log(e);
}
});
});
});
});
Thanks for your help.
This seems to a very common problem in the jQuery section. See the docs for .on() at http://api.jquery.com/on/, specifically the section about delegated events:
Delegated events have the advantage that they can process events from
descendant elements that are added to the document at a later time.
I use the following syntax in the doc ready that will create events for all future items with the "expand" class, should be able to be adjusted for you
$(document).on('click',"#myTable .expand", function(){
so yours should be something like this (maybe give your items a class rather than having an event to each element selector)
$(document).on('keyup',"#yourTable .urun_sirasi-key", function(){

jQuery ajax attaching events to elements

I working with some ajax at the moment, the result of a successful ajax result is that some more content is add to the page on the fly. My problem is that is added on the fly it looks like I cannot attach any events to the elements that are added.
The flow of what happens is that the user selects an option from a drop-down list, the value of that selection is sent to a PHP function which then returns some more HTML to the page which is appended to a div on the page.
I know there is a problem with the elements not existing on domReady as I run a length() check and it confirms they don't 'exist' on the page.
Is there away around this so that I can run click event on the HTML that gets added after the first ajax request has returned successfully?
$(document).ready(function() {
//customise the select menus
$('#customselector').SelectCustomizer();;
$('.career_select .selectitems').click(function(){
var selectedCareer = $(this).attr('title');
$.ajax({
type: 'POST',
url: '/roadmap/step_two',
data: 'career_choice='+selectedCareer+"&ajax=true&submit_career=Next",
success: function(html){
$('.hfeed').append(html);
$('#grade_choice').SelectCustomizer();
}
});
});
$('#grade_choice_options .selectitems').click(function(){
var selectedGrade = $('#grade_choice_customselect').val();
alert(selectedGrade);
})
});
Use live() instead of click() directly:
$('.career_select .selectitems').live('click', function() { ....
live() essentially wires up any new elements that match that are added subsequently.
Try using this plugin :
http://brandonaaron.net/code/livequery/docs : Live Query utilizes the power of jQuery selectors by binding events or firing callbacks for matched elements auto-magically, even after the page has been loaded and the DOM updated.

Categories