using System; using System.Linq; using System.Web.UI; using System.Web.UI.WebControls; using System.Xml.XPath; using umbraco.cms.businesslogic.datatype; namespace umbraco.editorControls.XPathDropDownList { class XPathDropDownListPreValueEditor : AbstractJsonPrevalueEditor { /// /// Radio buttons to select type of node to pick from: Content / Media / Members /// private RadioButtonList typeRadioButtonList = new RadioButtonList(); /// /// TextBox control to get the XPath expression /// private TextBox xPathTextBox = new TextBox(); /// /// RequiredFieldValidator to ensure an XPath expression has been entered /// private RequiredFieldValidator xPathRequiredFieldValidator = new RequiredFieldValidator(); /// /// Server side validation of XPath expression /// private CustomValidator xPathCustomValidator = new CustomValidator(); /// /// Drop Down List to pick either Node Name or Node Id /// private DropDownList valueTypeDropDownList = new DropDownList(); /// /// Data object used to define the configuration status of this PreValueEditor /// private XPathDropDownListOptions options = null; /// /// Gets the options data object that represents the current state of this datatypes configuration /// internal XPathDropDownListOptions Options { get { if (this.options == null) { // Deserialize any stored settings for this PreValueEditor instance this.options = this.GetPreValueOptions(); // If still null, ie, object couldn't be de-serialized from PreValue[0] string value if (this.options == null) { // Create a new Options data object with the default values this.options = new XPathDropDownListOptions(); } } return this.options; } } /// /// Initialize a new instance of XPathCheckBoxlistPreValueEditor /// /// XPathCheckBoxListDataType public XPathDropDownListPreValueEditor(umbraco.cms.businesslogic.datatype.BaseDataType dataType) : base(dataType, umbraco.cms.businesslogic.datatype.DBTypes.Nvarchar) { } /// /// Creates all of the controls and assigns all of their properties /// protected override void CreateChildControls() { //radio buttons to select type of nodes that can be picked (Document, Media or Member) this.typeRadioButtonList.Items.Add(new ListItem(uQuery.UmbracoObjectType.Document.GetFriendlyName(), uQuery.UmbracoObjectType.Document.GetGuid().ToString())); this.typeRadioButtonList.Items.Add(new ListItem(uQuery.UmbracoObjectType.Media.GetFriendlyName(), uQuery.UmbracoObjectType.Media.GetGuid().ToString())); this.typeRadioButtonList.Items.Add(new ListItem(uQuery.UmbracoObjectType.Member.GetFriendlyName(), uQuery.UmbracoObjectType.Member.GetGuid().ToString())); this.xPathTextBox.ID = "xPathTextBox"; this.xPathTextBox.CssClass = "umbEditorTextField"; this.xPathRequiredFieldValidator.ControlToValidate = this.xPathTextBox.ID; this.xPathRequiredFieldValidator.Display = ValidatorDisplay.Dynamic; this.xPathRequiredFieldValidator.ErrorMessage = " XPath expression required"; this.xPathCustomValidator.ControlToValidate = this.xPathTextBox.ID; this.xPathCustomValidator.Display = ValidatorDisplay.Dynamic; this.xPathCustomValidator.ServerValidate += new ServerValidateEventHandler(this.XPathCustomValidator_ServerValidate); this.valueTypeDropDownList.ID = "valueTypeDropDownList"; this.valueTypeDropDownList.Items.Add(new ListItem("Node Id", bool.TrueString)); this.valueTypeDropDownList.Items.Add(new ListItem("Node Name", bool.FalseString)); this.Controls.AddPrevalueControls( this.typeRadioButtonList, this.xPathTextBox, this.xPathRequiredFieldValidator, this.xPathCustomValidator, this.valueTypeDropDownList); } /// /// /// /// protected override void OnLoad(EventArgs e) { base.OnLoad(e); // Read in stored configuration values this.typeRadioButtonList.SelectedValue = this.Options.Type; this.xPathTextBox.Text = this.Options.XPath; this.valueTypeDropDownList.SelectedValue = this.Options.UseId.ToString(); } /// /// Will run the entered XPath expression to ensure it returns a collection /// /// xPathCustomValidator /// private void XPathCustomValidator_ServerValidate(object source, ServerValidateEventArgs args) { string xPath = args.Value; bool isValid = false; try { switch (this.options.UmbracoObjectType) { case uQuery.UmbracoObjectType.Document: if (uQuery.GetNodesByXPath(xPath).Count() >= 0) { isValid = true; } break; case uQuery.UmbracoObjectType.Media: if (uQuery.GetMediaByXPath(xPath).Count() >= 0) { isValid = true; } break; case uQuery.UmbracoObjectType.Member: if (uQuery.GetMembersByXPath(xPath).Count() >= 0) { isValid = true; } break; } } catch (XPathException) { this.xPathCustomValidator.ErrorMessage = " Syntax error in XPath expression"; } args.IsValid = isValid; } /// /// Saves the pre value data to Umbraco /// public override void Save() { if (this.Page.IsValid) { this.Options.Type = this.typeRadioButtonList.SelectedValue; this.Options.XPath = this.xPathTextBox.Text; this.Options.UseId = bool.Parse(this.valueTypeDropDownList.SelectedValue); this.SaveAsJson(this.Options); // Serialize to Umbraco database field } } /// /// Replaces the base class writer and instead uses the shared uComponents extension method, to inject consistant markup /// /// protected override void RenderContents(HtmlTextWriter writer) { writer.AddPrevalueRow( "Type", "the xml schema to query", this.typeRadioButtonList); writer.AddPrevalueRow( "XPath Expression", "can use the tokens $ancestorOrSelf, $parentPage and $currentPage", this.xPathTextBox, this.xPathRequiredFieldValidator, this.xPathCustomValidator); writer.AddPrevalueRow( "Value", "store the node id or the name", this.valueTypeDropDownList); } } }