part 4
A view is responsible for presenting some data to the user. This might be a single object, or a collection.
In FOAM, a View
needs to specify some HTML, by returning a Javascript string
from a method called toHTML()
.
Rather than writing a Javascript function that constructs and returns such a
string, FOAM supports a template syntax. A class can have a templates
section,
and at load time your templates are compiled into Javascript functions that
return strings.
Templates can also live in external files, which are introduced in part 6.
Template Syntax
FOAM’s template syntax is a superset of JSP syntax. This means templates are HTML overall, with the following extras:
<% %>
encloses Javascript code.- Real Javascript, not a restricted subset.
<%= %>
encloses a comma-separated list of Javascript expressions whose values are written to the DOM.%%foo
inserts the simple value ofthis.foo
into the page.$$foo
inserts theview
forthis.foo
at this location. That is, whatever thefoo
property’sview
is set to, one will be created and inserted here.$$foo{ x: 'abc', y: 'def' }
will pass along those values to.create
when it builds the view forfoo
.
Control Structures
Since <% %>
allows embedding arbitrary, real Javascript code, you can create
control structures like so:
However, code like this is rarely necessary, since FOAM contains many views that
handle creating rows from a collection of data. DAOListView
from
part 3 is one example; TableView
and
GridView
are two more.
Inline Templates
Let’s define the template for each phone in the catalog. Expand
PhoneCitationView
so it looks like this:
- FOAM uses multi-line comments in templates as a hack for multi-line strings in Javascript.
- Inside a template,
this
is bound to the view itself, not thePhone
object. - The
Phone
object isthis.data
instead. - The
$$foo
syntax puts a child view at this location.imageUrl
has itsview
set toImageView
, so$$imageUrl
will render anImageView
inside the first link tag. $$name{mode: 'read-only'}
will put the child view for thename
property (defaults toTextFieldView
) in the second link tag, creating the view with itsmode
property set to'read-only'
.mode: 'read-only'
on aTextFieldView
is simply text in a<span>
.- Similarly for
$$snippet{mode: 'read-only'}
.
Now 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. First, let’s add a second template, for the top-level ControllerView
. Add this code to Controller.js
, expanding our ControllerView
:
- Most FOAM views support
className
andtagName
. The defaulttagName
for aDAOListView
is<div>
, but we want to use<ul>
here. search
hasview
set toTextFieldView
, so it will render as a text box.order
’sview
isChoiceView
, which renders a drop-down list.filteredDAO
is theDAOListView
, which renders the list of entries.
The custom CSS still isn’t loaded, so add the following to index.html
’s
<head>
tag:
and reload your app. Now it should look much better, and the search and sort functions work!
Part 5 will add navigation to our app.