1. Summary
  2. Files
  3. Support
  4. Report Spam
  5. Create account
  6. Log in

Main Page

From extjs-orm

Jump to: navigation, search

Contents

ExtJS-ORM

Overview

ExtJS is really nice and comprehensive rich internet application framework that provides a lot of nice components to UI developer. But it also provides powerful model wiring framework between different model representations (like JSON, XML, etc) and UI widgets (like Grid, Form, ComboBox, etc). ExtJS defines meta-information rules based on which it runs such wiring. But a lot of ORM tools (like JPA) in Java world do the same on server side - they wire data between database and domain object model (and vice versa) based on meta-information that developer should provide with java classes from domain object model. Obviously, information overlaps in such cases.

ExtJS-ORM tries to solve this issue. It tries to:

  • simplify and standardize meta-information on both sides of web application (client-side and server side). So, it wire domain object model (on server side) to Ext.data.Store (that 'is' a model for a lot of widgets in ExtJS framework)
  • re-use server-side meta-information (that is already provided for domain object model) to generate client side meta-information and automate communication between ExtJS (client-side) and ORM framework (server-side)
  • make transparent synchronization between Ext.data.Store (that is in general just a data cache on client side) and server-side cache (like javax.persistence.EntityManager) with supporting REST methods like PUT/POST/GET/DELETE etc

So, let's

Getting started

Grids

Entity grid

Let's suppose in your application you have an entity class like it:

@Entity
@Table(name = "ORDER_")
public class Order extends AutoIncrementBaseEntity {
  public Order() {
  }

  public Order(String aNotes) {
    _notes = aNotes;
    _createDate = new Date();
  }

  public Date getCreateDate() {
    return _createDate;
  }

  public void setCreateDate(Date aCreateDate) {
    _createDate = aCreateDate;
  }

  private Date _createDate;

  public String getNotes() {
    return _notes;
  }

  public void setNotes(String aNotes) {
    _notes = aNotes;
  }

  private String _notes;
}

To yield grid that shows such data in searchable, pageable and filterable grid as so simple as define ExtJS component:

xtype:'crm.ui.orders.OrdersGrid'
Columns
Enum column

Let's we defined in our model class state property like it:

@Entity
public class Invoice {
  public static enum State {
    NEW, REJECTED, CONFIRMED
  }

  @Enumerated(EnumType.STRING)
  public State getState() {
    return _state;
  }

  public void setState(State aState) {
    _state = aState;
  }

  private State _state = State.NEW;

To add column that can accept just Invoice.State.values() values we need declare it in this way:

  },{
    dataIndex: 'state',
    header: 'State',
    editable: true,
    xtype: 'dictionarycolumn',
    storeId: 'invoice$States',
    displayField: 'name'

where:

  • xtype: 'dictionarycolumn', defines that we will have a dictionary column with reference on some store (see storeId property). Such columns will restrict user input by combobox values that such store provides.
  • storeId: 'invoice$States', was pointed into pre-generated store that extjs-orm will generate for you based on Invocice.State class. So, naming convention for store id is:
uncapitalize( simpleClassName ) + 's'

Store will contain rows with 2 columns: id,name

  • displayField: 'name' tells that we need to display for user name field of dictionary store row, not id

Such small configuration provides us nice features:

  • Combobox in column:

File:Combobox1.jpg

  • Filtering:

File:Combobox2.jpg

Dictionary column

Let's now take when we have ManyToOne relationship like it:

@Entity
public class Invoice {
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "client")
  public Company getClient() {
    return _client;
  }

  public void setClient(Company aClient) {
    _client = aClient;
  }

  private Company _client;
...

@Entity
public class Company  {
...

It would be nice to have automatically such nice feautures like:

  • Search by client name with paging

File:Dc2.JPG

Picture 1

  • Create new client on fly by clicking on special row when result set is empty:

File:Dc1.JPG

Picture 2

and have initially base form that can be customized latter:

File:Dc3.JPG

Picture 3

  • Filter data in grid based on multi-values:

File:Dc4.JPG

Picture 4

And it's easy! Everything what we need to do it is declare dictionarycolumn like it:

{
  dataIndex: 'client',
  header: 'Client',
  editable:true,
  required: true,
  xtype: 'dictionarycolumn',
  storeId: 'companys',
  displayField: 'name',
  newRecordForm: 'CompanyForm',
  newRecordFormTitle: "Create client form",
  emptyRowCaption: "Create new client...",
  showEmptyRow: true,
  createRecordIfNotFound: true
}

or, if we remember, that we can extend pre-defined column:

Ext.apply({}, crm.ui.InvoicesGrid.columns.client, {
  showEmptyRow: true,
  createRecordIfNotFound: true
})

Attributes:

  • storeId - defines which store will provide an options for searchable combobox of current column. In ManyToOne relationship case we are aware about referenced entity type and ExtJS ORM already provides (by default) store for such entities with predefined id: <uncapitilize( refType.simpleName ) + 's
  • displayField - name of field (of referenced entity) which value should be displayed in UI as column value and option display value.
  • newRecordForm - xtype of form that should be used in popup window when user choosed "Create new referenced entity" option. It can be any custom form or pre-generated by ExtJS ORM framework (See Picture 3)
  • newRecordFormTitle - title for such form/popup window (See Picture 3)
  • emptyRowCaption - Text for option that combobox should display when entity wasn't found (See Picture 2)
  • showEmptyRow - flag that shows when display such option:
    • false - means never. User will not be able dynamicly add new referenced entity.
    • true - show such option just when referenced entity with such criteria wasn't found
    • always - show such option always.
  • createRecordIfNotFound - means should we show popup window with form for new referenced entity (true) or not (false). Sometimes we want just to handle emptyRowSelected event which will be generated by combobox when end user clicked on special 'empty' option, but don't want to show popup window with form for new referenced entity. For example, we need it when we just want to change on fly light store were we lookuped referenced entity on some hard-to-get store (archived historical table, for example)

Internationalization and localization

If you want to define local headers of grid columns you need:

  • add define messageSource bean in spring context with basenames
  • in corresponded properties file add for each java class property property with localized header value like it:

com.app.model.Shop.address=Адрес


  • Smart serialization
    • maxDepth
    • no one2many properties
    • no blob properties
Personal tools