Common Custom EditorTask
Common_CustomEditorTask_CSharp\CustomEditorTask_CSharp\SimpleQueryPanel.cs
// Copyright 2010 ESRI
// 
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
// 
// You may freely redistribute and use this sample code, with or
// without modification, provided you include the original copyright
// notice and use restrictions.
// 
// See the use restrictions.
// 

namespace CustomEditorTask_CSharp
{
    [AjaxControlToolkit.ClientScriptResource("SimpleQueryPanel.js", "CustomEditorTask_CSharp.javascript.SimpleQueryPanel.js")]
    class SimpleQueryPanel : ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditorPanel
    {
        #region Instance Variable Declarations

        private System.Web.UI.HtmlControls.HtmlGenericControl m_panelDiv;
        private System.Collections.Specialized.NameValueCollection m_callbackArgsCollection;

        #endregion

        #region Constructor

        public SimpleQueryPanel(ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditorTask editorTask) :
            base("Simple Query", editorTask, "simpleQueryPanel")
        {
            // Add a handler that fires when a new editor layer is selected
            this.ParentEditor.LayerChanged +=
                new ESRI.ArcGIS.ADF.ArcGISServer.Editor.Editor.LayerChangedHandler(ParentEditor_LayerChanged);
        }

        #endregion

        #region WebControl Life Cycle Event Overrides

        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            // Create a container div for the client-side UI component
            m_panelDiv = new System.Web.UI.HtmlControls.HtmlGenericControl("div");
            m_panelDiv.ID = "simpleQueryPanelDiv";
            Controls.Add(m_panelDiv);
        }

        protected override void OnPreRender(System.EventArgs e)
        {
            base.OnPreRender(e);

            // Register the JavaScript file containing the SimpleQueryPanel JavaScript UI component and 
            // functions to control interaction between the client panel and the server
            //System.Web.UI.ScriptManager.RegisterClientScriptResource((System.Web.UI.Control)this, 
            //    this.GetType(), "CustomEditorTask_CSharp.javascript.SimpleQueryPanel.js");

            // Get a reference to the editor task's layers drop-down list
            System.Web.UI.WebControls.DropDownList editorLayerList = null;
            editorLayerList = CustomUtilities.FindControl(
                 "editTaskLayerList", this.ParentEditor as System.Web.UI.Control) as
                 System.Web.UI.WebControls.DropDownList;

            // Get strings containing the numeric and text fields for the current layer
            string numericFields = CustomUtilities.GetFields(CustomEditorInstance, 
                CustomUtilities.FieldType.Numeric);
            string textFields = CustomUtilities.GetFields(CustomEditorInstance, 
                CustomUtilities.FieldType.Text);

            // Get the URL of the activity_indicator image file
            string activityIndicatorUrl = this.Page.ClientScript.GetWebResourceUrl(
                typeof(CustomEditorTask), "CustomEditorTask_CSharp.images.activity_indicator.gif");


            // Construct the JavaScript necessary to initialize the client-side query panel with
            // server-side properties
            string scriptBlock = @"                
                function invokeSimpleQueryPanelInitialization(){{
                  initializeSimpleQueryPanel('{0}', '{1}', '{2}', '{3}', '{4}', ""{5}"");
                }}

                Sys.Application.add_init(invokeSimpleQueryPanelInitialization);";
            scriptBlock = string.Format(scriptBlock, m_panelDiv.ClientID, editorLayerList.ClientID,
                numericFields, textFields, activityIndicatorUrl, this.CallbackFunctionString);

            // Register the initialization code as a startup script
            this.Page.ClientScript.RegisterStartupScript(this.GetType(), this.ClientID + "_init", 
                scriptBlock, true);

            // Initialize the OIDFieldName property
            this.OIDfieldName = CustomEditorInstance.FeatureLayer.FeatureClass.OIDFieldName;
        }

        protected override void RenderContents(System.Web.UI.HtmlTextWriter writer)
        {
            base.RenderContents(writer);

            // Create a callback result that will call the renderSimpleQueryPanel JavaScript function, which
            // will expicitly re-render the client-side simple query panel.  This is necessary because the
            // server has no knowledge of the client-side panel's elements, so when the panel is rendered
            // (which is done with information stored in state on the server), these elements are lost.
            ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult redrawQueryPanelCallbackResult =
                ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript("renderSimpleQueryPanel();");
            this.ParentEditor.CallbackResults.Add(redrawQueryPanelCallbackResult);
        }

        #endregion

        #region Web ADF Event Handlers

        void ParentEditor_LayerChanged(ESRI.ArcGIS.Carto.IFeatureLayer featureLayer)
        {
            // Get the object ID field of the newly selected layer
            this.OIDfieldName = featureLayer.FeatureClass.OIDFieldName;

            // Get the numeric and text fields of the new layer
            string numericFields = CustomUtilities.GetFields(CustomEditorInstance, 
                CustomUtilities.FieldType.Numeric);
            string textFields = CustomUtilities.GetFields(CustomEditorInstance, 
                CustomUtilities.FieldType.Text);

            // Construct a call to a JavaScript function that will update the client-side query
            // panel with the new layer's fields
            string jsUpdateFields = string.Format("updateSimpleQueryPanelFields('{0}', '{1}');",
                textFields, numericFields);
            ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult updateFieldsCallbackResult =
                ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsUpdateFields);
            this.ParentEditor.CallbackResults.Add(updateFieldsCallbackResult);
        }

        #endregion;

        #region Callback Handler

        public override void RaiseCallbackEvent(string eventArgs)
        {
            // Parse callback arguments using the CallbackUtility included with Web ADF.
            m_callbackArgsCollection = 
                ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackUtility.ParseStringIntoNameValueCollection(eventArgs);

            // Check whether the current event argument indicates that a query was initiated by the user
            if (m_callbackArgsCollection["EventArg"] == "query")
            {
                // Get the database name of the specified query field 
                string queryField = CustomUtilities.ReplaceAliases(m_callbackArgsCollection["Field"], 
                    CustomEditorInstance);

                // Get the query value specified by the user
                string queryValue = m_callbackArgsCollection["value"];

                // Check the query type.  If text, enclose the query value in single quotes
                if (m_callbackArgsCollection["Type"] == "text")
                     queryValue = "'" + queryValue + "'";

                // Construct a query string from the field, operator, and value specified by the user
                string queryString = string.Format("{0} {1} {2}", queryField, 
                    m_callbackArgsCollection["Operator"], queryValue);

                // Get IDs of features satisfying query
                int[] matchingFeatureIDs = CustomUtilities.DoQuery(queryString, this.ParentEditor);

                // Get LayerDescription object for currently selected layer
                ESRI.ArcGIS.ADF.ArcGISServer.LayerDescription agsLayerDescription =
                    ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditorUtilities.GetLayerDescription(
                    this.ParentEditor.MapFunctionality, this.ParentEditor.SelectedLayerID);

                // Combine the feature IDs from the query with those currently selected.  How this
                // is done will depend on the selection option currently specified in the editor
                // task's settings
                bool selectionChanged;
                System.Collections.Generic.List<int> selectedIDsList =
                    CustomUtilities.UpdateSelection(agsLayerDescription.SelectionFeatures,
                    matchingFeatureIDs, out selectionChanged, this.ParentEditor.EditorTask);

                // Check whether the selected IDs changed
                if (selectionChanged)
                {
                    // Set selected features on layer currently being edited
                    agsLayerDescription.SelectionFeatures = selectedIDsList.ToArray();

                    // Get attributes panel and set to edit the attributes of selected features
                    ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditAttributesPanel editAttributesPanel =
                        this.ParentEditor.AttributesEditor as ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditAttributesPanel;
                    ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection editAttributesPanelResults =
                        editAttributesPanel.SetSelectedFeatures(agsLayerDescription.SelectionFeatures);
                    this.CallbackResults.CopyFrom(editAttributesPanelResults);

                    // Refresh map
                    ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditorUtilities.RefreshMap(this.ParentEditor, null);
                    this.CallbackResults.CopyFrom(this.ParentEditor.Map.CallbackResults);

                    // Refresh toolbars
                    this.ParentEditor.RefreshToolbars(this.CallbackResults);
                }

                // Create callback result that calls JavaScript to hide AJAX activity indicator
                string jsHideIndicator = string.Format("hideSimpleQueryIndicator();");
                ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult hideIndicatorCallbackResult =
                    ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsHideIndicator);
                this.CallbackResults.Add(hideIndicatorCallbackResult);
            }
            else
            {
                base.RaiseCallbackEvent(eventArgs);
            }

        }

        public override string GetCallbackResult()
        {
            // If the callback was initiated by a query operation, return the panel's callback results
            if (m_callbackArgsCollection["EventArg"] == "query")
                return this.CallbackResults.ToString();
            else
                return base.GetCallbackResult();
        }

        #endregion

        #region Instance Properties

        // Name of object ID field of selected layer
        protected string OIDfieldName
        {
            get
            {
                return (string)StateManager.GetProperty("selectedLayerOIDfield");
            }
            set
            {
                StateManager.SetProperty("selectedLayerOIDfield", value);
            }
        }

        // Easy access to the CustomEditor containing the panel instance
        protected CustomEditor CustomEditorInstance
        {
            get { return (CustomEditor)this.ParentEditor; }
        }

        #endregion
    }
}