Common Custom EditorTask
Common_CustomEditorTask_VBNet\CustomEditorTask_VBNet\QueryBuilderPanel.vb
' Copyright 2011 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.
' 

Imports Microsoft.VisualBasic
Imports System
Namespace CustomEditorTask_VBNet

    <AjaxControlToolkit.ClientScriptResource("CustomEditorTask_VBNet.QueryBuilderPanel", "QueryBuilderPanel.js")> _
    Friend Class QueryBuilderPanel
        Inherits ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditorPanel
#Region "Instance Variable Declarations"

        Private m_lblFields As System.Web.UI.WebControls.Label
        Private m_ddFields As System.Web.UI.WebControls.DropDownList
        Private m_lblOperator As System.Web.UI.WebControls.Label
        Private m_ddOperators As System.Web.UI.WebControls.DropDownList
        Private m_lblValues As System.Web.UI.WebControls.Label
        Private m_ddValues As System.Web.UI.WebControls.DropDownList
        Private m_btnAddToQuery As System.Web.UI.WebControls.Button
        Private m_btnAnd As System.Web.UI.WebControls.Button
        Private m_btnOr As System.Web.UI.WebControls.Button
        Private m_btnNot As System.Web.UI.WebControls.Button
        Private m_btnLtPara As System.Web.UI.WebControls.Button
        Private m_btnRtPara As System.Web.UI.WebControls.Button
        Private m_btnPct As System.Web.UI.WebControls.Button
        Private m_btnUnderscore As System.Web.UI.WebControls.Button
        Private m_txtQuery As System.Web.UI.WebControls.TextBox
        Private m_btnClearQuery As System.Web.UI.WebControls.Button
        Private m_btnDoQuery As System.Web.UI.WebControls.Button

#End Region

#Region "Constructor"

        Public Sub New(ByVal editorTask As ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditorTask)
            MyBase.New("Query Builder", editorTask, "queryBuilderPanel")
            AddHandler ParentEditor.LayerChanged, AddressOf ParentEditor_LayerChanged
        End Sub

#End Region

#Region "WebControl Life Cycle Event Overrides"

        Protected Overrides Sub OnInit(ByVal eventArgs As System.EventArgs)
            MyBase.OnInit(eventArgs)
            ' Set height to limit the amount of screen space occupied by the panel
            Me.Height = System.Web.UI.WebControls.Unit.Pixel(200)
        End Sub

        ' Instantiate the panel's child controls
        Protected Overrides Sub CreateChildControls()
            MyBase.CreateChildControls()

            ' Instantiate panel controls and add them to the custom panel's controls collection

            ' Label for the Fields drop-down
            m_lblFields = New System.Web.UI.WebControls.Label()
            m_lblFields.ID = "lblFields"
            m_lblFields.Text = "Fields:"
            Controls.Add(m_lblFields)

            ' Fields drop-down
            m_ddFields = New System.Web.UI.WebControls.DropDownList()
            m_ddFields.ID = "ddFields"

            ' Initialization of items in the fields drop-down.  Necessary include logic for doing this here
            ' in case only one version is available for editing.  In that case, the controls will not be
            ' instantiated before the layer changed event fires
            Dim fieldsInit As Boolean = False
            If CustomEditorInstance.FeatureLayer IsNot Nothing Then
                ' Get fields and add to fields drop-down
                Dim fields As String = CustomUtilities.GetFields(CustomEditorInstance)
                Dim delimiter() As Char = {":"c}
                Dim fieldList() As String = fields.Split(delimiter, System.StringSplitOptions.RemoveEmptyEntries)
                For i As Integer = 0 To fieldList.Length - 1
                    m_ddFields.Items.Add(fieldList(i))
                Next i

                fieldsInit = True
            End If
            Controls.Add(m_ddFields)

            ' Label for operator drop-down
            m_lblOperator = New System.Web.UI.WebControls.Label()
            m_lblOperator.ID = "lblOperator"
            m_lblOperator.Text = "Operators:"
            Controls.Add(m_lblOperator)

            ' Operator drop-down initialization
            m_ddOperators = New System.Web.UI.WebControls.DropDownList()
            m_ddOperators.ID = "ddOperators"
            m_ddOperators.Items.Add("=")
            m_ddOperators.Items.Add(">")
            m_ddOperators.Items.Add("<")
            m_ddOperators.Items.Add(">=")
            m_ddOperators.Items.Add("<=")
            m_ddOperators.Items.Add("LIKE")
            Controls.Add(m_ddOperators)

            ' Label for sample values drop-down
            m_lblValues = New System.Web.UI.WebControls.Label()
            m_lblValues.ID = "lblValues"
            m_lblValues.Text = "Sample Values:"
            Controls.Add(m_lblValues)

            ' Sample values drop-down initialization
            m_ddValues = New System.Web.UI.WebControls.DropDownList()
            m_ddValues.ID = "ddValues"

            If fieldsInit Then
                'get sample values and add to sample values drop-down
                Dim samples As String = CustomUtilities.GetSampleValues(m_ddFields.Items(m_ddFields.SelectedIndex).Text, Me.ParentEditor)
                Dim delimiter() As Char = {":"c}
                Dim sampleList() As String = samples.Split(delimiter, System.StringSplitOptions.RemoveEmptyEntries)

                Dim nvcSampleList As New System.Collections.Specialized.NameValueCollection()

                System.Array.Sort(sampleList)
                For i As Integer = 0 To sampleList.Length - 1
                    m_ddValues.Items.Add(sampleList(i))
                Next i
            End If
            Controls.Add(m_ddValues)

            ' Add to query button 
            m_btnAddToQuery = New System.Web.UI.WebControls.Button()
            m_btnAddToQuery.ID = "btnAddToQuery"
            m_btnAddToQuery.Text = "Add to Query"
            Controls.Add(m_btnAddToQuery)

            ' Left parentheses button
            m_btnLtPara = New System.Web.UI.WebControls.Button()
            m_btnLtPara.ID = "btnLtPara"
            m_btnLtPara.Text = "("
            Controls.Add(m_btnLtPara)

            ' Right parentheses button
            m_btnRtPara = New System.Web.UI.WebControls.Button()
            m_btnRtPara.ID = "btnRtPara"
            m_btnRtPara.Text = ")"
            Controls.Add(m_btnRtPara)

            ' Percent button
            m_btnPct = New System.Web.UI.WebControls.Button()
            m_btnPct.ID = "btnPct"
            m_btnPct.Text = "%"
            Controls.Add(m_btnPct)

            ' Underscore button
            m_btnUnderscore = New System.Web.UI.WebControls.Button()
            m_btnUnderscore.ID = "btnUnderscore"
            m_btnUnderscore.Text = "_"
            Controls.Add(m_btnUnderscore)

            ' AND button
            m_btnAnd = New System.Web.UI.WebControls.Button()
            m_btnAnd.ID = "btnAnd"
            m_btnAnd.Text = " AND "
            Controls.Add(m_btnAnd)

            ' OR button
            m_btnOr = New System.Web.UI.WebControls.Button()
            m_btnOr.ID = "btnOr"
            m_btnOr.Text = " OR "
            Controls.Add(m_btnOr)

            ' NOT button
            m_btnNot = New System.Web.UI.WebControls.Button()
            m_btnNot.ID = "btnNot"
            m_btnNot.Text = " NOT "
            Controls.Add(m_btnNot)

            ' Query textbox
            m_txtQuery = New System.Web.UI.WebControls.TextBox()
            m_txtQuery.ID = "txtQuery"
            m_txtQuery.TextMode = System.Web.UI.WebControls.TextBoxMode.MultiLine
            m_txtQuery.Wrap = True
            m_txtQuery.Height = CType(80, System.Web.UI.WebControls.Unit)
            Controls.Add(m_txtQuery)

            ' Clear query button
            m_btnClearQuery = New System.Web.UI.WebControls.Button()
            m_btnClearQuery.ID = "btnClearQuery"
            m_btnClearQuery.Text = "Clear"
            Controls.Add(m_btnClearQuery)

            ' Execute query button
            m_btnDoQuery = New System.Web.UI.WebControls.Button()
            m_btnDoQuery.ID = "btnDoQuery"
            m_btnDoQuery.Text = "Execute"
            Controls.Add(m_btnDoQuery)
        End Sub

        Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)
            MyBase.OnPreRender(e)

            ' Register the JavaScript file containing client-side functions used by the panel
            'System.Web.UI.ScriptManager.RegisterClientScriptResource((System.Web.UI.Control)this, this.GetType(),
            '    "CustomEditorTask_CSharp.javascript.QueryBuilderPanel.js");

            ' Initialize the OIDFieldName property
            Me.OIDfieldName = CustomEditorInstance.FeatureLayer.FeatureClass.OIDFieldName
        End Sub

        ' Render the panel's child controls
        Protected Overrides Sub RenderContents(ByVal writer As System.Web.UI.HtmlTextWriter)
            If ParentEditor.MapResource Is Nothing Then
                Return
            End If
            ' ==Format the layout of controls on the panel and wire necessary JavaScript

            ' Render a table to contain the panel's controls
            writer.AddAttribute(System.Web.UI.HtmlTextWriterAttribute.Cellpadding, "3px")
            writer.AddStyleAttribute(System.Web.UI.HtmlTextWriterStyle.OverflowY, "auto")
            writer.AddStyleAttribute(System.Web.UI.HtmlTextWriterStyle.Width, "90%")
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Table)

            ' Fields label and drop-down
            writer.AddStyleAttribute(System.Web.UI.HtmlTextWriterStyle.WhiteSpace, "nowrap")
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Tr)
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Td)

            m_lblFields.RenderControl(writer)
            writer.Write("&nbsp;&nbsp;")
            ' Link a JavaScript call to getValues to the onchange event of the Fields drop-down.  this will call
            ' getValues when the user selects a new field.
            Dim jsOnChange As String = System.String.Format("javascript:getValues('{0}','{1}','{2}')", m_ddFields.ClientID, m_ddValues.ClientID, Me.CallbackFunctionString.Replace("'", "\'"))
            m_ddFields.Attributes.Add("onchange", jsOnChange)
            m_ddFields.RenderControl(writer)

            writer.RenderEndTag() 'td
            writer.RenderEndTag() 'tr

            ' Operator label and drop-down
            writer.AddStyleAttribute(System.Web.UI.HtmlTextWriterStyle.WhiteSpace, "nowrap")
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Tr)
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Td)

            m_lblOperator.RenderControl(writer)
            writer.Write("&nbsp;&nbsp;")
            m_ddOperators.RenderControl(writer)

            writer.RenderEndTag() 'td
            writer.RenderEndTag() 'tr

            ' Values label and drop-down
            writer.AddStyleAttribute(System.Web.UI.HtmlTextWriterStyle.WhiteSpace, "nowrap")
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Tr)
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Td)

            m_lblValues.RenderControl(writer)
            writer.Write("&nbsp;&nbsp;")
            m_ddValues.RenderControl(writer)

            writer.RenderEndTag() 'td
            writer.RenderEndTag() ' tr

            ' Add to query button
            writer.AddStyleAttribute(System.Web.UI.HtmlTextWriterStyle.TextAlign, "center")
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Tr)
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Td)

            ' link JavaScript call to addToQuery to the onclick event.
            m_btnAddToQuery.OnClientClick = String.Format("addToQuery('{0}', '{1}', '{2}', '{3}')", m_ddFields.ClientID, m_ddOperators.ClientID, m_ddValues.ClientID, m_txtQuery.ClientID)
            m_btnAddToQuery.RenderControl(writer)

            writer.RenderEndTag() ' td
            writer.RenderEndTag() ' tr

            ' hr to separate sections of panel
            writer.AddStyleAttribute(System.Web.UI.HtmlTextWriterStyle.TextAlign, "center")
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Tr)
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Td)
            writer.AddStyleAttribute(System.Web.UI.HtmlTextWriterStyle.Width, "80%")
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Hr)
            writer.RenderEndTag() 'hr
            writer.RenderEndTag() 'td
            writer.RenderEndTag() ' tr

            ' Parentheses, percent, and underscore buttons
            writer.AddStyleAttribute(System.Web.UI.HtmlTextWriterStyle.WhiteSpace, "nowrap")
            writer.AddStyleAttribute(System.Web.UI.HtmlTextWriterStyle.TextAlign, "center")
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Tr)
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Td)

            ' Format JavaScript to add the text of the button clicked to query.
            Dim onclick As String = String.Format("var txt = document.getElementById('{0}');" & "txt.innerHTML += this.value; txt.focus();", m_txtQuery.ClientID)

            m_btnLtPara.OnClientClick = onclick
            m_btnLtPara.RenderControl(writer)
            writer.Write("&nbsp;&nbsp;")
            m_btnRtPara.OnClientClick = onclick
            m_btnRtPara.RenderControl(writer)
            writer.Write("&nbsp;&nbsp;")
            m_btnPct.OnClientClick = onclick
            m_btnPct.RenderControl(writer)
            writer.Write("&nbsp;&nbsp;")
            m_btnUnderscore.OnClientClick = onclick
            m_btnUnderscore.RenderControl(writer)
            writer.Write("&nbsp;&nbsp;")

            writer.RenderEndTag() ' td
            writer.RenderEndTag() ' tr

            'AND, OR, and NOT buttons
            writer.AddStyleAttribute(System.Web.UI.HtmlTextWriterStyle.WhiteSpace, "nowrap")
            writer.AddStyleAttribute(System.Web.UI.HtmlTextWriterStyle.TextAlign, "center")
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Tr)
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Td)

            m_btnAnd.OnClientClick = onclick
            m_btnAnd.RenderControl(writer)
            writer.Write("&nbsp;&nbsp;")
            m_btnOr.OnClientClick = onclick
            m_btnOr.RenderControl(writer)
            writer.Write("&nbsp;&nbsp;")
            m_btnNot.OnClientClick = onclick
            m_btnNot.RenderControl(writer)

            writer.RenderEndTag() 'td
            writer.RenderEndTag() ' tr

            ' hr to separate sections of panel
            writer.AddStyleAttribute(System.Web.UI.HtmlTextWriterStyle.TextAlign, "center")
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Tr)
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Td)
            writer.AddStyleAttribute(System.Web.UI.HtmlTextWriterStyle.Width, "80%")
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Hr)
            writer.RenderEndTag() 'hr
            writer.RenderEndTag() 'td
            writer.RenderEndTag() ' tr

            ' Query textbox
            writer.AddStyleAttribute(System.Web.UI.HtmlTextWriterStyle.TextAlign, "center")
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Tr)
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Td)

            writer.AddStyleAttribute(System.Web.UI.HtmlTextWriterStyle.Width, "100%")
            m_txtQuery.RenderControl(writer)

            writer.RenderEndTag() ' td
            writer.RenderEndTag() ' tr

            ' Clear Query and Execute buttons
            writer.AddStyleAttribute(System.Web.UI.HtmlTextWriterStyle.WhiteSpace, "nowrap")
            writer.AddStyleAttribute(System.Web.UI.HtmlTextWriterStyle.TextAlign, "center")
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Tr)
            writer.RenderBeginTag(System.Web.UI.HtmlTextWriterTag.Td)

            ' Link JavaScript to clear query text to fire when the Clear Query button is clicked.
            m_btnClearQuery.OnClientClick = String.Format("document.getElementById('{0}').innerHTML = ''", m_txtQuery.ClientID)
            m_btnClearQuery.RenderControl(writer)
            writer.Write("&nbsp;&nbsp;")
            ' Link JavaScript call to doQuery to fire when Execute button is clicked.
            m_btnDoQuery.OnClientClick = String.Format("doQuery('{0}','{1}')", m_txtQuery.ClientID, Me.CallbackFunctionString.Replace("'", "\'"))
            m_btnDoQuery.RenderControl(writer)

            writer.RenderEndTag() ' td
            writer.RenderEndTag() ' tr
            writer.RenderEndTag() ' table

        End Sub

#End Region

#Region "Web ADF Event Handlers"

        Private Sub ParentEditor_LayerChanged(ByVal featureLayer As ESRI.ArcGIS.Carto.IFeatureLayer)
            If m_ddFields IsNot Nothing Then
                ' Get object ID field
                Me.OIDfieldName = featureLayer.FeatureClass.OIDFieldName

                Dim fieldList As String = CustomUtilities.GetFields(CustomEditorInstance)

                ' Format JavaScript to populate the fields drop-down list and add to callback results
                Dim jsPopulateFieldsDropDown As String = String.Format("populateDropDown('{0}', '{1}');", m_ddFields.ClientID, fieldList)
                Dim populateFieldsCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsPopulateFieldsDropDown)
                Me.ParentEditor.CallbackResults.Add(populateFieldsCallbackResult)

                ' Put the fields contained in the fieldList string into a string array
                Dim separator() As Char = {":"c}
                Dim fieldsArray() As String = fieldList.Split(separator, System.StringSplitOptions.RemoveEmptyEntries)

                ' Get list of sample values for the first field in the fields list
                Dim sampleValueList As String = CustomUtilities.GetSampleValues(fieldsArray(0), Me.ParentEditor)
                ' Construct JavaScript call to populateDropDown to populate sample values based on the field selected
                Dim jsPopulateSampleValuesDropDown As String = String.Format("populateDropDown('{0}', '{1}', '{2}');", m_ddValues.ClientID, sampleValueList, "true")

                ' Create new callback result from JavaScript call and add to callback results
                Dim populateSampleValuesCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsPopulateSampleValuesDropDown)
                Me.ParentEditor.CallbackResults.Add(populateSampleValuesCallbackResult)

                ' Format JavaScript to clear the query textbox and add to callback results
                Dim jsClearQueryTextbox As String = String.Format("document.getElementById('{0}').innerHTML = ''", m_txtQuery.ClientID)
                Dim clearQueryCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsClearQueryTextbox)
                Me.ParentEditor.CallbackResults.Add(clearQueryCallbackResult)
            End If
        End Sub

#End Region ';

#Region "Callback Handler"

        Public Overrides Function GetCallbackResult() As String
            ' Replace HTML reserved character codes in the callback argument  
            Dim callbackArgument As String = Me.CallbackEventArgument.Replace("&gt;", ">")
            callbackArgument = callbackArgument.Replace("&lt;", "<")

            ' Parse callback arguments using the CallbackUtility included with Web ADF.
            ' The CallbackEventArgument is a member variable inherited from 
            ' ESRI.ArcGIS.ADF.Web.UI.WebControls.CompositeControl.  During a callback, it 
            ' contains the string argument passed to RaiseCallbackEvent().
            Dim nvcCallbackArgs As System.Collections.Specialized.NameValueCollection = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackUtility.ParseStringIntoNameValueCollection(callbackArgument)

            ' Get value of EventArg
            Dim eventArg As String = nvcCallbackArgs("EventArg")

            ' Check eventArg and take action accordingly
            If eventArg = "fieldSelected" Then
                ' Get list of sample values
                Dim sampleValuesList As String = CustomUtilities.GetSampleValues(nvcCallbackArgs("field"), Me.ParentEditor)

                ' Construct JavaScript call to populateDropDown to populate sample values based on field selected
                Dim jsPopulateSampleValuesDropDown As String = String.Format("populateDropDown('{0}', '{1}', '{2}');", m_ddValues.ClientID, sampleValuesList, "true")

                ' Create new callback result with JavaScript call and add to collection
                Dim populateSampleValuesCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsPopulateSampleValuesDropDown)
                Me.CallbackResults.Add(populateSampleValuesCallbackResult)

                'return callback results
                Return Me.CallbackResults.ToString()
            ElseIf eventArg = "doQuery" Then
                ' Replace aliases in query string with actual database field names
                Dim query As String = Me.ReplaceAliases(nvcCallbackArgs("query"))

                ' Exit without returning results if query is null
                If query Is Nothing Then
                    Return Nothing
                End If

                ' Get IDs of features satisfying query
                Dim ids() As Integer = CustomUtilities.DoQuery(query, Me.ParentEditor)

                ' Get LayerDescription object for currently selected layer
                Dim adfLayerDescription As ESRI.ArcGIS.ADF.ArcGISServer.LayerDescription = ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditorUtilities.GetLayerDescription(Me.ParentEditor.MapFunctionality, Me.ParentEditor.SelectedLayerID)

                Dim selectionChanged As Boolean
                Dim selectedIDsArray As System.Collections.Generic.List(Of Integer) = CustomUtilities.UpdateSelection(adfLayerDescription.SelectionFeatures, ids, selectionChanged, Me.ParentEditor.EditorTask)

                ' Exit function without returning callback results if selection is unchanged
                If (Not selectionChanged) Then
                    Return Nothing
                End If

                ' Set selected features on layer currently being edited
                adfLayerDescription.SelectionFeatures = selectedIDsArray.ToArray()

                ' Get attributes panel and set to edit the attributes of selected features
                Dim editAttributesPanel As ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditAttributesPanel = CType(Me.ParentEditor.AttributesEditor, ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditAttributesPanel)
                Dim editAttributesPanelCallbackResultsCollection As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection = editAttributesPanel.SetSelectedFeatures(adfLayerDescription.SelectionFeatures)
                Me.CallbackResults.CopyFrom(editAttributesPanelCallbackResultsCollection)

                ' Refresh map
                ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditorUtilities.RefreshMap(Me.ParentEditor, Me.CallbackResults)
                Me.CallbackResults.CopyFrom(Me.ParentEditor.Map.CallbackResults)

                ' Refresh toolbars
                Me.ParentEditor.RefreshToolbars(Me.CallbackResults)

                ' Create callback result that calls JavaScript to hide AJAX activity indicator
                Dim jsHideIndicator As String = String.Format("showEditorElement(false,'{0}');", "ajaxActivityID")
                Dim hideActivityIndicatorCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsHideIndicator)
                Me.CallbackResults.Add(hideActivityIndicatorCallbackResult)

                ' Return callback results
                Return Me.CallbackResults.ToString()
            Else
                Return MyBase.GetCallbackResult()
            End If
        End Function

#End Region

#Region "Instance Properties"

        ' Name of object ID field of selected layer
        Protected Property OIDfieldName() As String
            Get
                Return CStr(StateManager.GetProperty("selectedLayerOIDfield"))
            End Get
            Set(ByVal value As String)
                StateManager.SetProperty("selectedLayerOIDfield", value)
            End Set
        End Property

        ' Easy access to the CustomEditor containing the panel instance
        Protected ReadOnly Property CustomEditorInstance() As CustomEditor
            Get
                Return CType(Me.ParentEditor, CustomEditor)
            End Get
        End Property

#End Region

#Region "Instance Methods"

        ' Replace field aliases in passed-in string with corresponding actual database field names
        Private Function ReplaceAliases(ByVal query As String) As String
            ' Rebuild query string, replacing aliases with database field names
            Dim newQuery As String = query.Substring(0, query.IndexOf("["))
            query = query.Substring(query.IndexOf("["))

            Dim [alias] As String = Nothing
            Dim field As String = Nothing
            Do
                ' Get alias from query string
                [alias] = query.Substring(1, query.IndexOf("]") - 1)
                ' Get database field name of alias
                field = CustomUtilities.GetFieldName([alias], CustomEditorInstance)
                If field Is Nothing Then
                    Return Nothing
                End If

                query = query.Substring(query.IndexOf("]") + 1)

                If query.IndexOf("[") > -1 Then
                    newQuery &= field & query.Substring(0, query.IndexOf("["))
                    query = query.Substring(query.IndexOf("["))
                Else
                    newQuery &= field & query
                End If
            Loop While query.IndexOf("]") > -1

            Return newQuery
        End Function

#End Region
    End Class
End Namespace