Dojo1.8: _WidgetBase does not sound good to me - dojo

Hi It seems that using _WidgetBase is is a bad idea to use.
What I was looking for is that I can make instances (with different properties from the class button).
require(["dojo/_base/declare", "dojo/dom","dojo/dom_construct", "dijit/_WidgetBase", dojo/domReady!],
function(declare, dom, domConstruct, _WidgetBase)
{
ready(function()
{
declare("myBtn", [_WidgetBase],
{buildRendering: function()
{
this.domNode = domConstruct.create('button');
}
});
registry.byId(new myBtn(
{id:'btn1',
label:'HelloA'
}).placeAt(dom.byId('line1')));
registry.byId(new myBtn(
{id:'btn2',
label:'HelloB'
}).placeAt(dom.byId('line2')));
registry.byId(new myBtn(
{id:'btn3',
label:'HelloC'
}).placeAt(dom.byId('line3')));
}
});
So I am wondering if it is okay to use _WidgetBase, when I wanted to add different properties for each button?

I am not sure if I understand your issue, while you can just use dijit/form/button (http://dojotoolkit.org/api/1.8/dijit/form/Button). If the button is just an example and you still need to extend _WidgetBase - answer to your question is yes, it is ok to use it, but there's a bit more code to write to make it configurable and flexible.

Related

Enquire.js: Don't get the purpose of "setup" handler

I don't quite get the idea behind enquire.js' "setup" handler.
Case:
I want to load content through ajax once when you're not in a small viewport (lt 600px).
Naturally I would do enquire.register('(min-width: 600px)', { setup: myFunction });.
Problem:
Now I tested this multiple times but the setup handler also gets fired when you're in a small screen, which totally eliminates the benefit of the setup handler imo, because you would want to only load the ajax content once you enter a viewport bigger than 600px, wouldn't you?
See example jsfiddle.
Conclusion:
So actually I wouldn't even need the setup handler because I simply could load the content outside the enquire register and would have the same effect. (Which of course isn't what I want...)
Can someone tell me if I just misunderstood the purpose of setup or is there something I'm missing?
Combine with the deferSetup flag to defer the setup callback until the first match. This example illustrates the feature:
enquire.register(someMediaQuery, {
setup : function() {
console.log("setup");
},
deferSetup : true,
match : function() {
console.log("match");
},
unmatch : function() {
console.log("unmatch");
}
});
You can see a working example here: http://wicky.nillia.ms/enquire.js/examples/defer-setup/

How to use dojo On with Dojox Searchbox?

I am following this link http://dojotoolkit.org/reference-guide/1.9/dojox/mobile/SearchBox.html and am trying to do the same in my app. The only difference is that I want to use "onSearch" event using "dojo On" but I am not able to read results, query, options that we get by default in the onSearch function.Please help me in solving this problem.
My HTML code:
<input data-dojo-type="dojox/mobile/SearchBox" type="search" placeHolder="Search"
data-dojo-props='store:store, searchAttr: "label", ignoreCase: true, pageSize:2'>
<ul data-dojo-type="dojox/mobile/RoundRectList" jsId="list"></ul>
My JS code:
define(["dojo/has",
"dojo/_base/declare",
"dojo/_base/lang",
"dojo/_base/array",
"dojo/dom",
"dojo/dom-class",
"dojo/dom-construct",
"dojo/query",
"dojo/dom-style",
"dojo/dom-attr",
"dojo/on",
"dojo/_base/Deferred",
"dojo/topic",
"dojo/_base/connect",
"dijit/registry",
"dojo/store/Memory",
"dojox/mobile/SearchBox",
"dojo/selector/acme"
],
function(has,declare,lang,array,dom,domClass,domConstruct,query,domStyle,domAttr,on,Deferred,topic,connect,registry,MemoryStore,SearchBox)
{
declare("controllers.SearchController", [], {
started:false,
constructor : function(args) {
WL.Logger.debug("SearchController created");
lang.mixin(this,args);
},
start:function(){
if(!this.started)
{
console.log("i am in SearchController.start");
this.subscription();
this.started = true;
}
},
subscription:function(){
store = new MemoryStore({data: [
{label: "Alabama"},
{label: "Alaska"},
{label: "American Samoa"},
{label: "Arizona"},
{label: "Arkansas"},
{label: "Kansas"},
{label: "Kentucky"}
]});
var searchbox=registry.byId("searchbox");
on(searchbox.domNode,"search",lang.hitch(this,this.onSearch));
},
onSearch: function (results, query, options) {
// this.onSearch = function () {};
console.log(results);
}
});
return controllers.SearchController;
}
);
Also, I am following this link dojox/mobile/SearchBox 'onSearch' event runs twice on webkit
to use the workaround for dojox searchbox. How can I implement it in my case?
You should never try to access widget events through DOM nodes. There is a difference between widgets and DOM nodes, and this is one of them. Also, because dojo/on can only be used with DOM nodes and DOM events, you cannot use it to handle the onSearch event.
Every widget has a on() function that you can use to attach widget event handlers. For example:
searchbox.on("search", lang.hitch(this, this.onSearch));
If the event runs twice, you can try doing something like this (you will probably have to rewrite this in your object oriented design):
var myEventHandler = searchbox.on("search", lang.hitch(this, this.onSearch());
myEventHandler.remove();
According to the API documentation the return value of the on() function is undefined, but this topic its stated that it returns an object containing a remove() function able to remove the event listener.
I don't think it's possible. If you want to retrieve data from your database/webservice, you could use the dojo/store/JsonRest store (RESTful webservices) or you could implement your own store (or fetch the data and put it in a dojo/store/Memory).
Dojo chooses for an abstraction layer upon your data implementation called the store API. The advantages of these are that, because it's an abstraction layer, that you can use your store for multiple purposes (all Dijit widgets, Dojo mobile widgets, ...) work in a similar way that they use a store.
Concerning this part of your question:
I am following this link dojox/mobile/SearchBox 'onSearch' event runs twice on webkit to use the workaround for dojox searchbox. How can I implement it in my case?
I do not think such a workaround is needed. As I wrote in this answer, as long as you have a store specified, SearchBox.onSearch() should be called only once.
In short: just do not apply this workaround, it shouldn't be necessary.
In addition to the event mistake pointed out by Dmitri, there's an issue with the order of execution.
When does Dojo parse your HTML? Do you have parseOnLoad:true in your dojoConfig (or data-dojo-config)?
When the parser reaches data-dojo-type="dojox/mobile/SearchBox", it will try to instantiate a SearchBox widget. Because you have specified store:store in its properties, it will look for a variable called store.
Now, the store variable itself gets instantiated in your SearchController. So you have to make sure that subscription() is called before the parser runs. However, the subscription() method in turn tries to look for a widget called "searchbox". So the parser has to be called before subscription(). As you can tell, this isn't going to work :)
So you have to rewrite the SearchController a bit. For example, you can remove the store:store from data-dojo-props, and let the controller set it in the subscription method:
var store = new MemoryStore({data: [....]});
var searchbox = registry.byId("searchbox");
searchbox.set("store", store);
searchbox.on("search", lang.hitch(this, this.onSearch)); // See Dmitri's answer.

How can I hide a dijit/form/button?

I think it is a common sense that providing a simple way to hide/show and enable/disable a button, but I cannot find any document that describe dojo has done such thing.
Any way, I hope it is my fault that I have missed out something while googling, thanks!
The following coding is what I have tried but they just make the button's text invisible:
dojo.style(btnInsert, {'visibility':'hidden'});
dojo.style(btnInsert, {'display':'none'});
UPDATE Question:
To oborden2:
I have tried your code, the result is same as the above code, here is the captured screen:
To MiBrock:
I have also tried your code and also get the result that same as the above code:
Form widgets in Dijit are special. For all normal Dijit widgets, the domNode (outermost node) of the widget receives the id property. However, with form widgets, the focusNode (which corresponds to the <input> element) receives the ID instead, so that things like <label for="foo"> work properly. In this case, the outermost node has no ID, and you’re actually just hiding the inner HTML input element.
If you already have reference to the widget:
require([ 'dojo/dom-style' ], function (domStyle) {
domStyle.set(widget.domNode, 'display', 'none');
});
If you only have a reference to the ID of the widget/original DOM node:
require([ 'dojo/dom-style', 'dijit/registry' ], function (domStyle, registry) {
domStyle.set(registry.byId(nodeId).domNode, 'display', 'none');
});
Try
require(["dojo/dom-style","dojo/domReady!"], function(domStyle){
domStyle.set(dojo.byId(domNode),'display','none');
});
The variable "domNode" stays for the id of the Node that should be influenced. This is the way we make it.
Regards, Miriam
Try using the Toggler module
require(["dojo/fx/Toggler"], function(Toggler),{
// Create a new Toggler with default options
var toggler = new Toggler({
node: "btnInsert"
});
// Hide the node
toggler.hide();
// Show the node
toggler.show();
});
http://dojotoolkit.org/reference-guide/1.9/dojo/fx/Toggler.html
I imagine you would want to link this to some event using Dojo's on module. Link it up to whatever condition triggers the button's need to be hidden.

How to use dojox/mobile/ScrollablePane Events

ScrollablePane in dojo mobile have some event that we can use as they have mentioned in their API documentation. I try to use the as follows.
leftPane.on("onTouchEnd", function(e){
alert("sss");
});
(leftPane is a ScrollablePane) This does not work. But this works when I use a event like "click". I search throughout the net for a example but didn't find a one. Can someone help me out here.
Thank you.
use:
aspect.after(leftPane, 'onTouchEnd', function(e) { });
dojo/on is tricky when it comes to the event naming - you could start by ditching the "on" prefix. Most likely, simply changing onTouchEnd to touchend would work
The Dojo event system changed significantly between 1.6 and 1.7. The new on function and the Evented mixin is the recommended way of handling events in widgets, but there are some backward-compatibility functions in the _WidgetBase class.
In short, you can either use the legacy dojo.connect function, the new aspect function (which implementes the "connect to normal javascript method" functionality of the old dojo.connect), or use the new on method in the _WidgetBase class that is a bridge between the two.
1. dojo.connect(leftPane, 'onTouchEnd', function(e) { });
2. aspect.after(leftPane, 'onTouchEnd', function(e) { }, true); // <-- the 'true' is important!
3. leftPane.on('touchend', function(e) { });
YMMV on (3) depending on whether the widget was updated to provide this bridging.

How to programatically add and use elements (dialog box in this case)

So My first though was, that adding more, and more HTML elements is not a way to go, and I come up with this solution
var Jaxi = {
CurrentLocation: '/',
showLoginDialog: function () {
dojo.place('<div data-dojo-type="dijit.Dialog" style="width:600px;" id="loginDialog"><div id="dialog-content"></div><a href="javascript:Jaxi.CloseDialog()">Close</div>', dojo.body())
dojo.xhrGet({
url: "/Account/SingIn?ReturnUrl=" + Jaxi.CurrentLocation,
load: function (result) {
dojo.byId("dialog-content").innerHTML = result;
}
});
dojo.ready(function () {
dijit.byId("loginDialog").show();
});
},
CloseDialog: function () {
dijit.byId("loginDialog").hide();
dojo.destroy("loginDialog");
}
};
It's working.. To some degree at least. Dialog open, but no styles are appiled. But moreover I can't close dialog.
Question Is how to make it working ?
After you have placed the div in your body, Dojo needs to parse the HTML to "notice" the new widget. When it notices the data-dojo-type attribute it says "Hey, here's a widget, I need to make this into a beautiful Dialog".
showLoginDialog: function () {
dojo.place('<div data-dojo-type="dijit.Dialog" ....</div>', dojo.body());
dojo.parser.parse();
....
Of course, you also have to make sure your body tag has class="claro" (or any other theme you want to use).
That being said, I personally think this is a little messy way to make a dialog box. You are sort of mixing declarative with programmatic. I'm not sure what you mean by "My first though was, that adding more, and more HTML elements is not a way to go", but in my own opinion mixing HTML inside your javascript makes the code difficult to read. You may want to take a look at this sitepen article if you want a clean way to separate HTML and Javascript.