dijit.byId returns undefined - dojo

I have a hidden form and I am trying to put it into a variable via dijit.byId
Unfortunately it always returns undefined.
Am I missing something? dojo is flummoxing me at every corner - any help much appreciated.
js:
dojo.require("dijit.form.Form");
dojo.require("dijit.form.Button");
dojo.require("dijit.form.ValidationTextBox");
dojo.addOnLoad(function() {
var regForm = dijit.byId("hiddenRegister");
//regForm is undefined
});
html:
<div id="hiddenRegister" dojoType="dijit.form.Form" jsId="hiddenRegister" encType="multipart/form-data" action="" method=""></div>

id and jsId should not be the same
and if you are using jsId, then there is no need for dijit.byId. The widget is already assigned to a variable using the jsId as the variable name.

Related

Dojo NodeList-traverse - order of nodes returned

HTML
<div id="outer-container" class="container">
<div id="inner-container" class="container">
<div id="some-node"></div>
</div>
</div>
JS
require(["dojo/query", "dojo/NodeList-traverse"], function(query){
console.log(query("#some-node").parents('.container'));
});
This will log an array with two DOM nodes - the one with the id "outer-container", and the one with the id "inner-container".
What I want to know is, is there a way to know in what order will parent nodes appear in the array returned? My testing showed that there isn't, but that doesn't make sense, the method goes through the DOM structure either upwards or downwards, right?
I tested your code in JSFiddle and always got the same result:
[div#inner-container.container, div#outer-container.container]
If you really want to know what happens, check the "dojo/Nodelist-traverse" class in the Dojo source.
This is what the "parents()" method does:
parents: function(/*String?*/ query){
return this._getRelatedUniqueNodes(query, function(node, ary){
var pary = [];
while(node.parentNode){
node = node.parentNode;
pary.push(node);
}
return pary;
}); // dojo/NodeList
}
I haven't gone through the "_getRelatedUniqueNodes" method, but it seems that the "closest" parent is added to the list first, following it's parent .... and so on. This is exactly what happened in my JSFiddle.

Can I bind data to data-win-options?

I use the control MicrosoftNSJS.Advertising.AdControl in the ItemTemplate of a ListView.
I would like to bind some datas to the following data-win-options properties : ApplicationId and AdUnitId
The source datas are correctly set and are visible in my item template, I can display them with an h2 + a classic data-win-bind on innerText property
Ads are displayed correctly if I put directly static IDs in html code but these IDs need to be loaded from a config file...
Is it possible ? Thanks
If it's not possible, can I modify directly the item template in the JS code before to be injected in the listview ?
Come to find out this is possible (I was trying to do something similar)
The syntax for the control properties must be prefixed with winControl.
Example (I'm setting the application id here but binding the html element's className and the ad control's adUnitId)
<div id="adItemTemplate" data-win-control="WinJS.Binding.Template">
<div data-win-bind="className:css; winControl.adUnitId: adUnitId"
data-win-control="MicrosoftNSJS.Advertising.AdControl"
data-win-options="{ applicationId: 'd25517cb-12d4-4699-8bdc-52040c712cab'}">
</div>
</div>
I finally found a way to perform this without real binding, by using the itemTemplateSelector function like this :
function itemTemplateSelector(itemPromise)
{
return itemPromise.then(function (item)
{
if (item.type == "ad")
{
var template = _$(".adTemplate").winControl.render(item, null);
// Access to the AdControl through the DOM
var adControl = template._value.childNodes[1].childNodes[1].winControl;
// Set options that are specified in the item
WinJS.UI.setOptions(adControl, { applicationId: item.AdAppId, adUnitId: item.AdUnitId });
return template;
}
else
{
return _$(".itemTemplate").winControl.render(item, null);
}
}
}
I had this problem in ratings:
<div data-win-control="WinJS.UI.Rating" data-win-options="{averageRating: 3.4, onchange: basics.changeRating}"></div>
I bind it via winControl:
<div data-win-control="WinJS.UI.Rating" data-win-bind="winControl.averageRating: myrating" data-win-options="{onchange: basics.changeRating}"></div>
It worked fine.
<div data-win-bind="this['data-list_item_index']:id WinJS.Binding.setAttribute" >

Dojo : Use of declarative combobox with programmatic jsonreststore

This is the JSON from my REST Server:
[{"name":"REL"},{"name":"RBOW"},{"name":"EMLAWEB"}]
This is the programmatic creation of the JSON data store:
dojo.addOnLoad(function(){
var appPrefixStore = new dojox.data.JsonRestStore({target:"http://localhost:9080/AtRest/AtRest/tag/prefix"});`
This is the declaratively use of the data store in the comboxbox:
<input id="selectPrefixCombo"
name="appPrefix"
data-dojo-type="dijit.form.ComboxBox"
data-dojo-props="autocomplete:'false', trim:'true', maxHeight:'200', store:'appPrefixStore'">
</input>
However, nothing can displayed in the combobox. What gives?
I have even tried declaratively use of the data store:
<div data-dojo-type="dojo.data.JsonRestStore" ...
Anyway... here's the working code by using global variable
<script type="text/javascript">
//global variable container
var widgets = {};
require(
// Set of module identifiers
[ "dojo",
"dojo/parser",
"dojo/_base/xhr",
"dijit/form/ComboBox",
"dojo/store/JsonRest",
],
// Callback function, invoked on dependencies evaluation results
function(JsonRestStore) {
widgets.appPrefixStore = new dojo.store.JsonRest({target:"http://localhost:9080/AtRest/AtRest/tag/prefix"});
});
</script>
<select id="selectPrefixCombo" name="appPrefix" data-dojo-type="dijit.form.ComboBox"
data-dojo-props="autocomplete:'false', trim:'true', maxHeight:'200', store:widgets.appPrefixStore">
</select>
Thanks, Apparently I may have been misled by all the tutorials and examples I have seen.
Constructing the JsonRestStore is insufficient to trigger a request to the server. I have to add an appPrefixStore.fetch() to make it work.

Is there a way to disconnect an event added by dojoAttachEvent

I have a dojo widget which uses a a custom-library code having a link like this in its template.
Go Back
I need to find a way to disconnect this event from my widget. The only way i know how an event can be disconnected is, using a
dojo.disconnect(handle)
I could use this if I had the event connected using dojo,connect() which returns me the handle.
However with dojoAttachEvent i don't have the event handle hence no way to disconnect it.
Note :
Changing this html is not an option for me, since this an external library i am using.
Also, I am not looking for a solution to disconnect all events.
CODE:
otherWidget.js:
dojo.provide("otherWidget");
dojo.declare("otherWidget", [], {
templateString : dojo.cache("otherWidget","templates/otherWidget.html"),
_goBack: function(){
this.destroyWidgetAndRedirect();
},
destroyWidgetAndRedirect: function(){
//Code to destory and redirect.
},
});
otherWidget.html:
<div>
Go Back
<!-- Other Widget related code -->
...
</div>
myWidget.js:
dojo.provide("myWidget");
dojo.require("otherWidget");
dojo.declare("myWidget", [], {
templateString : dojo.cache("myWidget","templates/myWidget.html"),
this.otherWidget = new otherWidget({}, dojo.byId('otherWidgetContainer'));
});
myWidget.html:
<div>
<div id="otherWidgetContainer"></div>
<!-- My Widget related code -->
...
</div>
Any thoughts..
Thanks.
Extension points can be used directly on your html, or in javascript. Suppose the widget you are using is called 'my.custom.dojowidget', and that it has an onClick extension point. I will show here the declarative way, in your html. Try this :
<div data-dojo-type="my.custom.widget">
<script type="dojo/method" data-dojo-event="onClick" data-dojo-args"evt">
dojo.stopEvent(evt);
console.debug("did this work ?");
</script>
</div>
Now this depends on the existence of the extension point... if you can't still do what you want, please post the relevant parts of your widget's code.
So... based on the sample code you posted in your edit, I think you should do the following :
<div data-dojo-type="otherWidget">
<script type="dojo/method" data-dojo-event="destroyWidgetAndRedirect" data-dojo-args="evt">
dojo.stopEvent(evt);
// do whatever custom code you want here...
</script>
</div>

Dojo Issue: .parent() not a function

The HTML snippet:
<div class="hide_on_start">
<label>Type of Visit</label>
<div id="record_visit_type"></div>
</div>
<div class="hide_on_start">
<label>Visit Date</label>
<div id="record_visit_date"></div>
</div>
<div class="hide_on_start">
<label>Staff</label>
<div id="record_staff"></div>
</div>
The javascript I am using:
>>> dojo.byId('record_visit_type')
<div id="record_visit_type">
>>> dojo.byId('record_visit_type').parent().removeClass('hide_on_start')
TypeError: dojo.byId("record_visit_type").parent is not a function
I don't understand what the issue is with dojo.byId('record_visit_type').parent().removeClass('hide_on_start'). Can somebody explain?
Thanks
It looks like you're using dojo.byId as if it returns a dojo.NodeList, but it doesn't - it just returns a DOM node. Only dojo.query regularly returns dojo.NodeList objects.
dojo.NodeList objects have a removeClass function (which operates on all nodes in the list), and if you dojo.require("dojo.NodeList-traverse"), they also have a parent() function which returns a new NodeList containing the immediate parents of respective nodes in the original list.
http://dojotoolkit.org/reference-guide/dojo/NodeList-traverse.html
Theres a couple of problems I see with your code:
I think what you are looking for is the parentNode property of the domNode you are retrieving. This is not a method, but a property of the domNode you are looking up via dojo.byId.
Also, domNodes themselves to not have a removeClass method. You probably want to use dojo's dojo.removeClass(domNOde, cssClass) method to do this.
var recordVisitTypeDomNode = dojo.byId('record_visit_type');
dojo.removeClass(recordVisitTypeDomNode.parentNode, 'hide_on_start');
parentNode is right but here is how you do it in dojo:
// Go from the DOM node to a NodeList
var myDomNode = dojo.byId('record_visit_type');
var myNodeList = dojo.query(myDomNode);
// Get the parent
dojo.require("dojo.NodeList-traverse");
var parent = myNodeList.parent()[0];
This method of calling dojo.query is valid:
// Non-selector Queries:
// ---------------------
//
// If something other than a String is passed for the query,
// `dojo.query` will return a new `dojo.NodeList` instance
// constructed from that parameter alone and all further
// processing will stop. This means that if you have a reference
// to a node or NodeList, you can quickly construct a new NodeList
// from the original by calling `dojo.query(node)` or
// `dojo.query(list)`.
http://jsapi.info/dojo/1/dojo.query
It is like jquery $(myDomNode).parent().