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

Please Sign in or register to post replies

Write your reply to:

Draft