Work-around to render the custom field in list view

Work-around to render the custom field in list view

  • Comments 35

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
  • PingBack from http://mstechnews.info/2008/11/work-around-to-render-the-custom-field-in-list-view/

  • 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

  • Hi Reddy,

    I have sent a sample application to your gmail ID.

    Thanks,

    Sowmyan

  • Thanks for the code,But this code is giving me an error in the newform.aspx page saying the field type is not deployed properly.Actually my requirment is for running a javascript on the button click so there is no need for the server side code for me.If I am not using <Field Name="FieldTypeClass">4a71f8a6-a7d1-45bb-9ced-8ed1676c95d6</Field> this line then it is giving me an error.Any help with respect to this is really appreciated and Thanks for your help

  • 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

  • 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

  • Hi Subhan,

    I just sent a sample custom button field to you. Please check it out.

    Thanks,

    Sowmyan

  • 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

  • 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

  • Hi Subhan,

    I just checked my mail box and got your message.

    That is a CAML code and it is just for rendering the information in the list view. In [CDATA ] we can include only html controls and can't include server side controls and code. But, you can include javascript.

    Thanks,

    Sowmyan

  • 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

  • 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

  • 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

  • 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

  • I meant that, put the javascript inside the DisplayPattern itself. Using CDATA you can control the rendering of HTML controls.

    Thanks,

    Sowmyan

Page 1 of 3 (35 items) 123
Leave a Comment
  • Please add 7 and 2 and type the answer here:
  • Post