I want to know the difference between in html and javascript.
dijit.byId("link_id").value = linkData.link_id;
dijit.byId("link_id").set("value",linkData.link_id);
because, when I used the first option, it did not set the value in the linkid textbox, but the second option did that. So just wanted to know what is happening in both situations.
The difference is that using the first method, you're directly setting a property of the widget object, for example, setting the value.
In the second example however, you're using the setter provided by dijit/_WidgetBase, which in turn calls a _set function, for the value property it would be _setValueAttr(). Widgets can extend these setters with custom functionality that will happen when using that setter. For example it can take the necessary steps to display the value as well.
If we, for example pick a dijit/form/Select widget and look at the code of _setValueAttr(), we notice that it calls some extra functions like:
domAttr.set(this.valueNode, "value", this.get("value"));
this._refreshState(); // to update this.state
This functionality is only called when using dijit.byId("link_id").set("value", "myValue");, and that's the reason why your value is only displayed in this case. When you're directly setting the property, you're "short-circuiting" this functionality.
TL;DR: Always use the setter function when using Dojo widgets.
Related
After creating a new binding for the value property on an input, the value no longer changes when a user modifies it manually.
What is lost when the binding is changed? Does the regular user interaction use key press listeners?
I am changing the setter/getter to have an element's text automatically bound to an input's value property (using Object.defineProperty(input,'value')...
This is causing user interaction with the input to no longer change the value property. So if I, as the user, type '2' into the input, the value for the input will still be whatever it started as and not '2'.
So redefining the value property must be breaking the old setter.
I can't seem to find an authoritative reference right now, but it's not generally possible/safe to update host objects (basically any object provided by the browser, instead of by JS itself) in this way. If you insist, you might try Object.getOwnPropertyDescriptor to see if you can get at the default setter before you Object.defineProperty and overwrite it.
More info: http://perfectionkills.com/whats-wrong-with-extending-the-dom/ (see esp. "Host objects have no rules")
I have a page where users can choose to book a ticket for a concert. First, they click on a artist which launches them into the booking process (and passes "artist" to the starting function).
The program then loads the venues for the artists. When the user changes the venue (and the value isn't blank) it tried to load the dates available in another select drop down menu by calling another function.
The original code was like:
<select onchange="loadDates(artist)">...</select>
However for some reason this wasn't passing the parameter from the starting function to the next function.
So I changed it too:
<select onchange="loadDates.call(this, artist)">..</select>
However the next function still gives me the error "artist is not defined" when I try to run it. Can anyone see what I'm doing wrong here as I read online that this works perfectly. I can give more information if need be. Thanks
Code in onXyz attributes is run at global scope, so both of your examples require that there be a global variable called artist. If there isn't one, then you'll get a ReferenceError because you're trying to take the value of a symbol that isn't defined.
If you meant to pass a string, put quotes around it. If you meant to pass something else, you'll need to say what that was. But the fundamental issue is that artist is not a defined symbol at global scope, which is where you're trying to use it.
If you have artist defined in some non-global location (good! globals are a bad thing), then you'll want to hook up your event handler via modern techniques rather than using the onXyz attributes.
The simplest way if you're not using a DOM library (like jQuery or similar) is to assign to the onXyz property of the select box element:
(function() { // Something to keep the stuff inside from being globals
var artist = "Joe Cocker";
var selectBox = document.querySelector("selector for the select box");
selectBox.onchange = function() {
loadDates(artist); // `artist` is in scope now
};
})();
In general, though, I avoid the onXyz properties because they only allow a single handler per event per element, preferring the DOM method addEventListener (and its Microsoft-specific predecessor, attachEvent). I didn't use them above for simplicity. If you don't use a DOM library, you might want this hookEvent function given in another answer which uses addEventListener if it's there, or attachEvent if it isn't, and supplies some missing bits for the attachEvent browsers.
I was trying to determine the best way to observe a variable's value and track its changes, for example 'language' or 'time-zone', then when it will be changed take some actions depending on the new value.
I thought of using setInterval, but I have many 'interval's in my website, so I don't want to overuse it, I'm worried that it may affect the user experience. Instead I found my self compelled to trigger the actions which I want to be done after the value changes in each method may change the variable's value, this is simple but makes my code a bit tightly coupled.
what do you suggest for that.
It seems like Object.observe would be pretty much exactly what you need; unfortunately it is currently proposed as a "post ECMAScript 6" spec, so it will be a while until it is widely available in browsers. There are shim implementations though (e.g. here or here), which could give you the same functionality in current browsers.
An alternative approach would be wrapping the object in question in a direct proxy, but those are part of ES6, and also not widely adopted by browsers yet.
In languages like C++, you'd do this with accessor methods.
For example, instead of accessing a property of a class with something like foo.bar, you'd say foo.getBar().
getBar() would look something like this:
this.getBar = function(){
console.log("bar was accessed");
return bar;
}
You should also have a method to set the value of bar, i.e.
this.setBar = function(newBar){
console.log("Setting the value of bar");
bar = newBar;
}
These methods will give you more control of your variables, too. For example, if someone tries to assign a string to something that should be an integer, you could throw an error. Or if you have a variable called "length", you could throw an error if someone tries to make it less than zero.
You should use Object.prototype.watch() to track variable's change
The watch() method watches for a property to be assigned a value and
runs a function when that occurs.
Watches for assignment to a property named prop in this object,
calling handler(prop, oldval, newval) whenever prop is set and storing
the return value in that property. A watchpoint can filter (or
nullify) the value assignment, by returning a modified newval (or by
returning oldval).
If you delete a property for which a watchpoint has been set, that
watchpoint does not disappear. If you later recreate the property, the
watchpoint is still in effect.
To remove a watchpoint, use the unwatch() method. By default, the
watch method is inherited by every object descended from Object.
there is not standard, but you can use the gist polifill created by eli-grey
Anyway this is a duplicate of Listening for variable changes in JavaScript or jQuery
I want to trigger an event whenever a variable is incremented. Is that possible?
var a = 0;
// if this variable gets incremented ++ to 1, I want to trigger an event.
// how can I create listener for it?
Google didn't help.
Directly like your example, it's not possible.
But, if the value is in an object, you could use a setter using defineProperty to know when a value is changed: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
Eventually, you may be able to listen to changes on objects using Object.observe http://updates.html5rocks.com/2012/11/Respond-to-change-with-Object-observe
Support for legacy browsers
Note thought that defineProperty won't work on old browsers.
If you need to support old ones, you can create an interface to change object value and do what you want on the methods (like myInt.increment()). (This pattern is used inside Backbone, Ember and others)
Or you can do some dirty checking by running a loop (setTimeout) and comparing the new value with a cached old value... (This is the solution took by Angular.js)
In ASP.NET we are calling defined js-functions with the:
Page.ClientScript.RegisterStartupScript(GetType(), "", "JSFuncNameHere();", true);
I wonder:
Why there isn't any method, which has a name like: Page.ClientScript.CallJSScript("someJSFunc");
Why does the upper-method require the reflection method GetType() ? Something isn't defined at runtime, is it?
Why do I need the 2nd argument key? As I have tested, I can left it empty and the existed JS-function shall be called.
Why there isn't any method, which has a name like: Page.ClientScript.CallJSScript("someJSFunc");
Probably because this is more generic solution, since by just adding 2 characters you get the same result and if you need you can add arguments and anything else.
Why does the upper-method require the reflection method GetType() ? Something isn't defined at runtime, is it?
Why do I need the 2nd argument key? As I have tested, I can left it empty and the existed JS-function shall be called.
For both of these the same reason - the method will detect if you run the same script multiple times and in such case, call it just once. The two arguments are the means how it identifies duplicates - a key is not sufficient since another class in a different library might be using the same key - so you need to pass in the type of your own class to ensure that the script is executed when you want it to.