Asynchronous Sharepoint List Insert / Update.

Posted on Updated on

Hello SharePoint developers… This time I have a new stuff to a share with you all. Two weeks back I met with one of my friends, who is also working as Software developer in SharePoint Technology. In between our talks he explained about a technical issue that he is facing in his project. The issue was regarding the use of AJAX in MOSS 2007. Actually his requirement is to update a SharePoint List asynchronously through a web part and he was using ASP.NET AJAX ScriptManager, UpdatePanel to accomplish this task. But it gives some cross browser issues, JavaScript issues like “ScriptResource.axd” file issue etc. I have also read that there are some issues of ASP.NET AJAX with MOSS 2007. Any how that night I also sat down along with him to find a solution. After a few trouble shooting and “googling” we come to a conclusion that it can’t be done with a small span of time. We started thinking for a new solution and into my mind it came like shooting star. “ICallbackEventHandler”…….. Yes, we started creating a new web part that implements the interface ICallbackEventHandler.

Here we can look into some small piece of code that explains “How to update a SharePoint List asynchronously using ICallbackEventHandler?”. This post assumes that readers have idea regarding the SharePoint Web Part development. Please go through the following steps to know how things are done.

This is simple example where we will add SP List Item to a SP List asynchronously through a Webpart.

1. Create a SharePoint Custom List having 2 columns [Name, Age] on your SharePoint Site.

2. Create a new SharePoint WSP Project from your Visual Studio IDE. [Please install WSPBuilder from CodePlex, if you don’t have a WSPBuilder Template ].

3. Add a Web Part Feature into the project from the “Add new Item” option on the created project.

4. Switch to the webpart code .cs file . This will be under the WebPartCode folder in the project, if we use the WSPBuilder Template.

5. Utilize the CreateChildControls() Method to develop the UI for the webpart with 2 Textboxes and a button. One textbox is for input value of the “Name” and other for “Age”. The button will be used to Submit the input values.The below mentioned will be the code inside the CreateChildControls() Method.

protected override void CreateChildControls()
        {
                try
                {
                    base.CreateChildControls();

                    txtName = new TextBox();
                    txtName.ID = "txtName";

                    txtAge = new TextBox();
                    txtAge.ID = "txtAge";

                    btnSubmit = new HtmlButton();
                    btnSubmit.ID = "btnSubmit";
                    btnSubmit.InnerText = "Submit";
                    btnSubmit.Attributes.Add("onclick", "javascript:CallServer2();");

                    Table tbl = new Table();
                    TableRow tr1 = new TableRow();
                    TableRow tr2 = new TableRow();
                    TableRow tr3 = new TableRow();

                    TableCell cell11 = new TableCell();
                    TableCell cell12 = new TableCell();
                    TableCell cell21 = new TableCell();
                    TableCell cell22 = new TableCell();
                    TableCell cell31 = new TableCell();
                    TableCell cell32 = new TableCell();

                    tr1.Cells.Add(cell11);
                    tr1.Cells.Add(cell12);
                    tr2.Cells.Add(cell21);
                    tr2.Cells.Add(cell22);
                    tr3.Cells.Add(cell31);
                    tr3.Cells.Add(cell32);

                    cell11.Text = "Name";
                    cell12.Controls.Add(txtName);

                    cell21.Text = "Age";
                    cell22.Controls.Add(txtAge);

                    cell32.Controls.Add(btnSubmit);

                    tbl.Rows.Add(tr1);
                    tbl.Rows.Add(tr2);
                    tbl.Rows.Add(tr3);

                    this.Controls.Add(tbl);

                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }

        }

6. Implement the ICallbackEventHandler interface to the webpart class. Implementation of this interface will add functions, 1. RaiseCallbackEvent 2. GetCallbackResult.

RaiseCallbackEvent – This function will be used to write code logic to update/insert the item to the Sharepoint List. This method have a parameter of type string which bring client side input data to the server side.

GetCallBackResult – This function is used to return the server side feedback to the client side as string.

Along with these 2 server side functionalities there are 2 client side JavaScript functions also needed for the orchestra. These Javascript functions are used to Call Server [here we will create JS function CallServer] functionalities from client side and for receiving the server feedback[JS function name will be ReceiveServerdata]. These JS functionalities need to register to Page Client Script block as follows.

protected override void OnLoad(EventArgs e)
        {

                try
                {
                    base.OnLoad(e);
                    this.EnsureChildControls();

                    ClientScriptManager cm = Page.ClientScript;
                    String cbReference = cm.GetCallbackEventReference(this, "arg",
                        "ReceiveServerData", "");
                    String callbackScript = "function CallServer(arg, context) {" +
                        cbReference + "; }";
                    cm.RegisterClientScriptBlock(this.GetType(),
                        "CallServer", callbackScript, true);

                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }

        }

7. Also we need to write our own JavaScript function [SetInputValues]to create appended a global string variable with all input values delimited by semi colon “;”. This global string variable is passed through the CallServer JS Function to reach the server side.
To accomplish this client side functionalities cleaner we will create a JS Function CallServer2 to call previously mentioned CallServer JS function and SetInputValues JS function. This CallServer2 JS function will be called on the onclick of the submit button.

//global variable
            var inputValues;

            function SetInputValues()
            {

                inputValues='';
                var txtName = document.getElementById('ctl00_m_g_cebf30d1_69b5_4c77_b9ef_4c5dea6aa649_txtName');
                var txtAge = document.getElementById('ctl00_m_g_cebf30d1_69b5_4c77_b9ef_4c5dea6aa649_txtAge');

                var Name=txtName.value;
                var Age=txtAge.value;

                inputValues=Name+';'+Age;

            }
            function CallServer2()
            {
                SetInputValues();
                CallServer(inputValues,'');

            }

            function ReceiveServerData(arg, context)
            {
                        alert(arg);
            }

All these JS Functions will be written on the code file of the webpart as a string variable and these JS functions are registered to the page on the OnInit event.

private string jsString = @"
            //global variable
            var inputValues;

            function SetInputValues()
            {

                inputValues='';
                var txtName = document.getElementById('ctl00_m_g_cebf30d1_69b5_4c77_b9ef_4c5dea6aa649_txtName');
                var txtAge = document.getElementById('ctl00_m_g_cebf30d1_69b5_4c77_b9ef_4c5dea6aa649_txtAge');

                var Name=txtName.value;
                var Age=txtAge.value;

                inputValues=Name+';'+Age;

            }
            function CallServer2()
            {
                SetInputValues();
                CallServer(inputValues,'');

            }

            function ReceiveServerData(arg, context)
            {
                        alert(arg);
            }
           ";
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            Page.ClientScript.RegisterStartupScript(this.GetType(), "callback", jsString, true);
        }

8. From the Server side we can take this input string[global variable “inputValues”] values through the previously mentioned RaiseCallbackEvent method’s parameter and we split this string with semicolon to get the array of input values to insert into the SP List.

 public void RaiseCallbackEvent(string eventArgument)
        {

            char[] delimiter = new char[1];
            delimiter[0] = Convert.ToChar(";");
            string[] inputData = new string[2];
            inputData = eventArgument.Split(delimiter);

            string siteUrl = "http://galaxian:5050/default.aspx";
            string libName = "NameList";
            // Open the site
            using (SPSite site = new SPSite(siteUrl))
            {
                using (SPWeb web = site.OpenWeb())
                {

                    SPList list = web.Lists[libName];
                    SPListItem item = list.Items.Add();
                    item["Title"] = inputData[0];
                    item["Age"] = inputData[1];
                    item.Update();

                }
            }
        }

9. After the inserting the item we can intimate the client side using the GetCallbackResult() method

public string GetCallbackResult()
        {
            return "Data inserted successfully...!";
        }

This message will be displayed as a JS alert after the insertion of the data. This server side feedback will be received by the ReceiveServerData() JS Function as mentioned on the Step 7.

The whole Code file for the webpart will look as below.

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using Microsoft.SharePoint;

namespace Asynchronous_SharepointListUpdate
{
    [Guid("6e22a748-4b74-481f-8b08-98106f869cf3")]
    public class Asynchronous_SPWebPart : Microsoft.SharePoint.WebPartPages.WebPart, ICallbackEventHandler
    {
        private bool _error = false;
        private string _myProperty = null;

        public Asynchronous_SPWebPart()
        {
            this.ExportMode = WebPartExportMode.All;
        }

        TextBox txtName;
        TextBox txtAge;
        HtmlButton btnSubmit;

        /// <summary>
        /// Create all your controls here for rendering.
        /// Try to avoid using the RenderWebPart() method.
        /// </summary>
        protected override void CreateChildControls()
        {
                try
                {
                    base.CreateChildControls();

                    txtName = new TextBox();
                    txtName.ID = "txtName";

                    txtAge = new TextBox();
                    txtAge.ID = "txtAge";

                    btnSubmit = new HtmlButton();
                    btnSubmit.ID = "btnSubmit";
                    btnSubmit.InnerText = "Submit";
                    btnSubmit.Attributes.Add("onclick", "javascript:CallServer2();");

                    Table tbl = new Table();
                    TableRow tr1 = new TableRow();
                    TableRow tr2 = new TableRow();
                    TableRow tr3 = new TableRow();

                    TableCell cell11 = new TableCell();
                    TableCell cell12 = new TableCell();
                    TableCell cell21 = new TableCell();
                    TableCell cell22 = new TableCell();
                    TableCell cell31 = new TableCell();
                    TableCell cell32 = new TableCell();

                    tr1.Cells.Add(cell11);
                    tr1.Cells.Add(cell12);
                    tr2.Cells.Add(cell21);
                    tr2.Cells.Add(cell22);
                    tr3.Cells.Add(cell31);
                    tr3.Cells.Add(cell32);

                    cell11.Text = "Name";
                    cell12.Controls.Add(txtName);

                    cell21.Text = "Age";
                    cell22.Controls.Add(txtAge);

                    cell32.Controls.Add(btnSubmit);

                    tbl.Rows.Add(tr1);
                    tbl.Rows.Add(tr2);
                    tbl.Rows.Add(tr3);

                    this.Controls.Add(tbl);

                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }

        }

        private string jsString = @"
            //global variable
            var inputValues;

            function SetInputValues()
            {

                inputValues='';
                var txtName = document.getElementById('ctl00_m_g_cebf30d1_69b5_4c77_b9ef_4c5dea6aa649_txtName');
                var txtAge = document.getElementById('ctl00_m_g_cebf30d1_69b5_4c77_b9ef_4c5dea6aa649_txtAge');

                var Name=txtName.value;
                var Age=txtAge.value;

                inputValues=Name+';'+Age;

            }
            function CallServer2()
            {
                SetInputValues();
                CallServer(inputValues,'');

            }

            function ReceiveServerData(arg, context)
            {
                        alert(arg);
            }
           ";
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            Page.ClientScript.RegisterStartupScript(this.GetType(), "callback", jsString, true);
        }

        /// <summary>
        /// Ensures that the CreateChildControls() is called before events.
        /// Use CreateChildControls() to create your controls.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {

                try
                {
                    base.OnLoad(e);
                    this.EnsureChildControls();

                    ClientScriptManager cm = Page.ClientScript;
                    String cbReference = cm.GetCallbackEventReference(this, "arg",
                        "ReceiveServerData", "");
                    String callbackScript = "function CallServer(arg, context) {" +
                        cbReference + "; }";
                    cm.RegisterClientScriptBlock(this.GetType(),
                        "CallServer", callbackScript, true);

                }
                catch (Exception ex)
                {
                    HandleException(ex);
                }

        }

        /// <summary>
        /// Clear all child controls and add an error message for display.
        /// </summary>
        /// <param name="ex"></param>
        private void HandleException(Exception ex)
        {
            this._error = true;
            this.Controls.Clear();
            this.Controls.Add(new LiteralControl(ex.Message));
        }

        #region ICallbackEventHandler Members

        public string GetCallbackResult()
        {
            return "Data inserted successfully..!";
        }

        public void RaiseCallbackEvent(string eventArgument)
        {

            char[] delimiter = new char[1];
            delimiter[0] = Convert.ToChar(";");
            string[] inputData = new string[2];
            inputData = eventArgument.Split(delimiter);

            string siteUrl = "http://galaxian:5050/default.aspx";
            string libName = "NameList";
            // Open the site
            using (SPSite site = new SPSite(siteUrl))
            {
                using (SPWeb web = site.OpenWeb())
                {

                    SPList list = web.Lists[libName];
                    SPListItem item = list.Items.Add();
                    item["Title"] = inputData[0];
                    item["Age"] = inputData[1];
                    item.Update();

                }
            }
        }

        #endregion
    }
}

This was the workaround that we have done for the asynchronous insert on the sharepoint list.

Hope you have enjoyed this post…Thanks for reading.

Advertisements

6 thoughts on “Asynchronous Sharepoint List Insert / Update.

    rachat credit said:
    October 24, 2010 at 11:40 pm

    I agree with most of your points, but some need to be discussed further, I will hold a small discussion with my buddies and perhaps I will look for you some suggestion soon.

    – Henry

    2o3u99 said:
    October 18, 2011 at 6:41 pm

    I agree with most of your points, but some need to be discussed further, I will hold a small discussion with my buddies and perhaps I will look for you some suggestion soon.

    Neeraj said:
    December 30, 2011 at 6:19 pm

    this code results in page post back….not working without postback

    chinababu said:
    January 5, 2012 at 9:31 am

    Hi All,
    I want to insert data into a sharepoint list using javascript and webservices for that i created a new document library and added a basic page and designed it with required columns. Up to here is ok.

    The page contains dropdowns,radio buttons and checkbox’s .need help how to write code.

    Thanks in advance

    Ravikumar said:
    May 22, 2015 at 2:49 am

    Hi All.

    There is an “Save Conflict” exception am getting, while concurrent user try to upload a video file into a document library, can anybody help me in resolving this issue.

    Thanks in advance.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s