|
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;
using System.Runtime.InteropServices;
using System.ComponentModel;
using Microsoft.SharePoint;
using Mullivan.SharePoint.WebControls;
using System.Web.UI.WebControls;
using System.Xml;
using System.Web;
using System.Web.UI;
using Microsoft.SharePoint.WebPartPages.Communication;
using System.Security;
using Microsoft.SharePoint.WebControls;
namespace Mullivan.SharePoint.WebParts
{
[Guid("90f69852-2345-8786-8aad-35f177b7aaaa")]
[XmlRoot(Namespace = "ListQueryWebPart")]
public class ListQueryWebPart : Microsoft.SharePoint.WebPartPages.WebPart, IWebEditable
{
private const uint DEFAULT_PAGESIZE = 20;
private string _errorMessage = null;
private SPList _list = null;
private Button _btnSearch = null;
private XmlDocument _xDocQuery = null;
private List<InputField> _inputFields = null;
public ListQueryWebPart()
: base()
{
this.PageSize = DEFAULT_PAGESIZE;
}
[Browsable(false)]
[Personalizable(PersonalizationScope.Shared)]
public string Query
{
get;
set;
}
[Browsable(false)]
[Personalizable(PersonalizationScope.Shared)]
public string ListUrl
{
get;
set;
}
[Browsable(false)]
[Personalizable(PersonalizationScope.Shared)]
public string ViewFields
{
get;
set;
}
[Browsable(false)]
[Personalizable(PersonalizationScope.Shared)]
public uint PageSize
{
get;
set;
}
public ListQueryData CurrentQuery
{
get
{
return (ListQueryData)this.ViewState["CurrentQuery"];
}
set
{
this.ViewState["CurrentQuery"] = value;
}
}
[ConnectionProvider("List Query Provider", "listQueryProvider")]
public ListQueryData GetQueryData()
{
return this.CurrentQuery;
}
protected override void OnInit(EventArgs e)
{
try
{
base.OnInit(e);
if (string.IsNullOrEmpty(this.ListUrl)
|| string.IsNullOrEmpty(this.ViewFields)
|| string.IsNullOrEmpty(this.Query))
return;
_btnSearch = new Button();
_btnSearch.ID = "btnSearch";
_btnSearch.Text = "Search";
_btnSearch.Click += new EventHandler(_btnSearch_Click);
_list = GetList();
if (_list == null)
return;
_xDocQuery = new XmlDocument();
_xDocQuery.LoadXml("<Query>" + this.Query + "</Query>");
_inputFields = GetInputFields(_xDocQuery);
Literal litTableStart = new Literal();
litTableStart.Text = @"<table cellpadding=""1"" cellspacing=""0"">";
this.Controls.Add(litTableStart);
int idx = 0;
foreach (InputField field in _inputFields)
{
AppendFieldControl(field, idx);
idx++;
}
Literal litButtonRow = new Literal();
litButtonRow.Text = @"
<tr>
<td colspan=""3"" style=""padding-top:5px;padding-bottom:5px;text-align:right;"" />";
this.Controls.Add(litButtonRow);
this.Controls.Add(_btnSearch);
Literal litTableEnd = new Literal();
litTableEnd.Text = "</td></tr></table>";
this.Controls.Add(litTableEnd);
}
catch (Exception ex)
{
_errorMessage = ex.ToString();
}
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
//Make sure the consumer only updates when the
//when the search button is clicked
ListQueryData lqd = this.CurrentQuery;
if (lqd != null)
{
lqd.IsNew = false;
this.CurrentQuery = lqd;
}
}
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
if (_errorMessage != null)
writer.Write(HttpUtility.HtmlEncode(_errorMessage).Replace("\n", "<br/>"));
else
base.Render(writer);
}
protected void _btnSearch_Click(object sender, EventArgs e)
{
if (!ValidateInputControls())
return;
ListQueryData lqd = new ListQueryData();
lqd.ListId = _list.ID;
lqd.ViewFields = this.ViewFields;
lqd.IsNew = true;
lqd.PageSize = this.PageSize;
using (SPWeb web = _list.ParentWeb)
{
lqd.WebId = web.ID;
}
lqd.Query = BuildQuery();
this.CurrentQuery = lqd;
}
private string BuildQuery()
{
int idx = -1;
foreach (Control c in this.Controls)
{
if (c is SPFieldRenderer)
{
idx++;
SPFieldRenderer renderer = (SPFieldRenderer)c;
string value = renderer.Value;
InputField inputField = _inputFields[idx];
XmlElement xeValue = inputField.Document.CreateElement("Value");
if (!string.IsNullOrEmpty(value) || inputField.ComparerNode.ParentNode.Equals("Where"))
{
value = SecurityElement.Escape(value);
xeValue.SetAttribute("Type", inputField.SPField.TypeAsString);
if (inputField.SPField.Type == SPFieldType.DateTime)
xeValue.SetAttribute("IncludeTimeValue", "TRUE");
xeValue.InnerText = value;
//Replace the User Input node with the value node
inputField.UserInputNode.ParentNode.ReplaceChild(xeValue, inputField.UserInputNode);
}
else //If the value is empty then the user doens't want to filter on that value so
//we need to replace it according to the Nest Type
{
XmlElement xeImpersonateCondition = null;
if (inputField.ComparerNode.ParentNode.Name.Equals("And"))
//If the Parent Nest is an And then we always want this condition to validate
// as true so that if the sibling condition is true then the whole nest will be true
xeImpersonateCondition = inputField.Document.CreateElement("IsNotNull");
else
//If the parent nest is an Or then we always want this condition to validate
//as false so that if the sibling condition is false then the nest will fail as well
xeImpersonateCondition = inputField.Document.CreateElement("IsNull");
//This all words because the ID fill we never be null... so if we base our condition
//of of it being null or not being null then we can control the validation of this nest
XmlElement xeFieldRefID = inputField.Document.CreateElement("FieldRef");
xeFieldRefID.SetAttribute("Name", "ID");
xeImpersonateCondition.AppendChild(xeFieldRefID);
inputField.ComparerNode.ParentNode.ReplaceChild(xeImpersonateCondition, inputField.ComparerNode);
}
}
}
return _xDocQuery.DocumentElement.InnerXml;
}
private bool ValidateInputControls()
{
bool isValid = true;
foreach (Control c in this.Controls)
{
if (c is SPFieldRenderer)
{
SPFieldRenderer renderer = (SPFieldRenderer)c;
renderer.Validate();
if (!renderer.IsValid)
isValid = false;
}
}
return isValid;
}
private void AppendFieldControl(InputField field, int index)
{
SPFieldRenderer renderer = new SPFieldRenderer();
renderer.ID = "editControl_" + index.ToString() + "_";
renderer.Field = field.SPField;
renderer.List = _list;
renderer.Value = field.SPField.DefaultValue;
Literal litStart = new Literal();
litStart.Text = string.Format(@"
<TR>
<TD nowrap=""true"" valign=""top"" width=""190px"" class=""ms-formlabel""><H3 class=""ms-standardheader"">
<nobr>{0}</nobr>
</H3>
</TD>
<TD nowrap=""true"" valign=""top"" width=""30px"" class=""ms-formlabel"" style=""text-align:right;padding-right:3px"">
<nobr>{1}</nobr>
</TD>
<TD valign=""top"" class=""ms-formbody"" width=""400px"">
", renderer.Field.Title, " "); //field.GetComparerText());
Literal litEnd = new Literal();
litEnd.Text = @"
</TD>
</TR>";
this.Controls.Add(litStart);
this.Controls.Add(renderer);
this.Controls.Add(litEnd);
}
private SPList GetList()
{
SPSite site = SPControl.GetContextSite(this.Context);
using (SPWeb web = site.OpenWeb(GetWebUrl(this.ListUrl)))
{
string listName = GetListName(this.ListUrl);
return web.Lists[listName];
}
}
private string GetWebUrl(string listUrl)
{
string webUrl = string.Empty;
listUrl = listUrl.TrimEnd('/');
int lastIndex = listUrl.LastIndexOf("/");
if (lastIndex > -1)
webUrl = listUrl.Substring(0, lastIndex);
return webUrl.TrimEnd('/');
}
private string GetListName(string listUrl)
{
string listName = string.Empty;
listUrl = listUrl.Trim('/');
int lastIndex = listUrl.LastIndexOf("/");
if (lastIndex > -1)
listName = listUrl.Substring(lastIndex + 1, listUrl.Length - lastIndex - 1);
return listName;
}
private List<InputField> GetInputFields(XmlDocument xDoc)
{
List<InputField> inputFields = new List<InputField>();
XmlElement xeWhere = (XmlElement)xDoc.SelectSingleNode("Query/Where");
if (xeWhere != null)
{
GetInputFields(xeWhere.ChildNodes, inputFields);
}
return inputFields;
}
private void GetInputFields(XmlNodeList children, List<InputField> inputFields)
{
foreach (XmlElement xeChild in children)
{
switch (xeChild.Name)
{
case "And":
case "Or":
GetInputFields(xeChild.ChildNodes, inputFields);
break;
case "BeginsWith":
case "Contains":
case "Eq":
case "Geq":
case "Gt":
case "Leq":
case "Lt":
case "Neq":
//case "DateRangesOverlap":
case "IsNotNull":
case "IsNull":
CheckForInputField(xeChild, inputFields);
break;
default:
break;
}
}
}
private void CheckForInputField(XmlElement xeComparer, List<InputField> inputFields)
{
XmlElement xeInput = (XmlElement)xeComparer.SelectSingleNode("UserInput");
if (xeInput != null)
{
XmlElement xeFieldRef = (XmlElement)xeComparer.SelectSingleNode("FieldRef");
if (xeFieldRef == null)
return;
string internalName = xeFieldRef.GetAttribute("Name");
if (string.IsNullOrEmpty(internalName))
return;
SPField spField = _list.Fields.GetFieldByInternalName(internalName);
if (spField == null)
return;
InputField inputField = new InputField();
inputField.Document = xeInput.OwnerDocument;
inputField.UserInputNode = xeInput;
inputField.FieldRefNode = xeFieldRef;
inputField.ComparerNode = xeComparer;
inputField.SPField = spField;
inputFields.Add(inputField);
}
}
#region IWebEditable Members
EditorPartCollection IWebEditable.CreateEditorParts()
{
List<EditorPart> editors = new List<EditorPart>();
editors.Add(new ListQueryEditor(this.ID));
return new EditorPartCollection(editors);
}
object IWebEditable.WebBrowsableObject
{
get { return this; }
}
#endregion
}
public class InputField
{
public XmlDocument Document
{
get;
set;
}
public SPField SPField
{
get;
set;
}
public XmlElement UserInputNode
{
get;
set;
}
public XmlElement FieldRefNode
{
get;
set;
}
public XmlElement ComparerNode
{
get;
set;
}
public string GetComparerText()
{
if (this.UserInputNode == null ||
this.UserInputNode.ParentNode == null ||
string.IsNullOrEmpty(this.UserInputNode.ParentNode.Name))
return "?";
string comparer = string.Empty;
switch (this.UserInputNode.ParentNode.Name)
{
case "BeginsWith":
comparer = "BeginsWith";
break;
case "Contains":
comparer = "Contains";
break;
case "Eq":
comparer = "==";
break;
case "Geq":
comparer = ">=";
break;
case "Gt":
comparer = ">";
break;
case "Leq":
comparer = "<=";
break;
case "Lt":
comparer = "<";
break;
case "Neq":
comparer = "!=";
break;
//case "DateRangesOverlap":
case "IsNotNull":
comparer = "!=";
break;
case "IsNull":
comparer = "==";
break;
default:
break;
}
return HttpUtility.HtmlEncode(comparer);
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.