new ElementView(model, controller, document)
A constructor function to create new element view objects.
var elementView = new maria.ElementView();
This constructor function takes three optional arguments.
var model = new maria.Model();
var controller = new maria.Controller();
var myFrameDoc = window.frames['myFrame'].document;
var elementView =
new maria.ElementView(model, controller, myFrameDoc);
The null or undefined value can be passed for any of these three parameters to skip setting it.
The purpose of the third document parameter is to allow the creation of element views in one window that will be shown in another window. At least some older browsers do not allow a DOM element created with one document object to be appended to another document object.
An element view is a view (inheriting from maria.View) and so has a model and controller. See maria.View for more documentation about setting and getting the model and controller objects.
What makes maria.ElementView different from the more abstract maria.View is that an element view has the concept of a "root element" which is the main DOM element that acts as a container for all the other DOM elements that are part of the element view.
The DOM is built using the getTemplate method which should return a fragment of HTML for a single DOM element and its children. By default the template is just an empty div element. You can redefine or override this to suit your needs.
maria.ElementView.prototype.getTemplate = function() {
return '<div>' +
'<span class="greeting">hello</span>, ' +
'<span class="name">world</span>' +
'</div>';
};
When an element view is created and its HTML template is rendered as a DOM element, the view will automatically start listening to the DOM element or its children for the events specified in the map returned by the getUIActions method. This map is empty by default but you can redefine or override as necessary and supply the necessary handler functions which usually delegate to the controller.
maria.ElementView.prototype.getUIActions = function() {
return {
'mouseover .greeting': 'onMouseoverGreeting',
'click .name' : 'onClickName'
};
};
maria.ElementView.prototype.onMouseoverGreeting = function(evt) {
this.getController().onMouseoverGreeting(evt);
};
maria.ElementView.prototype.onClickName = function(evt) {
this.getController().onClickName(evt);
};
Only a few simple CSS selectors are allowed in the keys of the UI action map. An id can be used like "#alpha" but this is not recommended. A class name like ".greeting", a tag name like "div", or a combination of tag name and class name like "div.greeting" are acceptable. In almost all cases, a single class name is sufficient and recommended as the best practice. (If you need more complex selectors you can use a different query library to replace the Grail library used by default in Maria.)
You can find an element or multiple elements in a view using the element view's find and findAll methods.
elementView.find('.name'); // returns a DOM element
elementView.findAll('span'); // returns an array
Because maria.View objects are composite views, so are maria.ElementView objects. This means that sub-element-view objects can be added to an element view. By default the sub-element-view object's root DOM element will be added to the parent element view's root DOM element. You can change the element to which they are added by redefining or overridding the getContainerEl function.
maria.ElementView.prototype.getContainerEl = function() {
return this.find('.name');
};
A particularly useful pattern is using maria.ElementView as the "superclass" of your application's element views. The following example shows how this can be done at a low level for a to-do application. See maria.ElementView.subclass for a much more compact way to accomplish the same.
checkit.TodoView = function() {
maria.ElementView.apply(this, arguments);
};
checkit.TodoView.superConstructor = maria.ElementView;
checkit.TodoView.prototype = maria.create(maria.ElementView.prototype);
checkit.TodoView.prototype.constructor = checkit.TodoView;
checkit.TodoView.prototype.getDefaultControllerConstructor = function() {
return checkit.TodoController;
};
checkit.TodoView.prototype.getTemplate = function() {
return checkit.TodoTemplate;
};
checkit.TodoView.prototype.getUIActions = function() {
return {
'click .check' : 'onClickCheck' ,
'dblclick .todo-content': 'onDblclickDisplay',
'keyup .todo-input' : 'onKeyupInput' ,
'keypress .todo-input' : 'onKeypressInput' ,
'blur .todo-input' : 'onBlurInput'
};
};
checkit.TodoView.prototype.onClickCheck = function(evt) {
this.getController().onClickCheck(evt);
};
checkit.TodoView.prototype.onDblclickDisplay = function(evt) {
this.getController().onDblclickDisplay(evt);
};
checkit.TodoView.prototype.onKeyupInput = function(evt) {
this.getController().onKeyupInput(evt);
};
checkit.TodoView.prototype.onKeypressInput = function(evt) {
this.getController().onKeypressInput(evt);
};
checkit.TodoView.prototype.onBlurInput = function(evt) {
this.getController().onBlurInput(evt);
};
checkit.TodoView.prototype.buildData = function() {
var model = this.getModel();
var content = model.getContent();
this.find('.todo-content').innerHTML = checkit.escapeHTML(content);
this.find('.check').checked = model.isDone();
aristocrat[model.isDone() ? 'addClass' : 'removeClass'](this.find('.todo'), 'done');
};
checkit.TodoView.prototype.update = function() {
this.buildData();
};
checkit.TodoView.prototype.showEdit = function() {
var input = this.find('.todo-input');
input.value = this.getModel().getContent();
aristocrat.addClass(this.find('.todo'), 'editing');
input.select();
};
checkit.TodoView.prototype.showDisplay = function() {
aristocrat.removeClass(this.find('.todo'), 'editing');
};
checkit.TodoView.prototype.getInputValue = function() {
return this.find('.todo-input').value;
};
checkit.TodoView.prototype.showToolTip = function() {
this.find('.ui-tooltip-top').style.display = 'block';
};
checkit.TodoView.prototype.hideToolTip = function() {
this.find('.ui-tooltip-top').style.display = 'none';
};
Parameters:
Name | Type | Argument | Description |
---|---|---|---|
model |
maria.Model |
<optional> |
|
controller |
maria.Controller |
<optional> |
|
document |
Document |
<optional> |
- Source:
- maria.js, line 2730
Extends
Members
-
<static> superConstructor
-
- Source:
- maria.js, line 2740
Properties:
Name Type Description maria.ElementView.superConstructor
Methods
-
<static> subclass()
-
A function that makes subclassing
maria.ElementView
more compact.The following example creates a
checkit.TodoView
constructor function equivalent to the more verbose example shown in the documentation formaria.ElementView
.maria.ElementView.subclass(checkit, 'TodoView', { uiActions: { 'click .check' : 'onClickCheck' , 'dblclick .todo-content': 'onDblclickDisplay', 'keyup .todo-input' : 'onKeyupInput' , 'keypress .todo-input' : 'onKeypressInput' , 'blur .todo-input' : 'onBlurInput' }, properties: { buildData: function() { var model = this.getModel(); var content = model.getContent(); this.find('.todo-content').innerHTML = checkit.escapeHTML(content); this.find('.check').checked = model.isDone(); aristocrat[model.isDone() ? 'addClass' : 'removeClass'](this.find('.todo'), 'done'); }, update: function() { this.buildData(); }, showEdit: function() { var input = this.find('.todo-input'); input.value = this.getModel().getContent(); aristocrat.addClass(this.find('.todo'), 'editing'); input.select(); }, showDisplay: function() { aristocrat.removeClass(this.find('.todo'), 'editing'); }, getInputValue: function() { return this.find('.todo-input').value; }, showToolTip: function() { this.find('.ui-tooltip-top').style.display = 'block'; }, hideToolTip: function() { this.find('.ui-tooltip-top').style.display = 'none'; } } });
This subclassing function implements options following the "convention over configuration" philosophy. The
checkit.TodoView
will, by convention, use thecheckit.TodoController
andcheckit.TodoTemplate
objects. All of these can be configured explicitly if these conventions do not match your view's needs.maria.ElementView.subclass(checkit, 'TodoView', { controllerConstructor: checkit.TodoController, template : checkit.TodoTemplate , uiActions: { ...
Alternately you can use late binding by supplying string names of objects in the application's namespace object (i.e. the checkit object in this example).
maria.ElementView.subclass(checkit, 'TodoView', { controllerConstructorName: 'TodoController', templateName : 'TodoTemplate' , uiActions: { ...
You can augment
uiActions
in your subclass by specifying the declarativemoreUIActions
property (instead of usinguiActions
.)checkit.TodoView.subclass(checkit, 'ReminderView', { moreUIActions: { 'click .reminder': 'onClickReminder' }, properties: { showReminder: function() { this.find('.todo-reminder').style.display = 'block'; }, hideReminder: function() { this.find('.todo-reminder').style.display = 'none'; } } });
The
ReminderView
will inherit the properties defined inuiActions
fromTodoView
and augment it withmoreUIActions
. The subclassing function will generate the equivalent of the following function.checkit.TodoView.prototype.getUIActions = function () { var uiActions = checkit.TodoView.superConstructor.prototype.getUIActions.call(this); uiActions['click .reminder'] = 'onClickReminder'; return uiActions; };
- Source:
- maria.js, line 3542
-
build() → {Element}
-
Builds the root DOM element for the view from the view's template returned by
getTemplate
, attaches event handlers to the root and its descendents as specified by the UI actions map returned bygetUIActions
, calls thebuildData
method to allow model values to be inserted into the root DOM element and its descendents, and callsbuildChildViews
. This construction of the root DOM element is lazy and only done when this method is called.- Source:
- maria.js, line 2810
Returns:
The root DOM Element of the view.
- Type
- Element
-
buildData()
-
Does nothing by default. To be overridden by subclasses.
The intended use of this method is to populate the built root DOM element and its descendents with model data.
- Source:
- maria.js, line 2874
-
buildTemplate()
-
Parses the HTML template string returned by
getTemplate
to create aDocumentFragment
. The first child of thatDocumentFragment
is set as the root element of this view. All other sibling elements of theDocumentFragment
are discarded.- Source:
- maria.js, line 2828
-
buildUIActions()
-
Attaches event handlers to the root and its descendents as specified by the UI actions map returned by
getUIActions
.- Source:
- maria.js, line 2848
-
find(selector) → {Element}
-
Find the first element in this view that matches the CSS
selector
. The view's root element can be the result.By default Maria uses the Grail library as its DOM query engine. This is to support older browsers that do not have
querySelector
. The Grail engine only a limited set of simple selectors..class tag tag.class #id
If your application only needs to work in newer browsers then you can create a Maria plugin to use
querySelector
. Consider if you want the root element to be returned if it matchesselector
.If your application needs to work in older browsers but you need more complex CSS
selector
strings then you can create a Maria plugin to use some libray other than Grail.Parameters:
Name Type Description selector
string A CSS selector.
- Source:
- maria.js, line 2962
Returns:
The first DOM element matching
selector
.- Type
- Element
-
findAll(selector) → {Array}
-
Find all the elements in this view that matches the CSS
selector
. The view's root element can be in the result set.See
find
for more details.Parameters:
Name Type Description selector
string A CSS selector.
- Source:
- maria.js, line 2978
Returns:
An array of the DOM elements matching
selector
.- Type
- Array
-
getContainerEl() → {Element}
-
See
buildChildViews
for more details.- Source:
- maria.js, line 2899
Returns:
The DOM Element to which child view's should be attached.
- Type
- Element
-
getController() → {maria.Controller}
-
If this view has not yet had its controller set then this method creates a controller and sets it as this view's controller.
- Inherited From:
- Source:
- maria.js, line 2487
Returns:
The controller object.
- Type
- maria.Controller
-
getDefaultController() → {maria.Controller}
-
Creates a new default controller for this view.
- Inherited From:
- Source:
- maria.js, line 2473
Returns:
The controller object.
- Type
- maria.Controller
-
getDefaultControllerConstructor() → {function}
-
Returns a controller constructor function to be used to create a controller for this view.
- Inherited From:
- Source:
- maria.js, line 2462
Returns:
The controller constructor function.
- Type
- function
-
getDocument() → {Document}
-
Returns the web page document for the view. This document is the one used to create elements to be added to the page, for example.
- Source:
- maria.js, line 2754
Returns:
The document object.
- Type
- Document
-
getModel() → {maria.Model}
-
Returns the current model object of this view.
- Inherited From:
- Source:
- maria.js, line 2439
Returns:
The model object.
- Type
- maria.Model
-
getModelActions() → {Object}
-
When the model is set for this view, the view will automatically observe the events which are keys of the returned object. The values for each key is the view's handler method to be called when the corresponding event is dispatched on the model.
By default, a view will observe the model for
change
events and handle those events with the view'supdate
method.You can override this method but, beware, doing so can lead to the dark side.
- Inherited From:
- Source:
- maria.js, line 2521
Returns:
The map of model events and view handers.
- Type
- Object
-
getTemplate() → {string}
-
Returns the template for this view used during the build process.
- Source:
- maria.js, line 2780
Returns:
The template HTML string.
- Type
- string
-
getUIActions() → {Object}
-
The UI actions object maps a UI action like a click on a button with a handler method name. By default, the handler will be called on the controller of the view.
- Source:
- maria.js, line 2793
Returns:
The UI actions map.
- Type
- Object
-
insertBefore(newChild, oldChild)
-
Add a new child view before an existing child view. If the
oldChild
parameter is not supplied then thenewChild
is appened as the last child.Parameters:
Name Type Description newChild
maria.ElementView The child to be inserted.
oldChild
maria.ElementView The child to insert before.
- Source:
- maria.js, line 2913
-
removeChild(oldChild)
-
Remove an existing child view.
Parameters:
Name Type Description oldChild
maria.ElementView The child to be removed.
- Source:
- maria.js, line 2927
-
setController(The)
-
Set the current controller for this view.
Parameters:
Name Type Description The
maria.Controller controller object.
- Inherited From:
- Source:
- maria.js, line 2501
-
setDocument()
-
Set the web page document for the view. This document is the one used to create elements to be added to the page, for example.
- Source:
- maria.js, line 2765
-
setModel(model)
-
Set the current model object of this view.
Parameters:
Name Type Description model
maria.Model The model object.
- Inherited From:
- Source:
- maria.js, line 2450
-
update(event)
-
By default, a view will observe its model for
change
events. When achange
event is dispatched on the model then thisupdate
method is the handler. (The "change" and "update" names are inherited directly from Smalltalk implementations.)To be overridden by subclasses.
Parameters:
Name Type Description event
object The event object.
- Inherited From:
- Source:
- maria.js, line 2428