Custom Connectable Web Part
In MatchPoint we introduced a more sophisticated mechanism to consume data in one Web Part from another. Compared to the OOB SharePoint solution, with MatchPoint the data can be shared without a post back of the page, and individual controls and Web Parts can be refreshed using an Ajax callback.
In order to benefit from the Connection Framework you can extend the
MatchPoint BaseWebPart
class. This example shows a Web Part with a
text field input that provides its input to other MatchPoint WebParts
such as a Composite Web Part.
Additionally to show how data can be consumed from other controls, the given sample has a configurable label (PatternString) which can contain references to "ConnectionData". The label (or the control) should be updated whenever the referenced data is changed.
[Serializable]
public class ConnectableWebPartConfiguration: IWebPartConfiguration
{
// the name of under which this WebPart instance provides the connection data
public string Name;
// a configurable label text that can contain placeholder pointing to other
// connection data such as {ConnectionData.OtherGrid.SelectedRow.Title}
public PatternString Label;
}
public class ConnectableWebPart : BaseWebPart
{
...
}
As we have some JS code we have to register it. MatchPoint then will include the JS and auotmatically provide a proxy for Ajax callbacks.
If you want to provide some data to other controls and Web Parts you
have to register the control as a producer (data source). This is done
using the ConnectionManager.RegisterDataSource
method.
If you want to consume data you have to register the control as a
consumer. This is done calling ConnectionManager.RegisterConsumer
. As
you don't want to react on all ConnectionData changes but only on the
one that affect your control, you additionally pass in a
DepedencyCollection
. The DepedencyCollection
itself provides methods
to analyze PatternStrings
. If ConnectionData.xxx
references are
found in the placeholders the fields are added to the collection of
dependencies.
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
// register the corresponding JS file
// (has the same name as the class and is located)
JavaScriptBehaviorManager.RegisterBehavior(this, typeof(ConnectableWebPart));
// register as data source
ConnectionManager.RegisterDataSource(this, Configuration.Name, typeof(string));
// extract all ConnectionData field access from the pattern and register
// as consumer as well
DependencyCollection dependencies = new DependencyCollection();
dependencies.AddFromPattern(Configuration.Label);
ConnectionManager.RegisterConsumer(this, dependencies);
}
On the client side we have to send a notification to the consumer controls if the text input changes.
The MP.ConnectionManager.NotifyConsumers
method calls the Refresh
method on all controls that are registered as consumer.
We self implement the Refresh method as well and render the control including the label again doing an Ajax callback. As we registered the Web Part as a consumer for all ConnectionData references in the Label string the framework automatically calls the Refresh method on changes that affect the Web Part.
MP.Samples.ConnectableWebPart = function()
{
this.Setup = function()
{
this.BindEventHandlers();
};
this.TextBox_Change = function()
{
MP.ConnectionManager.SetData(this.ConnectionName, this.$textBox.val());
MP.ConnectionManager.NotifyConsumers(this);
};
this.BindEventHandlers = function()
{
this.$textBox = $(this.Control).find("input");
this.$textBox.blur($$.Delegate.Create(this, this.TextBox_Change));
};
this.Refresh = function()
{
$(this.Control).html(this.Callback.GetHtml());
this.BindEventHandlers();
};
}
In order that MatchPoint includes the JS automatically and knows where
to look it up you have to register your assembly as MatchPoint extension
in the MatchPoint Instance Configuration and define the script location
using the JavaScriptBaseAttribute
in the AssemblyInfo.cs:
[assembly: JavaScriptBase("MP.Samples", "/_layouts/Colygon.MatchPoint.Samples/scripts")]