Skip to content

Commit

Permalink
edited ch8
Browse files Browse the repository at this point in the history
  • Loading branch information
yfain committed May 4, 2013
1 parent 2b8ea6b commit c11cf71
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 60 deletions.
103 changes: 61 additions & 42 deletions ch6_ext_js.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ image::images/fig_06_04_SSC.png[image]
Such setup looks like an overkill, but we are talking about the enterprise development where you may jump through some hoops to create a convenient working environment for yourself.
********


The app.js is pretty short - it just declares SSC as the application name, views and controllers. By adding the property `autoCreateViewport: true` we requested the application to automatically load the main window, which must be called Viewport.js and located in the view directory.

[source, javascript]
Expand Down Expand Up @@ -582,6 +583,8 @@ The following figure shows a snapshot from WebStorm IDE, with collapsed code sec
.Collapsed Code of Viewport.js
image::images/fig_06_05_SSC.png[image]

TIP: Open its menu Preferences | JavaScript | Libraries and add the file ext-all-debug-w-comments.js as a global library and pressing the button F1 will display available comments about selected Ext JS element. Configuring Ext JS as external library allows you to remove Ext JS files from WebStorm project without losing context sensitive help.

In Ext JS the column layout is used when you are planning to present the information in columns as explained in the http://dev.sencha.com/deploy/ext-4.0.0/examples/layout-browser/layout-browser.html[product documentation]. Even though there are three columns in this layout, the entire content on this page is located in the middle column having the width of 980. The column on the left and the column on the right just hold one non-breakable space each to provide centering of the middle column in monitors with high resolution wider than 980 pixels (plus the browser's chrome).

The width of 0.5, 980, 0.5 means to give the middle column 980 pixels and share the remaining space equally between empty columns.
Expand Down Expand Up @@ -857,16 +860,22 @@ In this section we'll review the code supporting the lower half of the Save Sick
.Save Sick Child with live charts
image::images/fig_06_08_SSC.png[image]

This version has some additions comparing to the previous ones. Notice the bottom left panel with charts. First of all, the charts are placed inside the panel with tabs: Charts and Table. The same data can be rendered either as a chart or as a grid. Second, the charts became live thanks to ExtJS. We took snapshot of the Window shown in <<FIG6-8-SSC>> while hovering the mouse over the pie slice representing New York, and the pie slice has extended from the pie showing a tooltip.
This version has some additions comparing to the previous ones. Notice the bottom left panel with charts. First of all, the charts are placed inside the panel with tabs: Charts and Table. The same data can be rendered either as a chart or as a grid. Second, the charts became live thanks to ExtJS. We took snapshot of the Window shown in <<FIG6-8-SSC>> while hovering the mouse over the pie slice representing New York, and the slice has extended from the pie showing a tooltip.

The SSC_Complete_ExtJS has more Ext JS classes comparing to SSC_Top_ExtJS. You can see more views on <<FIG6-9-SSC>>. Besides, we've added two classes Donors.js and Campaigns.js to serve as data stores for the panels with charts and maps.

[[FIG6-9-SSC]]
.JavaScript classes of SSC_Complete_ExtJS
image::images/fig_06_09_SSC.png[image]




=== Productive Enterprise Web Development with Ext JS and CDB

The authors of this book work for http://faratasystems.com[Farata Systems], which has developed an open source freely available software Clear Toolkit for Ext JS, and the code generator and Eclipse IDE plugin CDB comes with it. CDB is a productivity tool that was created specifically for the applications that need to retrieve, manipulate, and save the data in some persistent storage. Such applications are known as _CRUD applications_ because they perform Create-Retrieve-Update-Delete operations with data. If the server side of your Web application is developed in Java, with CDB you can easily generate a CRUD application, where Ext JS front end communicates the Java back end. In this section you will learn how jump start development of such CRUD Web applications.
The authors of this book work for http://faratasystems.com[Farata Systems], which has developed an open source freely available software Clear Toolkit for Ext JS, and the code generator and Eclipse IDE plugin CDB comes with it. CDB is a productivity tool that was created specifically for the applications that need to retrieve, manipulate, and save the data in some persistent storage.

Such applications are known as _CRUD applications_ because they perform Create-Retrieve-Update-Delete operations with data. If the server side of your Web application is developed in Java, with CDB you can easily generate a CRUD application, where Ext JS front end communicates the Java back end. In this section you will learn how jump start development of such CRUD Web applications.

IMPORTANT: Familiarity with core Java concepts like classes, constructors, getters and setters, and annotations is required for understanding of the materials of this section.

Expand Down Expand Up @@ -1017,14 +1026,14 @@ CDB has generated a sample UI for us too. Check out the samples directory shown
.Folder with generated UI files
image::images/fig_06_07cdb.png[image]

CDB has generated `SampleController.js`, `SampleGridPanel.js`, and the Ext JS application entry point `sampleApp.js`. To test this application just copy the file `SampleController.js` into the controller folder, `SampleGridPanel.js` panel into the view folder, and the sample application in the root of the WebContent folder. Change the application entry point with to be `sampleApp.js` in the index.html of the Eclipse projectas shown below.
CDB has generated `SampleController.js`, `SampleGridPanel.js`, and the Ext JS application entry point `sampleApp.js`. To test this application just copy the file `SampleController.js` into the controller folder, `SampleGridPanel.js` panel into the view folder, and the sample application in the root of the WebContent folder. Change the application entry point with to be `sampleApp.js` in the index.html of the Eclipse project as shown below.

[source,html]
----------------------------------------------------------------------
<script type="text/javascript" src="sampleApp.js"></script>
----------------------------------------------------------------------

This is how the generated UI of the sample application looks like <<FIG6-8-CDB>>
This is how the generated UI of the sample application looks like <<FIG6-8-CDB>>.

[[FIG6-8-CDB]]
.Scaffolded CRUD application template
Expand All @@ -1043,51 +1052,60 @@ import clear.data.ChangeObject;
import dto.Person;
import service.generated.*;
public class PersonServiceImpl extends _PersonServiceImpl { // 1
@Override
public List<Person> getPersons() { // 2
List<Person> result = new ArrayList<>();
Integer id= 0;
result.add(new Person(++id, "Joe", "Doe", "555-55-55", "1111-11-1111"));
result.add(new Person(++id, "Joe", "Doe", "555-55-55", "1111-11-1111"));
result.add(new Person(++id, "Joe", "Doe", "555-55-55", "1111-11-1111"));
result.add(new Person(++id, "Joe", "Doe", "555-55-55", "1111-11-1111"));
return result; // 3
}
public class PersonServiceImpl extends _PersonServiceImpl { // <1>
@Override
public void getPersons_doCreate(ChangeObject changeObject) { // 4
Person dto = (Person) deserializeObject(
(Map<String, String>) changeObject.getNewVersion(),
Person.class);
@Override
public List<Person> getPersons() { // <2>
List<Person> result = new ArrayList<>();
Integer id= 0;
result.add(new Person(++id, "Joe", "Doe",
"555-55-55", "1111-11-1111"));
result.add(new Person(++id, "Joe", "Doe",
"555-55-55", "1111-11-1111"));
result.add(new Person(++id, "Joe", "Doe",
"555-55-55", "1111-11-1111"));
result.add(new Person(++id, "Joe", "Doe",
"555-55-55", "1111-11-1111"));
return result; // <3>
}
System.out.println(dto.toString());
}
@Override
public void getPersons_doCreate(ChangeObject changeObject) { // <4>
Person dto = (Person) deserializeObject(
(Map<String, String>) changeObject.getNewVersion(),
Person.class);
@Override
public void getPersons_doUpdate(ChangeObject changeObject) { // 5
// TODO Auto-generated method stub
super.getPersons_doUpdate(changeObject);
}
System.out.println(dto.toString());
}
@Override
public void getPersons_doDelete(ChangeObject changeObject) { // 6
// TODO Auto-generated method stub
super.getPersons_doDelete(changeObject);
}
@Override
public void getPersons_doUpdate(ChangeObject changeObject) { // <5>
// TODO Auto-generated method stub
super.getPersons_doUpdate(changeObject);
}
@Override
public void getPersons_doDelete(ChangeObject changeObject) { // <6>
// TODO Auto-generated method stub
super.getPersons_doDelete(changeObject);
}
}
----------------------------------------------------------------------
<1> Extend the generated class and provide the actual implementation.
<2> The `getPerson()` is our retrieve method (the R in CRUD) .
<3> For this sample application we can use `java.util.ArrayList` class as in-memory server side storage of the `Person` objects. In the real world applications you'd use a database or other persistent storage.
<4> +fillmethod++`doCreate()` is our create method (the C in CRUD).
<5> +fillmethod++`doUpdate` is our update method (the U in CRUD).
<6> +fillmethod++`doDelete` is our delete method (the D in CRUD).
<1> Extend the generated class and provide the actual implementation

<2> The `getPerson()` is our retrieve method (the R in CRUD)

Click on the +Load+ menu on the UI, and the application will retrieve four persons from our server.
<3> For this sample application we can use `java.util.ArrayList` class as in-memory server side storage of the `Person` objects. In the real world applications you'd use a database or other persistent storage

To test the rest of the CRUD methods, we'll ask the user to insert one new row, modify three existing ones and remove two rows using the generated Web client. The `Clear.data.DirectStore` object will automatically create a collection of six `ChangeObject`s - one to represent a new row, three to represent the modified ones, and two for the removed rows.
<4> +fillmethod++`doCreate()` is our create method (the C in CRUD)

<5> +fillmethod++` doUpdate` is our update method (the U in CRUD)

<6> +fillmethod++` doDelete` is our delete method (the D in CRUD)

Click on the +Load+ menu on the UI, and the application will retrieve four persons from our server

To test the rest of the CRUD methods, we'll ask the user to insert one new row, modify three existing ones and remove two rows using the generated Web client. The `Clear.data.DirectStore` object will automatically create a collection of six `ChangeObject`s - one to represent a new row, three to represent the modified ones, and two for the removed rows.

When the user clicks on the +Sync+ UI menu the changes will be sent to the corresponding `do...` remote method. When you `sync()` a standard `Ext.data.DirectStore` Ext JS is POST-ing new, modified and deleted items to the server. When the request is complete the server's response data is applied to the store expecting that some items can be modified by the server. In case of `Clear.data.DirectStore` instead of passing around items, we pass the deltas, wrapped in the `ChangeObject`.

Expand All @@ -1104,7 +1122,7 @@ The corresponding Java implementation of `ChangeObject` is available on the serv
[source,java]
----------------------------------------------------------------------
Person dto = (Person) deserializeObject(
(Map<String, String>) changeObject.getNewVersion(),Person.class);
(Map<String, String>) changeObject.getNewVersion(),Person.class);
----------------------------------------------------------------------

When the new version of the `Person` object is extracted from the `ChangeObject` you can do with it whatever has to be done to persist it in the appropriate storage. In our example we just print the new person information on the server-side Java console. This is why we said earlier, that it may be a good idea to provide a pretty printing feature on the class `Person` by overriding method `toString()`. Similarly, when you need to do a delete, the `changeObject.getPrevVersion()` would give you a person to be deleted.
Expand All @@ -1121,6 +1139,7 @@ The pagination feature is needed in almost every enterprise web application. Oft
** Use `DirectOptions` class to read the pagination parameters

We are going to improve our CRUD application by adding the paging toolbar component bound to the same store as the grid. The class `DirectOptions` will handle the pagination parameters on the server side.

So far CDB has generate the UI from the Java back end service as well as the Ext JS store and model. We'll refactor the service code from previous example to generate more data (a thousand objects) so we have something to paginate, see below.

[[LISTING_4]]
Expand Down
35 changes: 17 additions & 18 deletions ch8_testdriven_js.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -800,21 +800,18 @@ As you can see, testing of the DOM manipulation code is much like any other type

TBD...

// <vik>
==== Setup IDE for TDD

==== Setting up IDE for TDD

WARNING: Section under active development

In this section we will setup WebStorm to use described above tools within IDE. We will show how to integrate Grunt tool with WebStrom to run grunt tasks form IDE.
In this section we will setup WebStorm to use the described above tools inside this IDE. We will show how to integrate Grunt tool with WebStrom to run grunt tasks from there.

// TDB

===== Integrate the Grunt tool with WebStorm

Let's start with Grunt setup. Currently, there is no native support of the Grunt tool in WebStorm IDE.
But there is a good thing. Because grunt is a command line tool we can use universal feature of the WebStorm IDE - *External Tools*.

You need to open WebStorm preferences and navigate to _External Tools_ section to get access to the external tools configuration.
Let's start with the Grunt setup. Currently, there is no native support of the Grunt tool in WebStorm IDE. But since Grunt can be launched from a command line, we can use a universal feature of the WebStorm IDE and configure it as an _External Tool_. Open WebStorm preferences and navigate to _External Tools_ section to get access to the external tools configuration as in <<FIG_SO_AND_SO>>.

.External Tools configuration window in WebStorm
image::fig_08_08.png[]
Expand All @@ -824,31 +821,33 @@ Click the `+` button to create new External Tool configuration.
.External Tool configuration
image::fig_08_09.png[]

1. You need to specify full path to the application executable.
2. The some tools are require to have the command line parameters. In this example, we explicitly specify task runner configuration file (with `--gruntifle` command line option) and task that will be executed.
3. Also you need to specify _Working Directory_ to run the Grunt tool. In our case, grunt configuration file is in the root of our project. WebStorm allows to use macros instead hard-coded paths. Most likely, you don't want to setup external tools for each new project. Better to have universal setup. In this case, we use `$ProjectFileDir$` macros will be resolved as current WebStorm project folder root.
4. WebStorm allows to organize related tasks into logical groups.
5. You can configure how external tool launcher will be accessible.
1. You need to specify the full path to the application executable.

2. Some tools require to have the command line parameters. In this example, we explicitly specify the task runner configuration file (with the `--gruntifle` command line option) and thet task to be executed.

3. Also you need to specify the _Working Directory_ to run the Grunt tool. In our case, grunt configuration file is located in the root of our project. WebStorm allows to use macros to avoid hard-coded paths. Most likely, you don't want to setup external tools for each new project, just create a universal setup. In our example we use the `$ProjectFileDir$` macros will be resolved as current WebStorm project folder root.

After that you can find the launcher under _Tools_ menu as well under Main menu Editor menu, Project views and etc.
4. WebStorm allows you to organize related tasks into logical groups.

5. You can configure how to access the external tool launcher.

When all of the above steps are complete you can find the launcher under _Tools_ menu as well under Main menu Editor menu, Project views and etc.

.Grunt launcher available under _Tools/grunt_ menu
image::fig_08_11.png[]

The unit tests is very important thing to get feedback from your code. You can gain efficiency only if you manage how to minimize context switching during your coding flow. And likely, you don't want to waste your time digging through menu items of your IDE. In this case, assign keyboard shortcut for launching external tool sounds like a plan.
Unit tests are really important as a mean to get a quick feedback from your code. You can work more efficient if you manage to minimize context switching during your coding flow. Also, you don't want to waste time digging through the menu items of your IDE, so assigning a keyboard shortcut for launching external tool is a good idea.

Let's assign keyboard shortcut for just created external tool launcher. For that we need to go _Keymap_ section of WebStorm Preferences. Use the filter to find our created launcher `jasmine: grunt test`. You can specify either Keyboard short cut or Mouse shortcut by double clicking on desired list item.
Let's assign a keyboard shortcut for our newly configured external tool launcher. Go to the _Keymap_ section in WebStorm Preferences. Use the filter to find our created launcher `jasmine: grunt test`. Specify either the Keyboard of the Mouse shortcut by double clicking on the appropriate list item.

.Setup keyboard shortcut for grunt launcher
image::fig_08_10.png[]

By pressing combination of keys specified on previous screen, you will run the grunt with Jasmine tests. WebStorm will redirect all output from the grunt tool into IDE Run window.
By pressing a combination of keys specified in the previous screen, you will be able to launchgrunt with Jasmine tests with one click of a button(s). WebStorm will redirect all the output from the grunt tool into its Run window.

.Grunt output in WebStorm
image::fig_08_12.png[]

// </vik>

===== Setup Jasmine support for Jasmine library

//TBD
Expand Down
Binary file modified images/fig_06_08_SSC.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/fig_06_09_SSC.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions version.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Build date: 2013-04-05 14:27:15
version.major=3
version.minor=1
version.patch=0
version.build=12345
version.full=3.1.1.274
version.git.hash=067b0ece9f979c41723e65a84549398ec81fd5f2

0 comments on commit c11cf71

Please sign in to comment.