$(document).ready(function() {
$("#register button[name=btnPosta]").click(function() {
console.log('clicked');
thisBtn = $(this);
parent = $(this).parent();
name = parent.data('name');
$(this).attr('disabled', true);
$.post('register.php', {
name: ('name')
}, function(data) {
console.log('Ajax success');
parent.next('#message').html(data);
thisBtn.attr('disabled', false); // reset });
console.log('Ajax success');
});
});
});
This function is used to display name in the #message div
however nothing gets displayed in the div.
Assuming your markup is similar to the markup you posted in your duplicate post from an hour ago:
...
<tr>
<td> <td>
<td> <button class='regular' id = "btnPost" name='save'> Log In </button></td>
</tr>
...
The problem is in your use of .next(). When you pass a selector argument to .next(), you only get a result if the next sibling element matches the selector. Your call to parent.next("#message") returns an empty jQuery object because:
The next sibling of the button's parent element (which is the <td>) does not have an id of message.
Actually, there is no next sibling of that <td>.
Since parent.next("#message") returns an empty jQuery object, calling .html() on it has no effect. The solution is just to use $("#message") directly:
$('#message').html(data);
My original answer was just a red herring:
Make sure to use the var keyword when defining your variables. Without var, you are creating a property on the Global object (or window when running JavaScript inside a browser). But, parent is already a property of window. In IE, window.parent is read-only, so your value is never set and you will get an error when you call parent.data().
Your code works for me when I use var: http://jsfiddle.net/gilly3/MkS9X/
$(function() {
$("#register").find("button[name=btnPosta]").click(function() {
console.log('clicked');
//notice the use of `var` to keep the variables local, which will be faster
var thisBtn = $(this),
parent = thisBtn.parent(),
name = parent.data('name');
//notice the use of `.prop()` instead of `.attr()`, `.prop()` is new as of jQuery 1.6, so if you are using an older version then `.attr()` is the way to go
thisBtn.prop('disabled', true);
$.post('register.php', {
name: name //notice here that this references the `name` variable set further up
}, function(data) {
console.log('Ajax success');
parent.next('#message').html(data);
thisBtn.prop('disabled', false); // reset });
console.log('Ajax success');
});
});
});
Just a couple suggestions for your code. Mainly the variables were being created in the global scope for most likely no reason.
Related
Looked for the answer all over, tried reading seperatly but couldn't find an answer..
I have a site, on which Google Tag Manager is implemented, and I need to extract the id of a clicked button (or its parent).
this is my code:
function(){
$(document).ready(function(){
var editid;
$('div.uk-button').click(function() {
editid = $(this).attr('data-id');
});
return editid;
});
}
Thanks!
The simplest approach is to create the following custom javascript variable:
function(){
return $({{Click Element}}).attr('data-id');
}
This will return the data-id attribute for all events (including clicks).
Attach this variable to the relevant event tag, and use click class contains uk-button as the trigger.
You can remove the outer function and code like below.
$(document).ready(function () {
$('div.uk-button').click(function () {
var editid;
editid = $(this).attr('data-id');
alert(editid);
});
});
Hey it looks like you may be not be catching the returned value of the document ready callback.
For example, this returns undefined since the return of $(document).ready() callback is not being returned by the containing function:
function testfunc() {
$(document).ready(function(){
var editid = 'this is the return value';
return editid;
});
}
testFunc()
"returns undefined"
I'm guessing that you might be trying to set up a custom javascript variable in GTM. You can still use document ready to ensure the elements are present but the returned value needs to be returned by the outer function for it to be passed into the variable.
So your example should work as follows:
function(){
var editid;
$(document).ready(function(){
$('div.uk-button').click(function() {
editid = $(this).attr('data-id');
});
});
return editid;
}
I am currently adding flagging functionality to a project of mine, and I can't get jQuery's $(this) selector to work.
The goal of this is to change the text in the div from flag to flagged when the user clicks it, and the ajax query runs successfully. My HTML/PHP is:
<div class="flag" post_to_flag='".$post_to_flag."'>Flag</div>
And my javascript that deals with the div is:
$('.flag').live('click', function () {
$.post('../php/core.inc.php', {
action: 'flag',
post_to_flag: $(this).attr('post_to_flag')
}, function (flag_return) {
if (flag_return == 'query_success') {
$(this).text('flagged');
} else {
alert(flag_return);
}
});
});
I can't replace the text with flagged, but if I replace the this selector with the .flag selector, it will replace everything with the class of flag on the page.
I have checked, and the $(this) selector is getting the attribute of 'post_to_flag' just fine. Why is this happening, and how can I fix it?
You should add a context variable:
$('.flag').live('click', function () {
var $context = $(this);
$.post('../php/core.inc.php', {
action: 'flag',
post_to_flag: $context.attr('post_to_flag')
}, function (flag_return) {
if (flag_return == 'query_success') {
$context.text('flagged');
} else {
alert(flag_return);
}
});
});
You are calling multiple functions within your jQuery selection call. When you go into that $.post() function, your scope changes. this now refers to a different scope from when you were inside one().
#Moak's suggestion, if you set a variable to a jQuery object, it's probably best to denote the variable with a beginning $ just for potential clarity for future readers or yourself.
this inside the ajax callback is not the element, but it is the Ajax object itself.
You can use $.proxy to pass in the context.
Ref $.proxy
$('.flag').live('click', function () {
$.post('../php/core.inc.php',
{action: 'flag', post_to_flag: $(this).attr('post_to_flag')},
$.proxy(function(flag_return) {
if(flag_return == 'query_success'){
$(this).text('flagged'); //Now this here will represent .flag
}else{
alert(flag_return);
}
},this)); //Now here you are passing in the context of `.flag`
<globemedia id="1"></globemedia>
<script type="text/javascript">
$("globemedia").each(function(index, value) {
var globeIDxMedia = $(this).attr("id");
$.get("getmedia.jsp?mediaID="+globeIDxMedia,function(a){
$(this).html(a);
});
});
</script>
The above Script i use to load content to my customized tag say <getmedia id="1"></getmedia>
script works fine till getting data from the page getmedia.jsp but when i use $(this).html(a); its not loading the data.
Got Answer from jquery forum
It'll work with custom tag as well
<script type="text/javascript">
$(document).ready(function(){
$("div[data-globalmedia]").each(function(index, value) {
var globeIDxMedia = $(this).attr("id");
$(this).load("getmedia.jsp?mediaID="+globeIDxMedia);
});
});
</script>
jQuery expert gave me solution you have to use $(document).ready(function(){}); and it works like a charm
Keep a reference to $(this) outside the $.get() function.
<script type="text/javascript">
$("globemedia").each(function(index, value) {
var globeIDxMedia = $(this).attr("id");
var self = $(this);
$.get("getmedia.jsp?mediaID="+globeIDxMedia,function(a){
$(self).html(a);
});
});
</script>
The meaning of this is different within the callback of $.get than it is within the callback of the outer $().each. You can read more about the semantics of this here: http://www.sitepoint.com/javascript-this-gotchas/
As a rule, if you want to refer to the "outer" value of this within a callback function, you first have to bind it to a variable that is accessible within the callback (in this case, I've used the common convention of a variable named self).
You can't this ( which refers to globemedia ) within $.get() callback function scope. Within $.get() callback function this refers to something else but not globemedia.
So, get keep reference of this outside of $.get() which refers to globalmedia like following:
$("globemedia").each(function(index, value) {
var globeIDxMedia = $(this).attr("id");
// keep referece to this
// ie. globemedia
var media = $(this);
$.get("getmedia.jsp?mediaID="+globeIDxMedia,function(a){
// here self refers to
// globemedia element
media.html(a);
});
});
Note
I think $("globemedia") should be $(".globemedia"). That means you should use a class selector.
You can't make your own custom HTML tag. See HERE
As you can't create you own HTML tag (here, globalmedia), instead of that you can use data attribute to them. For example:
<div data-globalmedia="media1" id="id_1">Media 1</div>
<div data-globalmedia="media2" id="id_2">Media 2</div>
and so on. And for jQuery you can use:
$('[data-globalmedia]').each(function() {
var globeIDxMedia = $(this).attr("id");
// keep referece to this
// ie. globemedia
var self = $(this);
$.get("getmedia.jsp?mediaID=" + globeIDxMedia, function(a) {
// here self refers to
// globemedia element
self.html(a);
});
});
Working sample
REVISED QUESTION (SEE BELOW FOR ORIGINAL):
Here is an example of a simple ajax load with an event binding on an element within the loaded content:
soTest.htm
<!DOCTYPE html>
<html>
<head>
<script language="JavaScript" type="text/javascript" src="http://code.jquery.com/jquery-1.6.min.js"></script>
<script>
function changeBG(obj)
{
alert('Color 1: Should Turn Red');
jQuery(obj).css('background-color','red');
alert('Color 2: Should Turn Green');
jQuery('#' + jQuery(obj).attr('id')).css('background-color','green');
}
jQuery(document).ready(
function() {
jQuery('.loadedContent').load('soTest2.htm');
jQuery('body').delegate("#theElem","click",
function(){
var obj = this;
jQuery('.loadedContent').load('soTest2.htm',
function(){
changeBG(obj);
}
);
});
}
);
</script>
</head>
<body>
<div class="loadedContent">
</div>
</body>
</html>
Ajax loaded content, soTest2.htm:
<div id="theElem" >
Hello
</div>
So why is it that this doesn't work:
jQuery(obj).css('background-color','red');
But this does:
jQuery('#' + jQuery(obj).attr('id')).css('background-color','red');
++++++++++ORIGINAL QUESTION:++++++++++
I have a table that I want to sort when specific table headings are clicked (those with the class "sort").
For instance:
Location
To do that I have this code:
jQuery('body').delegate("click", ".sort", function(event) {
event.preventDefault();
jQuery('.searchResults').html('<div align="center" style="margin-top:35px;"><img src="/common/images/ajax-loader_big.gif" /></div>');
var TimeStamp = new Date().getTime();
var sortItem = this;
jQuery('.searchResults').load('modules/configSearchResultsOutput.cfm?' + TimeStamp + '&sortby=' + jQuery(this).attr('sortby') + '&direction=' + jQuery(this).attr('direction'), {
data: jQuery('#results').val()
}, function() {
sortCallback(sortItem);
});
});
So on the click event for one of these sortable column headings I'm storing the entire 'this' scope in a var to pass through to this function.
To simplify the question I'll just say that we're trying to change the background color of the clicked element based on the custom attr 'direction' I'm using:
function sortCallback(obj) {
//Returns correct attribute value
alert('In Callback: ' + jQuery(obj).attr('direction'));
//Does not return correct attribute value -- almost like it's cached or something
alert('Long hand reference: ' + jQuery('.sort[sortby="' + jQuery(obj).attr('sortby') + '"]').attr('direction'));
//Must reference value via (obj) to get correct updated value
if (jQuery(obj).attr('direction') == 'asc') {
//Changing a value within the element via this longhand approach works
jQuery('.sort[sortby="' + jQuery(obj).attr('sortby') + '"]').css('background-color', 'red');
//Changing a value within the element via this shorter approach does not work
jQuery(obj).css('background-color', 'red');
}
else {
//Works
jQuery('.sort[sortby="' + jQuery(obj).attr('sortby') + '"]').css('background-color', 'green');
//Doesn't work
jQuery(obj).css('background-color', 'green');
}
}
I'm assuming I'm not understanding some aspect of javascript scoping (understanding 'this' has been very elusive to me).
Question summarized:
If I'm passing a var'd 'this' scope to a function why can't I change the aspects of the 'this' element, why must I drill down using the long way to change them?
A tricky question for me to articulate, hopefully I did a good enough job.
Thanks!
This is happening because your ajax call replaces the DOM element. obj refers to a DOM element that was in the DOM before you called .load, but was replaced. Another element with the same ID does exist, though! That's the one you're referring to with your 'longhand' method.
I think your problem is because that load call is asynchronous, causing jQuery to get confused. Put your code inside a callback for load and it should work:
jQuery(document).ready(function() {
jQuery('.loadedContent').load('soTest2.htm',
function(resp, status, xhr){
jQuery("#theElem").bind('click',
function(){
changeBG(this);
});
});
});
In my html page, I have a select with some options.
When selecting an option, an ajax call is fired passing the option's value to a php script, which returns an html fragment (another select) with a certain id that is appended to the page.
When the user selects another option from the first select, the event is fired again, the ajax call is executed and another html fragment (with the same id) gets appended to the page.
I want that, if the event is fired a second time, the appended element is removed form the page before appending the new one.
At the moment I'm using this code:
$(document).ready(function() {
$("#id_serie").change(function() { //#id_serie is the if of the first select
if ($("#id_subserie_label")) { //#id_subserie_label is the id of the html element returned by the ajax call
console.log("Removing");
$("#id_subserie_label").empty().remove();
}
var url = 'myscript.php';
var id_s = $(this).val();
$.post(url, {id_serie: id_s}, function(data) {
$("#id_serie").parent().after(data);
});
});
});
This is not working though, the html element returned by the second ajax call is appended after the element returned from the first call (because the element with id #id_subserie_label is not in the page when the script is loaded?).
How can I achieve what I need?
You're very close.
Just change if ($("#id_subserie_label")) to if ($("#id_subserie_label").length):
$(document).ready(function() {
$("#id_serie").change(function() {
if ($("#id_subserie_label").length) { // <=== change this line
console.log("Removing");
$("#id_subserie_label").empty().remove();
}
var url = 'myscript.php';
var id_s = $(this).val();
$.post(url, {id_serie: id_s}, function(data) {
$("#id_serie").parent().after(data);
});
});
});
See The jQuery FAQ: How do I test whether an element exists?.
This is because, as Ivo points out:
$("#id_subserie_label") is an object, and objects always evaluate to true.
As per Andy E's comment, you can simplify your code to this, if you don't need the console.log() call:
$(document).ready(function() {
$("#id_serie").change(function() {
$("#id_subserie_label").empty().remove();
var url = 'myscript.php';
var id_s = $(this).val();
$.post(url, {id_serie: id_s}, function(data) {
$("#id_serie").parent().after(data);
});
});
});