part 6
Our last important task to make this app functional is to define the custom
template for PhoneDetailView
.
External Templates
For large or complex templates, it can be unwieldy to put them inline in the
class, as we’ve done for PhoneCitationView
and ControllerView
. FOAM allows
you to place templates in external files.
You specify that an external template exists by defining a template
object in
your class that provides only its name. Update PhoneDetailView
to look like
this:
CLASS({
name: 'PhoneDetailView',
extendsModel: 'DetailView',
templates: [
{ name: 'toHTML' }
]
});
When a class (PhoneDetailView
) has a template with only a name
(toHTML
)
FOAM will look in the same directory for a file called
PhoneDetailView_toHTML.ft
. (.ft
is for “FOAM template”.)
Create this file now, and add the following, which was adapted from the AngularJS Phonecat tutorial. There’s a lot here, but most of it is pretty straightforward:
<%
var phone = this.data;
var imgId = this.nextID();
function checkmark(b) { return b ? '\u2713' : '\u2718'; }
%>
<div class="phone-images">
$$imageUrl{model_: 'foam.ui.ImageView', className: 'phone'}
</div>
<h1>{{phone.name}}</h1>
<p>{{phone.description}}</p>
<ul class="phone-thumbs">
<% phone.images.forEach(function(image) { %>
<li>
<img src="<%= image %>" id="<%= self.on('click', function() { phone.imageUrl = image; }) %>">
</li>
<% }); %>
</ul>
<ul class="specs">
<li>
<span>Availability and Networks</span>
<dl>
<dt>Availability</dt>
<% phone.availability.forEach(function(availability) { %> <dd><%= availability %></dd> <% }); %>
</dl>
</li>
<li>
<span>Battery</span>
<dl>
<dt>Type</dt>
<dd><%= phone.battery.type %></dd>
<dt>Talk Time</dt>
<dd><%= phone.battery.talkTime %></dd>
<dt>Standby time (max)</dt>
<dd><%= phone.battery.standbyTime %></dd>
</dl>
</li>
<li>
<span>Storage and Memory</span>
<dl>
<dt>RAM</dt>
<dd><%= phone.storage.ram %></dd>
<dt>Internal Storage</dt>
<dd><%= phone.storage.flash %></dd>
</dl>
</li>
<li>
<span>Connectivity</span>
<dl>
<dt>Network Support</dt>
<dd><%= phone.connectivity.cell %></dd>
<dt>WiFi</dt>
<dd><%= phone.connectivity.wifi %></dd>
<dt>Bluetooth</dt>
<dd><%= phone.connectivity.bluetooth %></dd>
<dt>Infrared</dt>
<dd><%= checkmark(phone.connectivity.infrared) %></dd>
<dt>GPS</dt>
<dd><%= checkmark(phone.connectivity.gps) %></dd>
</dl>
</li>
<li>
<span>Android</span>
<dl>
<dt>OS Version</dt>
<dd><%= phone.android.os %></dd>
<dt>UI</dt>
<dd><%= phone.android.ui %></dd>
</dl>
</li>
<li>
<span>Size and Weight</span>
<dl>
<dt>Dimensions</dt>
<% phone.sizeAndWeight.dimensions.forEach(function(dim) { %> <dd><%= dim %></dd> <% }); %>
<dt>Weight</dt>
<dd><%= phone.sizeAndWeight.weight %></dd>
</dl>
</li>
<li>
<span>Display</span>
<dl>
<dt>Screen size</dt>
<dd><%= phone.display.screenSize %></dd>
<dt>Screen resolution</dt>
<dd><%= phone.display.screenResolution %></dd>
<dt>Touch screen</dt>
<dd><%= checkmark(phone.display.touchScreen) %></dd>
</dl>
</li>
<li>
<span>Hardware</span>
<dl>
<dt>CPU</dt>
<dd><%= phone.hardware.cpu %></dd>
<dt>USB</dt>
<dd><%= phone.hardware.usb %></dd>
<dt>Audio / headphone jack</dt>
<dd><%= phone.hardware.audioJack %></dd>
<dt>FM Radio</dt>
<dd><%= checkmark(phone.hardware.fmRadio) %></dd>
<dt>Accelerometer</dt>
<dd><%= checkmark(phone.hardware.accelerometer) %></dd>
</dl>
</li>
<li>
<span>Camera</span>
<dl>
<dt>Primary</dt>
<dd><%= phone.camera.primary %></dd>
<dt>Features</dt>
<dd><%= phone.camera.features.join(', ') %></dd>
</dl>
</li>
<li>
<span>Additional Features</span>
<dd><%= phone.additionalFeatures %></dd>
</li>
</ul>
There’s quite a lot there, but it’s mostly the same pattern repeated for each group of specs. A few points of interest:
this.nextID()
is a function allView
s have, which returns a fresh identifier they can use as the ID of a DOM element.- We can define new variables and functions in templates, like
checkmark
.
Once you’ve got this file saved, reload the app and navigate to a phone, and you should see its information nicely laid out. Clicking a thumbnail image will load the larger version.
Finished
And that’s the complete app! Hopefully you now have a better feel for the steps of building a FOAM app, and are ready to start building your own.
See the Appendix for further reading.