Custom Field Controls in Data Form webpart does not save data in Database

Any input control for that matter, a simple custom field control with a single text box into the DataFormWebPart. The field gets displayed well in the NewForm and EditForm. But on saving the form data is not saved.No errors thrown.

Build and deploy the project attached to this post.

Create a custom list and create a column of Custom field control added by the project. (SimpleTextFieldField)
3. Open SPD.
4. Go to File -- Open Project -- Select the URL of the site.
5. Expand the Lists tree in the Left pane and expand the List which was created in step 2
6. Double Click on NewForm.aspx of the list.
7. Switch to Split mode of NewForm.aspx in SPD.
8. Select the ListForm Webpart in NewForm.aspx page
9. After </WebPartPages:ListFormWebPart> tag hit enter.

10. Go to Insert Menu -- SharePoint Controls -- Custom List Form. If Custom List Form option is not enabled save the NewForm.aspx and try again.

First
11. A pop up window appear where you can select the List which we created in step 2 and let the Content Type to use for from be selected to Item, check the radio button "New item form (used to add new items to the list).

Second

12. Right click on List Form webpart -- Webpart properties -- Layout -- Select both checkboxes "Hidden" and "Close the webpart" -- Click OK button
13. Save the NewForm.aspx page in SPD.
14. Open IE, browse to the list created -- Click on New -- Add entry for Title column and a value for the Custom field control which we have added and click OK
14. It will come back to AllItems.aspx where we can find that the value entered to the custom column is blank.

Schema of Title Field
---------------------------
<Field ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Type="Text" Name="Title" DisplayName="Title" Required="TRUE" SourceID="https://schemas.microsoft.com/sharepoint/v3" StaticName="Title" FromBaseType="TRUE" ColName="nvarchar1"/>

Schema of Custom Field control
-------------------------------------
<Field Type="SimpleTextFieldField" DisplayName="huha" Required="TRUE" ID="{9df3f794-4a49-4019-a41a-3d29ae500903}" SourceID="{e68e397e-fb36-4971-955e-904f56a57d10}" StaticName="huha" Name="huha" ColName="nvarchar3" RowOrdinal="0"/>

Schema of Field added through UI
---------------------------------------------
<Field Type="Text" DisplayName="BoomCol" Required="FALSE" MaxLength="255" ID="{ef0b772f-af19-467a-9afd-2920ba1b10d8}" SourceID="{e68e397e-fb36-4971-955e-904f56a57d10}" StaticName="BoomCol" Name="BoomCol" ColName="nvarchar4" RowOrdinal="0"/>

This behaviour was because, the TextBox we exposed is a child control, the main control is SPTextFieldFieldControl. When you convert to a DataForm webpart, these custom controls will be replaced by the SPForm controls.  This control does not identify what is the original value. If you look inside the SPTextFieldFieldControl, I do have HtmlTable, LiteralControl, TextBox etc. So now we get the inner control value and set the “Text/Value” property of the main control(SPTextFieldFieldControl)

===========================================

Code changes for SimpleTextField attached below.

=======================================

using System;
using System.Runtime.InteropServices;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Web.UI.HtmlControls;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace SimpleTextFieldControl
{
    // TODO: Replace, as needed, "TextField" with some other class derived from Microsoft.SharePoint.WebControls.BaseFieldControl.
    [CLSCompliant(false)]
    [Guid("f6fdae87-e10d-4aa6-bd80-db14d41a19d6")]
    public class SimpleTextFieldFieldControl : TextField
    {
        private HtmlTable table;
        private TextBox txtName;
        private string _textValue;
        private void RefreshValues()
        {
            if (txtName != null && this.Context != null && this.Context.Request != null)
            {
                foreach (string key in this.Context.Request.Form.Keys)
                {

                    if (key.ToLower() == txtName.UniqueID.ToLower())
                    {
                        string[] enteredValue = this.Context.Request.Form.GetValues(key);
                        textBox.Text = enteredValue[0];
                        _textValue = textBox.Text;
                    }
                }
            }
        }

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

            this.table = new HtmlTable();

            HtmlTableRow row = new HtmlTableRow();
            table.Rows.Add(row);

            HtmlTableCell cell = null;

            if (this.ControlMode == SPControlMode.Edit ||
                this.ControlMode == SPControlMode.New)
            {
                cell = new HtmlTableCell();
                cell.ColSpan = 2;
                cell.Attributes["class"] = "ms-formdescription";
                cell.InnerText = "Enter a Text:";

                row.Cells.Add(cell);

                row = new HtmlTableRow();
                cell = new HtmlTableCell();

                // a text field
                this.txtName = new TextBox();
                // Get the current value of the field.
                string currentValue = (string)this.ItemFieldValue;

                if (currentValue != null && currentValue != string.Empty)
                {
                    this.txtName.Text = currentValue;
                }

                cell.Controls.Add(this.txtName);
                row.Cells.Add(cell);
                table.Rows.Add(row);
            }

            cell = new HtmlTableCell();

            LiteralControl literalControl = new LiteralControl();

            string text = null;
            object textObject = this.ItemFieldValue;

            if (textObject != null)
            {
                text = (string)textObject;
            }

            if (text == null || text == string.Empty)
            {
                text = this.txtName.Text;
            }

            literalControl.Text = text;

            cell.Controls.Add(literalControl);
            row.Cells.Add(cell);

            base.Controls.Add(table);
        }

        public override string Text
        {
            get
            {
                RefreshValues();
                return _textValue;
            }
            set
            {
                base.Text = value;
            }
        }

        public override void UpdateFieldValueInItem()
        {
            base.UpdateFieldValueInItem();
            try
            {
                this.Value = this.txtName.Text;
                this.ItemFieldValue = this.Value;
            }
            catch
            {
                throw new Exception("error in text field") ;
            }
        }

        protected override void Render(HtmlTextWriter output)
        {
            this.table.RenderControl(output);
        }

    }   
}

Comments

  • Anonymous
    May 25, 2009
    PingBack from http://microsoft-sharepoint.simplynetdev.com/custom-field-controls-in-data-form-webpart-does-not-save-data-in-database/

  • Anonymous
    May 25, 2009
    Thank you... I've been waiting for this solution for a long time. :)

  • Anonymous
    July 14, 2010
    How coluld i stop method UpdateFieldValueInItem to be called on post back

  • Anonymous
    November 20, 2010
    Can you put a little more description?  I have this same problem with a custom SPFieldMultiColumn.  But what exactly are you changing (you don't have before and after and your description is very limited). Perhaps you could just post what the code looked like before you got it working and what it looked like after, which bold text for the changes or something like that.  I think this is the answer to my problem, but I'm really struggling with it. Thanks.