[Chameleon] HTML Legend with Javascript
Paul Spencer
pagameba at magma.ca
Tue Sep 28 20:44:18 EDT 2004
Robin,
I have put some thought into this and I cannot see how we could
accomplish the same 'trick' in this scenario.
In Internet Explorer you can access an array document.all and search it
for elements of a given name or id. Now that I think about it, I don't
think you can do that in Mozilla/Netscape. So the following would be a
better approach:
legend template:
[leg_group_html]
<div class="cssClickable cssExpander cssGroup" id="[leg_group_name]"
onclick="this.expander.toggle()">
<script langauge="JavaScript" type="text/javascript">
oGroup = new cExpander( CWCDHTML_GetLayer( '[leg_group_name]', true ));
</script>
[leg_group_name]
</div>
[/leg_group_html]
[leg_layer_html order=ascending opt_flag=15]
<div class="cssClickable cssExpander cssLayer" id="[leg_layer_name]"
style="display:none" onclick="this.expander.toggle()">
<script langauge="JavaScript" type="text/javascript">
oLayer = new cExpander( CWCDHTML_GetLayer( '[leg_layer_name]', true ));
oGroup.addElement( oLayer );
</script>
<input type="checkbox" name="legendlayername[]"
value="[leg_layer_name]"
[if name=layer_status oper=eq value=1]CHECKED[/if]
[if name=layer_status oper=eq value=2]CHECKED[/if]>[leg_layer_name]
</div>
[/leg_layer_html]
[leg_class_html]
<div class="cssExpander cssClass" id="[leg_class_name]"
style='display:none'>
<script langauge="JavaScript" type="text/javascript">
oClass = new cExpander( CWCDHTML_GetLayer( '[leg_class_name]', true ));
oLayer.addElement( oClass );
</script>
<img src="[leg_icon width=20 height=18]" width="20"
height="20">[leg_class_name]<br>
</div>
[/leg_class_html]
application template:
<script language="JavaScript">
function cExpander( elm )
{
this.element = elm;
this.element.expander = this;
this.children = new Array();
this.bIsOpen = false;
this.addElement = cExpander_AddElement;
this.open = cExpander_Open;
this.close = cExpander_Close;
this.expand = cExpander_Expand;
this.contract = cExpander_Contract;
this.toggle = cExpander_Toggle;
}
function cExpander_AddElement( elm )
{
this.children[this.children.length] = elm;
}
function cExpander_Open()
{
for( var i=0; i<this.children.length; i++)
{
this.children[i].element.style.display = 'block';
if (this.children[i].bIsOpen)
{
this.children[i].open();
}
}
}
function cExpander_Close()
{
for( var i=0; i<this.children.length; i++)
{
this.children[i].element.style.display = 'none';
this.children[i].close();
}
}
function cExpander_Expand()
{
this.bIsOpen = true;
this.open();
}
function cExpander_Contract()
{
this.bIsOpen = false;
this.close();
}
function cExpander_Toggle()
{
if (this.bIsOpen)
this.contract();
else
this.expand();
}
</script>
<style>
.cssClickable {
cursor: pointer;
}
.cssExpander {
width: 100px;
font-family: arial;
font-size: 12px;
font-weight: normal;
padding: 2px;
}
.cssGroup {
font-size: 14px;
font-weight: bold;
background-color: #cccccc;
border: 1px solid #c9c9c9;
}
.cssLayer {
background-color: #dddddd;
border: 1px solid #d9d9d9;
padding: 5px 2px 2px 2px;
}
.cssClass {
font-style: italic;
background-color: #eeeeee;
border: 1px solid #e9e9e9;
padding: 10px 2px 2px 2px;
}
</style>
Note the css is just for effect ;) Also, the open/close status is not
preserved between page loads ... I leave that as an exercise for the
reader :>
Cheers,
Paul
Robin Brown wrote:
> Paul,
>
> thanks. that makes sense. The only problem is now that I am trying to extend this to
> groups, the layer division gets closed before anything gets in it. Here is my legend
> template code:
>
> [leg_group_html]
> </div></div>
> <div id=[leg_group_name]>
> <a href="javascript:void(0);" onclick="toggleLayer('[leg_group_name]_layer');"><img
> src="C:\ms4w\apps\chameleon\samples\htdocs\images\ClosedFolder.gif"></a>
> <b>[leg_group_name]</b><br>
> </div>
> <div id="[leg_group_name]_layer" style='display:none'>
> [/leg_group_html]
>
> [leg_layer_html order=ascending opt_flag=15]
> </div>
> <a href="javascript:void(0);" onclick="toggleLayer('[leg_layer_name]_class');"><img
> src="C:\ms4w\apps\chameleon\samples\htdocs\images\ClosedFolder.gif"></a>
> <input type="radio" name="my_legend" onclick="CWCSelectLayer('[leg_layer_name]',
> true)"[if name=selected value=1] CHECKED[/if] >
> <input type="checkbox" name="legendlayername[]" value="[leg_layer_name]"[if
> name=layer_status oper=eq value=1]CHECKED[/if][if name=layer_status oper=eq
> value=2]CHECKED[/if]>
> [if name=wms_name oper=isnull]
> <a href="#"
> onclick="javascript:LegendTemplateLayerInfo('[leg_layer_name]');"><span
> class="label">[leg_layer_name]</span></a><BR>
> [/if]
>
> [if name=wms_name oper=isset]
> <a href="#"
> onclick="javascript:LegendTemplateLayerInfo('[leg_layer_name]');"><span
> class="label">[metadata name=WMS_TITLE]</span></a><BR>
> [/if]
>
> <div id="[leg_layer_name]_class" style='display:none'>
> [/leg_layer_html]
>
>
> [leg_class_html]
> <img src="[leg_icon width=20 height=18]" width="20"
> height="20">[leg_class_name]<br>
> [/leg_class_html]
>
>
> I was wondering if it is possible to write a code in the Chameleon template called
> setName( name) an getName(). I was thinking that I could set the variable when a group
> was created then retrieve it to name the layers inside that group. Inside each layer
> division I would then reset the name and retrieve it to name the classes inside that
> layer. I think in theory this would work but I don't know how to call the function
> from within my legend template without having an event. I would like it if I could do
> the following:
> <div setName('[leg_#_name]')> replacing the # with group/layer as appropriate
> onclick="toggleLayer(getName()+'class/layer');"
>
> I have tried this without success. Does anyone with more javascripting experience know
> how to make this happen?
>
> If this is not possible, Paul, can you expand on your suggestion below that I could
> search for the div id?
>
> Thanks for any help
>
> Robin Brown
>
>
>
> Quoting Paul Spencer <pagameba at magma.ca>:
>
>
>>this is a side effect of where names are accessible in the legend template.
>>
>>In order to get the javascript to work, we need to be able to 'find' the
>>div we want to expand/contract ... we can do this by either knowing the
>>id of the div or by searching for it. Searching is expensive, so
>>knowing the id is much preferred. Within the [leg_layer_html] block,
>>the only unique value we know of is the [leg_layer_name] so it would be
>>ideal if we could name the div associated with the classes using that
>>name. But [leg_layer_name] is not available in the [leg_class_html]
>>block so I output the <div id='[leg_layer_name]_class'> at the end of
>>[leg_layer_html]. Then the [leg_class_html] is invoked ... but this
>>doesn't get output unless there is at least one class, which isn't
>>always the case if you are using WMS or raster layers ... so the div
>>would never get closed in those cases ... workaround is to close the div
>>in the next layer block. So the problem is on the very first layer,
>>there is no opening div ... hence the div just before the widget tag ...
>>and also on the last layer there is no closing div.
>>
>>Best thing to do is 'view source' to see how it works :)
>>
>>HTH
>>
>>Paul
>>
>>Robin Brown wrote:
>>
>>>Thanks. I tried this and it works great. I was wondering if you can explain the
>>
>>first
>>
>>></div> on line 2 of your legend template? The templage doesn't work if this isn't
>>
>>here
>>
>>>so I'm wondering what it does...
>>>
>>>Thanks
>>>
>>>Robin
>>>
>>>Quoting Paul Spencer <pagameba at magma.ca>:
>>>
>>>
>>>
>>>>Robin,
>>>>I just tried this:
>>>>
>>>>
>>>>legend template file:
>>>>
>>>>[leg_layer_html order=ascending opt_flag=15]
>>>></div>
>>>><div id="[leg_layer_name]">
>>>><input type="checkbox" name="legendlayername[]"
>>>>value="[leg_layer_name]"
>>>> [if name=layer_status oper=eq value=1]CHECKED[/if]
>>>> [if name=layer_status oper=eq value=2]CHECKED[/if]><a
>>>>href="javascript:void(0)"
>>>>onclick="toggleLayer('[leg_layer_name]_class')">[leg_layer_name]</a>
>>>></div>
>>>><div id="[leg_layer_name]_class" style='display:none'>
>>>>[/leg_layer_html]
>>>>[leg_class_html]
>>>><img src="[leg_icon width=20 height=18]" width="20"
>>>>height="20">[leg_class_name]<br>
>>>>[/leg_class_html]
>>>>
>>>>
>>>>in chameleon template:
>>>>
>>>><script language="JavaScript" type="text/JavaScript">
>>>>function toggleLayer( szName )
>>>>{
>>>> var layer = CWCDHTML_GetLayer( szName );
>>>>
>>>> if (layer.display == 'block')
>>>> layer.display = 'none';
>>>> else
>>>> layer.display = 'block';
>>>>}
>>>></script>
>>>><div>
>>>> <cwc2 type="LegendTemplate" visible="true" embedded="true"
>>>>template="fancy_legend.html" popupstyleresource="TextButtons"
>>>>popupwidth="500" popupheight="400" status="false" menubar="false"/>
>>>></div>
>>>>
>>>>this displays each layer with a checkbox and a clickable layer name.
>>>>Clicking the layer name expands the class list below the layer.
>>>>
>>>>I would assume you could extend this to support groups of layers too.
>>>>
>>>>Cheers,
>>>>
>>>>Paul
>>>>
>>>>Robin Brown wrote:
>>>>
>>>>
>>>>>Thanks Paul. I wasn't sure if it was even possible. Now that I know it is, is
>>>>
>>>>there
>>>>
>>>>
>>>>>anyone out there that has done this? I am very new to Javascript (just did a
>>>>
>>>>tutorial
>>>>
>>>>
>>>>>last week). I got the divisions in but I'm not sure how to make them
>>>>
>>>>expand/collapse
>>>>
>>>>
>>>>>when they are clicked on. I tried to write a script in the template but that
>>
>>seems
>>
>>>>to
>>>>
>>>>
>>>>>throw an error. Any examples or suggestions are welcome. Thanks again.
>>>>>
>>>>>Robin
>>>>>Quoting Paul Spencer <pagameba at magma.ca>:
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>>Robin,
>>>>>>
>>>>>>the XML Theme Legend doesn't display classes. It is intended more for
>>>>>>use with OGC layers (WMS) which don't have that level of information
>>>>>>available. I may extend it in the future but not right now.
>>>>>>
>>>>>>So your only resource now is to use the html legend template. It should
>>>>>>be relatively easy (if you know dhtml/css/javascript) to make expandable
>>>>>>sections in a legend template file. For instance, you can place layer
>>>>>>names and classes into separate div elements in the template and use
>>>>>>javascript to set the display to block or none to show/hide the classes.
>>>>>>Similarly you can use groups to do the same thing for layers.
>>>>>>
>>>>>>Cheers,
>>>>>>
>>>>>>Paul
>>>>>>
>>>>>>Robin Brown wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>>>Hi all,
>>>>>>>
>>>>>>>I am using an html legend template and I have a question. Is there a way to
>>
>>make
>>
>>>>>>this
>>>>>>
>>>>>>
>>>>>>
>>>>>>>legend more dynamic? I would like let the user expand and collapse the groups
>>
>>as
>>
>>>>>>my
>>>>>>
>>>>>>
>>>>>>
>>>>>>>legend is rather large. I have tried doing this using the XML Theme legend but
>>
>>I
>>
>>>>>>want
>>>>>>
>>>>>>
>>>>>>
>>>>>>>to show layers as well as classes in my legend and I couldn't see how to do
>>
>>that
>>
>>>>>>with
>>>>>>
>>>>>>
>>>>>>
>>>>>>>the XML. If anyone knows how to show layers and classes with XML this would
>>
>>also
>>
>>>>>>be
>>>>>>
>>>>>>
>>>>>>
>>>>>>>helpful since I think I may be able to get expanding and collapsing using this
>>>>>>
>>>>>>method.
>>>>>>
>>>>>>
>>>>>>
>>>>>>>BTW, I do know that by only placing one layer in each group with xml you get
>>
>>the
>>
>>>>>>look
>>>>>>
>>>>>>
>>>>>>
>>>>>>>of layers displaying in the legend, but I haven't seen any solution for
>>
>>classes.
>>
>>>>>>>Thanks for any help you can give!
>>>>>>>
>>>>>>>Robin Brown
>>>>>>
>>>>>>--
>>>>>>-----------------------------------------------------------------
>>>>>>|Paul Spencer pspencer at dmsolutions.ca |
>>>>>>|-----------------------------------------------------------------|
>>>>>>|Applications & Software Development |
>>>>>>|DM Solutions Group Inc http://www.dmsolutions.ca/|
>>>>>>-----------------------------------------------------------------
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>--
>>>> -----------------------------------------------------------------
>>>>|Paul Spencer pspencer at dmsolutions.ca |
>>>>|-----------------------------------------------------------------|
>>>>|Applications & Software Development |
>>>>|DM Solutions Group Inc http://www.dmsolutions.ca/|
>>>> -----------------------------------------------------------------
>>>>
>>>>
>>>
>>>
>>>
>>--
>> -----------------------------------------------------------------
>>|Paul Spencer pspencer at dmsolutions.ca |
>>|-----------------------------------------------------------------|
>>|Applications & Software Development |
>>|DM Solutions Group Inc http://www.dmsolutions.ca/|
>> -----------------------------------------------------------------
>>
>>
>
>
>
--
-----------------------------------------------------------------
|Paul Spencer pspencer at dmsolutions.ca |
|-----------------------------------------------------------------|
|Applications & Software Development |
|DM Solutions Group Inc http://www.dmsolutions.ca/|
-----------------------------------------------------------------
More information about the Chameleon
mailing list