04.View
- Overview
- Manipulate with a single element
- Generating a complex view (using template)
- View manipulating cautions (unique id))
- Reference
Overview
In JavaScript, you can perform view manipulation (also called screen or DOM manipulation) from anywhere.
As result, on a screen that enables functions to be flexibly written, it is difficult to recognize where and which processing is being executed, and modify view even a little at maintenance phase.
In hifive, in principle, view manipulation is only defined within the controller.
Therefore, it is clear that "the controller will perform view manipulation",making it easier for user to understand
where to perform maintenance and inheritance.
In order to generate view, hifive features EJS template engine.
Using template engine, complex structure tags can be visually edited, increasing maintainability and readability.
Manipulate with a single element
If you want to, for example, read <input> tag value, or pass a string to <div> tag, use jQuery to read and write
to a single element.
However, if you are working with a DOM element,
use this.$find() method which is available to use in the controller instead of jQuery $().
This method searches for an element from subordinates of the element that controller is bound to, preventing
wrongly manipulating with an element that is out of scope of the element (that controller is bound to).
Operation example
※Since this.$find() returns "a jQuery object in such status as an element specified by selector is selected",
after it is selected, you can manipulate with the element same as a normal jQuery object.
Manipulating activities | Implementation method |
---|---|
Generating an element | $(tag) |
Selecting an element | this.$find(selector); |
Removing an element | this.$find(selector).remove(); |
Updating element content | this.$find(selector).html(element); this.$find(selector).text(value); this.$find(selector).val(value); |
※"this" indicates the controller itself.
Generating a complex view (using template)
Basic syntax
A view template should be used in order to generate a complex view (containing various complex tags)
A template is defined by <script type="text/ejs"></script> tags.
Each template must be assigned an unique ID (set the id attribute in <script> tag).
EJS syntax is very similar to JSP.
JavaScript code is opened and closed with [% and %] . You can put [% %] anywhere in the code.
You can use for and if statements etc. to customize view:
[% for (var i = 1, len = num + 1; i < len; i++) { %]
<li>
<span style="[%= 'color: ' + (i % 2 === 0 ? 'blue;': 'red;') %]">[%= i %]</span>
</li>
[% } %]
</script>
Defining template
Template can be defined:
- in an independent file
- or directly in the HTML file
Basically, it is recommended that a template is defined in an independent file. However, in following cases:
- the template is only used for a specific view (HTML).
- in case you want to minimize the number of HTTP request:
- in fact, a HTTP request occurs for each file the template is defined.
template should be defined directly in the HTML file.
- in fact, a HTTP request occurs for each file the template is defined.
If you define a template as an independent file, it is recommended to use .ejs extension
Loading template file
__templates: ['view/template1.ejs', 'view/template2.ejs'],
};
- If a template is defined as an external file, insert the template file url in templates property
of the controller that uses the file, so that it will automatically be imported at controllization time.
Since the controller starts operation after the specified template file is imported,
certainly the event handler can also make use of the template file. - If a template is defined directly in a HTML file, it is available for use at anytime (no need to define templates property).
Installing debug library for syntax checking
If a wrongly defined template is loaded, it is impossible to understand where the error happens in the template just by reading error messages.
Using an ejs library that can give detailed error messages and line number where error happens, can be a solution to the problem.
You can download from the link below:
http://embeddedjavascript.googlecode.com/files/ejs_fulljslint.js
Refer to the following links for guidelines about how to use the library.
EJS - google code
EJS公式HP
Working with template
The following this.view methods are used in the controller when customizing view using template.
※this indicates the controller itself.
(The following methods can be used in the controller )
Method name | Description |
update(target element object or selector, templateID, parameter) | Update target element content with specified template. |
append(target element object or selector, templateID, parameter) | Append the specified template to the end of target element. |
prepend(target element object or selector, templateID, parameter) | Append the specified template at the beginning of target element. |
If you want to get the returned HTML tag (using code) without directly displaying to view, use
this.view.get(templateID, substitution parameter).
Implementation example
1.Write a HTML file.
<html>
<head>
<meta charset="UTF-8">
<script src="jquery.js"></script>
<script src="ejs-1.0.h5mod.js"></script>
<script src="h5.js"></script>
<!-- Import your js file here -->
<script src="step5.js"></script>
<title>Manipulating with view in hifive</title>
</head>
<body>
<div id="container">
<div>
From 1 to entered value, print to view: even numbers are colored <span style="color: red;">red</span>,
odd numbers are colored <span style="color: blue;">blue</span>.
</div>
<input type="text" id="to" value="" />
<input type="button" id="output" value="出力" />
<ul id="list"></ul> <!-- Template outputs flushed here -->
</div>
</body>
</html>
2. Create list.ejs file
[% for (var i = 1, len = num + 1; i < len; i++) { %]
<li>
<span style="[%= 'color: ' + (i % 2 === 0 ? 'blue;': 'red;') %]">[%= i %]</span>
</li>
[% } %]
</script>
※ The list in id attribute of <script> tag will become required template ID when this.view.get() is called.
3. Create step5.js file.
// Create an object that is source of the controller
var controller = {
// Set controller name
__name: 'NumListController',
// Define template file path
__templates: 'list.ejs', // Declare an array if you want to import multiple ejs files.
// Define an event handler that processes when id=output is pressed
'#output click': function() {
// Get input value
var to = this.$find('#to').val();
// Exit processing unless value exists in #to
if (!to) {
return;
}
// Convert from String to Number. Exit processing if conversion fails
try {
to = parseInt(to);
} catch(e) {
return;
}
// Print template with value entered to view
this.view.append('#list', 'list', {num: to});
}
};
// Bind controller to id="container" element
h5.core.controller('#container', controller);
});
4. Open HTML file in browser.
5. Enter a number value in textbox then click output button.
Checking operation
How to pass value to template
Similar to JSP, in hifive template you can insert any optional value between [% %] or [%= %] . Text between [%= %] will automatically be HTML escaped. Using [%:= %] wiil not make text be escaped.
You can pass a value to template using the syntax below:
{template variable name: value}
Example (1)
Example (2)
Similar to object literal, if you want to pass several values:
{template variable name: value, template variable name: value, ...}
You can define as above.
In the above implementation example, in line 27 of step5.js file:
value is passed to the third argument {num: to}. In line 2 of list.ejs file:
this value is used for num .
As result, by specifying same name as template variable name for object key, value can be passed using view.get(), view.append(), view.update(), view.prepend() methods.
Defining various templates
You can define various templates, even in external file or directly in HTML file. However, remember that id must be unique.
<div>Test 1</div>
</script>
<script type="text/ejs" id="list2">
<span>Test 2</span>
</script>
Actions performed after importing a template containing duplicated template ID
If id is duplicated, the later imported id will be prioritized (overwrite).
Otherwise, you will have to specify an unique id, regardless of defining in the same HTML file or in other files.
Importing priority order for ejs file is as below.
- Since the priority order is from top down, the last definition will be prioritized.
- If multiple ejs files is specified to controller __templates property, the last specified ejs file will be prioritized.
For example, executing the below code will display "hello 2".
view.ejs
hello 1
</script>
<script type="text/ejs" id="list">
hello 2
</script>
test.js
__name: 'TestController',
__templates: 'view.ejs',
__ready: function() {
alert(this.view.get('list'));
}
}
h5.core.controller('body', testController);
test.html
<html>
<head>
<meta charset="UTF-8">
<script src="jquery.js"></script>
<script src="jquery.blockUI.js"></script>
<script src="ejs-1.0.h5mod.js"></script>
<script src="h5.js"></script>
<script src="test.js"></script>
</head>
<body>
</body>
</html>
View manipulating cautions (unique id))
id set for an element must be unique on view.
This is specification of HTML.
- Similar to list, when displaying multiple times on view, instead of using id, you can use CSS class, or assign unique ID to data-* attribute .
- You need to pay special attention while dynamically rewriting view using Ajax.
- In case multiple elements have same id, if you get the element using this.$find('#id') or document.getElementById('id'), in many browsers, the first element with specified id will be retrieved. However, the operation may vary depending on the system.
Just by separating View (template) and Controller (event handling), code becomes considerably comprehensive.
If there's not much calculation code at client side, using only these two features is OK.
Next chapter will describe about Logic that handles calculation and communication processing.
Next chapter ⇒ 05.Logic