3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
17 * <p>Represents an HTML fragment template. Templates may be {@link #compile precompiled}
18 * for greater performance.</p>
19 * An instance of this class may be created by passing to the constructor either
20 * a single argument, or multiple arguments:
21 * <div class="mdetail-params"><ul>
22 * <li><b>single argument</b> : String/Array
23 * <div class="sub-desc">
24 * The single argument may be either a String or an Array:<ul>
25 * <li><tt>String</tt> : </li><pre><code>
26 var t = new Ext.Template("<div>Hello {0}.</div>");
27 t.{@link #append}('some-element', ['foo']);
29 * <li><tt>Array</tt> : </li>
30 * An Array will be combined with <code>join('')</code>.
32 var t = new Ext.Template([
33 '<div name="{id}">',
34 '<span class="{cls}">{name:trim} {value:ellipsis(10)}</span>',
38 t.{@link #append}('some-element', {id: 'myid', cls: 'myclass', name: 'foo', value: 'bar'});
41 * <li><b>multiple arguments</b> : String, Object, Array, ...
42 * <div class="sub-desc">
43 * Multiple arguments will be combined with <code>join('')</code>.
45 var t = new Ext.Template(
46 '<div name="{id}">',
47 '<span class="{cls}">{name} {value}</span>',
49 // a configuration object:
51 compiled: true, // {@link #compile} immediately
55 * <p><b>Notes</b>:</p>
56 * <div class="mdetail-params"><ul>
57 * <li>For a list of available format functions, see {@link Ext.util.Format}.</li>
58 * <li><code>disableFormats</code> reduces <code>{@link #apply}</code> time
59 * when no formatting is required.</li>
63 * @param {Mixed} config
66 Ext.define('Ext.Template', {
68 /* Begin Definitions */
70 requires: ['Ext.core.DomHelper', 'Ext.util.Format'],
74 * Creates a template from the passed element's value (<i>display:none</i> textarea, preferred) or innerHTML.
75 * @param {String/HTMLElement} el A DOM element or its id
76 * @param {Object} config A configuration object
77 * @return {Ext.Template} The created template
80 from: function(el, config) {
82 return new this(el.value || el.innerHTML, config || '');
88 constructor: function(html) {
96 me.initialConfig = {};
99 for (; i < length; i++) {
101 if (typeof value == 'object') {
102 Ext.apply(me.initialConfig, value);
103 Ext.apply(me, value);
108 html = buffer.join('');
110 if (Ext.isArray(html)) {
111 buffer.push(html.join(''));
118 me.html = buffer.join('');
126 * @cfg {Boolean} disableFormats true to disable format functions in the template. If the template doesn't contain format functions, setting
127 * disableFormats to true will reduce apply time (defaults to false)
129 disableFormats: false,
131 re: /\{([\w\-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
133 * Returns an HTML fragment of this template with the specified values applied.
134 * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
135 * @return {String} The HTML fragment
137 applyTemplate: function(values) {
139 useFormat = me.disableFormats !== true,
140 fm = Ext.util.Format,
144 return me.compiled(values);
146 function fn(m, name, format, args) {
147 if (format && useFormat) {
149 args = [values[name]].concat(Ext.functionFactory('return ['+ args +'];')());
151 args = [values[name]];
153 if (format.substr(0, 5) == "this.") {
154 return tpl[format.substr(5)].apply(tpl, args);
157 return fm[format].apply(fm, args);
161 return values[name] !== undefined ? values[name] : "";
164 return me.html.replace(me.re, fn);
168 * Sets the HTML used as the template and optionally compiles it.
169 * @param {String} html
170 * @param {Boolean} compile (optional) True to compile the template (defaults to undefined)
171 * @return {Ext.Template} this
173 set: function(html, compile) {
177 return compile ? me.compile() : me;
181 compileBRe: /(\r\n|\n)/g,
184 * Compiles the template into an internal function, eliminating the RegEx overhead.
185 * @return {Ext.Template} this
187 compile: function() {
189 fm = Ext.util.Format,
190 useFormat = me.disableFormats !== true,
193 function fn(m, name, format, args) {
194 if (format && useFormat) {
195 args = args ? ',' + args: "";
196 if (format.substr(0, 5) != "this.") {
197 format = "fm." + format + '(';
200 format = 'this.' + format.substr(5) + '(';
205 format = "(values['" + name + "'] == undefined ? '' : ";
207 return "'," + format + "values['" + name + "']" + args + ") ,'";
210 bodyReturn = me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn);
211 body = "this.compiled = function(values){ return ['" + bodyReturn + "'].join('');};";
217 * Applies the supplied values to the template and inserts the new node(s) as the first child of el.
218 * @param {Mixed} el The context element
219 * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
220 * @param {Boolean} returnElement (optional) true to return a Ext.core.Element (defaults to undefined)
221 * @return {HTMLElement/Ext.core.Element} The new node or Element
223 insertFirst: function(el, values, returnElement) {
224 return this.doInsert('afterBegin', el, values, returnElement);
228 * Applies the supplied values to the template and inserts the new node(s) before el.
229 * @param {Mixed} el The context element
230 * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
231 * @param {Boolean} returnElement (optional) true to return a Ext.core.Element (defaults to undefined)
232 * @return {HTMLElement/Ext.core.Element} The new node or Element
234 insertBefore: function(el, values, returnElement) {
235 return this.doInsert('beforeBegin', el, values, returnElement);
239 * Applies the supplied values to the template and inserts the new node(s) after el.
240 * @param {Mixed} el The context element
241 * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
242 * @param {Boolean} returnElement (optional) true to return a Ext.core.Element (defaults to undefined)
243 * @return {HTMLElement/Ext.core.Element} The new node or Element
245 insertAfter: function(el, values, returnElement) {
246 return this.doInsert('afterEnd', el, values, returnElement);
250 * Applies the supplied <code>values</code> to the template and appends
251 * the new node(s) to the specified <code>el</code>.
252 * <p>For example usage {@link #Template see the constructor}.</p>
253 * @param {Mixed} el The context element
254 * @param {Object/Array} values
255 * The template values. Can be an array if the params are numeric (i.e. <code>{0}</code>)
256 * or an object (i.e. <code>{foo: 'bar'}</code>).
257 * @param {Boolean} returnElement (optional) true to return an Ext.core.Element (defaults to undefined)
258 * @return {HTMLElement/Ext.core.Element} The new node or Element
260 append: function(el, values, returnElement) {
261 return this.doInsert('beforeEnd', el, values, returnElement);
264 doInsert: function(where, el, values, returnEl) {
266 var newNode = Ext.core.DomHelper.insertHtml(where, el, this.applyTemplate(values));
267 return returnEl ? Ext.get(newNode, true) : newNode;
271 * Applies the supplied values to the template and overwrites the content of el with the new node(s).
272 * @param {Mixed} el The context element
273 * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
274 * @param {Boolean} returnElement (optional) true to return a Ext.core.Element (defaults to undefined)
275 * @return {HTMLElement/Ext.core.Element} The new node or Element
277 overwrite: function(el, values, returnElement) {
279 el.innerHTML = this.applyTemplate(values);
280 return returnElement ? Ext.get(el.firstChild, true) : el.firstChild;
285 * Alias for {@link #applyTemplate}
286 * Returns an HTML fragment of this template with the specified <code>values</code> applied.
287 * @param {Object/Array} values
288 * The template values. Can be an array if the params are numeric (i.e. <code>{0}</code>)
289 * or an object (i.e. <code>{foo: 'bar'}</code>).
290 * @return {String} The HTML fragment
291 * @member Ext.Template
294 this.createAlias('apply', 'applyTemplate');