Developing A Form WebPart – Part 4 – Setup the Validation Controls

The data that is being submitted with the Forms WebPart requires validation before it is committed to the database in order to maintain integrity of the information being stored. Doing validation with WebParts typically occurs in two main ways. One can choose to script a separate method in order to validate the entry by using an option like ServerValidateEventArgs.IsValid against the argument, or the inherent validation controls that ASP.NET 2.0 provides can be called in order to validate the information. Considering software architecture concerns and code bloat as a factor, it is typically preferable to use the inherent ASP.NET 2.0 validation options, which will also allow the extension of the validation being used to be assimilated by sister validation controls such as ValidationSummary.

Be aware that when using the inherent validation controls your WebPart will become subject to using client side script as the validation will depend on it. When leveraging the RequiredValidation controls in a WebPart, it will append some JavaScript to the form page on which it is added by calling ValidatorOnWSubmit(). There are known issues when trying to use multiple Form WebParts that use the inherent validation controls. SharePoint will always call the first validation control even when validating a secondary control on the page.

Here, you’re validating a numeric entry manually with a custom method.

[csharp]

            public void ValidateNumeric(object source, ServerValidateEventArgs args)
            {
                try
                {
                    Decimal temp = Decimal.Parse(args.Value);
                    args.IsValid = true;
                }
                catch
                {
                    args.IsValid = false;
                }
            }

[/csharp]

And now, validate input using the native validation controls.

[csharp]

            protected override void CreateChildControls()
            {
                base.CreateChildControls();
                textTextBox = new TextBox();
                textTextBox.ID = “textTextBox”;
                Controls.Add(textTextBox);
                rfvFieldValidator = new rfvFieldValidator();
                rfvFieldValidator.ControlToValidate = “textTextBox”;
                Controls.Add(rfvFieldValidator);
            }

[/csharp]

Share

Developing A SharePoint Form WebPart – Part 2 – Declare Variables, Assign Controls, And Set up Exception Management

Once the class is setup for the Form WebPart, you need to declare relevant variables and instantiate the required controls by overriding the CreateChildControls() method. For the Forms WebPart, which only accepts an ID input, the only required controls are a TextBox control and a new button that is wired to a submission event.

[csharp]

        // Current Site
        SPSite siteThis = null;
        // Current Web
        SPWeb webThis = null;
        // Text Box Control
        private TextBox txtTextBox;
        // Button Control
        private Button save;
        // String Build In Order To Parse Relevant Errors
        private StringBuilder msgError = new StringBuilder();
        // SQL connection variable
        SqlConnection sqlConn = null;
        // Validator Control to Verify User Input
        private RequiredFieldValidator fieldVal;

[/csharp]

There are two best practices to consider when starting to script a piece of functionality such as the Forms WebPart. Firstly, it is advantageous to build a reference to the current site and web since this can be passed on the OnInit method in order to harvest the current site and web context by using SPControl.GetContextSite(Context). In terms of exception management, organizations typically vary in whether there are enterprise standards such as using the trapping logic out of the Microsoft Exception Handling Enterprise Library or a custom common exception library. If managing individual loose exceptions, use a class available StringBuilder() in order to append the string exception text by using (stringbuildervariable).Append within the relevant try/catch blocks.

Next, the controls have to be declared by overriding the CreateChildControls() method. The two controls that need to be instantiated are the TextBox control to accept the ID input from the user and the button control that is wired to an event handler to manage the data submission. This is accomplished by initializing each of the controls, and then call the add method out of the Controls property to add it to the WebPart output.

Wrapping this in a try/catch block, it is noticeable that the StringBuilder() being used to manage the exceptions is being called in the catch block if there is an error that occurs in the CreateChildControls().

[csharp]       

protected override void CreateChildControls()
        {
            base.CreateChildControls();
            try
            {
                // Call a new text box control
                txtTextBox = new TextBox();
                txtTextBox.ID = “txtTextBox”;
                Controls.Add(txtTextBox);
                // Call a new button control and bind it to an event
                save = new Button();
                save.Text = “Save”;
                save.Click += new EventHandler(save_Click);
                Controls.Add(save);
            }
            catch (Exception ex)
            {
                msgError.Append(“Error in CreateChildControls: ” + ex.Message);
            }
        }

[/csharp]

If more controls were required for data entry, such as using a ListBox control with relevant bound list items, the relevant variables need only be declared and the control added in the same fashion.

[csharp]      

private ListBox lbListBox
        // Under base.CreateChildControl() in the CreateChildControls Method
        lbListBox = new ListBox();
        lbListBox.Rows = 1;
        lbListBox.Items.Add(new ListItem(“my lbListBox Item”,” my lbListBox Item “));
        Controls.Add(lbListBox);

[/csharp]

Share

Customzing Connection Information Using The FilterInfoBar Class

Ok, I am done with my rants, I probably could have brought up 15 other subjects, but I will quit now. I was kinda enjoying not doing something entirely technical on this blog and expressing my feelings about some things, but apparently several people took exception to my writing, particularly some recruiting companies I work with. :)

In this post, I am going to explain to you how to use the FilterInfoBar class, which is responsible, as you can probably guess, for controlling enhanced information that is displayed when a WebPart, such as one that is inheriting from the ITransformableFilterValues (ITransformableFilterValues will be responsible for sending filter values to the consumer) interface as we will see shortly, is appropriately connected in the orthodox provider / consumer fashion. Modifying your WebPart to include the FilterInfoBar class (which can function like the default connection types that SharePoint provides by hiding it except in design mode if you want), provides people that are going to use your WebPart insight into the current connection settings that they have. For this reason, it makes good business sense to incorporate with your connectible WebPart deliverables.

So, let’s say that you are having a very exciting morning because you are developing your first custom filter WebPart, thereby developing by inheriting from some new fun interfaces, particularly in this case, you are going to be inheriting from ITransformableFilterValues out of the Microsoft.SharePoint.WebPartPages namespace (as discussed earlier). So therefore, when decorating your WebPart class file, you will have to structure it as such:

[csharp]

public class AdamsFilter : WebPart, ITransformableFilterValues

[/csharp]

Then, once you have read the remainder of this post, you can call your new FilterInfoBar control just like any child control by doing a Controls.Add(YourNewInfoBar()), after instantiating it as a new object (I am not going to go over Filter WebParts to that extent in this post, perhaps in another if there is appropriate interest) within your overridden CreateChildControls() method.

The ITransformableFilterValues interface is important when writing your provider filter WebPart since it is responsible for the actual passing of the value to the consumer WebPart, and provides access to crucial filter properties that will control the actual behavior of the passing of values (like whether multiple values can be passed to the consumer through the use of the AllowMultipleValues property, which is a very clutch decoration since you can then have multiple provider points to a singular consumer, which I find just awesome).

Now you want to define a new FilterInfoBar class in your filter WebPart in order to provide some textual information to users that are responsible for building the relevant connection out, or maybe just to yourself for debugging purposes. Firstly, make your appropriate references in your new class:

[csharp]

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls.WebParts;
using AspNetControl = System.Web.UI.Control;
using SharePointFilterInfoBar = Microsoft.SharePoint.WebPartPages.FilterInfoBar;

[/csharp]

Afterwards, get your namespace going and decorate your class inheritance so that it is set to inherit from your SharePointFilterInfoBar class (we are going to be using the imported reference as written above, therefore simply set the class inheritance as FilterInfoBar or whatever your namespace assignment is):

[csharp]

namespace adams.Examples
{

// this inheritance is deriving from the import reference we establish above
class AdamsFilterInfoBar : SharePointFilterInfoBar
{

}

}

[/csharp]

Now you have something going, but you haven’t structured the information display that should be rendered to the user when this class is called from your filter WebPart, so this isn’t very interesting at all. Because you desire to grab this connection information BEFORE the WebPart is rendered, you have to override the OnPreRender event so that these values are available before the actual HTML is rendered out to the user (since these values will be a part of the interface that you are providing your users with). Following your override, your class file should then have this structure.

[csharp]

namespace adams.Examples
{

class AdamsFilterInfoBar : FilterInfoBar
{

protected override void OnPreRender( EventArgs e )
{

}
}

}
[/csharp]

Now we need to inject the code that we will actually trigger during the OnPreRender process. Firstly, you must take note that the FilterInfoBar class object hierarchy, in order to understand how to structure the code. FilterInfoBar looks like this:

System.Object
System.Web.UI.Control
System.Web.UI.WebControls.WebControl
Microsoft.SharePoint.WebPartPages.FilterInfoBar

The FilterInfoBar class is useless unless it is a child of another control, it MUST be bound to another parent control by which it can read the relevant values and display said values within textual information that is relevant to the user (or where the hell else is it going to get the connection values :) ). Therefore, you can ensure that your FilterInfoBar class is the sub of a parent control by simply doing a Parent property reference which will ensure a parent control in the page control hierarchy (not a necessity in the code, however a nice to have, and simple requires testing the parent for a null reference by getting the Parent property of the current instance of the class , i.e. if(Parent == null)).

Now with the OnPreRender method, you start to develop the actual code that will be responsible for displaying that contextual information to the user. In order to iterate through the connections that are available, you are going to use a WebPartConnection object, since this is responsible for providing the functionality that will allow two WebParts to manifest a communication, iterating for these objects using a WebPartManager object which has a Connections property. Ultimately, your loop will look like this:

[csharp]

foreach ( WebPartConnection l_oConnection in WebPartManager.Connections )
{
// This will return all the WebPartConnection objects.
}

[/csharp]

Once you have the loop to iterate through the entire Connection object set up, you can start to use the results in order to build conditional results that are output to the user. Depending on whether you are integrating your custom FilterInfoBar class into a provider or consumer will heavily impact the output. Fortunately, there is a property that allows you to distinguish between the two so that the output can be controlled, namely the WebPartConnection.Consumer and WebPartConnection.Provider, which you put against the parent control. Within your foreach loop, you can distinguish between them like this:

This will allow you to test whether the parent control is a Provider:

[csharp]

foreach ( WebPartConnection l_oConnection in WebPartManager.Connections )
{
if (Parent.Equals(l_oConnection.Provider))
}

[/csharp]

and this will allow you test whether your parent control is a Consumer:

[csharp]

foreach (WebPartConnection l_oConnection in WebPartManager.Connections)
{
if (Parent.Equals(l_oConnection.Consumer))
}

[/csharp]

Subsequently, you can inject whatever handling code you wanted within your new if loop.

So what is an example of this type of code? It is very much up to your own design; you just have to use the AddMessage method that is provided by the FilterInfoBar class. There are very few methods that are available from this class, since it is mostly tiered around simply displaying this message to the user, but you can display even your own type of icon if you choose to. The AddMessage just takes a string value as a parameter.

For displaying information, you can use the WebPartConnection object to generate interesting data to display to the user, which can be generic to the connection if you just want to create one InfoBar generic helper class to use across a variety of projects. For example, you can use properties such as the ProviderConnectionPoint and ConsumerConnectionPoint classes in order to get valuable information about the connection that you are specifying using the InterfaceType property, or if you are simply looking to display basic information such as the name of the connection, you can just use the WebPartConnection.Consumer.DisplayTitle or WebPartConnection.Provider.DisplayTitle in order to structure the message to the user. To include this simply do a:

[csharp]

AddMessage(Put Your Message In Here);

[/csharp]

And your message will be rendered out!

Happy connecting!

Share