I am using D3 to render into an ExtJs component from a Json data source.
from test.html:
<html>
<head>
<title>Test</title>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
<script type="text/javascript" src="http://docs.sencha.com/ext-js/4-0/extjs/ext-all.js"></script>
<script type="text/javascript" src="Test.js"></script>
</head>
<body>
<script type='text/javascript'>
Ext.onReady(function(){
Ext.create('Ext.panel.Panel',
{
layout: 'fit',
renderTo: Ext.getBody(),
items: [
{
xtype: 'panel',
html : 'There should be a test below this'
},
{
id: 'testPanel',
xtype: 'xxxviewtest'
}
]
});
d3.json("Test1.json", function(json) { Ext.getCmp ('testPanel').deliverJson (json); });
});
</script>
</body>
</head>
and Test.js:
Ext.define('xxx.view.Test', {
extend: 'Ext.Component',
alias: 'widget.xxxviewtest',
deliverJson: function(json) {
var target = d3.select("#" + this.id);
if (target[0][0]) {
// install svg element and draw
...
}
}
});
In simple test cases this is working fine, but in a more complex document case involving tab panels and a lot of UI components, the call to d3.select in Test.js is returning an empty selection.
What do I need to do for this to work correctly?
If "d3.select in Test.js is returning an empty selection", I think at that time the Ext components which you queried have not fully displayed. So I recommend moving the d3.json(...) into render event's handler to eliminate one possibility. If the issues still happen, we will find another way.
Related
I am trying to test an Ext JS 5.0.1 application with Jasmine 2.3.4. I keep getting the error "Uncaught ReferenceError: describe is not defined". It is as though it is not seeing describe, it, and other global functions. If I switch out the Jasmine files to 1.3, then it does see these global functions. I want to use the newest version of Jasmine and furthermore, I am not sure 1.3 plays well with Ext JS 5. Has anyone else run into this issue? Code snippets below:
specrunner.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test Application</title>
<!--Jasmine Files -->
<link rel="stylesheet" type="text/css" href="/app_name/app/js/jasmine/jasmine.css">
<script type="text/javascript" src="/app_name/app/js/jasmine/jasmine.js"></script>
<script type="text/javascript" src="/app_name/app/js/jasmine/jasmine-html.js"></script>
<!-- ExtJS Files -->
<script type="text/javascript" src="//cdn-tst.corporate.com/LNF/4/4.0.1/extjs/ext-all-debug.js"></script>
<script type="text/javascript" src="//cdn-tst.corporate.com/LNF/4/4.0.1/extjs/packages/ext-theme-classic/build/ext-theme-classic.js"></script>
<!-- Jasmine Test Case File -->
<script type="text/javascript" src="/app_name/app/js/spec/AppSpec.js"></script>
<!-- app Test Case File -->
<script type="text/javascript" src="/app_name/app/js/test/app.js"></script>
</head>
<body>
</body>
</html>
app.js (for testing)
Ext.Loader.setConfig ({enabled: true});
// Loading different components like controller, model, view..
Ext.application ({
models: [ 'Trip' ],
stores: [ 'Trips' ],
// views: [ 'simpleTrip' ], Views are throwing an error
autoCreateViewport: false,
name: 'carrier360',
// using the Launch method of Application object to execute the Jasmine Test Cases
launch: function () {
debugger;
var jasmineEnv = jasmine.getEnv ();
jasmineEnv.updateInterval = 1000;
var htmlReporter = new jasmine.HtmlReporter ();
jasmineEnv.addReporter (htmlReporter);
jasmineEnv.execute ();
}
});
AppSpec.js
describe ("ExtJS App Test Suite", function () {
debugger;
beforeEach (function () {
// Initializing the mainPanel
debugger;
tripsStore = Ext.StoreManager.lookup ('Trips');
simpleTrip = Ext.create ('app.view.simpleTrip');
controller = Ext.create ('view.controller.tripController');
});
/* Test if View is created Successfully.*/
it ('View is loaded', function () {
debugger;
expect (simpleTrip != null).toBeTruthy ();
});
/* Test if store is loaded successfully.*/
it ('Store shouldn’t be null', function () {
debugger;
expect (tripsStore != null).toBeTruthy();
});
/* Test controller is initialized successfully.*/
it ('Controller shouldn’t be null', function () {
debugger;
expect (controller != null).toBeTruthy();
});
});
Any suggestions on why describe and other functions are not visible would be appreciated!
Descibre, it, ... are no longuer defined in jasmine.js but instead in the boot.js included with jasmine library.
This one will be most probably easy question. I'm very new to Web programming and I was given a task to learn Ext JS (I don't know anything about it they just told me to learn this, may be there are some better frameworks out there, but I don't know). So I started with a very simple example.
This is the Ext JS code
Ext.define('Cookbook.Vehicle', {
config: {
Manufacturer: 'Aston Martin',
Model: 'Vanquish'
},
constructor: function(config) {
// initialise config object
this.initConfig(config);
},
getDetails: function() {
alert('I am an ' + this.getManufacturer() + ' ' + this.getModel());
},
});
var myVehicle = Ext.create('Cookbook.Vehicle');
myVehicle.getDetails(); // alerts 'I am an Aston Martin Vanquish'
And this is the HTML Code
<html>
<head>
<link rel="stylesheet" type="text/css" href="extjs/resources/css/extall.css" />
<script type="text/javascript" src="extjs/ext-all-debug.js"></script>
<script type="text/javascript" src="Chapter 1.js"></script>
</head>
<body>
<h2 id="h2">Nothing seem to work</h2>
</body>
</html>
I suppose that Ext JS code should run after the .hmtl file is launched right? But the thing is, nothing happens. Just a plane page which says Nothing seems to work. Is there a problem in my code? Or is there a special thing to be done to run Ext JS code. I don't really know what to do.
I want to inject an old style, procedurally built string into a DIV element that's created in a standard ExtJS 4 MVC application, and I'm having a hard time wrapping my head around how I'm supposed to leverage dynamic loading.
So say I have this function by itself in a javascript file called "createHtml.js":
function fillDiv(strDivName) {
document.getElementById(strDivName).innerHTML = "<h1>TEST</h1>";
}
Elsewhere, in my MVC ExtJS 4 app (so in an object referenced within app.js, I have the following:
myPanel = Ext.create('Ext.panel.Panel', {
title: 'Map',
html: '<div style="width:100%; height:100%" id="map"></div>'
});
In my index.html page, I include a reference to createHtml.js. In my app.js file, I have something like the following:
( function() {
Ext.Loader.setConfig({
enabled : true,
paths : {
MyJive: 'media/js/ext/MyCom/MyJive',
}
});
Ext.onReady( function() {
var urlparams = document.URL.split('?')[1];
var param = Ext.urlDecode( urlparams ? urlparams : '' );
var pcard = Ext.create( 'MyJive.view.MyUI',{
param1 : param.param1,
param2: param.param2
});
Ext.create( 'Ext.container.Viewport', {
layout: 'fit',
items: [pcard]
});
});
})();
Now if I attach a listener to a button somewhere on MyUI and have it call fillDiv('map'); I get a Uncaught ReferenceError: fillDiv is not defined error.
If I put fillDiv not in its own file (createHtml.js) but MyUI.js (referenced by pcard, above), I'm golden. So I know it's not a super-stupid issue like having the div id wrong or some wacky, invalid innerHTML value.
I would have thought the app would know about fillDiv() because fillDiv()'s parent file is in index.html's javascript includes, but fine, createHtml.js isn't being dynamically loaded. I've got that, I guess.
But how do I tell app.js that my function exists in a file outside of its bounds?
(Now, "IRL", I've got fillDiv creating a complicated piece of html via OpenLayers so that we can display a map identified by param1 and param2 embedded in the ExtJS form, but I've gone to this simpler setup to try and figure out what I'm doing wrong.)
EDIT: Added index.html. createHtml.js contains the fillDiv() method. Note that the DIV that takes the map isn't in the index.html; it's, again, defined in an ExtJS Panel.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My Project</title>
<link rel="stylesheet" type="text/css"
href="media/js/ext/ext-4.0/css/ext-all.css" />
<link rel="stylesheet" type="text/css"
href="media/js/ext/MyCom/MyJive/css/main.css" />
<script type="text/javascript"
src="media/js/ext/MyCom/MyJive/createHtml.js"></script>
<script type="text/javascript"
src="media/js/ext/MyCom/MyJive/OpenLayers-2.11/OpenLayers.js"></script>
<script type="text/javascript"
src="media/js/ext/ext-4.0/ext-all-debug-w-comments.js"></script>
<script type="text/javascript"
src="media/js/ext/MyCom/MyJive/app.js"></script>
</head>
<body>
<div id="divParent"></div>
</body>
</html>
EDIT: Adding app.js:
( function() {
Ext.Loader.setConfig({
enabled : true,
paths : {
MyProj: 'media/js/ext/MyCom/MyProj',
OpenLayers: 'media/js/ext/MyCom/MapJive/OpenLayers-2.11',
MyComExt : 'media/js/ext/MyCom/MyComExt'
}
});
Ext.onReady( function() {
var urlparams = document.URL.split('?')[1];
var param = Ext.urlDecode( urlparams ? urlparams : '' );
var pcard = Ext.create( 'MyProj.view.MyProj',{
param1: param.p1,
param2: param.p2
});
Ext.create( 'Ext.container.Viewport', {
layout: 'fit',
items: [pcard]
});
});
})();
I would leave just a comment, but I don't have enough points for that.
You didn't include a index.html file with imports of your createHtml.js and app.js files. But the first thing I would check is that your createHtml.js import is placed above app.js.
just been thru the following example.
http://docs.sencha.com/ext-js/4-0/#/guide/application_architecture
This walks thru setting a clean mvc structure and adding a grid to a page. On my website i wish to use many extjs features. But would like some clarity on the following.
1) typically would 1 website have only one app.js or would i create a new application per feature. So if i would like 1) contact info grid 2) news grid 3) a chart. Does mean 3 applications.
This is how i currently load my application ( which is a grid )
index.html
<html>
<head>
<title>Account Manager</title>
<link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css" />
<script type="text/javascript" src="extjs/ext-debug.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body></body>
</html>
app.js
Ext.application({
name: 'AM',
appFolder: 'app',
controllers: [
'Users'
],
launch: function () {
Ext.create('Ext.container.Viewport', {
layout: 'fit',
items: [
{
xtype: 'userlist',
title: 'Users',
html: 'List of users will go here'
}
]
});
}
});
#Frosty, You only need one application file per website.
You are encouraged to create separate classes for grids, charts and any other components that you will be using in your website. Each class should go into a separate file.
So then when you create an instance of your component using Ext.create, EXTJS4 will dynamically load that javascript file. This helps with performance issues in a large application as all the files don't need to be brought down on the page load.
In the 4.0.2a docs: http://docs.sencha.com/ext-js/4-0/#/...pp.Application
I see this:
Ext.application({
name: 'MyApp',
launch: function() {
Ext.create('Ext.container.Viewport', {
items: {
html: 'My App'
}
});
}
});
"This does several things. First it creates a global variable called 'MyApp' - all of your Application's classes (such as its Models, Views and Controllers) will reside under this single namespace, which drastically lowers the chances of colliding global variables."
When I run this code, I do not see a global variable called MyApp... does anybody else have this problem?
Here is my entire app (in a single HTML page):
<!DOCTYPE html>
<html>
<head>
<title>Testing ExtJS 4</title>
<link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css" />
<script type="text/javascript" src="extjs/ext-all-debug-w-comments.js"></script>
<script type="text/javascript">
Ext.application({
name: 'MyApp',
launch: function() {
Ext.create('Ext.container.Viewport', {
items: {
html: 'My App'
}
});
}
});
Ext.onReady(function() {
alert(typeof MyApp);
});
</script>
</head>
<body></body>
</html>
it's not working because as the api states (guide/mvc application architecture):
"... All Ext JS 4 applications should only use a single global variable, with all of the application's classes nested inside it...".
If you try with this code:
Ext.application({
name: 'MyApp',
appFolder: '/app',
autoCreateViewport: true,
launch: function() {
console.log(MyApp);
}
});
you will see that the global variable exists. You don't need to access the application from any other place than the application itself
I get the same error, and here are what I found.
In index.html:
Ext.Loader.setConfig({enabled:true});
Ext.application({
name: 'MyApp',
controllers: ['Test'],
launch: function() {
Ext.create('Ext.container.Viewport', {
items: {
html: 'My App'
}
});
}
});
Ext.onReady(function() {
alert(typeof MyApp);
});
Create a small controller: app/controller/Test.js (/app has the same parent folder as /extjs)
Ext.define('MyApp.controller.Test', {
extend: 'Ext.app.Controller',
init: function() {
console.log('The controller was initialised');
}
});
When running, in Firebug you will see the MyApp global variable. However, a messagebox of 'undefined' still appeared for alert statement.
IMHO MyApp is an object to "maintains references to all of the models, views and controllers used by the app". Maybe extjs use some type of class "Dynamic loading"; so it will not create that global variable until there is something (controllers, views, models) to contain inside (I am not sure of this). In this case the variable must be created to contain the controller Test. However, I cannot explain the 'undefined' message for alert. Maybe at that time the Ext object is ready but "Dynamic loading" to create the viewport and the variable MyApp is not finished (not sure).
Hope this help.