[Chameleon] Layer order change WITHOUT reloading the page for
JSAPI
Carlo Trönnberg
carlo.t at chello.hu
Thu Jun 22 19:43:36 EDT 2006
Hi Julien,
Thanks for your tip!
I will look into this.
I have no experience with the JSAPI coding but will definitively try to get
into it.
Concerning the draggable sorting of the layers, I based my solution on the
excellent JavaScript library with DHTML from Tim Taylor
http://tool-man.org/examples/sorting.html
The sorting is made my manipulating the DOM (Document Object Model) with
JavaScript, XHTML and CSS (DHTML), the same as used in Chameleon...
This code is very reliable and worked on all the browsers I have tried
(which is rare).
I based my code on the long list example which has a function to query the
order of the list (the values) as a delimited string.
Looking at the source through the browser of a running chameleon
application, you can find a function called "LegendTemplateGetLayerName"
which maps the order number and the name of a layer. I made an ugly double
for loop to generate an array of numbers (the order of the layers compared
to the order defined in the map file) from the list (with names) returned by
the ordering JavaScript code. The reason I did it this way is that this
mapping function (LegendTemplateGetLayerName) is regenerated at each reload
of the page with the changed order from the previous state becoming the
default ordering.
The generated numbered list is then stored in the hidden form element and
parsed at page reload in my phtml file.
I am sure this can be solved in a much nicer and straightforward way and I
think we all could profit from this highly interactive way. Anyone with a
better approach?
My application of it is right now rather dirty (the code...). There is a lot
of tweaking done to use the LegendTemplate...
Hereafter is my legend_template.html template as is (it might contain other
interesting stuff for other newbies around :-) ). It still holds the
previous radio button for selecting a layer for the promotion, demotion or
removal of it. Right now I only use it for the removal. I am planning to
make a trash can icon on which I could drop a layer I want to remove. Then
this radio button would be obsolete. I use 2 LegendTemplates in my solution
why I have the conditional statement [if name=isStation oper=isnull]...
==== legend_template.html start =====
[leg_layer_html order=ascending opt_flag=15][if name=isStation oper=isnull]
<li itemID="[leg_layer_name]" onmouseover="this.className =
'highlighted';" onmouseout="this.className = 'nothighlighted';"><div
class="handle2" TITLE="Move this layer by dragging it to desired
position"></div>
<div id="c4View" class="view"><table border=0 cellpadding="0"
cellspacing="0"><tr id='[leg_layer_name]_t'>
<td><input type="radio" name="my_legend"
onclick="CWCSelectLayer('[leg_layer_name]', true)" [if name=selected
value=1] CHECKED[/if] ></td>
<td align="left" width=25><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]></td>
<td width="24"><img src="[leg_icon width=20 height=18]" width="20"
height="20"></td>
[if name=wms_name oper=isnull]<td><a href="#"
onclick="javascript:LegendTemplateLayerInfo('[leg_layer_name]');"><span
class="label">[leg_layer_name]</span></a></td>
</tr>[/if][if name=wms_name oper=isset]
<td><a href="#"
onclick="javascript:LegendTemplateLayerInfo('[leg_layer_name]');"><span
class="label">[metadata name=WMS_TITLE]</span></a></td>
</tr>
[/if]</table></div></li>[/if][/leg_layer_html]
==== legend_template.html end =====
==== in my CSS file: ====
.highlighted {
background-color: #CCCCFF;
font-weight: bold;
}
.nothighlighted {
background-color: #FFFFCC;
font-weight: normal;
}
#phoneticlong .handle2 {
float: left;
background-color: #ccc;
background-image: url(images/handle.gif);
width: 11px;
height: 19px;
}
.handle2 {
cursor: move;
}
#phoneticlong li .view {
cursor: text;
}
ul.sortable li {
position: relative;
}
ul.boxy {
list-style-type: none;
padding: 0px;
margin: 0px;
width: 100%;
font-size: 13px;
font-family: Arial, sans-serif;
}
ul.boxy li {
cursor:move;
padding: 0px 0px;
}
==================
In my html template I enclosed the LegendTemplate widget in a list structure
(same as in the example on Tim Taylor's page):
...
<ul id="phoneticlong" class="sortable boxy">
<cwc2 type="LegendTemplate" visible="true" embedded="true"
template="legend_template.html" popupstyleresource="TextButtons"
popupwidth="500" popupheight="400" status="false" menubar="false"/>
</ul>
...
=====================================
Sorry for this long post, butI hope this is helpful and would really
appreciate anybody's comments or ideas on this.
Cheers,
Carlo
----- Original Message -----
From: "Julien-Samuel Lacroix" <jlacroix at mapgears.com>
To: "Carlo Tronnberg" <temp at chello.hu>
Cc: <chameleon at lists.maptools.org>
Sent: Tuesday, June 20, 2006 16:41
Subject: Re: [Chameleon] Layer order change WITHOUT reloading the page for
JSAPI
> Hi,
> Cool! That seems really great! Do you think you will be able to contribute
> it back? For the page reloading, you ca check the file
> chameleon/htdocs/widgets/NavTool.php
>
> In the NavSetActiveTool JS function, you will have some code that trig the
> map refresh. It looks like:
>
> {$this->mszHTMLForm}.NAV_CMD.value = "LEGENDTEMPLATE_LAYERS";
> {$this->mszHTMLForm}.NAV_ALLOW_RECTANGLE.value=false;
> {$this->mszHTMLForm}.NAV_SUBMIT.value=false;
> goCWCJSAPI.UpdateNavTools();
>
>
> Then you will have to add a LEGENDTEMPLATE_LAYERS event in the
> chameleon/htdocs/UpdateMap.php
>
> Hope that helps
>
> Julien
>
>
> Carlo Tronnberg wrote:
>> Dear List!
>> I have made a sortable Legend management based on the LegendTemplate
>> widget but using drag and drop to move the layers. It works very well but
>> since I do not need to refresh the layer list anymore (reload the page).
>> Is it possible to tell mapserver about the new order WITHOUT reloading
>> the whole page?
>> Right now, my JavaScript layer ordering code returns a string with the
>> order of the layers stored in a hidden form element called
>> 'setlayerorder'.
>> In the base phtml file of my solution, I simply split this string to an
>> array which I pass to the setlayersdrawingorder function.
>> $layerlist = split('~~', $_REQUEST['setlayerorder'] );
>> $oApp->moMapSession->oMap->setlayersdrawingorder( $layerlist );
>> The amount of code in the solution starts to be large why I want to
>> minimize unnecessary reload of the page with JSAPI.
>> The layer list does not need to be reloaded anymore since I simply drag
>> around the layers to wished position. Dropping the element should trigger
>> the mapserver legend ordering if the element's position has changed.
>> I think this approach is far more intuitive (and cool!) than having a
>> radio button with option to promote or demote the layer. If you add a
>> layer it will automatically get on top of all the others. The user might
>> have to click several times on the demote button (with page reload in
>> between) to get the layer to wished position.
>> Any ideas how to avoid the page reloading but still tell mapserver to
>> regenerate the map with the new legend order?
>> Cheers,
>> Carlo
>>
>>
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> Chameleon mailing list
>> Chameleon at lists.maptools.org
>> http://lists.maptools.org/mailman/listinfo/chameleon
>
> --
> Julien-Samuel Lacroix
> Mapgears
> http://www.mapgears.com/
>
More information about the Chameleon
mailing list