Common_CustomEditorTask_CSharp\CustomEditorTask_CSharp\QueryBuilderPanel.cs
// 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. // namespace CustomEditorTask_CSharp { [AjaxControlToolkit.ClientScriptResource("QueryBuilderPanel.js", "CustomEditorTask_CSharp.javascript.QueryBuilderPanel.js")] class QueryBuilderPanel : ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditorPanel { #region Instance Variable Declarations private System.Web.UI.WebControls.Label m_lblFields; private System.Web.UI.WebControls.DropDownList m_ddFields; private System.Web.UI.WebControls.Label m_lblOperator; private System.Web.UI.WebControls.DropDownList m_ddOperators; private System.Web.UI.WebControls.Label m_lblValues; private System.Web.UI.WebControls.DropDownList m_ddValues; private System.Web.UI.WebControls.Button m_btnAddToQuery; private System.Web.UI.WebControls.Button m_btnAnd; private System.Web.UI.WebControls.Button m_btnOr; private System.Web.UI.WebControls.Button m_btnNot; private System.Web.UI.WebControls.Button m_btnLtPara; private System.Web.UI.WebControls.Button m_btnRtPara; private System.Web.UI.WebControls.Button m_btnPct; private System.Web.UI.WebControls.Button m_btnUnderscore; private System.Web.UI.WebControls.TextBox m_txtQuery; private System.Web.UI.WebControls.Button m_btnClearQuery; private System.Web.UI.WebControls.Button m_btnDoQuery; #endregion #region Constructor public QueryBuilderPanel(ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditorTask editorTask) : base("Query Builder", editorTask, "queryBuilderPanel") { this.ParentEditor.LayerChanged += new ESRI.ArcGIS.ADF.ArcGISServer.Editor.Editor.LayerChangedHandler(ParentEditor_LayerChanged); } #endregion #region WebControl Life Cycle Event Overrides protected override void OnInit(System.EventArgs eventArgs) { base.OnInit(eventArgs); // Set height to limit the amount of screen space occupied by the panel this.Height = System.Web.UI.WebControls.Unit.Pixel(200); } // Instantiate the panel's child controls protected override void CreateChildControls() { base.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 bool fieldsInit = false; if (CustomEditorInstance.FeatureLayer != null) { // Get fields and add to fields drop-down string fields = CustomUtilities.GetFields(CustomEditorInstance); char[] delimiter = { ':' }; string[] fieldList = fields.Split(delimiter, System.StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < fieldList.Length; i++) { m_ddFields.Items.Add(fieldList[i]); } fieldsInit = true; } 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) { //get sample values and add to sample values drop-down string samples = CustomUtilities.GetSampleValues(m_ddFields.Items[m_ddFields.SelectedIndex].Text, this.ParentEditor); char[] delimiter = { ':' }; string[] sampleList = samples.Split(delimiter, System.StringSplitOptions.RemoveEmptyEntries); System.Collections.Specialized.NameValueCollection nvcSampleList = new System.Collections.Specialized.NameValueCollection(); System.Array.Sort(sampleList); for (int i = 0; i < sampleList.Length; i++) { m_ddValues.Items.Add(sampleList[i]); } } 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 = (System.Web.UI.WebControls.Unit)80; 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); } protected override void OnPreRender(System.EventArgs e) { base.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 this.OIDfieldName = CustomEditorInstance.FeatureLayer.FeatureClass.OIDFieldName; } // Render the panel's child controls protected override void RenderContents(System.Web.UI.HtmlTextWriter writer) { if (ParentEditor.MapResource == null) return; // ==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(" "); // 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. string jsOnChange = System.String.Format("javascript:getValues('{0}','{1}','{2}')", m_ddFields.ClientID, m_ddValues.ClientID, this.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(" "); 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(" "); 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. string onclick = 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(" "); m_btnRtPara.OnClientClick = onclick; m_btnRtPara.RenderControl(writer); writer.Write(" "); m_btnPct.OnClientClick = onclick; m_btnPct.RenderControl(writer); writer.Write(" "); m_btnUnderscore.OnClientClick = onclick; m_btnUnderscore.RenderControl(writer); writer.Write(" "); 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(" "); m_btnOr.OnClientClick = onclick; m_btnOr.RenderControl(writer); writer.Write(" "); 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(" "); // Link JavaScript call to doQuery to fire when Execute button is clicked. m_btnDoQuery.OnClientClick = string.Format("doQuery('{0}','{1}')", m_txtQuery.ClientID, this.CallbackFunctionString.Replace("'", "\\'")); m_btnDoQuery.RenderControl(writer); writer.RenderEndTag(); // td writer.RenderEndTag(); // tr writer.RenderEndTag(); // table } #endregion #region Web ADF Event Handlers void ParentEditor_LayerChanged(ESRI.ArcGIS.Carto.IFeatureLayer featureLayer) { if (m_ddFields != null) { // Get object ID field this.OIDfieldName = featureLayer.FeatureClass.OIDFieldName; string fieldList = CustomUtilities.GetFields(CustomEditorInstance); // Format JavaScript to populate the fields drop-down list and add to callback results string jsPopulateFieldsDropDown = string.Format("populateDropDown('{0}', '{1}');", m_ddFields.ClientID, fieldList); ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult populateFieldsCallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsPopulateFieldsDropDown); this.ParentEditor.CallbackResults.Add(populateFieldsCallbackResult); // Put the fields contained in the fieldList string into a string array char[] separator = { ':' }; string[] fieldsArray = fieldList.Split(separator, System.StringSplitOptions.RemoveEmptyEntries); // Get list of sample values for the first field in the fields list string sampleValueList = CustomUtilities.GetSampleValues(fieldsArray[0], this.ParentEditor); // Construct JavaScript call to populateDropDown to populate sample values based on the field selected string jsPopulateSampleValuesDropDown = string.Format("populateDropDown('{0}', '{1}', '{2}');", m_ddValues.ClientID, sampleValueList, "true"); // Create new callback result from JavaScript call and add to callback results ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult populateSampleValuesCallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsPopulateSampleValuesDropDown); this.ParentEditor.CallbackResults.Add(populateSampleValuesCallbackResult); // Format JavaScript to clear the query textbox and add to callback results string jsClearQueryTextbox = string.Format("document.getElementById('{0}').innerHTML = ''", m_txtQuery.ClientID); ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult clearQueryCallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsClearQueryTextbox); this.ParentEditor.CallbackResults.Add(clearQueryCallbackResult); } } #endregion; #region Callback Handler public override string GetCallbackResult() { // Replace HTML reserved character codes in the callback argument string callbackArgument = this.CallbackEventArgument.Replace(">", ">"); callbackArgument = callbackArgument.Replace("<", "<"); // 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(). System.Collections.Specialized.NameValueCollection nvcCallbackArgs = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackUtility.ParseStringIntoNameValueCollection(callbackArgument); // Get value of EventArg string eventArg = nvcCallbackArgs["EventArg"]; // Check eventArg and take action accordingly if (eventArg == "fieldSelected") { // Get list of sample values string sampleValuesList = CustomUtilities.GetSampleValues(nvcCallbackArgs["field"], this.ParentEditor); // Construct JavaScript call to populateDropDown to populate sample values based on field selected string jsPopulateSampleValuesDropDown = string.Format("populateDropDown('{0}', '{1}', '{2}');", m_ddValues.ClientID, sampleValuesList, "true"); // Create new callback result with JavaScript call and add to collection ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult populateSampleValuesCallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsPopulateSampleValuesDropDown); this.CallbackResults.Add(populateSampleValuesCallbackResult); //return callback results return this.CallbackResults.ToString(); } else if (eventArg == "doQuery") { // Replace aliases in query string with actual database field names string query = this.ReplaceAliases(nvcCallbackArgs["query"]); // Exit without returning results if query is null if (query == null) return null; // Get IDs of features satisfying query int[] ids = CustomUtilities.DoQuery(query, this.ParentEditor); // Get LayerDescription object for currently selected layer ESRI.ArcGIS.ADF.ArcGISServer.LayerDescription adfLayerDescription = ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditorUtilities.GetLayerDescription( this.ParentEditor.MapFunctionality, this.ParentEditor.SelectedLayerID); bool selectionChanged; System.Collections.Generic.List<int> selectedIDsArray = CustomUtilities.UpdateSelection(adfLayerDescription.SelectionFeatures, ids, out selectionChanged, this.ParentEditor.EditorTask); // Exit function without returning callback results if selection is unchanged if (!selectionChanged) return null; // Set selected features on layer currently being edited adfLayerDescription.SelectionFeatures = selectedIDsArray.ToArray(); // Get attributes panel and set to edit the attributes of selected features ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditAttributesPanel editAttributesPanel = (ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditAttributesPanel)this.ParentEditor.AttributesEditor; ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection editAttributesPanelCallbackResultsCollection = editAttributesPanel.SetSelectedFeatures(adfLayerDescription.SelectionFeatures); this.CallbackResults.CopyFrom(editAttributesPanelCallbackResultsCollection); // Refresh map ESRI.ArcGIS.ADF.ArcGISServer.Editor.EditorUtilities.RefreshMap(this.ParentEditor, this.CallbackResults); 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("showEditorElement(false,'{0}');", "ajaxActivityID"); ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult hideActivityIndicatorCallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsHideIndicator); this.CallbackResults.Add(hideActivityIndicatorCallbackResult); // Return callback results 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 #region Instance Methods // Replace field aliases in passed-in string with corresponding actual database field names private string ReplaceAliases(string query) { // Rebuild query string, replacing aliases with database field names string newQuery = query.Substring(0, query.IndexOf("[")); query = query.Substring(query.IndexOf("[")); string alias = null; string field = null; 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 == null) return null; query = query.Substring(query.IndexOf("]") + 1); if (query.IndexOf("[") > -1) { newQuery += field + query.Substring(0, query.IndexOf("[")); query = query.Substring(query.IndexOf("[")); } else newQuery += field + query; } while (query.IndexOf("]") > -1); return newQuery; } #endregion } }