Why doesn't $(this) work inside a javascript function? - javascript

I've attached an onlick event to a function. I want to reference the element being clicked from inside the function so I can change its inner HTML, but why is it not working? Is there any other way to reference the clicked element?
HTML
<div class="save_button" onclick="toggle_save_star(<?php echo $listing->listing_id ?>,'<?php echo base_url()?>')">
<?php if($listing->saved_element_id):?>
<img src="<?php echo site_url('images/core/icons/basic2/star1_16.png')?>" />
<?php else:?>
<img src="<?php echo site_url('images/core/icons/basic2/star1_16_gray.png')?>" />
<?php endif; ?>
</div>
Javascript Function
function toggle_save_star(element_id, site_url) {
var url = site_url+"AJAX/ajax_default/modify_saved";
var button = $(this);
$.post(url,{action: 'toggle', element_id: element_id, type: 'listing' }, function(data) {
if(data == 'saved') {
$(button).html('<img src="'+site_url+'images/core/icons/basic2/star1_16.png" />');
}
else{
$(button).html('<img src="'+site_url+'images/core/icons/basic2/star1_16_gray.png" />');
}
});
}

I think in this case "this" don't reference to the div. You should try:
$('.save_button').click(function(){
$(this)...
});

Try $("#"+element_id) instead. $(this) isn't working because you're not running this function as a method on an object.
Improving on the other answers, try this:
$(".save_button").click(function(){
toggle_save_star(element_id, site_url, $(this));
});
and in your function, the third new argument (called "target", let's say) could be used like this:
var button = target;
then use button like button.html(...);

The main problem here is that when you assign a string to onclick in your markup as in:
<div class="save_button" onclick="toggle_save_star..."
then, the code in the quotes gets evaluated by eval() and the this pointer will be set to point to the window object, not to the object that generated the click. If you want this set appropriately, then you can't assign the onclick handler in the markup, you would need to do it with JS as in:
$(".save_button").click();
or some other way in code.
In addition, there's a coding error in your toggle_save_star function.
Your button variable is already a jQuery object so you don't need to try to make it into another one with $(button). If you were going to use that function, you would have to change it to this:
function toggle_save_star(element_id, site_url) {
var url = site_url+"AJAX/ajax_default/modify_saved";
var button = $(this);
$.post(url,{action: 'toggle', element_id: element_id, type: 'listing' }, function(data) {
if(data == 'saved') {
button.html('<img src="'+site_url+'images/core/icons/basic2/star1_16.png" />');
}
else{
button.html('<img src="'+site_url+'images/core/icons/basic2/star1_16_gray.png" />');
}
});
}

You would be better off removing the onclick from your div and going with something like the following:
http://jsfiddle.net/cpeele00/epD3v/
This allows you access the clickable item, in this case 'save_button'.
Then, at the bottom of your page (before you reach the closing body tag, insert your script there).
<script>
$(document).ready(function(){
//CALL THE FUNCTION HERE
//DEFINE THE FUNCTION HERE (see the jsFiddle link above)
});
</script>
</body>

Related

Google Tag Manager - storing id of a clicked div/button

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;
}

how to use a dynamically added html class inside ajax

I am trying to pull all images from a folder on a page. Then I have added html class to the '.append' function against an element of jquery inside ajax. Now I want to use the class outside ajax in another function. But it seems the class was local and hence not defined outside ajax. Can you please tell me how to solve this? My code -
/* html code */
<body>
<div id="imageWrapper">
<div id="spanImage"></div>
</div>
<script>
var folder = "images/";
$.ajax({
url : folder,
success: function (data) {
$(data).find("a").attr("href", function (i, val) {
if( val.match(/\.(jpe?g|png|gif)$/) ) {
$("#spanImage").append( "<img src='"+ folder + val +"' class='imageThumbnails'>");
}
});
}
});
/* I have added class = 'imageThumbnails' dynamically to each image appended. Now I would like to use the class to work on individual image to make them pop up
*/
$(".imageThumbnails").click(function() {...}
</script>
</body>
This is not working as 'imageThumbnails' is not recognized by the system as a valid class. Can you please help?
you can use below code to bind event
$(document).on("click",".imageThumbnails",function() {...});
this call dynamic binding.
Delegate it. Attach the listener to its parent and let the event bubbles.
$("body").on('click', '.imageThumbnails', function() {...}
See Its working..
You are not closing your clicking function .`
$(document).ready(function () {
$(".imageThumbnails").click(function() {...})
})
`
(function () {
$('body').append('<img class="imageThumbnails" src="some.png" alt="submit" >')
})()
$(document).ready(function () {
$('.imageThumbnails').click(function () {
console.log('work');
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Why returned value from AJAX disappears almost instantly?

this is my server-side code:
modify_emp.php
<?php
echo $_POST[id];
?>
And this is my Javascript in my html page:
<script>
$(document).ready(function () {
var alreadyClicked = false;
$('.element').hover(
//mouseenter function
function(){
$('.element').click(
function(){
$(this).css("color","blue");
var objName = $(this).attr('name');
var objColumn = $(this).attr('id');
if(!alreadyClicked){
alreadyClicked = true;
$(this)
.prepend('<form method="POST" class="newInput"><input type="text" name="newInput" style="width:140px"></input></form>');
var elemento = $(".newInput");
var position = elemento.position();
$(".newInput").css({
'position': 'absolute',
'top': position.top + 15,
'opacity':0.9,
'z-index':5000,
})
.focus();
//on enter keypress
$(document).keypress(function(e) {
if(e.which == 13) {
$.ajax({
url: 'modify_imp.php',
type: 'post',
data: { id : objName, column : objColumn },
success: function(data, status){
$("#debug").html(data);
}
});
}
});
} //if (!alreadyClicked) end
}); //end mouseenter function
},
//mouseleave function
function () {
alreadyClicked = false;
$(this).css("color","red");
$(".newInput").remove();
}
); //end .hover
});
The debug is a <div id="debug"> </div> at the end of my html page where i want to show my response from server. When i press 'ENTER' I can actually see the value for 0.1s inside that div, but then it disappears.
I already tried to pass the return value to a local or global variable but it didn't work.
For some reason the value inside response is lost after 0.1s, even if i pass it to another variable elsewhere.
Can someone explain me why and how can i "store" the server response?
EDIT: Just edited with my entire <script>
Since you see the result momentarily, I'm going to hazard a guess that you have a form element on your page and when you hit return, it's actually submitting the form. You briefly see the result of the ajax operation and then your form submits causing the page to reload as a new blank page. This is a common issue and always has these same symptoms.
You can either remove the form element or block the default submission of the form with javascript.
If you show us more of your actual HTML, we could help more specifically with how to prevent the form from submitting.
You can solve this by calling the function in the form tag i.e,
<form action="javascript:AnyFunction();">
your code goes here
.
Another way would be to assign a BUTTON to trigger the ajax, and set the button outside of the FORM

jQuery $(this) does not insert text into my element

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`

jquery plugin set value of this

I am creating star rating box...
my php page is as below
<html>
<head>
<script src='jquery.js'></script>
<script src='alamStars.js'></script>
<script>
$().ready(function(){
$("#txtStar").alamStar();
});
</script>
</head>
<body>
<?php
if(isset($_GET[]))
{
echo $_GET['txtStar'];
}
?>
<form>
<input type='text' name='txtStar' id='txtStar'>
<input type='submit'>
</form>
</body>
</html>
my plugin code is as below
;(function ($) {
$.fn.alamStar = function (options) {
var defaultVal = {
img: '../images/start_rating.png',
width: 105,
height: 120
}; //end array of default values
var obj = $.extend(defaultVal, options);//overwrite default values if there
this.after("<div id='alamStarBox' stars='"+this.val()+"'></div>");//dynamically create div
var alamStarBox=$("#alamStarBox");//assign alamStarBox to a variable
alamStarBox.html(this.val());//set initial value from textbox
alamStarBox.css({
'color' : 'red',
'background-image' : 'url('+obj.img+')',
'max-width' : obj.width+"px",
'max-height' : obj.height+"px",
'overflow' : 'hidden'
});//end styling css to alamStarBox
alamStarBox.mousemove(function(e){
var l=alamStarBox.offset().left;//Left value of alaStarBox
var c=parseInt(e.pageX)+21;//current-position
if(c>(parseInt(l)+parseInt(10)))
{
$(this).html("0");
$(this).css('background-position-Y','0px');
}
if(c>(parseInt(l)+parseInt(30)))
{
$(this).html("1");
$(this).css('background-position-Y','-20px');
}
if(c>(parseInt(l)+parseInt(50)))
{
$(this).html("2");
$(this).css('background-position-Y','-40px');
}
if(c>(parseInt(l)+parseInt(70)))
{
$(this).html("3");
$(this).css('background-positionY','-60px');
}
if(c>(parseInt(l)+parseInt(90)))
{
$(this).html("4");
$(this).css('background-positionY','-80px');
}
if(c>(parseInt(l)+parseInt(110)))
{
$(this).html("5");
$(this).css('background-positionY','-100px');
}
});//end moue move function
alamStarBox.mouseout(function(){
var p=parseInt($(this).attr("stars"))*20;
$(this).css('background-positionY','-'+p+'px');
$(this).html($(this).attr("stars"));
});//end function alamStarBox mouseOut
alamStarBox.click(function(){
$(this).attr("stars",$(this).text());
});//end function alamStarBox click
var frm=this.closest("form");
frm.submit(function(){
this.val(alamStarBox.text());//on submit form copy text from starbox to textBox
//////////////////////////////////the above line is not working////////////////
});
};//end alamStar function
})(jQuery);
I want to set textbox value equal to div text, in last function named frm.submit
but it is not working even assigning it static string like "static value"
You have to save the copy of this in the parent function into another variable that you can then refer to in the callback function like this:
var self = this;
var frm = this.closest("form");
frm.submit(function(){
self.val(alamStarBox.text()); //on submit form copy text from starbox to textBox
});
This happens because inside the submit callback function this will have a different value (most likely it will be the form DOM object). Using a local variable named self or that or me is a very common design pattern for allowing a reference to the original object inside a local callback function.
You are using a callback on the jQuery .submit method of the form, so this is most likely not what you think it is (log it to console to see what it actually is).
Even $(this) will not work here, because that would be the form itself – and calling .val() on that makes no sense.
Select the input field explicitly in this function, then it should work: $("#txtStar").val(…)
Either you use jfriend00's suggestion or you can use $.proxy() which change the scope of the submit hanlder to the original "this" value.
frm.submit($.proxy(function(){
this.val(alamStarBox.text()); // NOW this=your textbox #txtStar
}, this));

Categories