Work-around to render the custom field in list view

Once I got a request from one of colleagues to create custom button field which will kick off a workflow for the list item which it get associated. Then, I had created a custom field which inherited from SPFieldText and rendered an ASP.net button control and in the click event I have implemented the code to kick off the workflow.

Everything worked fine and field rendered perfectly in the New, Edit, and Display form. But in the list view it doesn’t shows the button, we can see the column name in the list but can’t see the button in the list item. Below is the code that I have used to create the field and the FLDTypes.xml file.


ButtonFieldWF.Field.cs

    1: using System;
    2: using System.Runtime.InteropServices;
    3: using System.Security.Permissions;
    4: using Microsoft.SharePoint;
    5: using Microsoft.SharePoint.WebControls;
    6: using Microsoft.SharePoint.Security;
    7:  
    8: namespace CustomButtonField
    9: {
   10:     // TODO: Replace, as needed, "SPFieldText" with some other class derived from SPField. 
   11:     // TODO: Update, as needed, ParentType element in fldtypes*.xml in this solution. 
   12:     [CLSCompliant(false)]
   13:     [Guid("4a71f8a6-a7d1-45bb-9ced-8ed1676c95d6")]
   14:     public class ButtonFieldWFField : SPFieldText
   15:     {
   16:         public ButtonFieldWFField(SPFieldCollection fields, string fieldName)
   17:             : base(fields, fieldName)
   18:         {
   19:  
   20:         }
   21:         
   22:         public ButtonFieldWFField(SPFieldCollection fields, string typeName, string displayName)
   23:             : base(fields, typeName, displayName)
   24:         {
   25:         }
   26:  
   27:         public override BaseFieldControl FieldRenderingControl
   28:         {
   29:             [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
   30:             get
   31:             {
   32:                 BaseFieldControl fieldControl = new ButtonFieldWFFieldControl();
   33:                 fieldControl.FieldName = this.InternalName;
   34:  
   35:                 return fieldControl;
   36:             }
   37:         }
   38:  
   39:         
   40:     }
   41: }

ButtonFieldWF.FieldControl.cs

    1: using System;
    2: using System.Runtime.InteropServices;
    3:  
    4: using Microsoft.SharePoint;
    5: using Microsoft.SharePoint.WebControls;
    6: using Microsoft.SharePoint.Workflow;
    7:  
    8: using System.Web;
    9: using System.Web.UI;
   10: using System.Web.UI.WebControls;
   11: using System.Web.UI.HtmlControls;
   12:  
   13: namespace CustomButtonField
   14: {
   15:     // TODO: Replace, as needed, "TextField" with some other class derived from Microsoft.SharePoint.WebControls.BaseFieldControl.
   16:     [CLSCompliant(false)]
   17:     [Guid("9fbee449-9f7f-48de-999b-d7187dfe78cf")]
   18:     public class ButtonFieldWFFieldControl : TextField
   19:     {
   20:  
   21:         private Button oBtnWF = null;
   22:  
   23:         protected override void CreateChildControls()
   24:         {
   25:             base.CreateChildControls();
   26:  
   27:  
   28:             if (this.ControlMode == SPControlMode.Edit || this.ControlMode == SPControlMode.New || this.ControlMode == SPControlMode.Display)
   29:             {
   30:                 oBtnWF = new Button();
   31:                 oBtnWF.Text = "Start the custom WF";
   32:                 oBtnWF.Click += new EventHandler(oBtnWF_Click);
   33:                 base.Controls.Add(oBtnWF);
   34:  
   35:             }
   36:         }
   37:  
   38:         void oBtnWF_Click(object sender, EventArgs e)
   39:         {
   40:  
   41:             SPSite oSite = this.ListItem.Web.Site;
   42:  
   43:             //get the workflow associated with this doc lib and kick if off 
   44:             if (this.List.WorkflowAssociations.Count > 0)
   45:             {
   46:                 // kick off the first workflow..you can kick off your custom workflow by taking it properly
   47:                 SPWorkflowAssociation wrkFl = this.List.WorkflowAssociations[0];
   48:                 oSite.WorkflowManager.StartWorkflow(this.ListItem, wrkFl, wrkFl.AssociationData, true);
   49:             }
   50:             System.Web.HttpContext.Current.Response.Write("started...");
   51:  
   52:         }       
   53:  
   54:         protected override void Render(HtmlTextWriter output)
   55:         {
   56:             this.oBtnWF.RenderControl(output);
   57:         }
   58:     }
   59: }

fldtypes_ButtonFieldWF.xml

    1: <?xml version="1.0" encoding="utf-8"?>
    2: <FieldTypes>
    3:   <FieldType>
    4:     <Field Name="TypeName">ButtonFieldWFField</Field>
    5:     <Field Name="TypeDisplayName">ButtonFieldWFField</Field>
    6:     <Field Name="TypeShortDescription">ButtonFieldWFField</Field>
    7:     <Field Name="ParentType">Text</Field>
    8:     <Field Name="UserCreatable">TRUE</Field>
    9:     <Field Name="FieldTypeClass">4a71f8a6-a7d1-45bb-9ced-8ed1676c95d6</Field>
   10:   </FieldType>
   11: </FieldTypes>

After doing research on this issue confirmed that, by default we can’t render any controls like button, imagebutton, etc in list view. Because the items are rendering in the list view through CAML and <![CDATA [ html goes here ] ], so here the only work-around is construct the control using CDATA and display it.

    1: <?xml version="1.0" encoding="utf-8"?>
    2: <FieldTypes>
    3:   <FieldType>
    4:     <Field Name="TypeName">ButtonFieldWFField</Field>
    5:     <Field Name="TypeDisplayName">ButtonFieldWFField</Field>
    6:     <Field Name="TypeShortDescription">ButtonFieldWFField</Field>
    7:     <Field Name="ParentType">Text</Field>
    8:     <Field Name="UserCreatable">TRUE</Field>
    9:     <Field Name="FieldTypeClass">4a71f8a6-a7d1-45bb-9ced-8ed1676c95d6</Field>
   10:         <RenderPattern Name="DisplayPattern">
   11:               <Switch>
   12:                     <Expr>
   13:                           <Column Name="ContentTypeId" />
   14:                     </Expr>
   15:                     <!-- This is the Content Type Id for FOLDERs -->
   16:                     <Case Value="0x012000499529A73A47A1408DC7541F73C144CE">
   17:                           <!-- We do not want to display anything for folders -->
   18:                     </Case>
   19:                     <Default>
   20:                                                   
   21:                           <!-- This is the List ID -->
   22:                           <!-- ListProperty Select="Name" / -->
   23:                          
   24:                           <HTML>
   25:                                 <![CDATA[<input type="button" onClick="Test();" value="Start the custom WF" id="btn_]]>
   26:                           </HTML>
   27:                           <Column Name="ID" />
   28:                           <HTML>
   29:                                 <![CDATA[" />]]>
   30:                           </HTML>
   31:                           
   32:                           <HTML>
   33:                                 <![CDATA[
   34:                               <script type="text/javascript" language="javascript"> 
   35:                                     
   36:                                function Test()
   37:                                {
   38:                                     alert('hiii');                                  
   39:                                }
   40:                                </script>
   41:                                
   42:                                ]]>
   43:                           </HTML>
   44:                           
   45:                     </Default>
   46:               </Switch>
   47:         </RenderPattern>
   48:   </FieldType>
   49: </FieldTypes>

clip_image002

But, here another obstacle was the execution of server side code to kick off the workflow. We can’t write the server side code in <! [CDATA [] ]>, so we can kick off the workflow by putting that code in the page load of an aspx page and open it while clicking the button.

(eg : window.open(“_layouts/custompage.aspx”)).

 

Another work-around would be adding an ECB menu item for the list item and implement this functionality while clicking on it. 

Also please check this How-To video to know how we can create custom fields in WSS 3.0, if you are not familliar with this already.

Comments

  • Anonymous
    November 13, 2008
    PingBack from http://mstechnews.info/2008/11/work-around-to-render-the-custom-field-in-list-view/

  • Anonymous
    January 07, 2009
    Hi Can u send me the code of the work around, When I was trying to do the same proposed at the top it gives me an error saying the field types are not deployed properly My mail id is mmalireddy@gmail.com

  • Anonymous
    January 07, 2009
    Hi Reddy, I have sent a sample application to your gmail ID. Thanks, Sowmyan

  • Anonymous
    January 07, 2009
    The comment has been removed

  • Anonymous
    January 09, 2009
    Thanks for posting such a great post. I am trying to follow your steps in displaying the button in the list view. I modified the XML file to add the CDATA portion like what you did..but no luck in displaying the button. I added all the other part right. This is my Render Pattern i guess i messed this one. <RenderPattern Name="DisplayPattern">      <Switch>        <Expr>          <Column/>        </Expr>        <Case Value="">        </Case>        <Default>          <HTML>            <![CDATA[<input type="button" value="MarkMeComplete"id="btn_]]>          </HTML>        </Default>      </Switch>    </RenderPattern> New to CDATA concept what i am missing here?.please advise. Thanks, Subhan Email:Subhan.Turlapaty@gmail.com

  • Anonymous
    January 09, 2009
    Hi Reddy, For me the code worked fine. I wrote two classes(renamed to mine) in VS2005 c# library projet and using the same code of soumyan and build the project and placed the dll manually in GAC. I had no build errors though was never able to display the button Just my 2 cents. Thanks, Subhan

  • Anonymous
    January 09, 2009
    Hi Subhan, I just sent a sample custom button field to you. Please check it out. Thanks, Sowmyan

  • Anonymous
    January 09, 2009
    Reddy, could you please create a very simple custom field without renderpattern and see whether it is working fine or not. Check the deployment is happening correctly or not. Thanks, Sowmyan

  • Anonymous
    January 12, 2009
    Thanks Sowmyan, I recieved your code and i am able to show the button in the list view form. Also i sent an email about the customization i am working on for your guidance. Thanks, Subhan

  • Anonymous
    January 12, 2009
    The comment has been removed

  • Anonymous
    January 12, 2009
    As a work around, while clicking on the button you can redirect the page to an aspx page and write the server side code in the page_load. Thanks, Sowmyan

  • Anonymous
    January 13, 2009
    Oh ok..Thanks so much sowmyan for the idea. so in my case. i get hold of the sharepoint list date column modify the date and update and refresh the view right? makes sense..(all this in page_load?) one question still remains .. i have the button column to be shown..only if the date column is blank any code snippet sample or idea for the java script how to do this.. Thanks, Subhan

  • Anonymous
    January 14, 2009
    check how that column is rendering in the form of HTML by taking the view source of your page. After that try to find out value through javascript and you can plug it in the [CDATA] and using a if condition you can display the button. Thanks, Sowmyan

  • Anonymous
    January 14, 2009
    Thanks sowmyan for the feedback. so i have a jscript function hideButtonField() which has all the functionality.. where do i call this function it needs to be called on sharepoint page(my custom list view)load.. how can i do this? Thanks again, Subhan

  • Anonymous
    January 15, 2009
    I meant that, put the javascript inside the DisplayPattern itself. Using CDATA you can control the rendering of HTML controls. Thanks, Sowmyan

  • Anonymous
    January 15, 2009
    Hi sowmyan its me again.. in the edit mode i am able to locate the text field id of the date picker control. however in the display mode i am not able to find the input field of the calendar control all find is a table with rows( my items ) an in that row for the completed date column i find <TD Class ="ms-vb2"<NOBR></NOBR></TD>. where the is a date it puts the date in <NOBR></NOBR> like this <TD Class ="ms-vb2"<NOBR>15/20/2009</NOBR></TD> So i came down one step down.. i still have a button..(EDIT)this time all it needs to do is take me to the edit form of that particular record.(here i wil update the completed date field to present date) how can i redirect to EditForm.aspx i tried onclick=window.open("http://vsservername:23485/sites/intranet/Lists/Employees/EditForm.aspx?ID=2&Source=http%3A%2F%2Fvsmoss%3A23485%2Fsites%2Fintranet%2FLists%2FEmployees%2FAllItems%2Easpx") pretty much i pasted the real url of the edit page of that record in my sharepoint list. when i click nothing happengs.. please advise. thanks again.. Subhan

  • Anonymous
    January 15, 2009
    same post but with corrected grammar..please consider this one.sorry about my grammar in the previous post. Hi Sowmyan, in the edit mode i am able to locate the text field id of the date picker control. however in the display mode i am not able to find the input text field of the calendar control in the view source page.. all i find is a table with rows( my items ). and in that row for the completed date column i find <TD Class ="ms-vb2"<NOBR></NOBR></TD>. when there is  date it puts the date in <NOBR></NOBR> like this <TD Class ="ms-vb2"<NOBR>15/20/2009</NOBR></TD> So i came down one step down :-( Now,i still have a button..(EDIT)this time all it needs to do is take me to the edit form of that particular record.(here i wil update the completed date field to present date) how can i redirect to EditForm.aspx i tried onclick=window.open("http://vsservername:23485/sites/intranet/Lists/Employees/EditForm.aspx?ID=2&Source=http%3A%2F%2Fvsmoss%3A23485%2Fsites%2Fintranet%2FLists%2FEmployees%2FAllItems%2Easpx") pretty much i pasted the real url of the edit page of that record in my sharepoint list. when i click nothing happengs.. please advise. thanks again.. Subhan

  • Anonymous
    January 16, 2009
    Yes, the <td> column doesn't have an ID. Otherwise you have to use the <table name=""> and need to iterate its childs but it will be a complex way. About the window.open(), are you able to open any other page instead of editform.aspx ? Thanks, Sowmyan

  • Anonymous
    January 18, 2009
    Hi Sowmyan, Yep i see what are u saying regarding table iteration..will check if there are alternatives or else need to go with the same route if the client is not convincing.. regarding the window.open() i guess nothing is happening with other pages to.. in your example redirecting to custompage.aspx it worked right? thanks, Subhan

  • Anonymous
    January 20, 2009
    Hi Sowmyan, in all honesty your blogs helped me a lot in understanding customization of UI. can you please let me know if you have blogs/posts on workflows through visual studio 2005/2008. i have a few questions on certain scenarios.. let me know if i can go ahead and post here.. Thanks, Subhan

  • Anonymous
    January 28, 2009
    can u pls send me the code.I am new to sharepoint.The field type seems to be very good. neosri@gmail.com REgards, Sriram

  • Anonymous
    February 26, 2009
    Hi Sriran, I had sent the code to you ...

  • Anonymous
    February 26, 2009
    Subhan, I have couple of WF posts let me know your questions. Also you can post it in those posts thus it will help others too.

  • Anonymous
    April 02, 2009
    Hi Sowmyan, can you pls send me the code.I am new to sharepoint.I am interested in creation and usage of custom fields. raj5186@gmail.com regards, raju

  • Anonymous
    May 01, 2009
    Hi Sowmyan, This is really good post. You suggested that html code to display the button in a list be written in CDATA section and that clicking on it can open an aspx page which in turn invokes a workflow. Doesn't SharePoint complain about updating site content via requests using GET method? How did you solve this problem? Can you please let us know. Regards, Subbu.

  • Anonymous
    May 01, 2009
    Most probably you can get rid of that issue by following the below.     a.  Add the following register tag in your aspx page              <%@ Register Tagprefix="SharePoint"            Namespace="Microsoft.SharePoint.WebControls"            Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral,      PublicKeyToken=71e9bce111e9429c" %>   b.  Add the sharepoint “FormDigest” control in the page.         <SharePoint:FormDigest  ID="fd" runat="server"/> Thanks, Sowmyan

  • Anonymous
    May 03, 2009
    Hi Sowmyan, That did not work for me. I tried by putting the form digest control in the custom aspx page. There is no form in the list view page either. Regards, Subbu.

  • Anonymous
    June 25, 2009
    Hi Can u send me the code of the work around, When I was trying to do the same proposed at the top it gives me an error saying the field types are not deployed properly My mail id is kamalkatre@rediffmail.com

  • Anonymous
    July 14, 2009
    Eda Sowmyaney, Your code is awesome. -- Khilan

  • Anonymous
    September 03, 2009
    Starting the workflow from the button in list view page : Just create an XmlHttpRequest and call the StartWorkflow method in workflow webservice. Hope it helps :)

  • Anonymous
    March 20, 2011
    I deployed this code in sharepoint 2010. Button is showing in new list item form but it is not showing up in list .. I have fallowed all the steps correctly. I dono where I have gone wrong..

  • Anonymous
    March 20, 2011
    Hi all, I deployed this code in sharepoint 2010. Button is hsowing up in new form, edit form and display form but its not showing up in sharepoint list.. Can anyone tell me how to fix this..

  • Anonymous
    December 15, 2011
    The comment has been removed

  • Anonymous
    March 25, 2012
    I followed exactly the same as descibed in the post, but I'm not able to see the button in the list view as well , anybody got any ideas?

  • Anonymous
    September 09, 2012
    Nice post, can you please send me the code to plztk1999[AT]Yahoo[DOT]Com The code deployed successfully, I can see the custom filed type, but when I try to create the column using the custom field, I'm facing with "Field type ButtonFieldWFField is not installed properly. Go to the list settings page to delete this field. " Please send me the code to above id, thanks for your efforts.