Part III - Applied Learning - User Interface part 3c
Part III - Applied Learning - User Interface
A view is responsible for presenting specific data to the user. An example of this kind of data would be a single object or a collection.
In FOAM, a view needs to present a UI component by defining a template method initE() in the U2 library. The U2 library provides a variety of views such as DetailView, TableView, ImageView, etc. These views extend Element which is a virtual-DOM element that serves as the root model for all U2 UI components.
UI Library
FOAM’s U2 syntax provides methods for adding and interacting with UI components, including:
start()creates an element and adds it as a child.end()terminates astart().add(args)adds UI components to this element.addClass(cls)specifies a CSS class to this element.tag(spec, args, slot)creates a tag and adds it as a child.addEventListener(topic, listener)adds a DOM listener.
Tutorial Application
Let’s define the initE() for each phone in the catalog.
STEP #1. Expand PhoneCitationView in Controller.js so it looks like this:
foam.CLASS({
package: 'tutorial',
name: 'PhoneCitationView',
extends: 'foam.u2.DetailView',
methods: [
function initE() {
this
.start('li')
.start('a')
.attrs({ href: '#' + this.data.id })
.start({ class: 'foam.u2.tag.Image',
data: this.data.imageUrl })
.addClass('thumb').end()
.end()
.start('a')
.attrs({ href: '#' + this.data.id })
.add(this.data.name)
.end()
.start()
.add(this.data.snippet)
.end()
.end();
}
]
});STEP #2. Reload your app and see that… it’s a complete mess. That’s because PhoneCitationView is putting in <li> tags but they’re not in a <ul>, and the custom CSS for the app is not being loaded. We’ll get back to the CSS shortly.
STEP #3. Add a second template for the top-level ControllerView.
STEP #4. Add the followng code to Controller.jsand expand your ControllerView:
foam.CLASS({
package: 'tutorial',
name: 'Controller',
extends: 'foam.u2.Element',
exports: [
'as data',
],
properties: [
{
name: 'search',
class: 'String',
view: { class: 'foam.u2.TextField', onKey: true }
},
{
name: 'order',
value: Phone.NAME,
view: {
class: 'foam.u2.view.ChoiceView',
choices: [
[Phone.NAME, 'Alphabetical'],
[Phone.AGE, 'Newest']
]
}
},
{ name: 'dao', value: phones },
{
name: 'filteredDAO',
class: 'foam.dao.DAOProperty',
view: {
class: 'foam.u2.DAOList',
rowView: { class: 'tutorial.PhoneCitationView' }
},
expression: function (dao, search, order) {
var expr = foam.mlang.Expressions.create();
return dao.orderBy(order).where(expr.OR(
expr.CONTAINS_IC(Phone.SNIPPET, search),
expr.CONTAINS_IC(Phone.SNIPPET, search)));
}
},
'image'
],
methods: [
function initE() {
this.initHTML();
window.addEventListener('hashchange', this.initHTML.bind(this));
},
function initHTML() {
var self = this;
this.removeAllChildren();
this
.add('Search: ').add(this.SEARCH)
.br()
.add('Sort by: ').add(this.ORDER)
.br()
.start('ul')
.addClass('phones').add(this.FILTERED_DAO)
.end();
}
]
});About the Above Code:
- Most FOAM views support
classNameandtagName. The defaulttagNamefor aDAOListis<div>. searchhasviewset toTextField,so it will render as a text box.order’sviewisChoiceViewwhich renders a drop-down list.filteredDAOis theDAOListwhich renders the list of entries.
STEP #5. Add the following to index.html’s <head> tag to load the custom CSS:
<link rel="stylesheet" href="css/app.css" />
<link rel="stylesheet" href="css/bootstrap.css" />STEP #6. Reload your app.
Conclusion
Now your app should look much better and the search and sort functions work! You are now ready for the final stage of your basic app in FOAM. Please proceed to the next lesson on navigation.
NEXT: Part III - Applied Learning - Navigation
Tutorial Menu:
- Getting Started
- Core Concepts
- Applied Learning: Build a Basic App with FOAM