Differences

This shows you the differences between two versions of the page.

Link to this comparison view

search [2012/03/30 17:01]
srdjan.lukovic created
search [2012/07/09 10:51] (current)
srdjan.lukovic [GUI Code]
Line 1: Line 1:
-====== Submit Person Sample ====== +====== Search ====== 
-This sample is basic example of querying database with some advanced features.+ 
 +**Search** is a [[SOLoist Sample Applications|SOLoist sample application]] that shows a prototypical search form for searching the object space according to the user's input criteria. 
 + 
 +The filtering criteria are entered in the input controls in the top part of the form. The result set is returned and shown in the grid at the bottom. 
 + 
 +Searching without any of the fields filled in will return all objects of the class //Person// from the object space. Entering parameter values will filter the result set. Selecting one or more //Bank Advisers// from the list will search only for the //Persons// that have the selected objects as their //Bank Advisers// (linked over the //myBankAdvisers// association end). 
 + 
 +In the result table, additional options can be selected: 
 +  * the columns to be displayed or hidden 
 +  * the page size  
 +  * whether the size of the entire result set will be calculated and displayed or not (this may have a great performance impact for very large data sets and complex queries). 
 + 
 +Clicking on any column header of the result table will sort the results in the ascending/descending order of the values in that column. 
 + 
 +The results can be exported to an Excel table. 
 + 
 +A double-click on a //Person// object icon shows the form with the details of that object.
  
 ==== Live example ==== ==== Live example ====
  
 [[http://soloistdemo.org/SampleApplications/search.html]]\\ [[http://soloistdemo.org/SampleApplications/search.html]]\\
 +[[http://soloistdemo.org/SampleApplications/oql?q=SELECT+p%2C+p.name%2C+p.gender%2C+p.age%2C+p.dateOfBirth%2C+p.height%2C+p.isMarried%2C+p.photo%2C+p.rootFolder%0D%0AFROM+Person+p&f=html | OQL Query: Persons]]
 +|{{screen:search.png?250}}|
  
 ===== UML Model ===== ===== UML Model =====
 +{{bankadvisers.png}}
 {{search.png}} {{search.png}}
  
Line 29: Line 48:
  private static final SimpleQueryDefinition prototypeQuery;  private static final SimpleQueryDefinition prototypeQuery;
   
- @Parameter @Result("Name")+ @Parameter // @Parametar annotation means that QueryBuilder expects a parameter value from the element component named as the annotated string 
 + @Result("Name") // @Result annotation means that the column "Name" will be in the result table
  public static final String NAME = "NAME";  public static final String NAME = "NAME";
   
- @Result("Person") @OrderByAnother(NAME)+ @Result("Person") @OrderByAnother(NAME) // @OrderByAnother - objects of Person will be ordered by the name attribute
  public static final String PERSON = "PERSON";  public static final String PERSON = "PERSON";
   
Line 69: Line 89:
  ));  ));
   
- includeInResultOnce(+ includeInResultOnce( // Columns in the result table, in this order
  PERSON,  PERSON,
  GENDER,  GENDER,
Line 129: Line 149:
 import rs.sol.soloist.server.guiconfiguration.components.GUISearchPanelComponent; import rs.sol.soloist.server.guiconfiguration.components.GUISearchPanelComponent;
 import rs.sol.soloist.server.guiconfiguration.construction.GUIComponentBinding; import rs.sol.soloist.server.guiconfiguration.construction.GUIComponentBinding;
-import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUIElementComponent+import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUIEdit
-import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUIInputKind; +import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUIInput;
-import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUIListWidget; +
-import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUIMultipleElementWidget; +
-import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUISlotEditorKind; +
-import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUISubnodesInput; +
-import rs.sol.soloist.server.guiconfiguration.layout.CellLayoutData;+
 import rs.sol.soloist.server.guiconfiguration.layout.FlowLayout; import rs.sol.soloist.server.guiconfiguration.layout.FlowLayout;
-import rs.sol.soloist.server.guiconfiguration.layout.LayoutData;+import rs.sol.soloist.server.guiconfiguration.layout.TableLayoutData; 
 +import rs.sol.soloist.server.guiconfiguration.nonvisualcompoments.GUIFindAllInstancesSAPComponent;
 import rs.sol.soloist.server.guiconfiguration.style.GUIBindingsFeature; import rs.sol.soloist.server.guiconfiguration.style.GUIBindingsFeature;
 import rs.sol.soloist.server.guiconfiguration.style.GUIContext; import rs.sol.soloist.server.guiconfiguration.style.GUIContext;
Line 152: Line 168:
  public void init() throws InitializerFailedException {  public void init() throws InitializerFailedException {
  GUIApplicationComponent application = new GUIApplicationComponent();  GUIApplicationComponent application = new GUIApplicationComponent();
- application.name.set(Text.fromString("SearchSample"));+ application.setName("SearchSample");
  SoloistServiceServlet.registerApplication(application);  SoloistServiceServlet.registerApplication(application);
  
Line 158: Line 174:
  
  GUILabelComponent title = GUILabelComponent.create(root, "Search");  GUILabelComponent title = GUILabelComponent.create(root, "Search");
- title.styleName.set(Text.fromString("titleStyle"));+ title.setStyle("titleStyle");
  
  GUIPanelComponent topPanel = GUIPanelComponent.createFlow(root);  GUIPanelComponent topPanel = GUIPanelComponent.createFlow(root);
- topPanel.styleName.set(Text.fromString("topPanel"));+ topPanel.setStyle("topPanel");
  
  GUIDeckComponent mainDeck = GUIDeckComponent.create(topPanel);  GUIDeckComponent mainDeck = GUIDeckComponent.create(topPanel);
Line 167: Line 183:
  GUIPanelComponent wrapPanel = GUIPanelComponent.createFlow(mainDeck);  GUIPanelComponent wrapPanel = GUIPanelComponent.createFlow(mainDeck);
  GUISearchPanelComponent searchForm = GUISearchPanelComponent.create(wrapPanel, new FlowLayout());  GUISearchPanelComponent searchForm = GUISearchPanelComponent.create(wrapPanel, new FlowLayout());
- searchForm.styleName.set(Text.fromString("form searchForm")); + // GUISearchPanelComponent binds element components implicitly between the search form and the query builder based on the components' names 
- + searchForm.setStyle("form searchForm");
- GUILabelComponent.create(wrapPanel, "Search by Bank Advisers:"); +
- GUISearchPanelComponent searchList = GUISearchPanelComponent.create(wrapPanel, new FlowLayout()); +
- GUIElementComponent bankAdvisors = GUIElementComponent.createInput(searchList, PersonQueryBuilder.BANK_ADVISOR, new GUIListWidget(), +
- GUISubnodesInput.create(BankAdviser.CLASSIFIER), null); +
- GUIInputKind.get(bankAdvisors).upperBound.set(Integer.valueOf(-1)); +
- CellLayoutData.setSize(bankAdvisors, "250px", "154px"); +
- bankAdvisors.styleName.set(Text.fromString("listWidget")); +
- +
- GUIButtonComponent btnAll = GUIButtonComponent.create(wrapPanel, "Select All"); +
- GUIButtonComponent btnNone = GUIButtonComponent.create(wrapPanel, "Select None"); +
- GUIComponentBinding.create(btnAll.click, GUIMultipleElementWidget.get(bankAdvisors).selectAll); +
- GUIComponentBinding.create(btnNone.click, GUIMultipleElementWidget.get(bankAdvisors).unselectAll);+
  
  GUIPanelComponent table = GUIPanelComponent.createTable(searchForm);  GUIPanelComponent table = GUIPanelComponent.createTable(searchForm);
- table.styleName.set(Text.fromString("table")); + table.setStyle("table"); 
- LayoutData.setSize(table, "100%", null);+ table.setSize("100%", null);
  
  int row = 0;  int row = 0;
- GUIElementComponent.createInput(table, PersonQueryBuilder.NAME, Text.CLASSIFIER, row++, 1); + // name needs to be providedin this case PersonQueryBuilder.NAME constant 
- GUIElementComponent.createInput(table, PersonQueryBuilder.GENDER, Repository.getRepository().getEnumeration(Gender.FQ_TYPE_NAME), row++, 1); + GUIInput.createField(table, Text.CLASSIFIER, row++, 1).setName(PersonQueryBuilder.NAME); 
- GUIElementComponent.createInput(table, PersonQueryBuilder.DATE_OF_BIRTH, Date.CLASSIFIER, row++, 1); + GUIInput.createField(table, Repository.getRepository().getEnumeration(Gender.FQ_TYPE_NAME), row++, 1).setName(PersonQueryBuilder.GENDER); 
- GUIElementComponent.createInput(table, PersonQueryBuilder.IS_MARRIED, Boolean.CLASSIFIER, row++, 1); + GUIInput.createField(table, Date.CLASSIFIER, row++, 1).setName(PersonQueryBuilder.DATE_OF_BIRTH); 
- GUIElementComponent.createInput(table, PersonQueryBuilder.OLDER_THAN, Integer.CLASSIFIER, row++, 1); + GUIInput.createField(table, Boolean.CLASSIFIER, row++, 1).setName(PersonQueryBuilder.IS_MARRIED); 
- GUIElementComponent.createInput(table, PersonQueryBuilder.YOUNGER_THAN, Integer.CLASSIFIER, row++, 1);+ GUIInput.createField(table, Integer.CLASSIFIER, row++, 1).setName(PersonQueryBuilder.OLDER_THAN); 
 + GUIInput.createField(table, Integer.CLASSIFIER, row++, 1).setName(PersonQueryBuilder.YOUNGER_THAN);
  
  row = 0;  row = 0;
- GUILabelComponent.create(table, "Name", row++, 0).styleName.set(Text.fromString("formLabel")); + GUILabelComponent.create(table, "Name", row++, 0).setStyle("formLabel"); 
- GUILabelComponent.create(table, "Gender", row++, 0).styleName.set(Text.fromString("formLabel")); + GUILabelComponent.create(table, "Gender", row++, 0).setStyle("formLabel"); 
- GUILabelComponent.create(table, "Date of birth", row++, 0).styleName.set(Text.fromString("formLabel")); + GUILabelComponent.create(table, "Date of birth", row++, 0).setStyle("formLabel"); 
- GUILabelComponent.create(table, "Is married?", row++, 0).styleName.set(Text.fromString("formLabel")); + GUILabelComponent.create(table, "Is married?", row++, 0).setStyle("formLabel"); 
- GUILabelComponent.create(table, "Older than", row++, 0).styleName.set(Text.fromString("formLabel")); + GUILabelComponent.create(table, "Older than", row++, 0).setStyle("formLabel"); 
- GUILabelComponent.create(table, "Younger than", row++, 0).styleName.set(Text.fromString("formLabel"));+ GUILabelComponent.create(table, "Younger than", row++, 0).setStyle("formLabel"); 
 +  
 + GUILabelComponent.create(wrapPanel, "Search by Bank Advisers:"); 
 + GUISearchPanelComponent searchList = GUISearchPanelComponent.create(wrapPanel, new FlowLayout()); 
 + GUIFindAllInstancesSAPComponent advisersSource = GUIFindAllInstancesSAPComponent.create(searchList, BankAdviser.CLASSIFIER); 
 + GUIInput bankAdvisors = GUIInput.createList(searchList); 
 + GUIComponentBinding.create(advisersSource.opValue(), bankAdvisors.ipCollection()); 
 + bankAdvisors.setName(PersonQueryBuilder.BANK_ADVISOR); 
 + bankAdvisors.setUpperBound(-1); 
 + bankAdvisors.setSize("250px", "154px"); 
 + bankAdvisors.setStyle("listWidget"); 
 + 
 + GUIButtonComponent btnAll = GUIButtonComponent.create(wrapPanel, "Select All"); 
 + GUIButtonComponent btnNone = GUIButtonComponent.create(wrapPanel, "Select None"); 
 + GUIComponentBinding.create(btnAll.opClick(), bankAdvisors.ipSelectAll()); 
 + GUIComponentBinding.create(btnNone.opClick(), bankAdvisors.ipUnselectAll());
  
  GUIPanelComponent buttonPanel = GUIPanelComponent.createFlow(wrapPanel);  GUIPanelComponent buttonPanel = GUIPanelComponent.createFlow(wrapPanel);
- buttonPanel.styleName.set(Text.fromString("searchButtons"));+ buttonPanel.setStyle("searchButtons");
  
  GUIButtonComponent searchButton = GUIButtonComponent.create(buttonPanel, "Search");  GUIButtonComponent searchButton = GUIButtonComponent.create(buttonPanel, "Search");
- searchButton.styleName.set(Text.fromString("submitButton"));+ searchButton.setStyle("submitButton");
  
  GUIButtonComponent resetButton = GUIButtonComponent.create(buttonPanel, "Reset");  GUIButtonComponent resetButton = GUIButtonComponent.create(buttonPanel, "Reset");
- resetButton.styleName.set(Text.fromString("submitButton"));+ resetButton.setStyle("submitButton");
  
  GUIPanelComponent searchTable = GUIPanelComponent.createFlow(wrapPanel);  GUIPanelComponent searchTable = GUIPanelComponent.createFlow(wrapPanel);
- searchTable.styleName.set(Text.fromString("searchPanel"));+ searchTable.setStyle("searchPanel");
  
  PersonSearch searchResult = new PersonSearch();  PersonSearch searchResult = new PersonSearch();
- searchResult.parent.set(searchTable); + searchTable.add(searchResult); 
- searchResult.doInitialSearch.set(Boolean.FALSE); + searchResult.setDoInitialSearch(false); 
- searchForm.dynamicBindingDest.set(searchResult); + searchForm.addDynamicBindingDest(searchResult); // binds all fields in search form with corresponding query builder 
- searchList.dynamicBindingDest.set(searchResult);+ searchList.addDynamicBindingDest(searchResult);
  
- LayoutData.setSize(searchResult, "100%";, null);+ GUIComponentBinding.create(searchButton.opClick(), searchResult.ipSearch()); 
 + GUIComponentBinding.create(resetButton.opClick()searchForm.ipReset()); 
 + GUIComponentBinding.create(resetButton.opClick()searchResult.ipClearContents());
  
- GUIComponentBinding.create(searchButton.click, searchResult.search); + GUIComponentBinding.create(searchButton.opClick(), searchResult.ipSearch()); 
- GUIComponentBinding.create(resetButton.click, searchForm.reset); + GUIComponentBinding.create(resetButton.opClick(), searchForm.ipReset()); 
- GUIComponentBinding.create(resetButton.click, searchResult.clearContents);+ GUIComponentBinding.create(resetButton.opClick(), searchResult.ipClearContents());
  
- GUIComponentBinding.create(wrapPanel.output, searchResult.search);+ GUIComponentBinding.create(wrapPanel.opRelay2(), searchResult.ipSearch());
  
  GUIPanelComponent personDetails = GUIPanelComponent.createTable(mainDeck);  GUIPanelComponent personDetails = GUIPanelComponent.createTable(mainDeck);
- personDetails.styleName.set(Text.fromString("searchDetails"));+ personDetails.setStyle("searchDetails");
  
  GUIPanelComponent detailsTable = GUIPanelComponent.createTable(personDetails);  GUIPanelComponent detailsTable = GUIPanelComponent.createTable(personDetails);
- application.context.set(createContextAndStyles(detailsTable));+ application.setContext(createContextAndStyles(detailsTable));
  
  createDetails(detailsTable, wrapPanel);  createDetails(detailsTable, wrapPanel);
  }  }
  
 + /**
 + * Person details editors
 + */
  private void createDetails(GUIPanelComponent personDetails, GUIPanelComponent backTo) {  private void createDetails(GUIPanelComponent personDetails, GUIPanelComponent backTo) {
  int row = 0;  int row = 0;
  GUILabelComponent.create(personDetails, "Name: ", row, 0);  GUILabelComponent.create(personDetails, "Name: ", row, 0);
- GUIElementComponent nameEditor = GUIElementComponent.createSlotEditor(personDetails, Person.PROPERTIES.name, row++, 1);+ GUIEdit nameEditor = GUIEdit.createField(personDetails, Person.PROPERTIES.name, row++, 1);
  
  GUILabelComponent.create(personDetails, "Gender: ", row, 0);  GUILabelComponent.create(personDetails, "Gender: ", row, 0);
- GUIElementComponent genderEditor = GUIElementComponent.createSlotEditor(personDetails, Person.PROPERTIES.gender, row++, 1);+ GUIEdit genderEditor = GUIEdit.createField(personDetails, Person.PROPERTIES.gender, row++, 1);
  
  GUILabelComponent.create(personDetails, "Age: ", row, 0);  GUILabelComponent.create(personDetails, "Age: ", row, 0);
- GUIElementComponent ageEditor = GUIElementComponent.createSlotEditor(personDetails, Person.PROPERTIES.age, row++, 1);+ GUIEdit ageEditor = GUIEdit.createField(personDetails, Person.PROPERTIES.age, row++, 1);
  
  GUILabelComponent.create(personDetails, "Date of birth: ", row, 0);  GUILabelComponent.create(personDetails, "Date of birth: ", row, 0);
- GUIElementComponent dateOfBirthEditor = GUIElementComponent.createSlotEditor(personDetails, Person.PROPERTIES.dateOfBirth, row++, 1);+ GUIEdit dateOfBirthEditor = GUIEdit.createField(personDetails, Person.PROPERTIES.dateOfBirth, row++, 1);
  
  GUILabelComponent.create(personDetails, "Height [m]: ", row, 0);  GUILabelComponent.create(personDetails, "Height [m]: ", row, 0);
- GUIElementComponent heightEditor = GUIElementComponent.createSlotEditor(personDetails, Person.PROPERTIES.height, row++, 1);+ GUIEdit heightEditor = GUIEdit.createField(personDetails, Person.PROPERTIES.height, row++, 1);
  
  GUILabelComponent.create(personDetails, "Is married: ", row, 0);  GUILabelComponent.create(personDetails, "Is married: ", row, 0);
- GUIElementComponent isMarriedEditor = GUIElementComponent.createSlotEditor(personDetails, Person.PROPERTIES.isMarried, row++, 1);+ GUIEdit isMarriedEditor = GUIEdit.createField(personDetails, Person.PROPERTIES.isMarried, row++, 1);
  
- GUIComponentBinding.create(personDetails.inputGUISlotEditorKind.get(nameEditor).element); + GUIComponentBinding.create(personDetails.opRelay1()nameEditor.ipElement()); 
- GUIComponentBinding.create(personDetails.inputGUISlotEditorKind.get(genderEditor).element); + GUIComponentBinding.create(personDetails.opRelay1()genderEditor.ipElement()); 
- GUIComponentBinding.create(personDetails.inputGUISlotEditorKind.get(ageEditor).element); + GUIComponentBinding.create(personDetails.opRelay1()ageEditor.ipElement()); 
- GUIComponentBinding.create(personDetails.inputGUISlotEditorKind.get(dateOfBirthEditor).element); + GUIComponentBinding.create(personDetails.opRelay1()dateOfBirthEditor.ipElement()); 
- GUIComponentBinding.create(personDetails.inputGUISlotEditorKind.get(heightEditor).element); + GUIComponentBinding.create(personDetails.opRelay1()heightEditor.ipElement()); 
- GUIComponentBinding.create(personDetails.inputGUISlotEditorKind.get(isMarriedEditor).element);+ GUIComponentBinding.create(personDetails.opRelay1()isMarriedEditor.ipElement());
  
- GUIButtonComponent backButton = GUIButtonComponent.create(personDetails, "Back"row++, 0); + GUIButtonComponent backButton = GUIButtonComponent.create(personDetails, "Back"); 
- GUIComponentBinding.create(backButton.click, backTo.show);+ backButton.setLayoutData(TableLayoutData.create(row++, 0)); 
 + GUIComponentBinding.create(backButton.opClick(), backTo.ipShow());
  }  }
  
  private GUIContext createContextAndStyles(GUIPanelComponent personDetails) {  private GUIContext createContextAndStyles(GUIPanelComponent personDetails) {
  GUIContext context = new GUIContext();  GUIContext context = new GUIContext();
- context.supercontext.set(DefaultContextInit.getRoot());+ DefaultContextInit.getRoot().addContext(context);
  
  // how will Person objects look like in the GUI?  // how will Person objects look like in the GUI?
Line 278: Line 304:
  
  GUIBindingsFeature bf = GUIBindingsFeature.create(person);  GUIBindingsFeature bf = GUIBindingsFeature.create(person);
- GUIComponentBinding.create(bf.doubleClick, personDetails.input); + // doubleClick signal carries a Person object 
- GUIComponentBinding.create(bf.doubleClick, personDetails.show);+ GUIComponentBinding.create(bf.opDoubleClick(), personDetails.ipRelay1()); 
 + // double-clicking on a person in the result table will show the person's details 
 + GUIComponentBinding.create(bf.opDoubleClick(), personDetails.ipShow());
  
  return context;  return context;
Print/export