dojo require self defined functions version 2 - dojo

I have a problem about requiring my own self defined functions.
In my test.html, I wrote:
require(["dojo/query", "new"], function(query, New) {New();});
New is the new.js file, which is located in the same place as the dojo folder.
In new.js I wrote:
define(["dojo/dom"], function(dom){return dom.byId("d1")});
In this case, I can call my New function, when I require it.
But if I change the place of new.js, then when I require "new" again,
there is a dojo Loader error.
if I change the place of new.js, for test.html how should I write it? Like:
require(["dojo/query", "../new"], function(query, New) {...});
this did not work.
Does someone know, how to require self defined js file, which is located not in the same place with the dojo folder?
Thanks...

I have solved the problem like this.
First I include dojo in my <head> like this:
<script type="text/javascript"
src="https://myserver.com/dojo/1.7.2/dojo/dojo.js"></script>
Now dojo can be found in a require. Just so it is clear, my directory listing of dojo is like this:
https://myserver.com/dojo/1.7.2/
Also you could try using dojo from a CDN.
Second, I have all my javascript in a folder, /js. When I require, I include the folder name like this "js/MyGrid.js". js is deployed into the root of my project on the server. Now I can require like this:
require([ "dojo", "dijit/Dialog", "dojo/parser", "dojo/_base/lang",
"dojo/query", "dojo/dom-class", "js/MyGrid.js", "js/MyUploader.js",
"dijit/form/TextBox", "dijit/form/Textarea", "js/MyJsonHelper.js",
"dijit/form/SimpleTextarea", "dojox/form/BusyButton", "dojo/dom-attr",
"dijit/form/Select", "dijit/ProgressBar", "js/MyArray.js",
"dojo/domReady!" ],
function(dojo, Dialog, parser, lang, query, domClass) {
PS: In no way am I advocating this as a best practice. It worked for me. I know there are other ways of doing it, like setting up your data-dojo-config like this:
var dojoConfig = {
packages: [
{ name: "my", location: "js", main: "app" }
]
};
http://dojotoolkit.org/documentation/tutorials/1.7/modules/

Related

gridx modules won't load in my rational/worklight environment

as i attempt to load modules with the creation of a gridx/grid, my script goes to that strange place where errors are handled by code that looks like gobbledy gook.
if i create the grid without the modules attribute the rows are displayed just fine. i am coding with worklight 6.1 in rational app developer 9.1, using dojo 1.9 that's (delivered with RAD).
my dojo includes are specified like this:
function dojoInit() {
require([ "dojo/ready", "dojo/parser", "dojox/mobile", "dojo/dom",
"dijit/registry", "dojox/mobile/ScrollableView",
"dojox/mobile/Heading", "dojox/mobile/ScrollablePane",
"dojox/mobile/Pane", "dojox/mobile/TextArea", "dojox/mobile/ContentPane",
"dojo/Deferred", "dojo/store/Memory",
"gridx/Grid", "gridx/core/model/cache/Sync", "dojox/mobile/Container",
"gridx/modules/SingleSort"],
function(ready) { ...
Here are my stylesheet links:
<link rel="stylesheet" href="css/dojo.css" />
<link rel="stylesheet" href="css/claro.css" />
<link rel="stylesheet" href="css/document.css" />
<link rel="stylesheet" href="css/Gridx.css" />
<link rel="stylesheet" href="css/Gridx_rtl.css" />
i moved the css files from gridx/resources/claro/Gridx.css and other locations within the dojo toolkit library to a known relative location, temporarily, in order to eliminate the possibility that the css files could not be resolved. and i am specifying just the 'claro' class in the div wherein this grid is placed. there is no difference in the behavior of the grid in either case.
My grid is created like this:
toStore=new dojo.store.Memory({ idProperty: 'PICYNO', data: resultSet });
toColumns=[
{ id: 'PICYNO', field: 'PICYNO', name: 'Cycle' , width: '80px' , editable: true },
{ id: 'PIDSC1', field: 'PIDSC1', name: 'Description' , width: '300px', editable: true },
{ id: 'PICYCS', field: 'PICYCS', name: 'Status' , width: '60px' , editable: true },
{ id: 'PPICSDJ',field: 'PPICSDJ', name: 'Date' , width: '80px' , editable: true },
{ id: 'PICYIT', field: 'PICYIT', name: 'Items' , width: '60px' , editable: true },
{ id: 'PICYLO', field: 'PICYLO', name: 'Locations' , width: '60px' , editable: true }
];
var cacheClass = "gridx/core/model/cache/Sync";
var tsGrid = new gridx.Grid({
id: 'idHeaderGrid',
cacheClass: cacheClass,
store: toStore,
// modules:[modules.SingleSort, modules.SelectRow],
// modules:[gridx.modules.SingleSort],
// modules:[gridx/modules/SingleSort],
// modules: [ SingleSort ],
// modules: [ Sort ],
structure: toColumns
});
tsGrid.placeAt('idGridContentPane');
tsGrid.startup();
if i comment all the lines that specifiy 'modules:' as you see, then the grid is displayed (but it's ugly, as if the stylesheets weren't applied at all.)
if i try any variation of specifying the standard sort module, this function will tank. i know it's probably because i'm not specifying my environment correctly, but i can't see how.
Any known problems with any of the versions that i'm using? any suggestion is appreciated.
--------- Updated ------------
I have progressed to the extent that i can display a grid, but the formatting is still off.
Based on the results of experimenting with a non-worklight project where i was able to materialize the grid with modules, and also realizing that with either type of project (web or worklight), i was able to resolve dojo and Gridx objects even though the javascript resources are configured differently, i decided to try a local require statement to specify the dojo modules in the immediate context and it worked. The original dojo configuration in worklight was ocnfigured in the main.js object that's automatically generated with a worklight application. it looked like this:
function wlCommonInit() {
require([ "layers/core-web-layer", "layers/mobile-ui-layer" ], dojoInit);
}
function dojoInit() {
require([ "dojo/ready", "dojo/parser", "dojox/mobile", "dojo/dom",
"dijit/registry", "dojox/mobile/ScrollableView",
"dojox/mobile/Heading", "dojox/mobile/ScrollablePane",
"dojox/mobile/Pane", "dojox/mobile/TextArea", "dojox/mobile/ContentPane",
"dojo/Deferred", "dojo/store/Memory", "dojox/mobile/Container",
"gridx/modules/SingleSort", "gridx/modules/ColumnResizer", "gridx/modules/RowHeader"
],
function(ready) {
ready(function() {
ccInit();
});
});
}
I removed the module declarations from the main.js and added them in the ccInit.js application where the grid is created, like this:
function populateGrid() {
require([
'dojo/store/Memory',
'gridx/Grid',
'gridx/core/model/cache/Sync',
'gridx/modules/SingleSort',
'gridx/modules/ColumnResizer',
'gridx/modules/RowHeader'
], function(Store, Grid, Cache, Sort, ColumnResizer, RowHeader) {
. . .
var tsGrid = new gridx.Grid({
id: 'idHeaderGrid',
cacheClass: Cache,
store: toStore,
modules: [ Sort, ColumnResizer, RowHeader ],
structure: toColumns,
selectRowTriggerOnCell: true
});
...
The grid is created successfully when it is created within an immediate require context as shown. Lots of dojo calls and even a grid without modules will work if i use the non-immediate approach.
The syles are still messed up, though. Column headings are blank and the table looks nothing like a claro-styled grid. I am sure that i have set up the css includes in the html header correctly (using my working web project as a model). Is there some worklight initialization or 'skin' overlay that's messing this up?
Thanks for any comment.
--- workaround is to refer to all classes, locally.
I solved the problem with stylesheets by creating the gridx.css in the common\css folder, then I edited it by replacing each #import with a copy/paste of the imported css source. So my gridx.css is a merge of all the source code from all the imports. i point to that css\gridx in my header link and i get reasonable results.
So in summary, i had to explicitly require the gridx classes in the custom function rather than in the dojo require statement in the main.js. And i had to merge all of the gridx styles and refer to them locally as well. The problem where gridx.css and other style sheets are not resolved through relative path includes that point to the dojo toolkit seems like a bug. Those stylesheets seem to be loaded in the run-time-generated server as evidenced by the console messages that look like this:
Failed to load resource: the server responded with a status of 404 (Not Found) http://myWLdevServer.mycomputer.local:10080/JustGridx/apps/services/preview/JustGridx/common/0/default/dojo/gridx/resources/claro/Gridx.css
If a developer is supposed to do some kind of server config to point to those CSS files, then I'm not seeing it.
I am leaving this post as unsolved in case someone agrees with me that this is a bug at worst or is not intuitive and should be documented at best.
From the comments by user3208130:
Sorry for not following up for all this time. i did finally work
around the problem by not importing anything. I copied the main
gridx.css from gridx\resources into my project, and then for each of
the imports listed in that file, i copy/pasted the source from the
various locations within the gridx collection as well as all of the
claro css files since gridx only uses that font. i had to turn off
theme switching depending on the device since claro looks awful on
windows8 and android otherwise.
I know this makes no sense, but i tried every variation of relative and explicit path that i could imagine for the import
statements in both of the html header and within the main css files
and nothing else worked. i suspected that the css files are not copied
automatically when device environments are created but i couldn't
prove that.

Dojo amd loading cross-domain modules at runtime

I want to load Dojo1.9 amd modules from an ad-hoc server on the www, but I won't know from where until runtime (with url params).
In essence, I want to do the equivalent of this:
require(['http://www.foo.com/SomeRandomModule'], function( SomeRandomModule ) {
// use SomeRandomModule
});
Quick and dirty way
Might have some unexpected quirks when it comes to the module system and relative paths, I haven't used it enough to say:
require([ "//host/myext/mod1/mod2.js" ],function(mod2){
// If current webpage is http:// or https:// or file://
// it tries to use the same protocol
});
Better way
Configure require() to treat all modules that start with a certain package name (e.g. foo) as coming from a particular URL. From your starter page, something like:
<script src="dojo/dojo.js"
data-dojo-config="packages:[{name:'myext',location:'//host/js/myext'}], async: 1, >
</script>
This lets you vastly improve your first example to:
require([ "myext/mod1/mod2" ],function(mod2){
});
If you are using a Dojo Bootstrap installation instead, you can avoid touching your data-dojo-config and instead put it inside the run.js startup file:
require({
baseUrl: '',
packages: [
'dojo',
'dijit',
'dojox',
'myapp',
{ name: 'myext', location: '//host/js/myext', map: {} }
]
}, [ 'myapp' ]);

is this the correct declarative, data-dojo-type syntax to require a package?

I have a package, defined in dojoConfig like this:
packages: [
{ name: 'Widget', location: '/widgets/Widget' }
]
The /widgets/Widget/main.js file defines my main module. With this config, in Javascript i can require the module Widget/main directly by its package name like this:
require(["Widget"], function(Widget){
var widget = new Widget();
// all is well
});
But doing the same using declarative syntax throws a Unable to resolve constructor for: 'Widget' error:
<div data-dojo-type="Widget"></div>
Am I doing something wrong, or is this expected behaviour?
It would be easier to see how widget is created, but the complaint is that you have no constructor.
a constructor is required for a widget. If you extend WidgetBase its done for you.
check the doc:
http://dojotoolkit.org/reference-guide/1.9/quickstart/writingWidgets.html
You need to add the
require(["Widget"], function(Widget){});
part in a script tag in the HTML document you are using
<div data-dojo-type="Widget"></div>
It should look like something:
<script> require(["Widget"], function(Widget){}); </script>
You have to require the module/widget before you can call it in an HTML page the same way you need to do it in a script tag.

on reloading/refreshing the page the dojo/ready function is not called

When refreshing/reloading a page, the dojo/ready function is not called, so the page is not loaded properly. Sometimes it is working properly; some times not.
window.onload = function() {
setTimeout(function(){document.body.style.opacity="100";},100);
require(["dojo/ready"], function(ready){
ready(function(){
alert("ready");
});
});
};
This is my window onload code. Sometimes I am getting the alert ready, sometimes not. I cannot figure out the issue.
Thanks in advance
I'd suggest to not use window.onload.
Instead, include your script as a js file like this:
<script type="text/javascript" src="/appRoot/js/my.js"></script>
Then in your my.js file:
require([ "dojo", "dojo/domReady!" ], function(dojo) {
// Code in here will be run only when the page is ready.
});
I am using this with dojo 1.7, but this is valid through 1.9.
See also the dojo/domReady! documentation.

How do I use Dojo inside of Worklight correctly?

I need some help as well as some advice on how to use Dojo correctly in my project. At the moment, this is what I'm doing:
Say I setup a project named 'Test'. Test.html is the first file hit, and in that file I have the following:
<script type="text/javascript" data-dojo-config="isDebug: false, async: true, parseOnLoad: true" src="dojo/dojo.js"></script>
<script type="text/javascript" src="dojo/core-web-layer.js"></script>
<script type="text/javascript" src="dojo/mobile-ui-layer.js"></script>
<script type="text/javascript" src="dojo/mobile-compat-layer.js"></script>
<script type="text/javascript">
require(
// Set of module identifiers
[ "dojo", "dojox/mobile/parser", "dojox/mobile/SwapView", "dojox/mobile", "dojox/mobile/compat", "dojox/mobile/deviceTheme", "dojox/mobile/ScrollableView" ],
// Callback function, invoked on dependencies evaluation results
function(dojo) {
dojo.ready(function() {});
});
</script>
I also have this in Test.js:
require([ "dojo", "dojox/mobile/parser", "dojox/mobile/deviceTheme",
"dojox/mobile/ScrollableView", "dojox/mobile/compat", "dojox/mobile",
"dojox/mobile/Button", "dojox/mobile/View", "dojox/mobile/Heading",
"dojox/mobile/TabBarButton", "dojox/mobile/TabBar",
"dojox/mobile/TextBox", "dojox/mobile/RoundRectList",
"dojox/mobile/ListItem", "dojox/mobile/Button",
"dojox/mobile/SpinWheel", "dojox/mobile/SpinWheelSlot",
"dojox/mobile/IconContainer", "dojox/mobile/SwapView" ],
function(dojo, parser) {
dojo.ready(function() {
});
});
Now, when I click a on one of my buttons, it triggers the WL.Page.Load method and my pagePort div now shows my new page inside of my Test.html page (let's say this is Page2.html), however, there's a problem. The Dojo stuff works fine on page one, but now it doesn't work on page two. I'm not sure what's happening behind the scenes but I feel I'm missing a step (do I need to unload Dojo? Declare it again in the next page?).
If somebody could help me get Dojo working on this second page so I'm able to use Dojo on further pages (after learning what I'm doing wrong) I would be really grateful!
My best guess based on the info you've given is that Page2.html is not really inside Test.html and its a new page. In this case you will need to have the script references in Page2 as well.
If you're testing your code in a web browser you can view the Console and hopefully gain some insight as to what exactly is going wrong.
You can also try working with the Worklight logger to help locate the problem.
http://wpcertification.blogspot.com/2012/03/enabling-debuglog-console-in-worklight.html
Here is a general link for "Problem Determination" from IBM as well
http://publib.boulder.ibm.com/infocenter/ieduasst/v1r1m0/index.jsp?topic=/com.ibm.iea.worklight/worklight/5.0/Problem_Determination/IMFV50_ProblemDetermination/player.html
As Nick said if you load totally different HTML page you will have that page to declare the classes your are using. In dojox/mobile/tests see test_IconContainer.html for example.
That said you could proceed differently by for example having your alternate views defined in the same HTML or as your are in Worklight by using the fragment mechanism (see https://www.ibm.com/developerworks/mobile/worklight/getting-started/ modules 60.1, 2 and 3).