Dojo subscribe treenode select - dojo

I am using Struts 2 dojo plugin to make html tree. It generate some dojo-html code for tree node
<div dojoType="struts:StrutsTreeNode" id="2" title="car">
I want to process tree node click by this
<script language="JavaScript" type="text/javascript">
dojo.event.topic.subscribe("treeSelected", function treeNodeSelected(message) {
dojo.io.bind({
url: "<s:url value='../roseindia/objectsList2.action'/>?categoryId="+message.node.title,
load: function(type, data, evt) {
var divDisplay = dojo.byId("displayIt");
divDisplay.innerHTML=data;
},
mimeType: "text/html"
});
});
I can pass title(car) as message.node.title . I need to pass id not title, but where is not propertie message.node.id.
How can I get access to id(of treenode) in JavaScript function?

oohhkay, so youre in a 0.4.3 dojo.version!? im not sure how API works in that old a version, however the simplest current api hook is the onClick.
As i recall, with tree.onClick override you will get the item and the TreeNode, both being objects where the item is reference to your store json data and the treenode is the currently clicked row (dijit Widget, meaning you should have .getChildren, .domNode etc).
So in terms of code, try
<div dojoType="struts:StrutsTreeNode" id="2" title="car">
<script type="dojo/method" event="onClick" args="item, treeNode">
alert(treeNode.id);
alert(treeNode.domNode.tagName);
alert(treeNode.domNode.innerHTML.substr(0,30);
</script>
</div>

Related

How to change contents of a virtual dom element in Mithril?

How do I access a virtual dom element to change its contents using Mithril? I am new to Mithril and still trying to figure things out. For example, I want to access the third div with id "three" and change it's contents to "Blue Jays" without touching any of the other div's.
Thanks.
<div id='main'>
<div id='one'>Yankees</div><br>
<div id='two'>Red Sox</div><br>
<div id='three'>Orioles</div>
</div>
In mithril, like in react/vue/angular, you dont act on the actual DOM directly. Instead, you define the outcome that you want, so for example, to render the DOM tree that you posted you would do something like this:
var my_view = {
view: vnode => m('div#main', [
m('div#one', 'Yankees'),
m('div#two', 'Red Sox'),
m('div#three', 'Orioles')
])
}
m.mount(root, my_view)
<script src="https://cdnjs.cloudflare.com/ajax/libs/mithril/2.0.4/mithril.js"></script>
<div id="root"></div>
the m(...) functions inside the array have a string as their second argument, that makes the output static, but we can change that to a variable:
var my_view = {
oninit: vnode => vnode.state.fave_team = 'Orioles',
view: vnode => m('div#main', [
m('div#one', 'Yankees'),
m('div#two', 'Red Sox'),
m('div#three', vnode.state.fave_team)
])
}
m.mount(root, my_view)
<script src="https://cdnjs.cloudflare.com/ajax/libs/mithril/2.0.4/mithril.js"></script>
<div id="root">
</div>
In this case I used the state property of the vnode argument, but you can also use a third party state manager like flux or any other.
Now that we have it as a variable, it will show the current value on every call m.redraw(), most of the times we dont have to do this call ourselves, for example:
var my_view = {
oninit: vnode => {
vnode.state.fave_team = 'Orioles'
},
view: vnode => m('div#main', [
m('div#one', 'Yankees'),
m('div#two', 'Red Sox'),
m('div#three', vnode.state.fave_team),
m('button', { onclick: () => vnode.state.fave_team = 'Dodgers' }, 'Change')
])
}
m.mount(root, my_view)
<script src="https://cdnjs.cloudflare.com/ajax/libs/mithril/2.0.4/mithril.js"></script>
<div id="root"></div>
And thats it, any dynamic content in your DOM elements you set it as a variable/property in an object.
One of the beautiful things about mithril is that it doesnt force you to do things one specific way, so if you really want to work on the actual DOM node, there are lifecycle events that you can attach to any virtual node ("vnode")
You can easily capture the HTMLElement (i.e., HTMLInputElement) with the Mithril Lifecycle event of oncreate(). This is an actual example from my code (in TypeScript) where I need to hook up a few event listneres after the canvas element was created and its underlying DOM is available to me at "raw" HTML level. Once you get a hold of dom, then I manipulate that element directly. Many people think that why not use oninit(), but oninit() is before the generation of dom, so you will not get the element back at that stage.
Now, if you just do that, you will likely be posting another question - "Why the browser views not updating?" And that's because you do have to manually do a m.redraw() in your event handlers. Otherwise Mithril would not know when the view diffs to be computed.
const canvas = m(`.row[tabIndex=${my.tabIndex}]`, {
oncreate: (element: VnodeDOM<any, any>) => {
const dom = element.dom;
dom.addEventListener("wheel", my.eventWheel, false);
dom.addEventListener("keydown", my.eventKeyDown, false);
}
},

Dojo1.9: Custom widget inherited from another custom widget template string update not reflected

I have a custom widget which extends _WidgetBase, _TemplatedMixin with template
<div dojoAttachPoint="widget">
<div dojoAttachPoint="title">${name}</div>
<div dojoAttachPoint="dnmschart"></div>
</div>
and another widget which extends above widget
require([
'dojo/_base/declare',
'my/widget/view/AbstractWidget'
], function (declare, AbstractWidget) {
return declare("my.widget.view.AbstractChart", [AbstractWidget], {
constructor:function(){
},
buildRendering: function(){
this.inherited(arguments);
var gridDiv = document.createElement("div");
gridDiv.setAttribute("dojoAttachPoint", "gridPlaceHolder");
},
postCreate:function(){
this.inherited(arguments);
//Here I could not get newly created node gridPlaceHolder
console.log(" POST CREATION");
}
});
});
When I print in console (Break point in post create method)
this.domNode
It shows newly created node at last in document(last node in above template)
<div dojoattachpoint="gridPlaceHolder"></div>
But I could not access gridPlaceHolder attach point in post create method.
Is there anything else need to configure?
Please help me on this:)
data-dojo-attach-point (which you should use for 1.6+ instead of dojoAttachPoint) allows you to have handles for dom nodes in your template.. It is parsed by _TemplatedMixin's buildRendering(), so it will be available in your buildRendering method just after this.inherited line.
You can not set data-dojo-attach-point using setAttribute, it can only be defined in templates to be parsed by TemplatedMixin. If you need your child widget to add some markup in addition to what there is in its parent's template, you can define a variable in your parent's markup, and overwrite it in your child widget:
Your AbstractWidget template:
<div data-dojo-attach-point="widget">
<div data-dojo-attach-point="title">${name}</div>
<div data-dojo-attach-point="dnmschart"></div>
${childMarkup}
</div>
And then you need to add your additional markup in child's buildRendering, before this.inherited:
require([
'dojo/_base/declare',
'my/widget/view/AbstractWidget'
], function (declare, AbstractWidget) {
return declare("my.widget.view.AbstractChart", [AbstractWidget], {
buildRendering: function(){
this.childMarkup = '<div data-dojo-attach-point="gridPlaceHolder"></div>';
this.inherited(arguments);
}
});
As stafamus said, the primary problem here is that you're attempting to assign data-dojo-attach-point or dojoAttachPoint to a node after the template has already been parsed (which happens during the this.inherited call in your buildRendering.
Going beyond that, given the code in the original post, it also appears you're never actually adding the markup you create in buildRendering to your widget's DOM at all - you've only created a div that is not attached to any existing DOM tree. I'm a bit confused on this point though, since you claim that you are seeing the markup for the node you added, which shouldn't be possible with the code above, or the code in stafamus' answer.
Rather than attempting to dump extra markup into your template, you might as well do the programmatic equivalent to what an attach point would be doing in this case anyway: create your DOM node, attach it to your widget's DOM, and assign it to this.gridPlaceHolder. e.g.:
buildRendering: function () {
this.inherited(arguments);
this.gridPlaceHolder = document.createElement('div');
this.domNode.appendChild(this.gridPlaceholder);
}

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>

Dispatching events from webkit for consumption in Adobe AIR

I have a webkit HTML component in my AIR application, and would like to be able to respond to events such as onclick and ondoubleclick generated from the HTML in the webkit component. Is there any way to accomplish this?
There is, although it took me a little while to find it.
This should serve as a pretty good starting off point: http://livedocs.adobe.com/flex/3/html/help.html?content=ProgrammingHTMLAndJavaScript_04.html
Here's the key code:
var html:HTMLLoader = new HTMLLoader();
var foo:String = "Hello from container SWF."
function helloFromJS(message:String):void {
trace("JavaScript says:", message);
}
var urlReq:URLRequest = new URLRequest("test.html");
html.addEventListener(Event.COMPLETE, loaded);
html.load(urlReq);
function loaded(e:Event):void{
html.window.foo = foo;
html.window.helloFromJS = helloFromJS;
}
The HTML content (in a file named test.html) loaded into the HTMLLoader object in the previous example can access the foo property and the helloFromJS() method defined in the parent SWF file:
<html>
<script>
function alertFoo() {
alert(foo);
}
</script>
<body>
<button onClick="alertFoo()">
What is foo?
</button>
<p><button onClick="helloFromJS('Hi.')">
Call helloFromJS() function.
</button></p>
</body>
</html>