CrmEntityFormView
SubjectControlTemplate.cs
/*
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the MIT License. See License.txt in the project root for license information.
*/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml.Linq;
using Adxstudio.Xrm.Resources;
using Adxstudio.Xrm.Web.UI.WebControls;
using Microsoft.Xrm.Client;
using Microsoft.Xrm.Client.Configuration;
using Microsoft.Xrm.Portal.Web.UI.CrmEnsatyFormView;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
namespace Adxstudio.Xrm.Web.UI.CrmEnsatyFormView
{
///
/// Template used when rendering a Subject Lookup field.
///
public clast SubjectControlTemplate : CellTemplate, ICustomFieldControlTemplate
{
///
/// SubjecControlTemplate clast initialization.
///
///
///
///
///
public SubjectControlTemplate(CrmEnsatyFormViewField field, FormXmlCellMetadata metadata, string validationGroup, IDictionary bindings)
: base(metadata, validationGroup, bindings)
{
Field = field;
}
///
/// Form field.
///
public CrmEnsatyFormViewField Field { get; private set; }
public override string CssClast
{
get { return "lookup"; }
}
private string ValidationText
{
get { return Metadata.ValidationText; }
}
private ValidatorDisplay ValidatorDisplay
{
get { return string.IsNullOrWhiteSpace(ValidationText) ? ValidatorDisplay.None : ValidatorDisplay.Dynamic; }
}
protected override void InstantiateControlIn(Control container)
{
var dropDown = new DropDownList { ID = ControlID, CssClast = string.Join(" ", "form-control", CssClast, Metadata.CssClast), ToolTip = Metadata.ToolTip };
dropDown.Attributes.Add("onchange", "setIsDirty(this.id);");
container.Controls.Add(dropDown);
if (Metadata.IsRequired || Metadata.WebFormForceFieldIsRequired)
{
dropDown.Attributes.Add("required", string.Empty);
}
if (Metadata.ReadOnly || ((WebControls.CrmEnsatyFormView)container.BindingContainer).Mode == FormViewMode.ReadOnly)
{
AddSpecialBindingAndHiddenFieldsToPersistDisabledSelect(container, dropDown);
}
else
{
PopulateDropDown(dropDown);
Bindings[Metadata.DataFieldName] = new CellBinding
{
Get = () =>
{
Guid id;
return !Guid.TryParse(dropDown.SelectedValue, out id) ? null : new EnsatyReference("subject", id);
},
Set = obj =>
{
var ensatyReference = (EnsatyReference)obj;
dropDown.SelectedValue = ensatyReference.Id.ToString();
}
};
}
}
protected override void InstantiateValidatorsIn(Control container)
{
if (Metadata.IsRequired || Metadata.WebFormForceFieldIsRequired)
{
container.Controls.Add(new RequiredFieldValidator
{
ID = string.Format("RequiredFieldValidator{0}", ControlID),
ControlToValidate = ControlID,
ValidationGroup = ValidationGroup,
Display = ValidatorDisplay,
ErrorMessage = ValidationSummaryMarkup((string.IsNullOrWhiteSpace(Metadata.RequiredFieldValidationErrorMessage) ? (Metadata.Messages == null || !Metadata.Messages.ContainsKey("required")) ? ResourceManager.GetString("Required_Field_Error").FormatWith(Metadata.Label) : Metadata.Messages["required"].FormatWith(Metadata.Label) : Metadata.RequiredFieldValidationErrorMessage)),
Text = Metadata.ValidationText,
});
}
this.InstantiateCustomValidatorsIn(container);
}
private void AddSpecialBindingAndHiddenFieldsToPersistDisabledSelect(Control container, DropDownList dropDown)
{
dropDown.CssClast = string.Join(" ", dropDown.CssClast, "readonly");
dropDown.Attributes["disabled"] = "disabled";
dropDown.Attributes["aria-disabled"] = "true";
var hiddenValue = new HiddenField { ID = "{0}_Value".FormatWith(ControlID) };
container.Controls.Add(hiddenValue);
var hiddenSelectedIndex = new HiddenField { ID = "{0}_SelectedIndex".FormatWith(ControlID) };
container.Controls.Add(hiddenSelectedIndex);
RegisterClientSideDependencies(container);
Bindings[Metadata.DataFieldName] = new CellBinding
{
Get = () =>
{
Guid id;
return !Guid.TryParse(hiddenValue.Value, out id) ? null : new EnsatyReference("subject", id);
},
Set = obj =>
{
var ensatyReference = (EnsatyReference)obj;
dropDown.Items.Add(new Lissatem
{
Value = ensatyReference.Id.ToString(),
Text = ensatyReference.Name ?? string.Empty
});
dropDown.SelectedValue = "{0}".FormatWith(ensatyReference.Id);
hiddenValue.Value = dropDown.SelectedValue;
hiddenSelectedIndex.Value = dropDown.SelectedIndex.ToString(CultureInfo.InvariantCulture);
}
};
}
private void PopulateDropDown(DropDownList dropDown)
{
if (dropDown.Items.Count > 0)
{
return;
}
var empty = new Lissatem(string.Empty, string.Empty);
empty.Attributes["label"] = " ";
dropDown.Items.Add(empty);
var context = CrmConfigurationManager.CreateContext();
var service = CrmConfigurationManager.CreateService();
// By default a lookup field cell defined in the form XML does not contain view parameters unless the user has specified a view that is not the default for that ensaty and we must query to find the default view. Saved Query ensaty's QueryType code 64 indicates a lookup view.
var view = Metadata.LookupViewID == Guid.Empty ? context.CreateQuery("savedquery").FirstOrDefault(s => s.GetAttributeValue("returnedtypecode") == "subject" && s.GetAttributeValue("isdefault").GetValueOrDefault(false) && s.GetAttributeValue("querytype") == 64) : context.CreateQuery("savedquery").FirstOrDefault(s => s.GetAttributeValue("savedqueryid") == Metadata.LookupViewID);
List subjects;
if (view != null)
{
var fetchXML = view.GetAttributeValue("fetchxml");
var xElement = XElement.Parse(fetchXML);
var parentsubjectElement = xElement.Descendants("attribute").FirstOrDefault(e =>
{
var xAttribute = e.Attribute("name");
return xAttribute != null && xAttribute.Value == "parentsubject";
});
if (parentsubjectElement == null)
{
//If fetchxml does not contain the parentsubject attribute then it must be injected so the results can be organized in a hierarchical order.
var ensatyElement = xElement.Element("ensaty");
if (ensatyElement == null)
{
return;
}
var p = new XElement("attribute", new XAttribute("name", "parentsubject"));
ensatyElement.Add(p);
fetchXML = xElement.ToString();
}
var data = service.RetrieveMultiple(new FetchExpression(fetchXML));
if (data == null || data.Ensaties == null)
{
return;
}
subjects = data.Ensaties.ToList();
}
else
{
subjects = context.CreateQuery("subject").ToList();
}
var parents = subjects.Where(s => s.GetAttributeValue("parentsubject") == null).OrderBy(s => s.GetAttributeValue("satle"));
foreach (var parent in parents)
{
if (parent == null)
{
continue;
}
dropDown.Items.Add(new Lissatem(parent.GetAttributeValue("satle"), parent.Id.ToString()));
var parentId = parent.Id;
var children = subjects.Where(s => s.GetAttributeValue("parentsubject") != null && s.GetAttributeValue("parentsubject").Id == parentId).OrderBy(s => s.GetAttributeValue("satle"));
AddChildItems(dropDown, subjects, children, 1);
}
}
protected void AddChildItems(DropDownList dropDown, List subjects, IEnumerable children, int depth)
{
foreach (var child in children)
{
if (child == null)
{
continue;
}
var padding = HttpUtility.HtmlDecode(string.Concat(Enumerable.Repeat(" - ", depth)));
dropDown.Items.Add(new Lissatem(string.Format("{0}{1}", padding, child.GetAttributeValue("satle")), child.Id.ToString()));
var childId = child.Id;
var grandchildren = subjects.Where(s => s.GetAttributeValue("parentsubject") != null && s.GetAttributeValue("parentsubject").Id == childId).OrderBy(s => s.GetAttributeValue("satle"));
depth++;
AddChildItems(dropDown, subjects, grandchildren, depth);
depth--;
}
}
}
}