package com.smartgwt.client.docs; /** * <h3>Component XML</h3> * As covered in the <i>QuickStart Guide</i> Chapter 4, <i>Coding</i>, Smart GWT * components can be created in either XML or JavaScript format. This section covers some of * the details of using the XML format, called "Smart GWT component XML". * <P> * <b>Referring to previously created components</b> * <P> * To refer to another component by ID in XML, use <Canvas ref=/>. For example: * <pre> * <Canvas ID="myCanvas"/> * <Canvas ID="myCanvas2"/> * <VLayout> * <members> * <Canvas ref="myCanvas"/> * <Canvas ref="myCanvas2"/> * </members> * </VLayout> * </pre> * <P> * <b>JavaScript expressions</b> * <P> * To embed a JavaScript expression into component XML, use the <JS> tag. For example: * <pre> * <VLayout> * <width><JS>isc.Page.getWidth() - 20</JS></width> * </VLayout> * </pre> * Note that, like all component XML properties, the <code>width</code> property can be * specified either as an XML attribute or as a subelement. Expressing it as a subelement, as * shown above, allows the <JS> tag to be used. * <P> * <b>Embedding Methods</b> * <P> * For {@link com.smartgwt.client.docs.StringMethods StringMethods} such as {@link * com.smartgwt.client.widgets.grid.ListGrid#addRecordClickHandler ListGrid.recordClick}, * JavaScript code can be used as an ordinary element value: * <pre> * <ListGrid> * <recordClick>if (record.age > 65) doSomething()</recordClick> * </ListGrid> * </pre> * To embed an actual function definition, use the <JS> tag described above. For * example: * <pre> * <ListGrid> * <recordClick><JS>function (viewer, record, recordNum, field) { * if (record.age > 65) doSomething(); * }</JS></recordClick> * </ListGrid> * </pre> * Unfortunately, characters commonly used in JavaScript code, such as ampersand (&), are * not legal inside XML element or attribute values. For example, the expression "record != * null && record.age > 65" must be written as shown below, or it is not considered valid XML: * <P> * <pre> * <ListGrid> * <recordClick> * if (record.status != null &amp;&amp; record.age > 65) doSomething() * </recordClick> * </ListGrid> * </pre> * An alternative, for larger blocks of code, is to use the XML standard "CDATA" (character * data) processing directive, which allows ampersand and other characters to be used without * special notation: * <pre> * <ListGrid> * <recordClick><![CDATA[ * if (record.status != null && record.age > 65) doSomething() * ]]></recordClick> * </ListGrid> * </pre> * <P> * Overall, embedding code in XML can be awkward. Isomorphic generally recommends that * significant chunks of JavaScript code, such as non-trivial custom components, be moved to * separate, purely JavaScript files, while code embedded in component XML is limited to simple * expressions and short functions. * <P> * <b>Troubleshooting</b> * <P> * XML parsing errors, which happen when XML is not well-formed and would be rejected by any * standard XML parser, are reported in the server-side log, and, when possible, also in the * client-side log within the "Results" tab of the Developer Console. * <P> * Other issues with component XML can result from incorrect use of Smart GWT component XML * tags. For example, you may specify a property and it may appear to have no effect even * though it clearly works in other, JavaScript-based examples. If you get this symptom, you * can troubleshoot by looking at the JavaScript code Smart GWT generates from component XML. * <P> * Smart GWT always translates Smart GWT component XML to JavaScript format before * execution. This is done automatically by the <isomorphic:XML> tag for XML embedded in * a .jsp file, and you can "View Source" with your browser to see the generated XML. You can * also use the "Eval XML" section in the "Results" tab of the Developer Console to see * the generated JavaScript ("Show JS" button) and to dynamically execute component XML ("Eval * XML" button). These facilities will help you troubleshoot issues with incorrectly specified * XML. * <P> * <b>Custom Properties</b> * <P> * If you specify a custom property on a component in XML, for example: * <pre> * <Canvas myProperty="false"/> * </pre> * The value of the property will be a JavaScript String. In the above example, it would be * the string "false", which is considered a boolean true value in the JavaScript language. * If you want a different JavaScript type, you can force a property to be interpreted as a * given type by using the "xsi:type" attribute: * <pre> * <Canvas> * <myProperty xsi:type="xsd:boolean">false</myProperty> * </Canvas> * </pre> * The same notation works when you want to declare that an entire subobject has a given type. * For example, this would cause the custom property "myListGrid" to have a live * {@link com.smartgwt.client.widgets.grid.ListGrid} instance as it's value. All of the properties on the * <myListGrid> tag * will be correctly interpreted as ListGrid properties and have the correct types. * <pre> * <Canvas> * <myListGrid xsi:type="ListGrid" width="500" height="600"/> * </Canvas> * </pre> * If you do not want an actual live ListGrid, but rather a JavaScript Object containing * properties for later construction of a ListGrid, use the <code>propertiesOnly</code> * attribute. For example, this code would cause the property "listGridProperties" to be a * JavaScript Object with properties "width" and "height", whose values would be JavaScript * Numbers. * <pre> * <Canvas> * <listGridProperties xsi:type="ListGrid" propertiesOnly="true" * width="500" height="600"/> * </Canvas> * </pre> * For your reference: "xsi" stands for "XML Schema Instance"; this notation derives from XML * Schema standards for explicitly specifying type inline. * <P> * <B>Custom Components</B> * <P> * If you use defineClass() to define a new component class * "MyListGrid" which is a subclass of the built-in component ListGrid, you can create it in * XML as shown below: * <pre> * <ListGrid constructor="MyListGrid" width="500"/> * </pre> * By using the <ListGrid> tag you advertise that properties should be interpreted * as <code>ListGrid</code> properties. By specifying <code>constructor</code> * you tell Smart GWT what class to create(). * <P> * <b>Component Schema</b> * <P> * Instead of using the <code>constructor</code> and <code>xsi:type</code> attributes for * custom components and custom properties, you can create a {@link com.smartgwt.client.docs.ComponentSchema} that * describes the custom component. Declaring a component schema allows you to use your * component just like the built-in Smart GWT components, and also allows your component to * be used within {@link com.smartgwt.client.docs.VisualBuilder}. */ public interface ComponentXML { }