123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390 |
- <!DOCTYPE html>
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>The source code</title>
- <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
- <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
- <style type="text/css">
- .highlight { display: block; background-color: #ddd; }
- </style>
- <script type="text/javascript">
- function highlight() {
- document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
- }
- </script>
- </head>
- <body onload="prettyPrint(); highlight();">
- <pre class="prettyprint lang-js"><span id='Ext-XTemplate'>/**
- </span> * A template class that supports advanced functionality like:
- *
- * - Autofilling arrays using templates and sub-templates
- * - Conditional processing with basic comparison operators
- * - Basic math function support
- * - Execute arbitrary inline code with special built-in template variables
- * - Custom member functions
- * - Many special tags and built-in operators that aren't defined as part of the API, but are supported in the templates that can be created
- *
- * XTemplate provides the templating mechanism built into {@link Ext.view.View}.
- *
- * The {@link Ext.Template} describes the acceptable parameters to pass to the constructor. The following examples
- * demonstrate all of the supported features.
- *
- * # Sample Data
- *
- * This is the data object used for reference in each code example:
- *
- * var data = {
- * name: 'Don Griffin',
- * title: 'Senior Technomage',
- * company: 'Sencha Inc.',
- * drinks: ['Coffee', 'Water', 'More Coffee'],
- * kids: [
- * { name: 'Aubrey', age: 17 },
- * { name: 'Joshua', age: 13 },
- * { name: 'Cale', age: 10 },
- * { name: 'Nikol', age: 5 },
- * { name: 'Solomon', age: 0 }
- * ]
- * };
- *
- * # Auto filling of arrays
- *
- * The **tpl** tag and the **for** operator are used to process the provided data object:
- *
- * - If the value specified in for is an array, it will auto-fill, repeating the template block inside the tpl
- * tag for each item in the array.
- * - If for="." is specified, the data object provided is examined.
- * - While processing an array, the special variable {#} will provide the current array index + 1 (starts at 1, not 0).
- *
- * Examples:
- *
- * <tpl for=".">...</tpl> // loop through array at root node
- * <tpl for="foo">...</tpl> // loop through array at foo node
- * <tpl for="foo.bar">...</tpl> // loop through array at foo.bar node
- *
- * Using the sample data above:
- *
- * var tpl = new Ext.XTemplate(
- * '<p>Kids: ',
- * '<tpl for=".">', // process the data.kids node
- * '<p>{#}. {name}</p>', // use current array index to autonumber
- * '</tpl></p>'
- * );
- * tpl.overwrite(panel.body, data.kids); // pass the kids property of the data object
- *
- * An example illustrating how the **for** property can be leveraged to access specified members of the provided data
- * object to populate the template:
- *
- * var tpl = new Ext.XTemplate(
- * '<p>Name: {name}</p>',
- * '<p>Title: {title}</p>',
- * '<p>Company: {company}</p>',
- * '<p>Kids: ',
- * '<tpl for="kids">', // interrogate the kids property within the data
- * '<p>{name}</p>',
- * '</tpl></p>'
- * );
- * tpl.overwrite(panel.body, data); // pass the root node of the data object
- *
- * Flat arrays that contain values (and not objects) can be auto-rendered using the special **`{.}`** variable inside a
- * loop. This variable will represent the value of the array at the current index:
- *
- * var tpl = new Ext.XTemplate(
- * '<p>{name}\'s favorite beverages:</p>',
- * '<tpl for="drinks">',
- * '<div> - {.}</div>',
- * '</tpl>'
- * );
- * tpl.overwrite(panel.body, data);
- *
- * When processing a sub-template, for example while looping through a child array, you can access the parent object's
- * members via the **parent** object:
- *
- * var tpl = new Ext.XTemplate(
- * '<p>Name: {name}</p>',
- * '<p>Kids: ',
- * '<tpl for="kids">',
- * '<tpl if="age &gt; 1">',
- * '<p>{name}</p>',
- * '<p>Dad: {parent.name}</p>',
- * '</tpl>',
- * '</tpl></p>'
- * );
- * tpl.overwrite(panel.body, data);
- *
- * # Conditional processing with basic comparison operators
- *
- * The **tpl** tag and the **if** operator are used to provide conditional checks for deciding whether or not to render
- * specific parts of the template.
- *
- * Using the sample data above:
- *
- * var tpl = new Ext.XTemplate(
- * '<p>Name: {name}</p>',
- * '<p>Kids: ',
- * '<tpl for="kids">',
- * '<tpl if="age &gt; 1">',
- * '<p>{name}</p>',
- * '</tpl>',
- * '</tpl></p>'
- * );
- * tpl.overwrite(panel.body, data);
- *
- * More advanced conditionals are also supported:
- *
- * var tpl = new Ext.XTemplate(
- * '<p>Name: {name}</p>',
- * '<p>Kids: ',
- * '<tpl for="kids">',
- * '<p>{name} is a ',
- * '<tpl if="age &gt;= 13">',
- * '<p>teenager</p>',
- * '<tpl elseif="age &gt;= 2">',
- * '<p>kid</p>',
- * '<tpl else>',
- * '<p>baby</p>',
- * '</tpl>',
- * '</tpl></p>'
- * );
- *
- * var tpl = new Ext.XTemplate(
- * '<p>Name: {name}</p>',
- * '<p>Kids: ',
- * '<tpl for="kids">',
- * '<p>{name} is a ',
- * '<tpl switch="name">',
- * '<tpl case="Aubrey" case="Nikol">',
- * '<p>girl</p>',
- * '<tpl default>',
- * '<p>boy</p>',
- * '</tpl>',
- * '</tpl></p>'
- * );
- *
- * A `break` is implied between each case and default, however, multiple cases can be listed
- * in a single &lt;tpl&gt; tag.
- *
- * # Using double quotes
- *
- * Examples:
- *
- * var tpl = new Ext.XTemplate(
- * "<tpl if='age &gt; 1 && age &lt; 10'>Child</tpl>",
- * "<tpl if='age &gt;= 10 && age &lt; 18'>Teenager</tpl>",
- * "<tpl if='this.isGirl(name)'>...</tpl>",
- * '<tpl if="id == \'download\'">...</tpl>',
- * "<tpl if='needsIcon'><img src='{icon}' class='{iconCls}'/></tpl>",
- * "<tpl if='name == \"Don\"'>Hello</tpl>"
- * );
- *
- * # Basic math support
- *
- * The following basic math operators may be applied directly on numeric data values:
- *
- * + - * /
- *
- * For example:
- *
- * var tpl = new Ext.XTemplate(
- * '<p>Name: {name}</p>',
- * '<p>Kids: ',
- * '<tpl for="kids">',
- * '<tpl if="age &gt; 1">', // <-- Note that the > is encoded
- * '<p>{#}: {name}</p>', // <-- Auto-number each item
- * '<p>In 5 Years: {age+5}</p>', // <-- Basic math
- * '<p>Dad: {parent.name}</p>',
- * '</tpl>',
- * '</tpl></p>'
- * );
- * tpl.overwrite(panel.body, data);
- *
- * # Execute arbitrary inline code with special built-in template variables
- *
- * Anything between `{[ ... ]}` is considered code to be executed in the scope of the template.
- * The expression is evaluated and the result is included in the generated result. There are
- * some special variables available in that code:
- *
- * - **out**: The output array into which the template is being appended (using `push` to later
- * `join`).
- * - **values**: The values in the current scope. If you are using scope changing sub-templates,
- * you can change what values is.
- * - **parent**: The scope (values) of the ancestor template.
- * - **xindex**: If you are in a looping template, the index of the loop you are in (1-based).
- * - **xcount**: If you are in a looping template, the total length of the array you are looping.
- *
- * This example demonstrates basic row striping using an inline code block and the xindex variable:
- *
- * var tpl = new Ext.XTemplate(
- * '<p>Name: {name}</p>',
- * '<p>Company: {[values.company.toUpperCase() + ", " + values.title]}</p>',
- * '<p>Kids: ',
- * '<tpl for="kids">',
- * '<div class="{[xindex % 2 === 0 ? "even" : "odd"]}">',
- * '{name}',
- * '</div>',
- * '</tpl></p>'
- * );
- *
- * Any code contained in "verbatim" blocks (using "{% ... %}") will be inserted directly in
- * the generated code for the template. These blocks are not included in the output. This
- * can be used for simple things like break/continue in a loop, or control structures or
- * method calls (when they don't produce output). The `this` references the template instance.
- *
- * var tpl = new Ext.XTemplate(
- * '<p>Name: {name}</p>',
- * '<p>Company: {[values.company.toUpperCase() + ", " + values.title]}</p>',
- * '<p>Kids: ',
- * '<tpl for="kids">',
- * '{% if (xindex % 2 === 0) continue; %}',
- * '{name}',
- * '{% if (xindex > 100) break; %}',
- * '</div>',
- * '</tpl></p>'
- * );
- *
- * # Template member functions
- *
- * One or more member functions can be specified in a configuration object passed into the XTemplate constructor for
- * more complex processing:
- *
- * var tpl = new Ext.XTemplate(
- * '<p>Name: {name}</p>',
- * '<p>Kids: ',
- * '<tpl for="kids">',
- * '<tpl if="this.isGirl(name)">',
- * '<p>Girl: {name} - {age}</p>',
- * '<tpl else>',
- * '<p>Boy: {name} - {age}</p>',
- * '</tpl>',
- * '<tpl if="this.isBaby(age)">',
- * '<p>{name} is a baby!</p>',
- * '</tpl>',
- * '</tpl></p>',
- * {
- * // XTemplate configuration:
- * disableFormats: true,
- * // member functions:
- * isGirl: function(name){
- * return name == 'Aubrey' || name == 'Nikol';
- * },
- * isBaby: function(age){
- * return age < 1;
- * }
- * }
- * );
- * tpl.overwrite(panel.body, data);
- */
- Ext.define('Ext.XTemplate', {
- extend: 'Ext.Template',
- requires: 'Ext.XTemplateCompiler',
- <span id='Ext-XTemplate-property-emptyObj'> /**
- </span> * @private
- */
- emptyObj: {},
- <span id='Ext-XTemplate-cfg-compiled'> /**
- </span> * @cfg {Boolean} compiled
- * Only applies to {@link Ext.Template}, XTemplates are compiled automatically on the
- * first call to {@link #apply} or {@link #applyOut}.
- */
- <span id='Ext-XTemplate-cfg-definitions'> /**
- </span> * @cfg {String/Array} definitions
- * Optional. A statement, or array of statements which set up `var`s which may then
- * be accessed within the scope of the generated function.
- */
- apply: function(values, parent) {
- return this.applyOut(values, [], parent).join('');
- },
- applyOut: function(values, out, parent) {
- var me = this,
- compiler;
- if (!me.fn) {
- compiler = new Ext.XTemplateCompiler({
- useFormat: me.disableFormats !== true,
- definitions: me.definitions
- });
- me.fn = compiler.compile(me.html);
- }
- try {
- me.fn.call(me, out, values, parent || me.emptyObj, 1, 1);
- } catch (e) {
- //<debug>
- Ext.log('Error: ' + e.message);
- //</debug>
- }
- return out;
- },
- <span id='Ext-XTemplate-method-compile'> /**
- </span> * Does nothing. XTemplates are compiled automatically, so this function simply returns this.
- * @return {Ext.XTemplate} this
- */
- compile: function() {
- return this;
- },
- statics: {
- <span id='Ext-XTemplate-method-getTpl'> /**
- </span> * Gets an `XTemplate` from an object (an instance of an {@link Ext#define}'d class).
- * Many times, templates are configured high in the class hierarchy and are to be
- * shared by all classes that derive from that base. To further complicate matters,
- * these templates are seldom actual instances but are rather configurations. For
- * example:
- *
- * Ext.define('MyApp.Class', {
- * someTpl: [
- * 'tpl text here'
- * ]
- * });
- *
- * The goal being to share that template definition with all instances and even
- * instances of derived classes, until `someTpl` is overridden. This method will
- * "upgrade" these configurations to be real `XTemplate` instances *in place* (to
- * avoid creating one instance per object).
- *
- * @param {Object} instance The object from which to get the `XTemplate` (must be
- * an instance of an {@link Ext#define}'d class).
- * @param {String} name The name of the property by which to get the `XTemplate`.
- * @return {Ext.XTemplate} The `XTemplate` instance or null if not found.
- * @protected
- */
- getTpl: function (instance, name) {
- var tpl = instance[name], // go for it! 99% of the time we will get it!
- proto;
- if (tpl && !tpl.isTemplate) { // tpl is just a configuration (not an instance)
- // create the template instance from the configuration:
- tpl = Ext.ClassManager.dynInstantiate('Ext.XTemplate', tpl);
- // and replace the reference with the new instance:
- if (instance.hasOwnProperty(name)) { // the tpl is on the instance
- instance[name] = tpl;
- } else { // must be somewhere in the prototype chain
- for (proto = instance.self.prototype; proto; proto = proto.superclass) {
- if (proto.hasOwnProperty(name)) {
- proto[name] = tpl;
- break;
- }
- }
- }
- }
- // else !tpl (no such tpl) or the tpl is an instance already... either way, tpl
- // is ready to return
- return tpl || null;
- }
- }
- });
- </pre>
- </body>
- </html>
|