Today’s tip will cover some useful techniques as you develop more full-scale Zen applications. Zen allows you to create custom components and composites to capture some of your own commonly used features.
For instance, let’s say you have a tablePane on one of your pages:
<tablePane id="table"
caption="This is a tablePane"
tableName="ZENDemo_Data.Employee"
useSnapshot="true"
showQuery="true"
showFilters="true"
fixedHeaders="true"
bodyHeight="15.0em"
filtersDisabled="false"
autoExecute="true"
showZebra="true"
pageSize="10"
showRowNumbers="true"
valueColumn="ID"
maxRows="1000"
useKeys="true">
<column colName="ID" hidden="true"/>
.
.
.
<column colName="Salary" width="20%"/>
</tablePane>
You will probably use these same attribute definitions on many of your pages. To save on development time and add consistency to your application you can create a reusable component with these attributes. The <tablePane> component is an instance of %ZEN.Component.tablePane, and all of the attributes are properties of the class. You would start by subclassing the library class, then add an initial value for any properties you want to set. Dawn Wolthuis sent out a great example of this a couple of weeks ago, if you’d like to see an example “from the field”.
Class MyZEN.tablePane Extends %ZEN.Component.tablePane
{
Property useSnapshot
As %ZEN.Datatype.boolean [
InitialExpression =
1 ];
Property showQuery
As %ZEN.Datatype.boolean [
InitialExpression =
1 ];
Property showFilters
As %ZEN.Datatype.boolean [
InitialExpression =
1 ];
Property fixedHeaders
As %ZEN.Datatype.boolean [
InitialExpression =
1 ];
Property bodyHeight
As %ZEN.Datatype.length [
InitialExpression =
"15.0em" ];
Property filtersDisabled
As %ZEN.Datatype.boolean [
InitialExpression =
0 ];
Property autoExecute
As %ZEN.Datatype.boolean [
InitialExpression =
1 ];
Property showZebra
As %ZEN.Datatype.boolean [
InitialExpression =
1 ];
Property pageSize
As %ZEN.Datatype.integer [
InitialExpression =
"10" ];
Property showRowNumbers
As %ZEN.Datatype.boolean [
InitialExpression =
1 ];
Property valueColumn
As %ZEN.Datatype.string [
InitialExpression =
"ID" ];
Property maxRows
As %ZEN.Datatype.integer [
InitialExpression =
"1000" ];
Property useKeys
As %ZEN.Datatype.boolean [
InitialExpression =
1 ];
}
*NOTE: Use 1 and 0 instead of “true” and “false”. Client-side code expects string booleans, server-side code expects numeric booleans.
To reference this on a page, you need to define an xml namespace to identify your components by. This is usually a URL associated with your application to ensure that you don’t use the same namespace as someone else, but it’s really just a string. Add your namespace to the NAMESPACE parameter of the custom component class. You can use the same namespace for all of your components.
Parameter NAMESPACE = "www.myApplication.com";
You need to define a tag for components from your namespace to differentiate them from the default components. You can add your namespace declaration to the page tag to do so.
Class MyApp.CustomTableTest Extends %ZEN.Component.page
{
XData Contents [XMLNamespace="http://www.intersystems.com/zen"]
{
<page xmlns="http://www.intersystems.com/zen" xmlns:myzen="www.myApplication.com">
<myzen:tablePane tableName="Sample.Person">
<column colName="%ID"/>
<column colName="Name"/>
<column colName="FavoriteColors"/>
</myzen:tablePane>
</page>
}
}
Note that you still need to include the column definitions. Those are additional components.
If there is a whole set of components you reuse frequently, you can define a composite component. Let’s say the whole table from the previous example shows up on a bunch of your pages. You can save it as a custom component like this:
Class MyZEN.personTable Extends %ZEN.Component.composite
{
Parameter NAMESPACE =
"www.myApplication.com";
XData Contents [XMLNamespace="http://www.intersystems.com/zen"]
{
<composite xmlns:myzen="www.myApplication.com">
<myzen:tablePane tableName="Sample.Person">
<column colName="%ID"/>
<column colName="Name"/>
<column colName="FavoriteColors"/>
</myzen:tablePane>
</composite>
}
}
A composite has an XData Contents section, just like a Zen page, but there’s no <page> component. Note that you’ll have to add your namespace to the <composite> tag if you’re using any custom components in the composite.
Using the composite component my page now looks like this:
Class MyApp.CustomTableTest Extends %ZEN.Component.page
{
XData Contents [XMLNamespace="http://www.intersystems.com/zen"]
{
<page xmlns="http://www.intersystems.com/zen" xmlns:myzen="www.myApplication.com">
<myzen:personTable/>
</page>
}
}
Custom components and composites can also be used to help define a consistent look and feel for your application. You can add an XData Style block to either class. A good starting point is to find the style tags from the parent classes and copy them into your custom class. Then you can override the defaults with whatever you desire. Changes will automatically be applied to any classes that use your component.
For further reading and even more examples, check out this chapter in the documentation. Enjoy!
http://docs.intersystems.com/cache20111/csp/docbook/DocBook.UI.Page.cls?KEY=GZAP_customization
Nice example Emily – thanks for putting it together!
--
You received this message because you are subscribed to the Google Groups "InterSystems: MV Community" group.
To post to this group, send email to Cac...@googlegroups.com
To unsubscribe from this group, send email to CacheMV-u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/CacheMV?hl=en
--
You received this message because you are subscribed to the Google Groups "InterSystems: MV Community" group.
To post to this group, send email to Cac...@googlegroups.com
To unsubscribe from this group, send email to CacheMV-u...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/CacheMV?hl=en
Thanks Emily!�
We work with both delivered and custom components a lot. While I like writing simple custom components with MVBASIC and hope to learn more about them, I do not yet grok composite components. Maybe you guys will have some tips on that in the future.�
We have two composite components, neither of which I wrote, which might be why I do not understand them. We have not yet figured out things like onchange and other event handlers, so these composite components do not work like regular components yet (as we are not coding them with all features they need, we are figuring). Our current approach is not to use composite components until we better understand them. So, we subclass existing components and create new components from scratch, but even when it seems obvious that what we would like is a composite component, we avoid that.
For example, we have a timeSelect composite that has two comboxbox components, one for the hours and one for the minutes. In the page where we use it, we want to put an onchange on it, like we might on a single combobox, but we do not know how to code that. I'll admit that I have not spent hours and hours trying to figure this out, and I have received some hints in the past from the Zen list (I'll have to put my finger on those) that I passed along, but no joy on this front yet. �Any suggestions would be great, even if saved for a future tip of the week. �Thanks again! �--dawn
On Mon, Jan 23, 2012 at 6:13 PM, Emily Haggstrom <Emily.H...@intersystems.com> wrote:
Today�s tip will cover some useful techniques as you develop more full-scale Zen applications. Zen allows you to create custom components and composites to capture some of your own commonly used features.
�
For instance, let�s say you have a tablePane on one of your pages:
�
<tablePane�id="table"�
����������� caption="This is a tablePane"
����������� tableName="ZENDemo_Data.Employee"
����������� useSnapshot="true"
����������� showQuery="true"
����������� showFilters="true"
����������� fixedHeaders="true"
����������� bodyHeight="15.0em"����������� filtersDisabled="false"
����������� autoExecute="true"
����������� showZebra="true"
����������� pageSize="10"
����������� showRowNumbers="true"
����������� valueColumn="ID"
����������� maxRows="1000"
����������� useKeys="true">
<column�colName="ID"�hidden="true"/>
..
.
<column�colName="Salary"�width="20%"/>
</tablePane>�
You will probably use these same attribute definitions on many of your pages. To save on development time and add consistency to your application you can create a reusable component with these attributes. The <tablePane> component is an instance of %ZEN.Component.tablePane, and all of the attributes are properties of the class. You would start by subclassing the library class, then add an initial value for any properties you want to set. Dawn Wolthuis sent out a great example of this a couple of weeks ago, if you�d like to see an example �from the field�.
�
Class�MyZEN.tablePane�Extends�%ZEN.Component.tablePane
{
Property�useSnapshot As�%ZEN.Datatype.boolean�[ InitialExpression�= 1�];
Property�showQuery As�%ZEN.Datatype.boolean�[ InitialExpression�= 1�];
Property�showFilters As�%ZEN.Datatype.boolean�[ InitialExpression�= 1�];
Property�fixedHeaders As�%ZEN.Datatype.boolean�[ InitialExpression�= 1�];
Property�bodyHeight As�%ZEN.Datatype.length�[ InitialExpression�= "15.0em"�];
Property�filtersDisabled As�%ZEN.Datatype.boolean�[ InitialExpression�= 0�];
Property�autoExecute As�%ZEN.Datatype.boolean�[ InitialExpression�= 1�];
Property�showZebra As�%ZEN.Datatype.boolean�[ InitialExpression�= 1�];
Property�pageSize As�%ZEN.Datatype.integer�[ InitialExpression�= "10"�];
Property�showRowNumbers As�%ZEN.Datatype.boolean�[ InitialExpression�= 1�];
Property�valueColumn As�%ZEN.Datatype.string�[ InitialExpression�= "ID"�];
Property�maxRows As�%ZEN.Datatype.integer�[ InitialExpression�= "1000"�];
Property�useKeys As�%ZEN.Datatype.boolean�[ InitialExpression�= 1�];}
�
*NOTE: Use 1 and 0 instead of �true� and �false�. Client-side code expects string booleans, server-side code expects numeric booleans.
�
To reference this on a page, you need to define an xml namespace to identify your components by. This is usually a URL associated with your application to ensure that you don�t use the same namespace as someone else, but it�s really just a string. Add your namespace to the NAMESPACE parameter of the custom component class. You can use the same namespace for all of your components.
�
Parameter�NAMESPACE = "www.myApplication.com";
�
You need to define a tag for components from your namespace to differentiate them from the default components. You can add your namespace declaration to the page tag to do so.
�
Class�MyApp.CustomTableTest�Extends�%ZEN.Component.page
{
XData�Contents [XMLNamespace="http://www.intersystems.com/zen"]
{
<page�xmlns="http://www.intersystems.com/zen"�xmlns:myzen="www.myApplication.com">
<myzen:tablePane�tableName="Sample.Person">
<column�colName="%ID"/>
<column�colName="Name"/>
<column�colName="FavoriteColors"/>
</myzen:tablePane>
</page>
}
}�
Note that you still need to include the column definitions. Those are additional components.
�
If there is a whole set of components you reuse frequently, you can define a composite component. Let�s say the whole table from the previous example shows up on a bunch of your pages. You can save it as a custom component like this:
�
Class�MyZEN.personTable�Extends�%ZEN.Component.composite
{
Parameter�NAMESPACE = "www.myApplication.com";
XData�Contents [XMLNamespace="http://www.intersystems.com/zen"]
{
<composite�xmlns:myzen="www.myApplication.com">
<myzen:tablePane�tableName="Sample.Person">
<column�colName="%ID"/>
<column�colName="Name"/>
<column�colName="FavoriteColors"/>
</myzen:tablePane>
</composite>
}
}�
A composite has an XData Contents section, just like a Zen page, but there�s no <page> component. Note that you�ll have to add your namespace to the <composite> tag if you�re using any custom components in the composite.
�
Using the composite component my page now looks like this:
�
Class�MyApp.CustomTableTest�Extends�%ZEN.Component.page
{
XData�Contents [XMLNamespace="http://www.intersystems.com/zen"]
{
<page�xmlns="http://www.intersystems.com/zen"�xmlns:myzen="www.myApplication.com">
<myzen:personTable/>
</page>
}
}�
Custom components and composites can also be used to help define a consistent look and feel for your application. You can add an XData Style block to either class. A good starting point is to find the style tags from the parent classes and copy them into your custom class. Then you can override the defaults with whatever you desire. Changes will automatically be applied to any classes that use your component.
�
For further reading and even more examples, check out this chapter in the documentation. Enjoy!
http://docs.intersystems.com/cache20111/csp/docbook/DocBook.UI.Page.cls?KEY=GZAP_customization
--
You received this message because you are subscribed to the Google Groups "InterSystems: MV Community" group.
To post to this group, send email to Cac...@googlegroups.com
To unsubscribe from this group, send email to CacheMV-u...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/CacheMV?hl=en
--
Dawn M. Wolthuis
Take and give some delight today
We work with both delivered and custom components a lot. While I like writing simple custom components with MVBASIC and hope to learn more about them, I do not yet grok composite components..
From: Dawn WolthuisWe work with both delivered and custom components a lot. While I like writing simple custom components with MVBASIC and hope to learn more about them, I do not yet grok composite components..Web components like this are a huge, multi-billion dollar industry. The rest of the world has enjoyed controls for almost all languages for the last 15 years or so.
I Wish in the MV space there were more appreciation for such things as I would seriously enjoy cranking out a ton of these.
Unfortunately with little to no interest in third-party offerings (completely unlike every other industry),
MV developers are doomed to writing everything they want from scratch.
My position, shared with millions of others, is that it's more important for developers to spend their time on app functionality rather than on components which are often re-written many times over in each shop.
Sure it's critically important for a platform like Zen to include the ability to create custom components along with a wealth of built-in controls, but typically this will only be used for simple extensions of basic functionality, and individuals will generally not take it upon themselves to write more complex components like those enjoyed elsewhere.
This situation limits the scope of Zen for larger projects.
Newcomer developers from other environments can easily ask "where are the tools?" and "why should I hand-code all of this, or go without functionality when I can get this kind of stuff easily elsewhere - and a lot of it for free?"
I'm presenting this (certainly arguable) view for a few reasons.First, when you Zen developers can't find something you want, post a note here.
Someone else may already have it or may be willing to create it.
Second, when faced with a challenge, consider your time to make versus buy. How much is your time worth? Will it actually cost you more to not pay for something that you need to write yourself? Consider paying a little something for work that someone else does which will save you time.
Third, and finally, I'm guessing that most developers would prefer to (a) not write a complex component _and_ (b) not purchase one either. "We don't really need that, we can do with this..." The result being an end-user offering that pales in comparison to others.
This makes it even less appealing for developers to use this platform than others because the final product is not as marketable.
I don't say this to offend the platform but to encourage developers to make better use of it,
and to foster an industry which is more likely to benefit everyone.Now after all of that, to our ISC friends: Where Infragistics or Telerik or Syncfusion provide complex components for ASP.NET developers, does anyone out there yet provide similar tools for Zen? If so, there ya go, make or buy.
Regards,TTony Gravagno
Nebula Research and Development
TG@ remove.pleaseNebula-RnD.com
Nebula R&D sells Pick/MultiValue products worldwide,and provides related development services
remove.pleaseNebula-RnD.com/blog
Visit http://PickWiki.com! Contribute!
http://Twitter.com/TonyGravagno
NEW! http://groups.google..com/group/mvdbms/about
--
You received this message because you are subscribed to the Google Groups "InterSystems: MV Community" group.
To post to this group, send email to Cac...@googlegroups.com
To unsubscribe from this group, send email to CacheMV-u...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/CacheMV?hl=en