Copied to clipboard

Flag this post as spam?

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


  • Kris Janssen 210 posts 569 karma points c-trib
    Feb 04, 2015 @ 17:49
    Kris Janssen
    0

    Allowing HTML input in contour forms

    Hi,

    A rather urgent question:

    I have built a custom contour form with a "Markdown" like control to allow users to send formatted text:

    Mardown form!!

    Everything works rather nicely but of course, everything went pear shaped when users tried to input stuff like:

    H<sub>2</sub>O
    

    Then I obviously get hit by the A potentially dangerous Request.Form value was detected

    Of the many solutions that exist to that problem I am wondering if I could get some feedback: since I do not have access to Contour source code I cannot use some of the attributes proposed in the previous reference (I think).

    How to properly handle this???

    I will be forever in your debt if you could help me out :)

    Update 1

    Using some javascript trickery I managed to circumvent this issue. For the sake of completeness I will try to add the full solution which consists of three parts:

    1. A custom "Markdown"text are FieldType
    2. A custom partial viewtype for this FieldType
    3. Some JS hacks

    First, the custom FieldType, which is just a straight copy of the regular text area:

    using System;
    using System.Collections.Generic;
    using System.Web;
    using Umbraco.Forms.Core;
    using Umbraco.Forms.Core.Common;
    using log4net;
    
    namespace KJ.UmbracoExtensions
    {
        using System.Web.Mvc;
        using System.Reflection;
    
        public class MarkDown : FieldType
        {
            private List<object> _value;
    
            public MarkDown()
            {
                base.Id = new Guid("E3570C1B-883A-4D46-872A-9D554855AE28");
                base.Name = "MarkDown Textfield";
                base.Description = "Renders a MarkDown editor";
                this.Icon = "textfield.png";
                this.DataType = FieldDataType.String;
                this._value = new List<object>();
            }
    
            public override List<object> ProcessValue(HttpContextBase httpContext)
            {
                List<object> objs = new List<object>();
                HttpRequestBase request = httpContext.Request;
                Guid id = this.AssociatedField.Id;
                string item = request[id.ToString()] ?? "";
                objs.Add(item);
                return objs;
            }
    
            public override string RenderPreview()
            {
                return "<input type=\"text\" class=\"textfield\" />";
            }
    
            public override string RenderPreviewWithPrevalues(List<object> prevalues)
            {
                return this.RenderPreview();
            }
        }
    }
    

    Next, the view:

    @model Umbraco.Forms.Mvc.Models.FieldViewModel
    
    <link rel="stylesheet" type="text/css" media="screen" href="~/css/bootstrap-markdown.min.css">
    
    <textarea name="@{@Model.Id}_mdin" id="@{@Model.Id}_mdin" rows="9"
          @{if (Model.Mandatory) {<text> data-val="true" </text>  }}
          @{if (Model.Mandatory) {<text> data-val-required="@Model.RequiredErrorMessage"</text>}}>
        @Model.Value.Replace("&lt;", "<").Replace("&gt;", ">").Trim()
    </textarea>
    
    <input type="hidden" name="@{@Model.Id}" id="@{@Model.Id}" value="@Model.Value"/>
    
    <script>
        $(function () {
        $('#@{@Model.Id}_mdin').siblings('span').attr('data-valmsg-for', '@{@Model.Id}_mdin');
    
        $('#@{@Model.Id}_mdin').markdown({ 
                        ... some bootstrap-markdown.js init stuff ... 
                        onChange: function (e) {
    
                                $("#@{@Model.Id}").attr("value", $("#@{@Model.Id}_mdin").val().replace(/</g, '&lt;').replace(/>/g, '&gt;'))
    
                }
    
                 })
    })
    </script>
    

    The JS hackery:

    First, I figured it would be sufficient to replace < and > by < and > respectively, this get handled by:

    $("#@{@Model.Id}").attr("value", $("#@{@Model.Id}_mdin").val().replace(/</g, '&lt;').replace(/>/g, '&gt;'))
    

    If you want to enable later editing of the data, you need to restore the < and > upon loading the data into the form:

    @Model.Value.Replace("&lt;", "<").Replace("&gt;", ">").Trim()
    

    Lastly, because I use a hidden input to hold the 'clean' input, the unobtrusive validation will not work correctly because a span gets generated:

    <span class="form-error field-validation-valid" data-valmsg-for="6a21853a-46c2-4bde-84b5-ea032302851b" data-valmsg-replace="true"></span>
    

    I modify the 'data-valmsg-for attribute like so:

    $('#@{@Model.Id}_mdin').siblings('span').attr('data-valmsg-for', '@{@Model.Id}_mdin');
    

    I hope this can be of use to someone.

    If there are cleaner ways to do this, feel free to share. It is likely that I overcomplicated things :)

    The end-result looks the part though:

    enter image description here

    And the processed and Emailed record:

    enter image description here

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies