Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Nov 02, 2010 @ 12:59
    Jeroen Breuer
    0

    Make custom datatype mandatory

    Hello,

    I'm creating my own custom datatype, but I don't know how to make it mandatory. If no value is selected I return null, but the data is still saved. Do I need to do something special to make my custom datatype mandatory?

    Jeroen

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Nov 02, 2010 @ 14:00
    Jeroen Breuer
    0

    Ok for now I just make sure the page isn't valid if no data has been selected. This makes it mandatory, but I only want to it be mandatory if the mandatory checkbox has been check on the documenttype property. How can I do this?

    Jeroen

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Nov 02, 2010 @ 14:31
    Jeroen Breuer
    1

    Ok I've found a solution to make my custom datatype mandatory, but there must be an easier way to do this:

    //Get the current document.
    Document document = new Document(Convert.ToInt32(Request.QueryString["id"]));
    
    //Get all the propertytypes that use this datatype.
    IEnumerable<PropertyType> propertyTypes = PropertyType.GetByDataTypeDefinition(DataTypeDefinitionId);
    
    //Get the current propertytype:
    PropertyType propertyType =
        (
            from property in propertyTypes
            where property.ContentTypeId == document.ContentType.Id
            select property
        ).Single();
    
    if (propertyType.Mandatory)
    {
        //If the propertytype is mandatory show an error message.
        DAMP_Validation.ShowError("This field is mandatory. That means you need to select at least 1 media item.");
    }

    Jeroen

  • Lee Kelleher 4020 posts 15802 karma points MVP 13x admin c-trib
    Nov 08, 2010 @ 20:01
    Lee Kelleher
    0

    Hey Jeroen,

    Embarrassingly, I've just come across this too with uComponents!

    Are you inheriting your data-type from the AbstractDataEditor class? As its looking like you can't associate a ValidationGroup attribute with the RenderControl property (which is using the AbstractDataEditorControl).  I'm not 100% sure if this is the case - but currently looking into it!

    I'll keep you posted if I have any news.

    Cheers, Lee.

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Nov 08, 2010 @ 21:03
    Jeroen Breuer
    0

    Hi Lee,

    I'm using the AbstractDataEditor class, but in the umbraco backend you don't need a ValidationGroup. It actually works if you don't pass a validation group because the save button uses validation but without a validation group. Here a sample which I use to throw an error:

    CustomValidator cv = new CustomValidator();
    cv.IsValid = false;
    cv.ErrorMessage = message;
    
    if (!string.IsNullOrEmpty(validationGroup))
    {
        cv.ValidationGroup = validationGroup;
    }
    
    Page currentPage = HttpContext.Current.Handler as Page;
    currentPage.Validators.Add(cv);
    

    There are easier ways to add an error to a page, but this sample supports a validation group (even if we don't need it in this situation).

    Jeroen

  • Lee Kelleher 4020 posts 15802 karma points MVP 13x admin c-trib
    Nov 09, 2010 @ 10:43
    Lee Kelleher
    0

    Hi Jeroen, where are you adding this validation code? (Trying to figure out how it all should piece together).

    Thanks, Lee.

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Nov 09, 2010 @ 10:49
    Jeroen Breuer
    1

    In my third post I have the following piece of code at the bottom:

    if (propertyType.Mandatory)
    {
       
    //If the propertytype is mandatory show an error message.
        DAMP_Validation
    .ShowError("This field is mandatory. That means you need to select at least 1 media item.");
    }

    In the ShowError method I call the sample I gave in my fourth post with the CustomValidator. I'm also using this technique in the Digibiz Email Form with TinyMCE package. I could send you the source code if you're interessted.

    Jeroen

  • Lee Kelleher 4020 posts 15802 karma points MVP 13x admin c-trib
    Nov 09, 2010 @ 10:54
    Lee Kelleher
    0

    Thanks Jeroen, much appreciated!

    It was a bit of a shock when I realised that the data-types in both my uComponents and uTube packages don't support the Mandatory option! :-(

    Cheers, Lee.

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Dec 07, 2010 @ 19:57
    Jeroen Breuer
    0

    I've been testing my sample code a bit more and unfortunately it still has some errors. For example the following line:

    PropertyType propertyType =
        (
            from property in propertyTypes
            where property.ContentTypeId == document.ContentType.Id
            select property
        ).Single();

    This works if you use the datatype only a 1 time on a documentype. If you use the datatype multiple times the following will not work:

            where property.ContentTypeId == document.ContentType.Id

    This will result into multiple results so the .Single() will throw an error. Somehow we need to get more info to get the correct PropertyType.

    Jeroen

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Dec 07, 2010 @ 20:14
    Jeroen Breuer
    0

    I've added a workitem for it because currently I think making a custom datatype mandatory is too hard: http://umbraco.codeplex.com/workitem/29681. Please vote.

    Jeroen

  • Lee Kelleher 4020 posts 15802 karma points MVP 13x admin c-trib
    Dec 07, 2010 @ 20:20
    Lee Kelleher
    0

    I agree with you Jeroen - seems far too difficult to make a custom data-type mandatory.  I wasn't too comfortable iterating over the Document's properties - felt like too much of an overhead.  Hopefully there'll be a fix for v4.6 Juno!

    Cheers, Lee.

  • Niels Hartvig 1951 posts 2391 karma points c-trib
    Dec 08, 2010 @ 09:55
    Niels Hartvig
    1

    To make a custom datatype mandatory you just have to follow .NET practices, which is making a validation attribute to your control class, where the parameter is the name of the property to test:

    [ValidationProperty("Text")]

    How could that be easier or am I missing something?

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Dec 08, 2010 @ 10:00
    Jeroen Breuer
    0

    Hi Niels,

    I haven't tried that yet. Will this make my custom datatype only mandatory if the mandatory checkbox is checked on the documenttype property which uses my custom datatype? That's the problem I'm having currently. It only needs to be mandatory if the user chose this on the documenttype.

    Jeroen

  • Niels Hartvig 1951 posts 2391 karma points c-trib
    Dec 08, 2010 @ 10:06
    Niels Hartvig
    1

    If the property that you specify in the ValidationProperty returns something - then it's considered as filled out. So if it's marked mandatory, then it'll be approved. For good inspiration on this, check out the relatedlinks source:

    http://umbraco.codeplex.com/SourceControl/changeset/view/81625#905786

  • Niels Hartvig 1951 posts 2391 karma points c-trib
    Dec 08, 2010 @ 10:15
    Niels Hartvig
    0

    (this will also be used for the regexp validation configuration, btw)

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Dec 08, 2010 @ 10:19
    Jeroen Breuer
    0

    Thanks! I will try it out and see if it works :).

    Jeroen

  • Lee Kelleher 4020 posts 15802 karma points MVP 13x admin c-trib
    Dec 08, 2010 @ 11:36
    Lee Kelleher
    1

    I've tried the ValidationProperty attribute before, (and again now - to double check), but it doesn't work when inheriting from the AbstractDataEditor class.

    Niels' example of the Related Links data-type inherits from BaseDataType (along with implementing the IDataType and IDataEditor interfaces).

    My gut feeling is that something goes astray in the AbstractDataEditor class?

    Cheers, Lee.

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Dec 08, 2010 @ 11:45
    Jeroen Breuer
    0

    In that case the workitem (http://umbraco.codeplex.com/workitem/29681) should stay open until there's a good solution for this.

    Jeroen

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Dec 10, 2010 @ 16:50
    Jeroen Breuer
    0

    Ok I found another solution, but it's still not really easy. In the DataType there is a way to get the PropertyType. Here's how:

    My IData can return DefaultData or DAMP_Data which returns xml. I need to show this sample so you can understand te rest of the code.

    public override IData Data
    {
        get
        {
            if (this._data == null)
            {
                if (!StoreAsXML)
                {
                    this._data = new DefaultData(this);
                }
                else
                {
                    this._data = new DAMP_Data(this);
                }
            }
    
            return this._data;
        }
    }

    Here is how I get the PropertyType in my DataType which inherits from the AbstractDataEditor.

    //Get the propertyId which we need to get the current PropertyType.
    int propertyId = StoreAsXML ? ((DAMP_Data)this.Data).PropertyId : ((DefaultData)this.Data).PropertyId;
    
    //Get the current PropertyType because we need the mandatory value.
    PropertyType propertyType = new PropertyType(SqlHelper.ExecuteScalar<int>("select propertytypeid from cmsPropertyData where id = @id", SqlHelper.CreateParameter("@id", propertyId)));
    
    //Store the mandatory value.
    bool mandatory = propertyType.Mandatory

    Now that I have the mandatory value I pass this value to my DataEditor where I can check if a field is mandatory and if anything has been filled in my custom control. Here is a sample:

    if (mandatory && string.IsNullOrEmpty(TxtMessage.Text))
    {
        //If the propertytype is mandatory and the textbox is empty show an error message.
        LitError.Text = "This field is mandatory";
        LitError.Visible = true;
        DAMP_Validation.ShowError(LitError.Text);
    }

    Here is my static DAMP_Validation method:

    public static class DAMP_Validation
    {
        public static void ShowError(string message)
        {
            ShowError(message, string.Empty);
        }
    
        public static void ShowError(string message, string validationGroup)
        {
            CustomValidator cv = new CustomValidator();
            cv.IsValid = false;
            cv.ErrorMessage = message;
            if (!string.IsNullOrEmpty(validationGroup))
            {
                cv.ValidationGroup = validationGroup;
            }
    
            ShowError(cv);
        }
    
        public static void ShowError(CustomValidator cv)
        {
            Page currentPage = HttpContext.Current.Handler as Page;
            currentPage.Validators.Add(cv);
        }
    }

    So with this code I can get the mandatory field in a DataType, pass it to the DataEditor and throw an error (making the page invalid) if mandatory is true and no value has been selected. Still hope there will be an easier solution for this in Umbraco v4.6 JUNO.

    Jeroen

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Dec 13, 2010 @ 11:30
    Jeroen Breuer
    0

    Here is a small update. The above code works, but there should be an extra check to see if the DataType is used on a custom section:

    //Get the propertyId which we need to get the current PropertyType.
    int propertyId = StoreAsXML ? ((DAMP_Data)this.Data).PropertyId : ((DefaultData)this.Data).PropertyId;
    
    bool mandatory = false;
    
    //Check if the propertyId is not 0. If it is this DataType is probably used in a custom section.
    if (propertyId != 0)
    {
        //Get the current PropertyType because we need the mandatory value.
        PropertyType propertyType = new PropertyType(SqlHelper.ExecuteScalar<int>("select propertytypeid from cmsPropertyData where id = @id", SqlHelper.CreateParameter("@id", propertyId)));
    
        //If a PropertyType is returned store the mandatory field.
        mandatory = propertyType.Mandatory;
    }

    Jeroen

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Dec 14, 2010 @ 09:58
    Jeroen Breuer
    0

    And again I've got an improved version :). This version also gets the property name and on which tab the property is. This can be used for the mandatory message:

    Code in the DataType:

    //Get the propertyId which we need to get the current PropertyType.
    int propertyId = StoreAsXML ? ((DAMP_Data)this.Data).PropertyId : ((DefaultData)this.Data).PropertyId;
    
    bool mandatory = false;
    
    //Check if the propertyId is not 0. If it is this DataType is probably used in a custom section and no PropertyType is available.
    if (propertyId != 0)
    {
        //Get the current PropertyType because we need some property data.
        PropertyType propertyType = new PropertyType(SqlHelper.ExecuteScalar<int>("select propertytypeid from cmsPropertyData where id = @id", SqlHelper.CreateParameter("@id", propertyId)));
    
        //Store the mandatory field.
        mandatory = propertyType.Mandatory;
    
        //Get the name of the tab.
        string tabCaption = SqlHelper.ExecuteScalar<string>("Select text from cmsTab where id = " + propertyType.TabId);
    
        if(string.IsNullOrEmpty(tabCaption))
        {
            //If no tab is found this means it's on the default (Generic Properties) tab.
            tabCaption = "Properties";
        }
    
        //Set the the mandatory text now that we have a property name and tab.
        mandatoryText = string.Format("The {0} field in the {1} tab is mandatory", propertyType.Name, tabCaption);
    }
    

    Code in the DataEditor:

    if (mandatory && string.IsNullOrEmpty(TxtMessage.Text))
    {
        //If the propertytype is mandatory and the textbox is empty show an error message.
        LitError.Text = mandatoryText;
    LitError.Visible = true; DAMP_Validation.ShowError(LitError.Text); }

    Now the mandatory message will look exactly like the default Umbraco mandatory message, but with complete control over the output so you can also change the mandatory message. I do this with my newest datatype because you can have a minimum and maximum node selection and those will give custom messages, but also in with the name and tab data.

    Jeroen

  • Comment author was deleted

    Dec 21, 2010 @ 12:00

    Hi,

    You'll be pleased to know that this issue will be fixed in Juno (just comitted the fix), the abstract data editor will now respect the validationproperty

    Cheers,
    Tim

  • Lee Kelleher 4020 posts 15802 karma points MVP 13x admin c-trib
    Dec 21, 2010 @ 12:01
    Lee Kelleher
    0

    Woo hoo! Nice one Tim! Thanks.

  • Comment author was deleted

    Dec 21, 2010 @ 12:13

    And also fixed it with the usercontrol wrapper (so you can make those datatypes mandatory as well)

    Cheers,
    Tim

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Dec 21, 2010 @ 12:33
    Jeroen Breuer
    0

    Hi Tim,

    That's great news! Also good to hear the usercontrol wrapper can be mandatory. This in combination with the DataEditorSetting will make the usercontrol wrapper so much more powerfull!

    Jeroen

     

     

  • Comment author was deleted

    Dec 21, 2010 @ 13:08

    Indeed, and if you save xml in the usercontrol wrapper it will detect it and won't add it inside a cdata section

  • Jeroen Breuer 4908 posts 12265 karma points MVP 4x admin c-trib
    Dec 21, 2010 @ 13:21
    Jeroen Breuer
    0

    Wow that's also cool! How does it detect if the usercontrol wrapper stores xml? Can you just return an XDocument or XmlDocument and it will be stored as xml or do you need to return a string which contains xml? With this I will use the abstract data editor a lot less because this is so much easier :D.

    Jeroen

  • Comment author was deleted

    Dec 21, 2010 @ 13:29

    Yup both methods should work (return xml as string or xmldocument)

  • Lennart Stoop 304 posts 842 karma points
    Apr 23, 2011 @ 16:31
    Lennart Stoop
    0

    Hey Tim,

    Did your changes also make it through Umbraco v 4.7.0 ?

    Maybe I am doing something wrong here but the validation property does not seem to get fired during save/publish.

    Here's what I did:

        [ValidationProperty("IsValid")]
        public partial class ScheduleEditor : System.Web.UI.UserControl,
            umbraco.editorControls.userControlGrapper.IUsercontrolDataEditor
            public string IsValid
            {
                get
                {
                    if (GetSchedule().IsValid)
                        return "Valid";
                    else
                        return String.Empty;
                }
            }

    I'm debugging it locally and added a breakpoint inside the property and it does not get fired.

    I have also tried returning a different type like bool or object, without any success.

    Am I missing something here?

  • Comment author was deleted

    Apr 26, 2011 @ 11:23

    Hi Lennart,

    Well when using the usercontrol wrapper the validation property is the value property, when that is null or en empty string it will be considered as not valid

  • Lennart Stoop 304 posts 842 karma points
    Apr 26, 2011 @ 20:45
    Lennart Stoop
    1

    Hi Tim,

    That makes sense and indeed it works for a single value. When working with multiple values or XML data however, the value property does not allow for a partial result to be returned in order to support the mandatory setting (e.g. if the property is not mandatory the user should be able to save some of the data).

    Is there perhaps another way of achieving this? Perhaps I can access the mandatory setting and return values based on that?

    Hope this makes sense :-)

  • Comment author was deleted

    Apr 27, 2011 @ 14:27

    Well I guess in your custom object you know if you have valid values or not, can't you just return null or en empty string when it is empty? And don't return the serialized object in that case.

    Should do the trick

  • Lennart Stoop 304 posts 842 karma points
    Apr 27, 2011 @ 20:30
    Lennart Stoop
    0

    Yup, I got that working but when the property isn't mandatory I want to allow an "invalid" (partial) value to be saved. 

    For example lets say there are 2 values, and when the property is mandatory, both values need to be completed.

    When the property is not mandatory however, I would allow the user to save just 1 value, but this is no longer possible as the validation would allow only to save a valid object or none. So it looks like I need a more complex logic to handle this, one way would be look at whether the property is mandatory or not..

  • LeszekP 27 posts 78 karma points
    Jun 16, 2015 @ 16:10
    LeszekP
    2

    how to check If property is set to mandatory I found it in

    {{model.validation.mandatory}}
    

    in html for rendering control.

Please Sign in or register to post replies

Write your reply to:

Draft