Using RadGrid inside Sitefinity Form Widget

Posted by Community Admin on 04-Aug-2018 22:11

Using RadGrid inside Sitefinity Form Widget

All Replies

Posted by Community Admin on 06-Sep-2013 00:00
Hi!

I'm trying to embed a RadGrid in a Sitefinity Form Widget, so i can add a field to a form which allows users to create a collection of attendees that will attend a specific event. The process works fine, until I try to integrate the code into a FieldControl, then neither the insert or update command events will fire, meaning i can never add or update rows.

I've attached code, any ideas? I'm fresh out!

Attendees.ascx
<%@ Control %>
<%@ Register Assembly="Telerik.Sitefinity" TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI" %>
 
<asp:Label runat="server" ID="titleLabel" CssClass="sfTxtLbl" Text="title label" AssociatedControlID="TextBox1" />
<div class="sfFieldWrp">
    <asp:TextBox ID="TextBox1" CssClass="sfTxt" runat="server" />
 
    <telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
        <AjaxSettings>
            <telerik:AjaxSetting AjaxControlID="RadGrid1">
                <UpdatedControls>
                    <telerik:AjaxUpdatedControl ControlID="RadGrid1" LoadingPanelID="RadAjaxLoadingPanel1">
                    </telerik:AjaxUpdatedControl>
                </UpdatedControls>
            </telerik:AjaxSetting>
        </AjaxSettings>
    </telerik:RadAjaxManager>
    <telerik:RadGrid ID="attendees" runat="server" AutoGenerateColumns="False" AllowSorting="false" AllowFilteringByColumn="false">
        <ItemStyle HorizontalAlign="Center"></ItemStyle>
        <AlternatingItemStyle HorizontalAlign="Center"></AlternatingItemStyle>
        <HeaderStyle HorizontalAlign="Center"></HeaderStyle>
        <MasterTableView CommandItemDisplay="Top" EditMode="InPlace" DataKeyNames="ID">
            <Columns>
                <telerik:GridTemplateColumn UniqueName="FirstName" HeaderText="First Name" SortExpression="FirstName">
                    <ItemTemplate>
                        <%# DataBinder.Eval(Container.DataItem, "FirstName") %>
                    </ItemTemplate>
                    <EditItemTemplate>
                        <telerik:RadTextBox ID="firstName" runat="server" Skin="Web20" Width="100px" Text='<%# Bind("FirstName")%>'>
                        </telerik:RadTextBox>
                    </EditItemTemplate>
                </telerik:GridTemplateColumn>
                <telerik:GridTemplateColumn UniqueName="LastName" HeaderText="Last Name" SortExpression="LastName">
                    <ItemTemplate>
                        <%# DataBinder.Eval(Container.DataItem, "LastName")%>
                    </ItemTemplate>
                    <EditItemTemplate>
                        <telerik:RadTextBox ID="lastName" runat="server" Skin="Web20" Width="100px" Text='<%# Bind("LastName")%>'>
                        </telerik:RadTextBox>
                    </EditItemTemplate>
                </telerik:GridTemplateColumn>
                <telerik:GridTemplateColumn UniqueName="DateOfBirth" HeaderText="Date of Birth" SortExpression="DateOfBirth">
                    <ItemTemplate>
                        <%# (DataBinder.Eval(Container.DataItem, "DateOfBirth")) %>
                    </ItemTemplate>
                    <EditItemTemplate>
                        <telerik:RadDateInput ID="dateOfBirth" runat="server" Skin="Web20" Culture="(Default)"
                            DbSelectedDate='<%# Bind("DateOfBirth")%>' DateFormat="dd/MM/yyyy" MinDate="01/01/1920"
                            Width="120px"></telerik:RadDateInput>
                    </EditItemTemplate>
                </telerik:GridTemplateColumn>
                <telerik:GridTemplateColumn UniqueName="Gender" HeaderText="Gender" SortExpression="Gender">
                    <ItemTemplate>
                        <%# DataBinder.Eval(Container.DataItem, "Gender")%>
                    </ItemTemplate>
                    <EditItemTemplate>
                        <telerik:RadMaskedTextBox ID="gender" Width="60px" runat="server" Skin="Web20"
                            Text='<%# Bind("Gender")%>' Mask="<M|F|m|f>" PromptChar="_"></telerik:RadMaskedTextBox>
                    </EditItemTemplate>
                </telerik:GridTemplateColumn>
                <telerik:GridEditCommandColumn ButtonType="ImageButton" UpdateText="Update" CancelText="Cancel"
                    EditText="Edit">
                </telerik:GridEditCommandColumn>
            </Columns>
        </MasterTableView>
    </telerik:RadGrid>
     
    <sf:SitefinityLabel runat="server" ID="descriptionLabel" WrapperTagName="div" CssClass="sfDescription"/>
    <sf:SitefinityLabel runat="server" ID="exampleLabel" WrapperTagName="div" CssClass="sfExample"/>
</div>


Attendees.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web.UI;
using System.Web.UI.WebControls;
using Telerik.Sitefinity.Data.Metadata;
using Telerik.Sitefinity.Metadata.Model;
using Telerik.Sitefinity.Model;
using Telerik.Sitefinity.Modules.Forms.Web.UI.Fields;
using Telerik.Sitefinity.Security;
using Telerik.Sitefinity.Web.UI;
using Telerik.Sitefinity.Web.UI.ControlDesign;
using Telerik.Sitefinity.Web.UI.Fields;
using Telerik.Sitefinity.Web.UI.Fields.Enums;
using System.Data;
using Telerik.Web.UI;
using System.Collections;
using System.Text;
using System.Web;
 
namespace SitefinityWebApp.Custom.Forms.Atendees
    /// <summary>
    /// Class used to create custom control for Form Builder
    /// </summary>
    /// <remarks>
    /// If this form widget is a part of a Sitefinity module,
    /// you can register it in the site's toolbox by adding this to the module's Install/Upgrade method(s):
    /// initializer.Installer
    ///    .Toolbox(CommonToolbox.FormWidgets)
    ///        .LoadOrAddSection(SectionName) // "TwoColumns" is Sitefinity's default
    ///            .SetTitle(SectionTitle) // When creating a new section
    ///            .SetDescription(SectionDescription) // When creating a new section
    ///            .LoadOrAddWidget<Attendees>("Attendees")
    ///                .SetTitle("Attendees")
    ///                .SetDescription("Attendees")
    ///                .LocalizeUsing<ModuleResourceClass>() // Optional
    ///                .SetCssClass(WidgetCssClass) // You can use a css class to add an icon (this is optional)
    ///            .Done()
    ///        .Done()
    ///    .Done();
    /// </remarks>
    [DatabaseMapping(UserFriendlyDataType.ShortText)]
    [PropertyEditorTitle("Attendees Properties"), Telerik.Sitefinity.Web.UI.ControlDesign.ControlDesigner(typeof(SitefinityWebApp.Custom.Forms.Atendees.Designer.AttendeesDesigner))]
    public class Attendees : FieldControl, IFormFieldControl
    
        #region Constructor
        /// <summary>
        /// Initializes a new instance of the Attendees class.
        /// </summary>
        public Attendees()
        
            this.Title = "Attendees";
        
        #endregion
 
        #region Public properties (will show up in dialog)
        /// <summary>
        /// Example string
        /// </summary>
        public override string Example get; set;
 
        /// <summary>
        /// Title string
        /// </summary>
        public override string Title get; set;
 
        /// <summary>
        /// Description string
        /// </summary>
        public override string Description get; set;
        #endregion
 
        #region IFormFieldControl members
        /// <summary>
        /// Gets or sets MetaField property to persist data from control to the DB when form is submitted
        /// </summary>
        [TypeConverter(typeof(ExpandableObjectConverter))]
        public IMetaField MetaField
        
            get
            
                if (this.metaField == null)
                
                    this.metaField = this.LoadDefaultMetaField();
                
 
                return this.metaField;
            
            set
            
                this.metaField = value;
            
        
        #endregion
 
        #region Value method
        /// <summary>
        /// Get and set the value of the field.
        /// </summary>
        public override object Value
        
            get
            
                return this.TextBox1.Text;
            
 
            set
            
                this.TextBox1.Text = value.ToString();
            
        
        #endregion
 
        #region Template
        /// <summary>
        /// Obsolete. Use LayoutTemplatePath instead.
        /// </summary>
        protected override string LayoutTemplateName
        
            get
            
                return string.Empty;
            
        
 
        /// <summary>
        /// Gets the layout template's relative or virtual path.
        /// </summary>
        public override string LayoutTemplatePath
        
            get
            
                if (string.IsNullOrEmpty(base.LayoutTemplatePath))
                    return Attendees.layoutTemplatePath;
                return base.LayoutTemplatePath;
            
            set
            
                base.LayoutTemplatePath = value;
            
        
        #endregion
 
        #region Labels on control template
        /// <summary>
        /// Gets reference to the TitleLabel
        /// </summary>
        protected internal virtual Label TitleLabel
        
            get
            
                return this.Container.GetControl<Label>("titleLabel", true);
            
        
 
        /// <summary>
        /// Gets reference to the DescriptionLabel
        /// </summary>
        protected internal virtual Label DescriptionLabel
        
            get
            
                return Container.GetControl<Label>("descriptionLabel", true);
            
        
 
        /// <summary>
        /// Gets reference to the ExampleLabel
        /// </summary>
        protected internal virtual Label ExampleLabel
        
            get
            
                return this.Container.GetControl<Label>("exampleLabel", this.DisplayMode == FieldDisplayMode.Write);
            
        
 
        /// <summary>
        /// Reference to the TitleControl
        /// </summary>
        protected override WebControl TitleControl
        
            get
            
                return this.TitleLabel;
            
        
 
        /// <summary>
        /// Reference to the DescriptionControl
        /// </summary>
        protected override WebControl DescriptionControl
        
            get
            
                return this.DescriptionLabel;
            
        
 
        /// <summary>
        /// Gets the reference to the control that represents the example of the field control.
        /// Return null if no such control exists in the template.
        /// </summary>
        /// <value></value>
        protected override WebControl ExampleControl
        
            get
            
                return this.ExampleLabel;
            
        
        #endregion
 
        #region Textbox on control
        /// <summary>
        /// Gets reference to the TextBox1 control
        /// </summary>
        protected virtual TextBox TextBox1
        
            get
            
                return this.Container.GetControl<TextBox>("TextBox1", true);
            
        
        #endregion
 
        #region InitializeControls method
        /// <summary>
        /// Initializes the controls.
        /// </summary>
        /// <remarks>
        /// Initialize your controls in this method. Do not override CreateChildControls method.
        /// </remarks>
        protected override void InitializeControls(GenericContainer container)
        
            // Set the label values
            this.ExampleLabel.Text = this.Example;
            this.TitleLabel.Text = this.Title;
            this.DescriptionLabel.Text = this.Description;
 
            this.Grid.NeedDataSource += new GridNeedDataSourceEventHandler(Grid_NeedDataSource);
            this.Grid.UpdateCommand += new GridCommandEventHandler(Grid_UpdateCommand);
            this.Grid.InsertCommand += new GridCommandEventHandler(Grid_InsertCommand);
 
            this.TextBox1.Text = GetCurrentSitefinityUser();
        
        #endregion
 
        #region Get Current User
        /// <summary>
        /// Get the full name for the currently logged-in Sitefinity user.
        /// </summary>
        /// <returns>String with full name of current user, or empty string if user not logged in.</returns>
        private static string GetCurrentSitefinityUser()
        
            Telerik.Sitefinity.Security.Web.UI.ProfileView pv = new Telerik.Sitefinity.Security.Web.UI.ProfileView();
            Guid currentUserGuid = pv.CurrentUser.UserId;
 
            if (currentUserGuid != Guid.Empty)
            
                var userProfile = UserProfileManager.GetManager().GetUserProfiles(currentUserGuid).FirstOrDefault() as Telerik.Sitefinity.Security.Model.SitefinityProfile;
                if (userProfile != null)
                
                    return userProfile.FirstName + " " + userProfile.LastName;
                
            
            return String.Empty;
        
        #endregion
 
        #region Script methods
        /// <summary>
        /// Get list of all scripts used by control
        /// </summary>
        /// <returns>List of all scripts used by control</returns>
        public override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
        
            var descriptor = new ScriptControlDescriptor(typeof(Attendees).FullName, this.ClientID);
            descriptor.AddElementProperty("textbox", this.TextBox1.ClientID);
            descriptor.AddProperty("dataFieldName", this.MetaField.FieldName); //the field name of the corresponding widget
            return new[] descriptor ;
        
 
        /// <summary>
        /// Get reference to all scripts
        /// </summary>
        /// <returns>Reference to all scripts</returns>
        public override IEnumerable<System.Web.UI.ScriptReference> GetScriptReferences()
        
            var scripts = new List<ScriptReference>(base.GetScriptReferences())
            
                new ScriptReference(Attendees.scriptReference),
                new ScriptReference("Telerik.Sitefinity.Web.UI.Fields.Scripts.FieldDisplayMode.js", "Telerik.Sitefinity"),
            ;
            return scripts;
        
        #endregion
 
        #region Private fields and constants
        private IMetaField metaField = null;
        public static readonly string layoutTemplatePath = "~/Custom/Forms/Atendees/Attendees.ascx";
        public const string scriptReference = "~/Custom/Forms/Atendees/Attendees.js";
        #endregion
 
        #region RadGrid
        private List<int> IDS
        
            get
            
                if (HttpContext.Current.Session["IDS" + Grid.ClientID] == null)
                
                    HttpContext.Current.Session["IDS" + Grid.ClientID] = new List<int>();
                
 
                return (List<int>)HttpContext.Current.Session["IDS" + Grid.ClientID];
            
        
 
        /// <summary>
        /// Gets reference to the TextBox1 control
        /// </summary>
        protected virtual RadGrid Grid
        
            get
            
                return this.Container.GetControl<RadGrid>("attendees", true);
            
        
 
        private DataTable DataSource
        
            get
            
                if (HttpContext.Current.Session["RadGridCS" + Grid.ClientID] == null)
                
                    DataTable data = new DataTable();
                    data.Columns.Add("ID", typeof(int));
                    data.Columns.Add("FirstName");
                    data.Columns.Add("LastName");
                    data.Columns.Add("DateOfBirth", typeof(DateTime));
                    data.Columns.Add("Gender");
 
                    data.Rows.Add(new object[] GenerateNewId(), "Mr.", "John Smith", new DateTime(1998, 01, 01), "M" );
                    data.Rows.Add(new object[] GenerateNewId(), "Mrs.", "Jane Brown", new DateTime(2003, 01, 01), "F" );
                    data.Rows.Add(new object[] GenerateNewId(), "Mr.", "Peter Johnson", new DateTime(2001, 01, 01), "M" );
                    data.Rows.Add(new object[] GenerateNewId(), "Ms.", "Diane Klive", new DateTime(1999, 01, 01), "F" );
                    data.Rows.Add(new object[] GenerateNewId(), "Mrs.", "Megan Hammer", new DateTime(1997, 01, 01), "F" );
                    HttpContext.Current.Session["RadGridCS" + Grid.ClientID] = data;
                
                return (DataTable)HttpContext.Current.Session["RadGridCS" + Grid.ClientID];
            
        
 
        private int GenerateNewId()
        
            int id = 0;
            if (IDS.Count > 0)
            
                id = IDS.Max() + 1;
            
            IDS.Add(id);
 
            return id;
        
 
        protected void Grid_UpdateCommand(object source, GridCommandEventArgs e)
        
            GridEditableItem editedItem = e.Item as GridEditableItem;
 
            //Locate the changed row in the DataSource
            DataRow[] changedRows = DataSource.Select("ID = " + editedItem.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["ID"]);
 
            Hashtable newValues = new Hashtable();
            //The GridTableView will fill the values from all editable columns in the hash
            e.Item.OwnerTableView.ExtractValuesFromItem(newValues, editedItem);
 
            DataRow changedRow = changedRows[0];
            changedRow.BeginEdit();
            try
            
                foreach (DictionaryEntry entry in newValues)
                
                    changedRow[(string)entry.Key] = entry.Value;
                
                changedRow.EndEdit();
            
            catch (Exception ex)
            
                changedRow.CancelEdit();
                Grid.Controls.Add(new LiteralControl("Unable to update the data. Reason: " + ex.Message));
                e.Canceled = true;
            
        
        protected void Grid_NeedDataSource(object source, GridNeedDataSourceEventArgs e)
        
            Grid.DataSource = DataSource;
        
 
        protected void Grid_InsertCommand(object source, GridCommandEventArgs e)
        
            //Create new row in the DataSource
            DataRow newRow = this.DataSource.NewRow();
 
            GridDataInsertItem item = (GridDataInsertItem)e.Item;
            //Insert new values
            Hashtable newValues = new Hashtable();
 
            newValues["FirstName"] = ((RadTextBox)item["FirstName"].FindControl("firstName")).Text;
            newValues["LastName"] = ((RadTextBox)item["LastName"].FindControl("lastName")).Text;
            newValues["DateOfBirth"] = ((RadDateInput)item["DateOfBirth"].FindControl("dateOfBirth")).SelectedDate;
            newValues["Gender"] = ((RadMaskedTextBox)item["Gender"].FindControl("gender")).Text;
 
            //make sure that unique primary key value is generated for the inserted row
            newValues["ID"] = GenerateNewId();
            try
            
                foreach (DictionaryEntry entry in newValues)
                
                    newRow[(string)entry.Key] = entry.Value;
                
                this.DataSource.Rows.Add(newRow);
                this.DataSource.AcceptChanges();
            
            catch (Exception ex)
            
                Grid.Controls.Add(new LiteralControl("Unable to update the data. Reason: " + ex.Message));
                e.Canceled = true;
            
        
 
        private string DataSourceAsCSV()
        
            var result = new StringBuilder();
            for (int i = 0; i < DataSource.Columns.Count; i++)
            
                result.Append(DataSource.Columns[i].ColumnName);
                result.Append(i == DataSource.Columns.Count - 1 ? "\n" : ",");
            
 
            foreach (DataRow row in DataSource.Rows)
            
                for (int i = 0; i < DataSource.Columns.Count; i++)
                
                    result.Append(row[i].ToString());
                    result.Append(i == DataSource.Columns.Count - 1 ? "\n" : ",");
                
            
 
            string s = result.ToString();
            s = s.TrimEnd(new char[] '\r', '\n' );
            return s;
        
        #endregion
    
Posted by Community Admin on 11-Sep-2013 00:00
Hello,

 
The code for handling grid events have to be integrated into Attendees.js which is the client side functionality for the form control and it will get executed when the form control renders in the frontend. To subscribe and handle grid events implement event handlers for the client side events of the grid in Attendees.js initializeBase function.

SitefinityWebApp.Custom.Forms.Atendees.Attendees.initializeBase(this, [element]);

For more information on Field Controls refer this documentation.

Regards,
Stanislav Velikov
Telerik
Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
This thread is closed