Adding Custom Controls To Form Builder - General Discussions - General Discussions - Progress Community
 General Discussions

Adding Custom Controls To Form Builder

  • Adding Custom Controls To Form Builder
  • Is there a tutorial available to allow us to add controls to the form builder toolbox.

    I need to be able to create a control which the user can drag onto the form and which will create a field or fields in the backend database, just as the existing controls do.
  • Hi Matt,

    1. You have to create a control that inherits from FieldControl and implements IFormFieldControl

    2. You can register the control from Administration >> Settings >> Advanced >> Toolboxes >> FormControls

    Best wishes,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  • I tried to do this, but ran into problems...

    I managed to create a user control and build the project without any errors.

    I then added the control to the toolbox.

    I logged into SiteFinity, created a form and tried to drag my new control onto the form.

    I got the error: 'SitefinityWebApp.MyControls.LinkPicker' is not allowed here because it does not extend class 'System.Web.UI.UserControl'.

    I went back to Visual Studio 2010 to try to rectify this.  When I rebuilt the project, I got a mass of errors.

    The project lost references to Microsoft.Practices.ServiceLocation, MySql.Data and all of the Telerik references (all had a yellow triangle beside them).

    Could I request that you produce a detailed example of how to accomplish this? - I think it's something that your customers would like to do.

    Also, why is it so easy to run into problems with lost references like this?


    Matt.
  • Hello Matt,

    Here is a sample code.  It is working fine if you drop it on a form.You have to implement the custom logic you want to have inside IntializeControls

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Telerik.Sitefinity.Web.UI.Fields;
    using System.Web.UI.WebControls;
    using Telerik.Sitefinity.Web.UI.Fields.Enums;
     
    namespace Telerik.Sitefinity.Samples
        public class FiledControlCustom  : FieldControl
        
            protected override System.Web.UI.WebControls.WebControl TitleControl
            
                get
                
                    return this.TitleLabel;
                
            
     
            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;
                
            
     
     
            protected internal virtual Label TitleLabel
            
                get
                
                    return this.Container.GetControl<Label>("titleLabel", true);
                
            
     
         
            protected internal virtual Label DescriptionLabel
            
                get
                
                    return Container.GetControl<Label>("descriptionLabel", true);
                
            
     
         
            protected internal virtual Label ExampleLabel
            
                get
                
                    return this.Container.GetControl<Label>("exampleLabel", this.DisplayMode == FieldDisplayMode.Write);
                
            
     
     
            protected override void InitializeControls(Web.UI.GenericContainer container)
            
                throw new NotImplementedException();
            
     
            protected override string LayoutTemplateName
            
                get return FiledControlCustom.layoutTemplateName;
            
     
            private const string layoutTemplateName = "Telerik.Sitefinity.Samples.Resources.FieldControlCutom.ascx";
        


    All the best,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  • Hi Ivan,

    I'm not sure where  I would put that code.

    I'm following the instructions to create a widget.  The instructions say that I should create a Web User Control.

    When I do that, the cs file contains the following:

    public partial class TestControl : System.Web.UI.UserControl
        protected void Page_Load(object sender, EventArgs e)
        
     
        

    I can't see how to use your code in a Web User Control.

    Can you explain?

    Matt.
  • Hi Matt,

    You cannot use a user control. You have to create a custom control that inherits from FieldControl. Custom controls are compiled code components that execute on the server, expose the object model, and render markup text, such as HTML or XML, as a normal Web Form or user control does.

    Greetings,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  • Thanks Ivan,

    I'm not familiar with creating custom controls.

    In particular, I'm confused by this line:

    private const string layoutTemplateName = "Telerik.Sitefinity.Samples.Resources.FieldControlCutom.ascx";

    Clearly, I don't have that file and I don't know what it contains or how to create it.

    Can you advise?

    Matt.
  • Hi Matt,

    In this line you specify the template that your custom filed control will use. This template has to be build as an embedded resource.

    Kind regards,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  • Hi Ivan,

    I see that you did not implement the IFormFieldControl interface even though you told in your first post that it should be implemented. Could you please share an example of how to implement it?

    BR,
    Coskun
  • Hello Coskun,

    The interface is used when you want to l load default values to MetaField property , based on the attribute, from the configuration mapping.

    [TypeConverter(typeof(ExpandableObjectConverter))]
           public IMetaField MetaField
           
               get
               
                   if (this.metaField == null)
                   
                       this.metaField = this.LoadDefaultMetaField();
                   
                   return this.metaField;
               
               set
               
                   this.metaField = value;
               
     
           #region Private members
           private IMetaField metaField = null;
           #endregion

    when you implement the interface your class should use DatabaseMapping atrribute

    sample

    [DatabaseMapping(UserFriendlyDataType.ShortText)]

    Greetings,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  • Guys,

    Sorry to bump this post but I am having a little look at this myself and I am still a little confused.  I want to add a fileupload to a form and I am struggling a bit with how to write a control for forms. 

    Has anybody got a complete example for me to have a look at?  Not asking for the file upload code...I will do all that, just cannot see how to put all the pieces together so if someone could chuck together some files in a zip for me to breakdown it would be mucho appreciated.

    Cheers,
  • I agree, James.  That would be very helpful.

  • Hello James,

    Here is a sample code of a form control

    Below is a sample code

    Note that FieldDisplayMode should be in write mode.

    publicclassFiledControlCustom : FieldControl
     
        
     
      
     
            publicFiledControlCustom()
     
            
     
                this.DisplayMode = Sitefinity.Web.UI.Fields.Enums.FieldDisplayMode.Write;
     
            
     
      
     
            [TypeConverter(typeof(ObjectStringConverter))]
     
            publicoverrideobjectValue
     
            
     
                get
     
                
     
                    var val = DateTime.Now;
     
                    switch(this.DisplayMode)
     
                    
     
                        caseFieldDisplayMode.Read:
     
                            if(Picker.SelectedDate == null)
     
                            
     
                                val = DateTime.Now;
     
                            
     
                            else
     
                            
     
                                val = Picker.SelectedDate.Value;
     
                            
     
                            break;
     
                        caseFieldDisplayMode.Write:
     
                            if(Picker.SelectedDate == null)
     
                            
     
                                val = DateTime.Now;
     
                            
     
                            else
     
                            
     
                                val = Picker.SelectedDate.Value;
     
                            
     
                            break;
     
                    
     
                    returnval;
     
                
     
                set
     
                
     
                    if(this.ChildControlsCreated)
     
                    
     
                        switch(this.DisplayMode)
     
                        
     
                            caseFieldDisplayMode.Write:
     
      
     
                                this.Picker.SelectedDate.Value.ToString();
     
                                break;
     
      
     
                            caseFieldDisplayMode.Read:
     
                                Picker.SelectedDate.Value.ToString();
     
                                break;
     
                        
     
                        this.value = null;
     
                    
     
                    else
     
                    
     
                        this.value = value;
     
                    
     
                
     
            
     
      
     
      
     
            protectedoverrideSystem.Web.UI.WebControls.WebControl TitleControl
     
            
     
                get
     
                
     
                    returnthis.TitleLabel;
     
                
     
            
     
      
     
            protectedoverrideWebControl DescriptionControl
     
            
     
                get
     
                
     
                    returnthis.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  overrideWebControl ExampleControl
     
            
     
                get
     
                
     
                    returnthis.ExampleLabel;
     
                
     
            
     
      
     
      
     
            protectedinternalvirtualLabel TitleLabel
     
            
     
                get
     
                
     
                    returnthis.Container.GetControl<Label>("titleLabel", true);
     
                
     
            
     
      
     
          
     
            protectedinternalvirtualLabel DescriptionLabel
     
            
     
                get
     
                
     
                    returnContainer.GetControl<Label>("descriptionLabel", true);
     
                
     
            
     
      
     
          
     
            protectedinternalvirtualLabel ExampleLabel
     
            
     
                get
     
                
     
                    returnthis.Container.GetControl<Label>("exampleLabel", this.DisplayMode == FieldDisplayMode.Write);
     
                
     
            
     
      
     
            protectedvirtualRadDateTimePicker Picker
     
            
     
                get
     
                
     
                    returnthis.Container.GetControl<RadDateTimePicker>("RadDatePicker1", this.DisplayMode == FieldDisplayMode.Write);
     
                
     
            
     
      
     
      
     
            protectedoverridevoidInitializeControls(Web.UI.GenericContainer container)
     
            
     
      
     
                DateTime? dateValue = null;
     
                if(this.Value != null)
     
                
     
                    dateValue = (DateTime)this.Value;
     
                
     
                switch(this.DisplayMode)
     
                
     
                    caseFieldDisplayMode.Read:
     
                         
     
                        break;
     
                    caseFieldDisplayMode.Write:
     
                        this.Picker.SelectedDate = dateValue;
     
                        this.Picker.DateInput.DateFormat = "MM/dd/yyyy h:mm:ss tt";
     
                        this.Picker.SelectedDateChanged += newTelerik.Web.UI.Calendar.SelectedDateChangedEventHandler(Picker_SelectedDateChanged);
     
                        this.Picker.DateInput.TabIndex = this.TabIndex;
     
                        this.Picker.DatePopupButton.TabIndex = this.TabIndex;
     
                        this.Picker.TimePopupButton.TabIndex = this.TabIndex;
     
                        this.TabIndex = 0;
     
                        break;
     
                      
     
            
     
      
     
            voidPicker_SelectedDateChanged(objectsender, Telerik.Web.UI.Calendar.SelectedDateChangedEventArgs e)
     
            
     
                this.Value = e.NewDate;
     
            
     
      
     
            protectedoverridestringLayoutTemplateName
     
            
     
                get returnFiledControlCustom.layoutTemplateName;
     
            
     
      
     
      
     
      
     
            publicoverrideIEnumerable<ScriptDescriptor> GetScriptDescriptors()
     
            
     
                var descriptor = newScriptControlDescriptor(this.GetType().FullName, this.ClientID);
     
                descriptor.AddComponentProperty("picker", this.Picker.ClientID);
     
                returnnew[] descriptor ;
     
            
     
      
     
            publicoverrideIEnumerable<System.Web.UI.ScriptReference> GetScriptReferences()
     
            
     
                var scripts = newList<ScriptReference>(base.GetScriptReferences())
     
                                
     
                                    newScriptReference(FiledControlCustom.fieldScript, this.GetType().Assembly.FullName)
     
                                ;
     
                returnscripts;
     
            
     
      
     
            internalconststringfieldScript = "Telerik.Sitefinity.Samples.Resources.FiledControlCustom.js";
     
            privateconststringlayoutTemplateName = "Telerik.Sitefinity.Samples.Resources.FieldControlCutom.ascx";
     
            privateobjectvalue;
     
      
     
      
     
        
     

    js file

    Type.registerNamespace("Telerik.Sitefinity.Samples");
     
      
     
    Telerik.Sitefinity.Samples.FiledControlCustom = function (element)
     
      
     
        this._picker = null;
     
        Telerik.Sitefinity.Samples.FiledControlCustom.initializeBase(this, [element]);
     
     
      
     
      
     
      
     
      
     
    Telerik.Sitefinity.Samples.FiledControlCustom.prototype =
     
        /* --------------------------------- set up and tear down --------------------------------- */
     
        initialize: function ()
     
            Telerik.Sitefinity.Samples.FiledControlCustom.callBaseMethod(this, 'initialize');
     
        ,
     
        dispose: function ()
     
            Telerik.Sitefinity.Samples.FiledControlCustom.callBaseMethod(this, 'dispose');
     
        ,
     
      
     
      
     
        get_picker: function ()
     
            returnthis._picker;
     
        ,
     
        set_picker: function (value)
     
            this._picker = value;
     
        ,
     
      
     
      
     
        /* --------------------------------- public methods ---------------------------------- */
     
      
     
      
     
        reset: function ()
     
            this.set_value(null);
     
            Telerik.Sitefinity.Samples.FiledControlCustom.callBaseMethod(this, "reset");
     
        ,
     
      
     
        // Gets the value of the field control.
     
        get_value: function ()
     
      
     
      
     
            if(this.get_displayMode() == Telerik.Sitefinity.Samples.FiledControlCustom.FieldDisplayMode.Write)
     
                if(val == '')
     
      
     
                
     
            
     
            returnval;
     
        ,
     
      
     
        // Sets the value of the text field control depending on DisplayMode.
     
        set_value: function (value)
     
            if(this._hideIfValue != null&& this._hideIfValue == value)
     
                if(this.get_displayMode() == Telerik.Sitefinity.Samples.FiledControlCustom.Write)
     
      
     
                
     
                else
     
      
     
                
     
            
     
            else
     
                if(this.get_displayMode() == Telerik.Sitefinity.Samples.FiledControlCustom.Write)
     
      
     
                
     
                else
     
      
     
                
     
            
     
            this._value = value;
     
            this.raisePropertyChanged("value");
     
            this._valueChangedHandler();
     
        ,
     
      
     
        // Returns true if the value of the field is changed
     
        isChanged: function ()
     
            if(this._value == null) this._value = "";
     
            var notChanged = (this._value == this.get_value());
     
            if(notChanged)
     
                returnfalse;
     
            
     
            else
     
                returntrue;
     
            
     
        
     
      
     
      
     
        /* --------------------------------- event handlers ---------------------------------- */
     
      
     
        /* --------------------------------- private methods --------------------------------- */
     
      
     
        /* --------------------------------- properties -------------------------------------- */
     
     
      
     
    Telerik.Sitefinity.Samples.FiledControlCustom.registerClass('Telerik.Sitefinity.Samples.FiledControlCustom', Telerik.Sitefinity.Web.UI.Fields.FieldControl);


    Greetings,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  • Hi Ivan,

    I have this code working correctly as a form control. However, when I submit the form that contains the control, the DatePicker still doesn't persist it's data to the database. I read your earlier post and implemented the IFormFieldControl interface in the form control to match what was in your example implementation. Other than adding that implementation of the MetaField property and adding the "DatabaseMapping" attribute to the class, is there anything else that needs to be added to persist data from the control?

    Thanks,
    Peter