Dashboard sipadu mbip
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /*
  2. Copyright (c) 2010, Yahoo! Inc. All rights reserved.
  3. Code licensed under the BSD License:
  4. http://developer.yahoo.com/yui/license.html
  5. version: 3.4.0
  6. build: nightly
  7. */
  8. YUI.add('view', function(Y) {
  9. /**
  10. Represents a logical piece of an application's user interface, and provides a
  11. lightweight, overridable API for rendering content and handling delegated DOM
  12. events on a container element.
  13. @submodule view
  14. @since 3.4.0
  15. **/
  16. /**
  17. Represents a logical piece of an application's user interface, and provides a
  18. lightweight, overridable API for rendering content and handling delegated DOM
  19. events on a container element.
  20. The View class imposes little structure and provides only minimal functionality
  21. of its own: it's basically just an overridable API interface that helps you
  22. implement custom views.
  23. @class View
  24. @constructor
  25. @extends Base
  26. @since 3.4.0
  27. **/
  28. function View() {
  29. View.superclass.constructor.apply(this, arguments);
  30. }
  31. Y.View = Y.extend(View, Y.Base, {
  32. // -- Public Properties ----------------------------------------------------
  33. /**
  34. Container node into which this view's content will be rendered.
  35. The container node serves as the host for all DOM events attached by the
  36. view. Delegation is used to handle events on children of the container,
  37. allowing the container's contents to be re-rendered at any time without
  38. losing event subscriptions.
  39. The default container is a simple `<div>`, but you can override this in a
  40. subclass, or by passing in a custom `container` config value at
  41. instantiation time.
  42. When `container` is overridden by a subclass or passed as a config option at
  43. instantiation time, it may be provided as an HTML string, a DOM element, or
  44. a `Y.Node` instance. During initialization, this view's `create()` method
  45. will be called to convert the container into a `Y.Node` instance if it isn't
  46. one already.
  47. The container is not added to the page automatically. This allows you to
  48. have full control over how and when your view is actually rendered to the
  49. page.
  50. @property container
  51. @type HTMLElement|Node|String
  52. @default "<div/>"
  53. **/
  54. container: '<div/>',
  55. /**
  56. Hash of CSS selectors mapped to events to delegate to elements matching
  57. those selectors.
  58. CSS selectors are relative to the `container` element. Events are attached
  59. to the container, and delegation is used so that subscribers are only
  60. notified of events that occur on elements inside the container that match
  61. the specified selectors. This allows the container's contents to be
  62. re-rendered as needed without losing event subscriptions.
  63. Event handlers can be specified either as functions or as strings that map
  64. to function names on this view instance or its prototype.
  65. The `this` object in event handlers will refer to this view instance. If
  66. you'd prefer `this` to be something else, use `Y.bind()` to bind a custom
  67. `this` object.
  68. @example
  69. var view = new Y.View({
  70. events: {
  71. // Call `this.toggle()` whenever the element with the id
  72. // "toggle-button" is clicked.
  73. '#toggle-button': {click: 'toggle'},
  74. // Call `this.hoverOn()` when the mouse moves over any element
  75. // with the "hoverable" class, and `this.hoverOff()` when the
  76. // mouse moves out of any element with the "hoverable" class.
  77. '.hoverable': {
  78. mouseover: 'hoverOn',
  79. mouseout : 'hoverOff'
  80. }
  81. }
  82. });
  83. @property events
  84. @type Object
  85. @default {}
  86. **/
  87. events: {},
  88. /**
  89. Model instance associated with this view instance.
  90. This is entirely optional. There's no requirement that views be associated
  91. with models, but if you do intend to associate your view with a model, then
  92. specifying that model instance at instantiation time will cause a reference
  93. to be stored here for convenience.
  94. @property model
  95. @type Model
  96. @default undefined
  97. **/
  98. /**
  99. ModelList instance associated with this view instance.
  100. This is entirely optional. There's no requirement that views be associated
  101. with model lists, but if you do intend to associate your view with a model
  102. list, then specifying that list instance at instantiation time will cause a
  103. reference to be stored here for convenience.
  104. @property modelList
  105. @type ModelList
  106. @default undefined
  107. **/
  108. /**
  109. Template for this view.
  110. This is a convenience property that has no default behavior of its own. It's
  111. only provided as a convention to allow you to store whatever you consider to
  112. be a template, whether that's an HTML string, a `Y.Node` instance, a
  113. Mustache template, or anything else your little heart desires.
  114. How this template gets used is entirely up to you and your custom `render()`
  115. method.
  116. @property template
  117. @type any
  118. @default ''
  119. **/
  120. template: '',
  121. // -- Lifecycle Methods ----------------------------------------------------
  122. initializer: function (config) {
  123. config || (config = {});
  124. this.container = this.create(config.container || this.container);
  125. // Use config properties if present; otherwise default to prototype
  126. // properties.
  127. config.model && (this.model = config.model);
  128. config.modelList && (this.modelList = config.modelList);
  129. config.template && (this.template = config.template);
  130. // Merge events from the config into events in `this.events`, then
  131. // attach the events to the container node.
  132. this.events = config.events ?
  133. Y.merge(this.events, config.events) : this.events;
  134. this.attachEvents(this.events);
  135. },
  136. destructor: function () {
  137. // Remove the container from the DOM and purge all event listeners.
  138. this.container && this.container.remove(true);
  139. },
  140. // -- Public Methods -------------------------------------------------------
  141. /**
  142. Attaches delegated event handlers to this view's `container` element. This
  143. method is called internally to subscribe to events configured in the
  144. `events` property or config attribute when the view is initialized.
  145. You may override this method to customize the event attaching logic.
  146. @method attachEvents
  147. @param {Object} events Hash of events to attach. See the docs for the
  148. `events` property for details on the format.
  149. **/
  150. attachEvents: function (events) {
  151. var container = this.container,
  152. owns = Y.Object.owns,
  153. handler, handlers, name, selector;
  154. for (selector in events) {
  155. if (!owns(events, selector)) { continue; }
  156. handlers = events[selector];
  157. for (name in handlers) {
  158. if (!owns(handlers, name)) { continue; }
  159. handler = handlers[name];
  160. if (typeof handler === 'string') {
  161. handler = this[handler];
  162. }
  163. container.delegate(name, handler, selector, this);
  164. }
  165. }
  166. },
  167. /**
  168. Creates and returns this view's `container` node from the specified HTML
  169. string, DOM element, or existing `Y.Node` instance. This method is called
  170. internally when the view is initialized.
  171. By default, the created node is _not_ added to the DOM automatically.
  172. You may override this method to customize how the container node is created
  173. (such as by rendering it from a template). Your method should return a
  174. `Y.Node` instance.
  175. @method create
  176. @param {HTMLElement|Node|String} container HTML string, DOM element, or
  177. `Y.Node` instance to use as the container node.
  178. @return {Node} Node instance of the created container node.
  179. **/
  180. create: function (container) {
  181. return typeof container === 'string' ?
  182. Y.Node.create(container) : Y.one(container);
  183. },
  184. /**
  185. Removes this view's `container` element from the DOM (if it's in the DOM),
  186. but doesn't destroy it or any event listeners attached to it.
  187. @method remove
  188. @chainable
  189. **/
  190. remove: function () {
  191. this.container && this.container.remove();
  192. return this;
  193. },
  194. /**
  195. Renders the view.
  196. This method is a noop by default. Override it in your subclass to provide a
  197. custom implementation that renders this view's content and appends it to the
  198. `container` element. Ideally your `render` method should also return `this`
  199. as the end to allow chaining, but that's up to you.
  200. Since there's no default renderer, you're free to render your view however
  201. you see fit, whether that means manipulating the DOM directly, dumping
  202. strings into `innerHTML`, or using a template language of some kind.
  203. For basic templating needs, `Y.Node.create()` and `Y.Lang.sub()` may
  204. suffice, but there are no restrictions on what tools or techniques you can
  205. use to render your view. All you need To Do is append something to the
  206. `container` element at some point, and optionally append the `container`
  207. to the DOM if it's not there already.
  208. @method render
  209. @chainable
  210. **/
  211. render: function () {
  212. return this;
  213. }
  214. }, {
  215. NAME: 'view'
  216. });
  217. }, '3.4.0' ,{requires:['base-build', 'node-event-delegate']});