The server sends some JSON. It contains a list of structured data. I display this data as a list of textboxes, each of which has its own onClick event. On click, the value of the textbox is set to whatever is in the structured data (which is an unique ID, which means that each textbox should display the ID on click).
When I first click on any textbox, its value is set correctly -- with the ID from the data from the server. But as I click on other textboxes, they display IDs from the first-click textbox!
I've tried both closure var and $.proxy(), but they doesn't seem to work. I've checked the contents of myAttribute and they change on each iteration of the $.each() function. The click() event, however, seems to be evaluated at "runtime" and doesn't update.
The questions are:
How do I fix my problem, so that myProcessedAttribute will contain the correct data instead of the data on first click?
I feel my approach of having four nested functions might not be best practice.. Or is it?
Code:
$.ajax({
[...]
success: function (data) {
[...]
$.each(data.listOfData, function () {
[...]
var myAttribute = this.myCoolAttribute; // <-- closure
jQuery('<p/>')
[...]
.click(function () {
var myProcessedAttribute = process(myAttribute);
[jquery ui dialog...]
create: function () {
// it always contains the same data
// the data on first click, after that, it never changes.
$("#myDialog").html(myProcessedAttribute);
}
});
});
}
});
EDIT: I've just put alert(myProcessedAttribute) in click() and create events. In the former event, the alert displayed correct data. In latter event, the alert was displayed only on first click, but it never appeared again on subsequent clicks!
MY SOLUTION: I thought that on calling .dialog({...}) the new dialog replaces the old one, but I was wrong. I've solved the problem by destroying the old dialog before creating a new one.
BETTER SOLUTION: See answer below.
"create" event is called when dialog is created.
Second time you open dialog, create event is not fired, because dialog object already exist on that element.
If you want different values on same dialog widget, use "open" event.
This is a sample
http://jsfiddle.net/RaWrC/
Related
I have a modal with an accordion in it. There is an anchor tag for each image on the page that can open the modal window. Inside the modal, the accordion has slide switches where the user can choose to turn on or off a value for that image.
The undesired behavior occurs after one input has changed on a specific image. I am receiving the value of the input values that were previously changed as well.
What I would like to see is for each image to have it own values, that is, the values that were changed specific to that image. I shouldn't see the values from any other image. In addition, if I change the value of a specific image to
true, I don't want to see that value set to true for any other image. I hope this all makes sense. I'm not very savvy with JavaScript but I've tried to explain as best I can.
This is what the JavaScript looks like
$(".glyphicon-tags").on('click', function(){
var iid = $(this).data('iid'); // this is the imageId
$(".onoffswitch ").on("click", function(){
var tid = $(this).data('tid'); // this is the tagId
alert(iid + ' ' + tid);
});
});
Using
$(".onoffswitch ").off("click").on("click", function(){
should fix it.
The way you've got it now, every time glyphicon-tags is clicked, you just keep on adding extra event handlers for "onoffswitch" and never removing the old ones. Next time onoffswitch is clicked, it runs all the defined event handlers. Setting an event handler on an element doesn't remove the old one (unless you're running IE6 or something), it adds an extra one to the existing list of handlers.
The "off" method removes previously defined event handlers on an element. See http://api.jquery.com/off/ for more details of the options you can pass in etc.
I'm writing a simple single page application with Express.js. At the bottom of the page is a form, and this form is used to add users to a table, or to update a specific user. The 'submit' button will have a different function depending on the ID of the button at the time it is pressed.
Inside my document.ready function, I have 2 lines of interest:
$('#btnAddUser').on('click', addUser);
$('#btnUpdateUser').on('click', updateUser);
I also have methods that change the value of this id from #btnAddUser to #btnUpdateUser, and vice versa. I can get the ID to change. The issue is that the document.ready function doesn't seem to consider these changes.
For instance, the app starts out with the id #btnAddUser. Then I change it to have the Id #updateUser, and I can see that this works. When I press the button, though, the addUser method fires instead of the updateUser method, and I'm not sure why.
Pointy's answer should work, but this is an X->Y problem. You shouldn't be trying to toggle functionality by changing an element's ID.
Instead, store a value somewhere that says what the button should do, and then use that. You could use a data-* attribute on the button if you want:
<!-- Dynamically change data-action and value as needed -->
<input id="btnUserAction" type="button" data-action="add" value="Add" />
$('#btnUserAction').on('click', function (e) {
var action = ($(this).data("action") === "add") ? addUser : updateUser;
action.call(this, e);
});
Alternatively, you could have two separate buttons and show/hide them. Either approach should work.
You can get the effect you want by using event delegation to set up the handlers:
$(document).on('click', '#btnAddUser', addUser);
$(document).on('click', '#btnUpdateUser', updateUser);
By doing it that way, you defer the inspection of the element until the time a "click" actually happens. With your code, the elements were located at the time the handlers were assigned. After that, it doesn't matter what the "id" value is because the handler is directly associated with the DOM node (via an internal map that jQuery maintains).
This won't work, because the click event is assigned one time when ready function executes. I think the better way is to have two buttons and show/hide them instead of changing the id.
Another way would be to store the action you want in an attribute:
$('#mybutton').click(function() {
var action = $(this).attr("data-action");
if(action == "do_this")
// ...
});
And for changing the action:
$('#mybutton').attr("data-action", "do_this");
I am developing a application in MVC.
I have a view which contain another partial view.
I have textbox1 in a parent view but its value get assigned from partial view.
Now, the moment the Textbox1 get assigned with some value, I want to perform some action
like put the 10% value textbox1 value on the another textbox, textbox2 of the view.
( I want the event when textbox value get changed by code, not the manual entry.
so cant use blur() event. )
which event in jquery should I used to perform this task ?
Partials views are all processed server-side, where Javascript is not executed. Javascript only works with the full page and does not know anything about partials, so take this worry out of your question.
As already been mentioned, you need .change() and if that is not good enough, just create a function that updates value of your checkbox and do other stuff which you need doing.
//psudo-code using .trigger()
function updateTextbox(value){
$('#myTexboxId').val(value);
$('#myTexboxId').trigger('change');
}
And here another method where you create another function that updates your values and does the calculation for you.
//pseudo-code using another function
function updateMyTextbox(value){
$('#myTextboxId').val(value);
doCalculation();
}
$('#myTextBoxId').on('change',function(){
doCalculation();
});
function doCalculation(){
// update your other values
}
I have a page dynamically generated with javascript and it contains several input fields and a button. When I click the button, nothing happens...Is it because it is a javascript object and not a "real" dom object? If so, is there a way to interact with the object?
I just wrote a simple alert to see if the button is even working.
jQuery("#button").click(function() {
alert("yes it's working");
});
On first page load this works...I believe on first page load it is PHP generated and when I click to another section, this same button will show up BUT the page does not refresh so this leads me to believe when I click on to another section, it is dynamically re-generated with JS.
Now if I click the button, nothing happens...no errors or no alerts...
You need to use .live because at the point in time when you assign the handler the element doesn't exist.
$('#button').live('click', function() {
});
You should also look into delegate if you're doing this with multiple elements for efficiency purposes.
I think I get what you're saying.
When you run jQuery('#button'), it searches for the elements then and there. The event is attached to the button itself, not to the query string #button.
jQuery does, however, offer the behavior you want.
jQuery('#button').live('click', function () { /* on click event */ });
live attaches to the query string, not the elements, so it will apply to any #button ever generated in the future.
I have some JavaScript/jQuery code that watches for the "changed" event on a checkbox:
$(control).change(function() {
alert("changed to: " + $(this).is(":checked"));
});
This works fine.
I'd like to create a reference to the change() function on the particular object, and call it indirectly, like so:
var onSomeChange = $(control).change;
onSomeChange(function() {
alert("changed to: " + $(this).is(":checked"));
});
I need to call it indirectly because I'll want to switch the method I'm assigning to onSomeChange with a different one, depending on the circumstances. (The single assignment to onSomeChange is just here for illustration).
This doesn't work. In Firebug I get this error:
this.bind is not a function
How can I get a reference to an object's method and call it without calling it from the object directly?
Background
The context may be significant; if there's an entirely different way to do what I want, that's fine too.
The behavior of the change event in JavaScript is a bit different for check boxes and radio buttons. A check box fires change whenever its state changes (checked or unchecked). However, radio buttons (in Firefox at least; I think it's even more complicated in other browsers) only fire a change for the radio button group as a whole. That's understandable, but I want to bind different actions to the states of the individual radio buttons. (Specifically, I want to potentially hide or show certain divs depending on the radio button states).
I think I can handle the event discrepancies by binding a custom event to each radio and then triggering it based on a change in the group. So I have extended jQuery to add a radioChange() method. This method
Now, I'd like to swap out this code with something that calls a different event-handling method depending on the type of the control. (Aside: it's because radio button seem to be handled differently than check boxes, so I have a different radio-button-specific event). I've added a radioChanged() extension method to jQuery to support this.
Now I want to have a method that registers a listener to either changed() or radioChanged() depending on the type of the object. Determining that is easy:
var change = $(control).is(":radio") ? $(control).radioChange : $(control).change;
The problem is that I can't actually call the method at the change reference without generating the error above.
Is there something else I should be doing to make this work?
Answer to original question:
You need to apply it on a object which has bind as prototype. probably enough to just pass $(control) as object in question, or perhaps $ is enough.
var $control = $(control);
var change = $control.change;
change.call( $control,
function() {
alert("changed to: " + $(this).is(":checked"));
}
);
sounds like you just need to call the bind event and pass it the targeted event string
$(control).bind($(control).is(":radio") ? "radioChange", "change", function () {});