+ All Categories
Home > Documents > - 1 - jsm An introduction to jsm Ronald Plöger Version: 1.03 September, 25th 2006.

- 1 - jsm An introduction to jsm Ronald Plöger Version: 1.03 September, 25th 2006.

Date post: 01-Apr-2015
Category:
Upload: darwin-freeney
View: 217 times
Download: 0 times
Share this document with a friend
41
- 1 - jsm An introduction to jsm http://js-m.sourceforge.net/ Ronald Plöger Version: 1.03 September, 25th 2006
Transcript
Page 1: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 1 -

jsm

An introduction to jsm

http://js-m.sourceforge.net/

Ronald PlögerVersion: 1.03

September, 25th 2006

Page 2: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 2 -

What is jsm

jsm is a JavaScript library

Currently focusing on displaying/editing information in tables

Java classes to bridge the gap from the server to the client side.

Initialy created to build highly responsive and userfriendly CRUD screens in a rapid way

Page 3: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 3 -

Advantages of jsm

Rapid development of screens with table based information, eg. auto generated filter

Unified look & feel of tables, eg. developer can not forget to add title-attribute on table cell

User experiences ‘fast’ screens

Page 4: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 4 -

How to set jsm up

<!–- Include jsm.css--><link rel=stylesheet type="text/css" href="/css/jsm.css"><!–- Set image path and include jsm.js--><script type="text/javascript">jsmImageFolder='/images/';</script><script src="/scripts/jsm.js" type="text/javascript"></script>

<!–- Define HTML element to hold table (div, td, …) --><div id="myTableContainer"></div><script> //create table objectvar myTable = new JsmTable();//add header columnmyTable.setHeaderRow(new JsmTr().addCell(new JsmTh("my header");//add rowsmyTable.addRow(new JsmTr(1).addCell(new JsmTd("lalalala")));…//render tablemyTable.render();

</script>

Page 5: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 5 -

How to set jsm up (2)

<div id="tt"></div>

<script>var lala = new JsmTable("tt", "lala");…

JsmTable needs: An empty HTML element (specified by its id) to render itself

into (default: ‘myTableContainer’) The name of the variable holding it (default: ‘myTable’)

If your setup differs, for example because you need to display multiple JsmTables on a page, you have to hand over the element id and the variable name in the constructor

Page 6: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 6 -

Column index and name

In many functions you have to specify a column index or name.

The index is zero based, i.e. the 1st columns index is 0.

You can also add names to columns using the JsmTable method addColumnName(columnName, columnIdx).

If you add a header-row the header cells value will be used as a column names, if no column name has been specified using addColumnName(columnName, columnIdx).

Therefore you can only refer to columns by name after adding the header row or after specifying the column names explicitly.

Page 7: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 7 -

Attributes and meta data

Every object derived from JsmObject can have attributes and meta data.

Attributes will be attached to the rendered HTML element objects (the view component).

Meta data can be used to store information for any purpose.

new JsmTable().setAttribute("cellspacing", "2")

new JsmTh("one").setAttribute("width", "300")

new JsmTd("whatever").setAttribute("colspan", "2");

new JsmTd("whatever").setAttribute("onclick", "alert('hello world')").setAttribute("class", "jsmHand");

new JsmTr().addCell(new JsmTd("one")).setMetaData("id", "1"));

Page 8: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 8 -

Header & Footer

Every JsmTable can have one header and multiple footer which will not participate in sorting.

myTable.setHeaderRow(new JsmTr().addCell(new JsmTh("one").setAttribute("width", "300")).addCell(new JsmTh("two").setAttribute("width", "150")));

myTable.addFooter(new JsmTr(new JsmTd("This is a footer cell ").setAttribute("colspan", "2")));

Page 9: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 9 -

Events

The following onclick events will be triggert when clicking on a header cell, a data cell or a row respectively. Empty (except for ‘jsmOnTableHeaderClick’) stub functions exist. The user can implement its own version (after the include of jsm.js) which will be called instead. Parameters are:

table: the JsmTable object rowIdx: the index of the clicked-on row columnIdx: the index of the clicked-on column

function jsmOnTableHeaderClick(table, columnIdx)

function jsmOnTableCellClick(table, rowIdx, columnIdx)

function jsmOnTableRowClick(table, rowIdx)

Page 10: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 10 -

Events (2)

Instead of the default functions a user can specify the name of a function to be called (which will be called with the same parameters)

myTdObject.setOnClick(„nameOfMyFunctionToCall“);//--> will call nameOfMyFunctionToCall(table, rowIdx, columnIdx)myThObject.setOnClick(„nameOfMyFunctionToCall2“);//--> will call nameOfMyFunctionToCall2(table, columnIdx)myTrObject.setOnClick(„nameOfMyFunctionToCall3“);//--> will call nameOfMyFunctionToCall3(table, rowIdx)

Page 11: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 11 -

Events (3)

One can also add javascript-code to be called on certain events by specifying special attributes (case sensitive): 'onkeyup', 'onchange', 'onclick', 'onmousedown', 'onmouseup', 'onmousemove'

myCell.setAttribute("onkeyup", "myFunction()"); //--> will call myFunction with no parameters

myCell.setAttribute("onmousemove", "myFunction(‚lala‘, ‚1‘)"); //--> will call myFunction with the specified parameters

myCell.setAttribute("onclick", "self.status=‚hello world‘;alert(‚hello world‘);");

//--> will execute the specified JavaScript

Page 12: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 12 -

Layout

The layout of the table can be controlled using CSS. A default jsm.css comes with jsm, which you can adapt to your needs.

CSS class Used for

jsmTable Table

jsmHeader Table row (only on the header row)

jsmFooter Table row (only on footer rows)

jsmEven Table row (only on data rows)

jsmOdd Table row (only on data rows)

jsmHand JsmDoubleSelectField / Can be used to indicate that a cell is clickable

jsmButton Filter button

jsmLabel Filter label

Page 13: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 13 -

JsmActionCells

Action cells are adding functionallity to a table. Depending on this functionallity they can be displayed in

the header row (e.g. jsmAddRowActionCell) the footer row (e.g. jsmGotoFirstPageActionCell) every data row (e.g. jsmEditRowActionCell)

myTable.addFooterActionCell(jsmGotoFirstPageActionCell).addFooterActionCell(jsmGotoPreviousPageActionCell).addFooterActionCell(jsmPageCounter).addFooterActionCell(jsmGotoNextPageActionCell).addFooterActionCell(jsmGotoLastPageActionCell)

myTable.addHeaderActionCell(jsmAddRowActionCell)

myTable.addRowActionCell(jsmEditRowActionCell).addRowActionCell(jsmDeleteRowActionCell);

Page 14: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 14 -

JsmActionCells (2)

There are default JsmActionCell objects coming with jsm. If additional functionallity is needed it should be easy to create your own action cells.

Before rendering the init(table, rowIdx, columnIdx) method is called.

By default action cells are rendered on the right hand side of the table. Using myTable.setActionCellSide(„left“) the action cells can be displayed on the left hand side.

Page 15: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 15 -

JsmActionCells (3)

Action cell object Events

jsmEditRowActionCell jsmOnEditRow(table, rowIdx)

jsmOnSaveRow(table, rowIdx)

jsmDeleteRowActionCell jsmOnDeleteRow(table, rowIdx)

jsmAddRowActionCell jsmOnAddRow(table, rowIdx)

jsmShowOnlyHeaderActionCell

jsmHideTableActionCell

jsmGotoFirstPageActionCell

jsmGotoPreviousPageActionCell

jsmGotoNextPageActionCell

jsmGotoLastPageActionCell

jsmPageCounter

Page 16: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 16 -

Sortability

By default every table column is sortable by clicking on the columns header cell. This is due to the default implementation of the user event ‘jsmOnTableHeaderClick‘ (which can be overwritten).

myTable.sort("two");myTable.render();

function jsmOnTableHeaderClick(table, columnIdx) { table.sort(columnIdx); table.render();}

To sort manually you simply have to call the sort() method and afterwards re-render the table. The sort() methods accepts the column index or the column name as a parameter

Page 17: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 17 -

Comparators

Sorting of columns are dependent on comparators. The default comparator is ‘jsmAlphaComparator’. Other available comparators are ‘jsmNumberComparator’ and ‘jsmDateComparator’ (depends on the date.js library)

It is easy to write and plug in your own comparators if needed.

//add comparators to the table specifying the column index or namemyTable.addComparator("two", JsmNumberComparator);myTable.addComparator("three", JsmDateComparator);

Page 18: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 18 -

Resizability

The table is resizable if specified during construction of the JsmTable object

myTable = new JsmTable("myTableContainer", "myTable", true);

Page 19: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 19 -

Pageability

Using JsmActionCells a table can be made pageable. The action cells could be set in the header or in the footer.

…myTable.addFooterActionCell(jsmGotoFirstPageActionCell).addFooterActionCell(jsmGotoPreviousPageActionCell).addFooterActionCell(jsmPageCounter).addFooterActionCell(jsmGotoNextPageActionCell).addFooterActionCell(jsmGotoLastPageActionCell)

myTable.setPageingMaxRows(4);…myTable.addFooter(new JsmTr(new JsmTd("&nbsp").setTitle("")));

Page 20: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 20 -

Editability

Using JsmActionCells a table can be made editable.

myTable.addWidget(0, new JsmTextField()).addWidget(1, new JsmSelectField([{'value':0, 'label':"All"},{'value':1, 'label':"UK"},{'value':2, 'label':"Ireland"}]).addOption(3, 'Germany')).addWidget(2, new JsmCheckBox(false, "yes", "no"));

myTable.addHeaderActionCell(jsmAddRowActionCell);myTable.addRowActionCell(jsmEditRowActionCell).addRowActionCell(jsmDeleteRowActionCell);

function jsmOnSaveRow(table, rowIdx) { //do whatever you want to do on a save row table.getRow(rowIdx).setDirty(false);}…

Page 21: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 21 -

Widgets

To make a table editable and to generate a filter widgets are needed. There are standard widgets coming with jsm. It should be easy to create your own widgets if needed.

JsmTextField JsmCheckBox JsmSelectField JsmDoubleSelectField

new JsmTextField();new JsmSelectField([{'value':0, 'label':"All"},{'value':1, 'label':"UK"}]).addOption(2, 'Germany');

new JsmCheckBox(false, "yes", "no");new JsmDoubleSelectField([{'value':0, 'label':"All"},{'value':1, 'label':"UK"},{'value':2, 'label':"Ireland"}], null, 3)

Page 22: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 22 -

Create your own widgets

Each widget extends JsmWidget. Depending on the usage you will want to implement the following methods:

init(jsmTdObject): Will be called when a JsmTd object of a JsmTr object, which isEditMode() returns true, is rendered.

getNode(): Return the HTML element object

updateModel(table, rowIdx, columnIdx, theViewComponent): Called on save by the jsmEditRowActionCell

Page 23: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 23 -

Validators

One or more validators can be attached to a widget. The updateModel() method of the widget will call each of the validators before updating the model.

Currently jsm comes with the JsmNumbersOnlyValidator. It should be easy to add your own ones as needed.

A validator has to implement the validate(table, rowIdx, columnIdx, theViewComponent) method which returns true or false.

new JsmTextField().addValidator(new JsmNumbersOnlyValidator());

Page 24: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 24 -

Filters

Filters can be attached to a JsmTable. These filters will then be consulted before rendering the table.

Currently jsm comes with JsmExactFilter and JsmRegExFilter. It should be easy to implement your own filters if needed.

//remove existing filtersmyTable.removeFilters(); //add new RegEx filter myTable.addFilter(new JsmRegExFilter(0, ".*" + document.getElementById('myFilter').value + ".*", true));

//re-render the table myTable.render();

Page 25: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 25 -

Auto-generated filter area

A filter area can be auto-generated. You can define the columns for which filter elements will be generated and how many filter elements to display in one row.

The widgets associated with a column will be used as filter elements (using a case insensitive RegEx-Filter with .* at the start and the end).

If this is not sufficient you can add a filter config for a column, specifying a widget and filter.

<div id="myFilterContainer"></div><script>myTable.addWidget(0, new JsmTextField())); myTable.addFilterConfig(1, new JsmSelectField([{'value':'', 'label':"Please select..."}, {'value':0, 'label':"USA"},…]), new JsmExactFilter().setIgnoreCase(false)); myTable.generateFilter('myFilterContainer', [0,1], 2);

</script>

Page 26: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 26 -

Evaluate expressions

A JsmTd can evaluate JavaScript expressions and will display the return value as the cell value. The expression has to be contained in %{}

//calculate the sum of the values of the previous two cellsnew JsmTd("%{Number(this.tr.table.getValue(this.tr.getIndex(), this.getIndex()-1)) + Number(this.tr.table.getValue(this.tr.getIndex(), this.getIndex()-2))}"))

Page 27: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 27 -

Java bridge classes

Altough it is possible to write the JavaScript by hand, if the data comes from the server, the Java bridge classes should be used to generate it.

The server side:JsmTable table = new JsmTable().setSortColumn("0").addAttribute("cellSpacing", "1");

JsmTr header = new JsmTr();header.addCell(new JsmTh("one"));header.addCell(new JsmTh("two"));table.setHeader(header);//…add rows, etc. then put JsmTable object into requestrequest.setAttribute("myTable", table);

The client side:<%JsmTable table = (JsmTable) request.getAttribute("myTable");%><script type="text/javascript" language="JavaScript"><%=table.generateJavaScript()%>myTable.render();

</script>

Page 28: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 28 -

Generate table rows

It is possible, using reflection, to generate JsmTr objects from a collection of business objects. To give the user the opportunity to add information there are post/pre-processing callback methods.

table.addRows(JsmTableUtil.generateJsmTrs(myValueObjects,new String[] {"id", "name"},new String[] { "id" }, new AbstractGenerateJsmTrsCallback() {

public void postProcessing(JsmTr tr, Object valueObject) { ...

}public void preProcessing(JsmTr tr, Object valueObject)

{ ...}

}));

Page 29: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 29 -

jsm JSP-Tags

To create JavaScript code for simple tables you can use the jsm JSP-Tags. Specify the header names, the java.util.Collection to be used as rows-objects and the property path for each column. You can also specify the containe-id, the JavaScript variable name and if the generated code should contain a .render() call.

<%@ taglib uri="/WEB-INF/jsm.tld" prefix="jsm"%>…<jsm:table rows="<%=function.getChangeComments()%>" containerId="ChangeCommentsContainer" variableName="ChangeComments" render="true"><jsm:th name="Change date" /><jsm:th name="User" /><jsm:th name="Comment" /><jsm:propertyPath path="date"/><jsm:propertyPath path="user.name"/><jsm:propertyPath path="comment"/>

</jsm:table>

Page 30: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 30 -

RemoteCall

A RemoteCall object can be used to send data to the server. The RemoteCall object is instantated with the following params:

URL to call JSON Map of request parameters A renderer

The renderer will be called upon the server response. It has to have a render(requestParams, response) method.

requestParams: The JSON Map of request parameters send to the server response: The evaluated JSON string the server has responded with

Page 31: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 31 -

RemoteCall (2)

new RemoteCall('/dealMemo/deleteDraftLog.do', {'id':id, 'rowIdx':rowIdx}, new RemoveDraftLogRenderer());

function RemoveDraftLogRenderer() {}RemoveDraftLogRenderer.prototype.render = function(requestParams, response){//requestParams: A HashMap of the request parameters//response: The parsed JSON structure returned by the called url if ("error" == response['state']) {

addUserErrorMessage(response['message']);}if ("ok" == response['state']) {

myTable.removeRow(requestParams['rowIdx']);myTable.render();addUserMessage("The draft log has been deleted");

}}

Page 32: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 32 -

Renderers

jsm comes with the standard renders SaveRowRenderer and DeleteRowRenderer.

Both expect the request parameter ‚rowIdx‘ and the response object properties ‚state‘ and ‚message‘.

For further details see the JavaScriptDoc.

Page 33: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 33 -

Sending data to the server

On the client side:

Send the row’s data as a JSON Map to the server using a RemoteCall object

The keys of the JSON Map are the property paths of the columns or, if not specified, the column names.

The values of the JSON Map are the value meta data ‘value’ or, if not specified, the value of the cells

new RemoteCall('<%=request.getContextPath()%>/saveUser', {'rowIdx':rowIdx, 'jsonizedRow':row.getJSONized(true), 'id':row.getMetaData('id')}, new SaveRowRenderer(table.getVariableName()));

The request parameter 'jsonizedRow' could for example be:{"country":"6", 'lastName':'Caley'}

Page 34: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 34 -

Sending data to the server (2)

On the server side:

Retrieve the request parameters Load the business object Create a new JSONObject Assign converters to property paths as needed Call JsmTableUtil.setValuesOnObject

String id = request.getParameter("id");User user = userDAO.getById(id);String jsonizedRow = request.getParameter("jsonizedRow");JSONObject json = new JSONObject(jsonizedRow);HashMap converters = new HashMap();converters.put("companyCar", new BooleanConverter());JsmTableUtil.setValuesOnObject(user, json, converters);

Page 35: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 35 -

Sending data to the server (3)

Note:

You can add the columns property path by using

myJsmTable.addPropertyPath(String columnIdxOrName, String propertyPath)

on the JsmTable object (server-side)

Page 36: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 36 -

Converters

A converter has to implement the net.sf.jsm.utils.Coverter interface which defines the method:

public Object convert(Object objectToConvert) throws ConversionException

Jsm comes with a BooleanConverter.

private class CountryConverter implements Converter { public Object convert(Object objectToConvert) {

return new CountryDAO().getById(objectToConvert.toString()); }

}

Page 37: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 37 -

jsmMessage

The following JavaScript methods were created to present messages and warnings to the user. You need to define an HTML element with the id ‘jsmMessage’ and include the jsm.css where the style #jsmMessage is defined.

jsmAppendMessage(theHTML, timeout, warn) jsmAddMessage(theHTML, timeout, warn) jsmClearMessage()

<p id="jsmMessage"> </p>

<script>function jsmOnSaveRow(table, rowIdx) {…jsmAddMessage(„Saving row“);…

Page 38: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 38 -

Lazy load

To lazily load table data:

On the client: Specify the div’s overflow style to ‘scroll’ Add an onscroll event handler In the event handler function use a RemoteCall to retrieve more JsmTr objects to append to the table when the user has scrolled to the current bottom

On the server: Use JsmTableUtil.getJSONRows to get a JSON array of JsmTr objects

On the client: In the Renderer add the rows setting the ‘renderImmediately’ to true

Page 39: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 39 -

Lazy load (2)

<div id="myTableContainer" style="height:200px; overflow:scroll;"></div> <script>//add the onscroll eventhandler $('myTableContainer').onscroll=lazyLoad;

function lazyLoad(e) { if ((this.scrollTop + this.offsetHeight)>=(this.scrollHeight)) {

jsmAddMessage('Try to load next 100 words starting from: ' + myTable.getRowCount());

new RemoteCall('/lazyLoading/loadWords', {'start‚ : myTable.getRowCount()}, new LazyLoadRenderer());

}}

function LazyLoadRenderer(tableVariableName) {} LazyLoadRenderer.prototype.render = function(requestParams, response) {myTable.addRows(eval(response['rows']), true);// render immediately

}

//note: the array of JsmTr object contained in response['rows'] was filled//on the server side using://JsmTableUtil.getJSONRows(JsmTableUtil.generateJsmTrs(words), new String[] //{"word"}, null, null))

Page 40: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 40 -

Tips and Tricks

The rendered HTML element object (view component) has access to its underlying model via the property ‘model’

new JsmTd("click me to show model").setAttribute("onclick", "alert(this.model);")

A JsmCell object has access to its parent JsmTr object which in turn has access to its parent JsmTable objectJsmTd: this.tr.tableJsmTr: this.table

Widgets with values and labels (e.g. JsmSelectField, JsmDoubleSelectField) hold the selected value in a meta-data called ‘value’

Page 41: - 1 - jsm An introduction to jsm  Ronald Plöger Version: 1.03 September, 25th 2006.

- 41 -

Tips and Tricks (2)

To support multiple languages all labels, texts, images, etc. are defined in the file ‘jsmResourceBundle.js’. You can translate those and include the translation, for example depending on the browser locale, into the page.


Recommended