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.
16 * Represents an HTML fragment template. Templates may be {@link #compile precompiled} for greater performance.
18 * An instance of this class may be created by passing to the constructor either a single argument, or multiple
21 * # Single argument: String/Array
23 * The single argument may be either a String or an Array:
27 * var t = new Ext.Template("<div>Hello {0}.</div>");
28 * t.{@link #append}('some-element', ['foo']);
32 * An Array will be combined with `join('')`.
34 * var t = new Ext.Template([
35 * '<div name="{id}">',
36 * '<span class="{cls}">{name:trim} {value:ellipsis(10)}</span>',
39 * t.{@link #compile}();
40 * t.{@link #append}('some-element', {id: 'myid', cls: 'myclass', name: 'foo', value: 'bar'});
42 * # Multiple arguments: String, Object, Array, ...
44 * Multiple arguments will be combined with `join('')`.
46 * var t = new Ext.Template(
47 * '<div name="{id}">',
48 * '<span class="{cls}">{name} {value}</span>',
50 * // a configuration object:
52 * compiled: true, // {@link #compile} immediately
58 * - For a list of available format functions, see {@link Ext.util.Format}.
59 * - `disableFormats` reduces `{@link #apply}` time when no formatting is required.
61 Ext.define('Ext.Template', {
63 /* Begin Definitions */
65 requires: ['Ext.DomHelper', 'Ext.util.Format'],
69 * Creates a template from the passed element's value (_display:none_ textarea, preferred) or innerHTML.
70 * @param {String/HTMLElement} el A DOM element or its id
71 * @param {Object} config (optional) Config object
72 * @return {Ext.Template} The created template
76 from: function(el, config) {
78 return new this(el.value || el.innerHTML, config || '');
85 * Creates new template.
87 * @param {String...} html List of strings to be concatenated into template.
88 * Alternatively an array of strings can be given, but then no config object may be passed.
89 * @param {Object} config (optional) Config object
91 constructor: function(html) {
99 me.initialConfig = {};
102 for (; i < length; i++) {
104 if (typeof value == 'object') {
105 Ext.apply(me.initialConfig, value);
106 Ext.apply(me, value);
111 html = buffer.join('');
113 if (Ext.isArray(html)) {
114 buffer.push(html.join(''));
121 me.html = buffer.join('');
131 * @cfg {Boolean} compiled
132 * True to immediately compile the template. Defaults to false.
136 * @cfg {Boolean} disableFormats
137 * True to disable format functions in the template. If the template doesn't contain
138 * format functions, setting disableFormats to true will reduce apply time. Defaults to false.
140 disableFormats: false,
142 re: /\{([\w\-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
145 * Returns an HTML fragment of this template with the specified values applied.
147 * @param {Object/Array} values The template values. Can be an array if your params are numeric:
149 * var tpl = new Ext.Template('Name: {0}, Age: {1}');
150 * tpl.applyTemplate(['John', 25]);
154 * var tpl = new Ext.Template('Name: {name}, Age: {age}');
155 * tpl.applyTemplate({name: 'John', age: 25});
157 * @return {String} The HTML fragment
159 applyTemplate: function(values) {
161 useFormat = me.disableFormats !== true,
162 fm = Ext.util.Format,
166 return me.compiled(values);
168 function fn(m, name, format, args) {
169 if (format && useFormat) {
171 args = [values[name]].concat(Ext.functionFactory('return ['+ args +'];')());
173 args = [values[name]];
175 if (format.substr(0, 5) == "this.") {
176 return tpl[format.substr(5)].apply(tpl, args);
179 return fm[format].apply(fm, args);
183 return values[name] !== undefined ? values[name] : "";
186 return me.html.replace(me.re, fn);
190 * Sets the HTML used as the template and optionally compiles it.
191 * @param {String} html
192 * @param {Boolean} compile (optional) True to compile the template.
193 * @return {Ext.Template} this
195 set: function(html, compile) {
199 return compile ? me.compile() : me;
203 compileBRe: /(\r\n|\n)/g,
207 * Compiles the template into an internal function, eliminating the RegEx overhead.
208 * @return {Ext.Template} this
210 compile: function() {
212 fm = Ext.util.Format,
213 useFormat = me.disableFormats !== true,
216 function fn(m, name, format, args) {
217 if (format && useFormat) {
218 args = args ? ',' + args: "";
219 if (format.substr(0, 5) != "this.") {
220 format = "fm." + format + '(';
223 format = 'this.' + format.substr(5) + '(';
228 format = "(values['" + name + "'] == undefined ? '' : ";
230 return "'," + format + "values['" + name + "']" + args + ") ,'";
233 bodyReturn = me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn);
234 body = "this.compiled = function(values){ return ['" + bodyReturn + "'].join('');};";
240 * Applies the supplied values to the template and inserts the new node(s) as the first child of el.
242 * @param {String/HTMLElement/Ext.Element} el The context element
243 * @param {Object/Array} values The template values. See {@link #applyTemplate} for details.
244 * @param {Boolean} returnElement (optional) true to return a Ext.Element.
245 * @return {HTMLElement/Ext.Element} The new node or Element
247 insertFirst: function(el, values, returnElement) {
248 return this.doInsert('afterBegin', el, values, returnElement);
252 * Applies the supplied values to the template and inserts the new node(s) before el.
254 * @param {String/HTMLElement/Ext.Element} el The context element
255 * @param {Object/Array} values The template values. See {@link #applyTemplate} for details.
256 * @param {Boolean} returnElement (optional) true to return a Ext.Element.
257 * @return {HTMLElement/Ext.Element} The new node or Element
259 insertBefore: function(el, values, returnElement) {
260 return this.doInsert('beforeBegin', el, values, returnElement);
264 * Applies the supplied values to the template and inserts the new node(s) after el.
266 * @param {String/HTMLElement/Ext.Element} el The context element
267 * @param {Object/Array} values The template values. See {@link #applyTemplate} for details.
268 * @param {Boolean} returnElement (optional) true to return a Ext.Element.
269 * @return {HTMLElement/Ext.Element} The new node or Element
271 insertAfter: function(el, values, returnElement) {
272 return this.doInsert('afterEnd', el, values, returnElement);
276 * Applies the supplied `values` to the template and appends the new node(s) to the specified `el`.
278 * For example usage see {@link Ext.Template Ext.Template class docs}.
280 * @param {String/HTMLElement/Ext.Element} el The context element
281 * @param {Object/Array} values The template values. See {@link #applyTemplate} for details.
282 * @param {Boolean} returnElement (optional) true to return an Ext.Element.
283 * @return {HTMLElement/Ext.Element} The new node or Element
285 append: function(el, values, returnElement) {
286 return this.doInsert('beforeEnd', el, values, returnElement);
289 doInsert: function(where, el, values, returnEl) {
291 var newNode = Ext.DomHelper.insertHtml(where, el, this.applyTemplate(values));
292 return returnEl ? Ext.get(newNode, true) : newNode;
296 * Applies the supplied values to the template and overwrites the content of el with the new node(s).
298 * @param {String/HTMLElement/Ext.Element} el The context element
299 * @param {Object/Array} values The template values. See {@link #applyTemplate} for details.
300 * @param {Boolean} returnElement (optional) true to return a Ext.Element.
301 * @return {HTMLElement/Ext.Element} The new node or Element
303 overwrite: function(el, values, returnElement) {
305 el.innerHTML = this.applyTemplate(values);
306 return returnElement ? Ext.get(el.firstChild, true) : el.firstChild;
312 * @member Ext.Template
313 * Alias for {@link #applyTemplate}.
314 * @alias Ext.Template#applyTemplate
316 this.createAlias('apply', 'applyTemplate');