jquery plugin set value of this - javascript

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

Related

Javascript variable value lost

I need help.
I have two grids:
<table id="section"></table>
<div id="pager_sec"></div>
<table id="details"></table>
<div id="pager_det"></div>
And this variable:
<script type="text/javascript">
var section_id;
SET the variable with the row selected on section. alert show the right value:
jQuery("#section").jqGrid({
onSelectRow: function (id) {
section_id = id;
alert(section_id);
}
});
But in editData of navgrid add operation the variable has not value:
jQuery("#details").jqGrid({
});
jQuery("#details").navGrid('#pager_det',{add:true},{editData:{num_section: section_id});
Thanks!
You should use callback functions inside of editData instead of properties:
editData: {
num_section: function () { return section_id; }
}
If will force the usage of the current value of section_id variable. You current code uses the value of section_id variable at the moment of calling navGrid method.

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

YUI modifying and detecting changes of a <div>

I want to see an alert message when the value of a div changes. This value is being modified by modify_div. When I click the button this function modifies the div, but the alert "value changed" is not displayed. Am I missing something?
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" " http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<script src="http://yui.yahooapis.com/3.5.1/build/yui/yui-min.js"></script>
<script>
YUI().use('node', function (Y) {
var demo = Y.one('#test');
demo.on('click', function (e) {
//alert('You clicked me');
});
});
YUI().use('node','event', function (Y) {
var demo = Y.one('#variable-name');
demo.on('change', function (e) {
alert('Value changed');
});
});
</script>
<script type="text/javascript">
function modify_div()
{
//var thevar = "This is a test";
var thevar = 7;
document.getElementById('variable-name').innerHTML = thevar;
}
</script>
</head>
<body>
<!-- Click me button -->
<input type="button" id="test" value="Click me" enabled="true" onclick="modify_div();"> </input>
</br>
<div id="variable-name" style="display:inline;">01010101</div>
</body>
</html>
based on http://www.quirksmode.org/dom/events/change.html,
change event only fires if its form field
e.g. input textarea and select
so change event will not fire when contents of div is changed.
It will work if you replace div with input and update its value.
other option is to manually fire event where ever you are changing the value your variable
http://tech.groups.yahoo.com/group/ydn-javascript/message/13216
following SO question has answers but it requires jQuery
Detect element content changes with jQuery
The correct answer was given by #N30: there is no change event for divs. He provides good alternatives but no YUI specific information, so I'd like to extend his answer with an example of a YUI Plugin.
Like he explained, the basic idea is to keep a value in JavaScript memory and fire an event when you change that value. You can do this by extending Y.EventTarget which provides you with custom events:
YUI().use('node', 'plugin', function (Y) {
function NodeValuePlugin(config) {
// Boilerplate
NodeValuePlugin.superclass.constructor.apply(this);
// config.host is the Y.Node instance
this._node = config.host;
// we keep the value in a private property
this._value = this._node.get('text');
// we publish a 'change' event and set a default
// function to run when the event is fired
// This function will change the private property
// and update the DOM
// This means you can call e.preventDefault() and
// stop the default behavior (the change of value)
this.publish('change', {
emitFacade: true,
defaultFn: this._defValueChangeFn
});
}
Y.extend(NodeValuePlugin, Y.EventTarget, {
set: function (newVal) {
// we want to do stuff only when the value changes
if (newVal != this._value) {
// instead of changing the DOM here,
// we fire an event and let the event
// do the work
// We pass it the new and old values
this.fire('change', {
newVal: newVal,
prevVal: this._value
});
}
// make this method chainable
return this;
},
get: function () {
return this._value;
},
_defValueChangeFn: function (e) {
// sync everything
this._value = e.newVal;
this._node.set('text', e.newVal);
},
// this is necessary boilerplate for plugins
destroy: function () {}
}, {
// we can access the plugin from node[namespace]
// in this case, node.value
NS: 'value'
});
var node = Y.one('#test').plug(NodeValuePlugin);
node.value.on('change', function (e) {
console.log('Here\'s the old value: ' + e.prevVal);
console.log('Here\'s the new value: ' + e.newVal);
});
// Freebie:
// since we're using node.set('text', foo)
// this prevents XSS vulnerabilities
node.value.set('qwer');
});​
You can learn more about plugins from the Plugin User Guide in the YUI website.

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

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>

Javascript scope question: Can't change element via 'this' obj passed to function, but I can using longhand approach

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

Categories