Wednesday, December 21, 2011

Date Picker in Visual Web Parts

The problem:
I need to create a Visual Web Part where one of the fields should be a date. Using the SharePoint DateTimeControl does not work, because, when displayed in a user control, the calendar it shows looks horrible. Apparently the SharePoint DateTimeControl is meant to be used in an application page rather than a user control. There has to be a better way!

The solution:

A good alternative is a DatePicker jQueryUI plugin. You will have to add a LAYOUTS mapped folder to your project and create the css and js folders. In the js folder, put the jquery-1.6.1.min.js as well as jquery-ui-1.8.16.custom.min.js files; in the css folder, there should be the base folder where there will be three CSS files (jquery.ui.core.css, jquery.ui.datepicker.css, and jquery.ui.theme.css) as well as the images folder with all the images for the base theme. Then, in your ASCX file, make sure you have the following lines:

<link rel="stylesheet" type="text/css" media="all" href="_layouts/jQuery/css/base/jquery.ui.core.css" />
<link rel="stylesheet" type="text/css" media="all" href="_layouts/jQuery/css/base/jquery.ui.datepicker.css" />
<link rel="stylesheet" type="text/css" media="all" href="_layouts/jQuery/css/base/jquery.ui.theme.css" />       
<script type="text/javascript" src="_layouts/jQuery/js/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="_layouts/jQuery/js/jquery-ui-1.8.16.custom.min.js"></script>
<script type="text/javascript">
    $(function () {
        $('input[id*="dtDatePicker"]').datepicker({ dateFormat: 'mm/dd/yy' });
    });
</script>

For the actual date field, put this line into your ASCX file:

<asp:TextBox ID="dtDatePicker" runat="server" />

That's it. Whenever the focus is on the dtDatePicker control, the little pretty calendar will appear and the user will be able to pick the date. You also might want to use the jQueryUI date validator plugin to validate the date entered.

Sunday, December 18, 2011

Submitting an InfoPath Form

The problem: The requirements state that the InfoPath form should be submitted in the same location where it is located, and that, upon submission, it should no longer be editable (the submitter should have the read-only access to the form she has submitted.) Furthermore, the submitter should lose the Contribute access to that form and only have Read access.

The solution: 
1) Make a new field in the schema, called Submitted. It should be Yes/No and default to False.
2) Create a new view that is a copy of the original view, minus the Submit button. Make that view read-only and disable view switching on the ribbon.
3) Configure the submit options to be rule-based, so that, upon submission, three things happen:
    a) The Submitted field is assigned the value of True.
    b) The form is submitted to the submit data connection.
    c) The view is switched to the read-only one.
4) Publish the form and make sure that the Submitted field is promoted.
5) Add some event receiver to the form library that is triggered whenever a form residing there is being updated. In the ItemUpdated event, make changes to the updated item whenever its Submitted field changes.

Monday, December 12, 2011

Saving an InfoPath Form

The problem:
The requirements state that the browser-based form I designed should first be saved in the forms library as an empty form (this is done by some code), the permission inheritance for the corresponding list item should be broken, and then the Contribute permissions should be granted to some particular user (this is also done by some code.) Thus, this user will only be able to see and fill out his or her particular forms. Any time the user submits the form, the form should be submitted to its form library and its file name should not change (otherwise a new entry will appear in the Forms library and it will not have the same permissions as the original entry... which is not so great – remember, each form should only be visible to one particular user!)
While configuring the submit options for the form, I created a new Submit data connection. However, the Data Connection Wizard asks for the file name with which the form will be submitted. How to populate that field? It comes from the SharePoint list, but there is no way to query the SharePoint list from the Data Connection Wizard.
The solution:
1)      Create the new field for the file name (give it a name, say, strFileName).

2)       In the Form Options, make sure that the Save As button is NOT displayed. Since it is the code and not the user who creates the original empty form, the Save button as well as the Close buttons should not be displayed, either.

3)      While configuring Submit Options, specify this field as the file name with which the form will be submitted. Also make sure that the Overwrite checkbox is checked.

4)      Now we need to think of how to populate that particular field. It has to be populated when the form is loading. Thus, we need to add some code to the form loading event handler. What kind of code?

       To answer this question, look at the URL for the request when the form is displayed in the browser. The  file name can be found in the query string, in the XmlLocation parameter. (If the form does not have a file name yet, the XmlLocation parameter is missing.) Thus, the code we need to write is something like this:

public void FormEvents_Loading(object sender, LoadingEventArgs e)
      {
            // Write your code here.
            string xmlLocation = String.Empty;
            e.InputParameters.TryGetValue("XmlLocation"out xmlLocation);
            if (!String.IsNullOrEmpty(xmlLocation))
            {
                string[] parts = xmlLocation.Split(new char[] { '/' });
                string fileName = parts[parts.Length - 1];

                XPathNavigator form = MainDataSource.CreateNavigator();

form.SelectSingleNode("/my:myFields/my:strFilename", NamespaceManager).SetValue(fileName);
            }
 }

When the form is displayed, nothing is done if the file name for the list item is now known yet, because the XmlLocation parameter is missing. But when the file name is known for the list item, the XmlLocation parameter is parsed to find the file name. Then, the new strFileName field is populated. When the form is submitted, the old file that has this file name is overwritten. Voila!