MithrilJS Hyperscript - mithril.js

m("div", {
onclick: function(e) {
console.log(e);
},
}, "Test")
Hello, i would like to know if having an event handler such as the one above creates a new function on Mithril redraw? I want to avoid performance issues.

It will be recreated on each redraw. The perf impact is generally negligible.
https://jsperf.com/create-function-vs-reference isn't an exact test, but hopefully provides a rough idea of the difference.
Always profile though! If the function creation is your bottleneck abstracting it out would be an easy fix.

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/

Dojo1.8: _WidgetBase does not sound good to me

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.

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.

.queue() and .proxy(), animation timing in jQuery

I'm working on a pseudo plugin (just really an namespaced initializer on the jQuery object) and I'm having a bit of trouble with .proxy() and .queue() (seemingly two of the most misunderstood methods around)
Anyways, I thought I had the logic sorted out; the function $.cb() takes a map of functions as such:
$.cb({
'show': function(){ },
'hide': function(){ },
'open': function(){ },
'close': function(){ },
'beforeUpdate': function(){ },
'afterUpdate': function(){ }
});
These functions (should) contain animation sequences applied to $(this), the context of which has internally, via .proxy(), been changed to the respective element(s). They are stored in a settings variable, available to all methods of the "plugin".
Internally, some namespaced event handlers, attached via .live({ }):
// ...
'cb.hide': function(event){
if(event.isPropagationStopped()){
return false;
}
event.stopPropagation();
$.proxy(settings.hide, this)();
$(this).hide();
},
'cb.update': function(event, html){
if(event.isPropagationStopped()){
return false;
}
event.stopPropagation();
$.proxy(settings.beforeUpdate, this)();
$(this).html(html);
$.proxy(settings.afterUpdate, this)();
},
// ...
Anyways, the purpose is that there in inherent functionality brought to the table using this "plugin", but the implementer can pass the function map to opt for different transitional animations.
The problem, is that I can't seem to get these functions to queue properly; different ones taking precedence, etc. I've tried mocking around with .queue() but I can't seem to get anything right with it:
// in cb.update
var $this = $(this);
$(this).queue(function(next){
$.proxy(settings.beforeUpdate, $this)();
next();
}).queue(function(next){
$this.html(html);
next();
}).queue(function(next){
$.proxy(settings.afterUpdate, $this)();
}).dequeue();
The problem is especially prevalent with the 'cb.update' event, as the order should be:
beforeUpdate is called (animation sequence occurs and completes)
The element's contents are updated via .html()
afterUpdate is called (animation sequence occurs and completes)
Whats actually happening is:
The element's contents are updated via .html()
beforeUpdate is called (animation sequence occurs and completes)
afterUpdate is called (animation sequence occurs and completes)
So given the supplied animation is simply .fadeOut() and fadeIn() for beforeUpdate and afterUpdate respectively, it's updating the contents, then fading out and in.
So, any suggestions on this sort of implementation? How can I ensure the proper ordering of the events/animations? Have I gone a wildly stupid route in terms of trying to implement such a feature?

Using dijit.InlineEditBox with dijit.form.Select

I'm trying to use a dijit.form.Select as the editor for my dijit.InlineEditBox. Two problems / unexpected behavior seem to occur:
Inconsistently, the InLineEditBox doesn't have the initial value set as selected
Consistently, after selecting a choice, the value that should be hidden is shown instead of the label.
The width isn't set to 130px
Here's working code: http://jsfiddle.net/mimercha/Vuet8/7/
The jist
<span dojoType="dijit.InlineEditBox" editor="dijit.form.Select"
editorParams="{
options: [
{label:'None',value:'none'},
{label:'Student',value:'stu'},
{label:'Professor',value:'prof',selected:true},
],
style:'width:1000px;',
}"
editorStyle="width: 1000px;"
>
</span>
Any help is greatly appreciated! Thanks!
Okay, after a few MORE hours struggling with the mess that is dijit.InlineEditBox, I think I have the solution to the remaining issue (#2).
EDIT: My first solution to #2 is still flawed; the implementation at http://jsfiddle.net/kfranqueiro/Vuet8/10/ will never return the actual internal value when get('value') is called.
EDIT #2: I've revamped the solution so that value still retains the real (hidden) value, keeping displayedValue separate. See if this works better:
http://jsfiddle.net/kfranqueiro/Vuet8/13/
First, to recap for those who weren't on IRC:
Issue #1 was happening due to value not being properly set as a top-level property of the InlineEditBox itself; it didn't pick it up properly from the wrapped widget.
Issue #3 was happening due to some pretty crazy logic that InlineEditBox executes to try to resolve styles. Turns out though that InlineEditBox makes setting width particularly easy by also exposing it as a top-level numeric attribute. (Though IINM you can also specify a percentage as a string e.g. "50%")
Now, issue #2...that was the killer. The problem is, while InlineEditBox seems to have some logic to account for widgets that have a displayedValue attribute, that logic is sometimes wrong (it expects a displayedValue property to actually exist on the widget, which isn't necessarily the case), and other times missing entirely (when the InlineEditBox initializes). I've worked around those as best I could in my own dojo.declared extensions to InlineEditBox and the internal widget it uses, _InlineEditor - since generally it's a good idea to leave the original distribution untouched.
It's not pretty (neither is the underlying code I dug through to understand and come up with this), but it seems to be doing its job.
But man, this was rather interesting. And potentially pertinent to my interests as well, as we have used this widget in our UIs as well, and will be using it more in the future.
Let me know if anything backfires.
hm...
<span dojoType="dijit.InlineEditBox" editor="dijit.form.Select"
editorParams="{
options: [
{label:'None',value:'none'},
{label:'Student',value:'stu'},
{label:'Professor',value:'prof',selected:true},**<<<<** and this comma is for?
],
style:'width:1000px;',**<<<<** and this comma is for?
}"
editorStyle="width: 1000px;"
>
</span>
Also, when using dijit.form.Select, selected value is not attr "selected" but value.
And if you enter prof inside <span ...blah > prof </span> than your proper selected option will be selected ;)
Dijit select checks for VALUE, not attr.
This may be fixed in recent Dojo - see http://bugs.dojotoolkit.org/ticket/15141 - but using 1.7.3 I found this worked:
In my app directory, at the same level as dojo, dijit and dojox, I created a file InlineSelectBox.js which extends InlineEditBox with code to set the HTML on the associated domNode from the value of the Dijit, and which wires up that code to the onChange() event:
define(["dijit/InlineEditBox",
"dijit/form/Select",
"dojo/on",
"dojo/_base/declare",
"dojo/_base/array"
],
function(InlineEditBox, Select, on, declare, array){
return declare(InlineEditBox, {
_setLabel: function() {
array.some(this.editorParams.options, function(option, i){
if (option.value == this.value) {
this.domNode.innerHTML = option.label;
return true;
}
return false;
}, this);
},
postMixInProperties: function(){
this.inherited(arguments);
this.connect(this, "onChange", "_setLabel");
},
postCreate: function(){
this.inherited(arguments);
this._setLabel();
}
});
});
Then, in my view script:
require(["dojo/ready",
"app/InlineSelectBox",
"dijit/form/Select"
],
function(ready, InlineSelectBox, Select){
ready(function(){
// Add code to set the options array
var options = [];
// Add code to set the initial value
var initialValue = '';
var inlineSelect = new InlineSelectBox({
editor: Select,
editorParams: {options: options},
autoSave: true,
value: initialValue
}, "domNodeToAttachTo");
});
});
I was dealing with this situation a few months ago, and not finding a resolution i made my own algorithm.
I put a div with an event on Onclick that build programatically a Filtering Select on that div with the store i want to use.
function create(id,value){
var name = dojo.byId(id).innerHTML;
dojo.byId(id).parentNode.innerHTML = '<div id="select"></div>';
new dijit.form.FilteringSelect({
store: store,
autoComplete: true,
invalidMessage:"Invalid Selection",
style: "width: 80px;",
onBlur: function(){ },
onChange: function(){ },
required: true,
value: value,
disabled: false,
searchAttr: "name",
id: "status"+id,
name: "status"
},"select");
dijit.byId('status'+id).focus();
}
I used the onBlur event to destroy the widget and the onchange to save by xhr the new value.
The focus is below because the onBlur was not working properly.
note: the function is not complete.