/* How does this work? ------------------- First, let's create an HTML element (we'll call it 'syncIconDiv') that will be declared 'actionable'. [...] [...] Here, the call to imnedit_setElementAsActionElement() actually attaches two callbacks (bound to the element's 'syncOk' and 'syncCancel' properties). Those callbacks will be in charge of sending (or not) the change request to the server. Ok so far? (if not, maybe poking at the code below will help a bit) Then, to use interactive map navigator editing, you'll have to set the Show[Scale/Coord] tags as 'interactive', and say which element will be answering for application of the changes. For example: That's it for the setup of the thing. What happens next is 1/ Whenever one of the interactive Show* fields are being edited, the 'actionable' element's visibility will be set to 'visible'. 2/ The HTML element is then responsible for triggering a 'syncOk' or a 'syncCancel' callback. In our case, it's a very simple HTML element holding a single image, and only an 'syncOk' can be triggered. 3/ When either one of the two callbacks has been triggered, the element's visibility will be set back to 'hidden', and the action will be triggered server-side, updating all the views on the context 'Context' Why this kind of 'indirection' ------------------------------ What I refer to as indirection here is the fact that the HTML element needs to trigger one of it's callbacks. This is used so a wide variety of 'actionable' elements can be developed. The first one was a simple div holding a 'chain-link-like' image, but more complex ones can be coded. For ex: a div holding an 'Apply changes?' text and both 'ok' and 'cancel' buttons. Comments, questions, flames or suggestions? ------------------------------------------- ad@ionicsoft.com */ /** * This retrieves an HTML element in the current document, and * attaches the syncOk() and syncCancel() callbacks to it. * * @param viewName The ID of the view this element is supposed to modify * @param actionElementId The ID of the HTML ``action element'' * @param navigationFormId The name of the HTML FORM that was generated by the MapNavigator tag (it's styleId attribute) * @param coordDisplayerX The ID of the HTML field that shows the X coordinate * @param coordDisplayerY The ID of the HTML field that shows the Y coordinate * @param scaleDisplayer The ID of the HTML field that shows the scale */ function imnedit_setElementAsActionElement (viewName, actionElementId, navigationFormId, coordDisplayerX, coordDisplayerY, scaleDisplayer) { var actionElement = document.getElementById (actionElementId); if (! actionElement) alert ("Couldn't set html element " + actionElementId + " as action producer for interactive geometry editing"); else { actionElement.syncOk = function () { return imnedit_synchronizeMapNavigator (viewName, actionElementId, navigationFormId, coordDisplayerX, coordDisplayerY, scaleDisplayer, true); }; actionElement.syncCancel = function () { return imnedit_synchronizeMapNavigator (viewName, actionElementId, navigationFormId, coordDisplayerX, coordDisplayerY, scaleDisplayer, false); }; } } //--------------- Private function imnedit_setActionElementActive (viewName, actionElementId, elementActive) { var actionElement = document.getElementById (actionElementId); if (! actionElement) alert ("Couldn't find html element " + actionElementId); else { if (actionElement.isCurrentlyActive != elementActive) { var view = document.getElementById (viewName); if (view.mouseMapProcessor) view.mouseMapProcessor.setActive (! elementActive); actionElement.style.visibility = (elementActive ? 'visible' : 'hidden'); actionElement.isCurrentlyActive = elementActive; } } } function imnedit_synchronizeMapNavigator (viewName, actionElementId, navigationFormId, coordDisplayerX, coordDisplayerY, scaleDisplayer, doIt) { var actionElement = document.getElementById (actionElementId); if (! actionElement) alert ("Couldn't synchronize map view/navigator with actionElement of ID " + actionElementId); else { if (actionElement.style.visibility == 'visible') { if (doIt) { /* * Get the x/y coords displaying text fields */ var xid = (coordDisplayerX == null ? ('showCoordX4' + viewName) : coordDisplayerX); var yid = (coordDisplayerY == null ? ('showCoordY4' + viewName) : coordDisplayerY); var needSend = false; var form = document.getElementById (navigationFormId); form ['navAction'].value = 'PAN'; var oldSrs = form ['srs'].value; form ['srs'].value = 'navigatorSRS'; var fieldX = document.getElementById (xid); var fieldY = document.getElementById (yid); if (fieldX.needSync == true || fieldY.needSync == true) { form ['x'].value = fieldX.value; form ['y'].value = fieldY.value; top.pushAsyncEvent (form); fieldX.needSync = false; fieldY.needSync = false; needSend = true; } var sid = (scaleDisplayer == null ? ('showScale4' + viewName) : scaleDisplayer); form ['navAction'].value = 'SETSCALE'; var fieldS = document.getElementById (sid); if (fieldS.needSync == true) { form ['scale'].value = fieldS.value; top.pushAsyncEvent (form); fieldS.needSync = false; needSend = true; } if (needSend) top.sendEvents (); form ['srs'].value = oldSrs; } imnedit_setActionElementActive (viewName, actionElementId, false); } } } // This will be used as callback for the keypress event of the fields function imnedit_checkKey (event, viewId, entryId, actionId) { event = getEvent(event); var code; if (event.keyCode) code = event.keyCode; else if (event.which) code = event.which; var character = String.fromCharCode (code); // 8 = backspace; 46 = delete; 96 -> 105 are the numeric panel's digits if (code == 8 || code == 46 || (code >= 96 && code <= 105) || isDigit (character)) { // Need sync var entry = document.getElementById (entryId); imnedit_setActionElementActive (viewId, actionId, true); entry.needSync = true; } else if (code == 13) { // Enter pressed! var action = document.getElementById (actionId); action.syncOk (); } }