Extend Link Editor Functionality

Vote:
 

I'm trying to extend Link Editor adding a new link format for phone numbers.

I added a new field to the Link Editor by exending the class EditorDescriptior as shown below:

 [EditorDescriptorRegistration(
        TargetType = typeof(string),
        UIHint = "HyperLink",
        EditorDescriptorBehavior = EditorDescriptorBehavior.PlaceLast)
    ]
    internal class CustomLinkEditorDescriptor : EditorDescriptor
    {
        public override void ModifyMetadata(ExtendedMetadata metadata, IEnumerable<Attribute> attributes)
        {
            base.ModifyMetadata(metadata, attributes);

            if (!metadata.EditorConfiguration.ContainsKey(("providers")))
            {
                return;
            }

            var providers = (metadata.EditorConfiguration["providers"] as Enumerable<object>).ToList();

            providers.Add(new
            {
                Name = "Phone Number",
                Title = "Phone Number",
                DisplayName = "Phone Number",
                WidgetType = "dijit/form/ValidationTextBox",
            });

            metadata.EditorConfiguration["providers"] = providers;
 
        }
    }

The result was:

Link Editor

Generated code:

<a href="/EPiServer/CMS/+351914181987">call me</a>

Expected code:

<a href="tel:+351914181987">Call me</a>

Taking into consideration the scenario explained above, is there a way to format the tag generated to meet the html specification for phone number?

Product: EPiServer CMS
Version: 11.13.2.0

#221510
Edited, Apr 20, 2020 13:05
Vote:
 

Hi Marcelo 

Im believe you might need to create your own display template (/Views/Shared/DisplayTemplates) 

THe default view looking inside \modules\_protected\CMS\CMS.zip\Util\Views\Shared\DisplayTemplates\ 

The html is set out as 

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<EPiServer.SpecializedProperties.LinkItem>" %>
<%@ Import Namespace="EPiServer.Web.Mvc.Html" %>
<%: Html.ContentLink(Model) %>

You might be able to interate through the providers and output something different if its a Phone Number 

#221520
Apr 20, 2020 14:24
Vote:
 

Hi Marcelo,

As far as I'm aware, you'll need to add your own Dojo widget. Here is one based very closely on the EmailValidationTextBox:

define("scripts/PhoneValidationTextBox", [
    "dojo/_base/declare",
    "dojo/_base/lang",
    "dijit/form/ValidationTextBox"
],
function (
    declare,
    lang,
    ValidationTextBox
) {

    var module = declare([ValidationTextBox], {
        // summary:
        //    Represents the phone number input textbox.
        // tags:
        //    internal

        invalidMessage: "Invalid phone number",

        // addTel: Boolean
        //      If true the value will always be prepended
        //      with the tel protocol
        addTel: true,

        validator: function (value, constraints) {
            // summary:
            //		Validate the text input with telephone number validation.
            // tags:
            //		override

            value = value || "";

            if (!this.required && this._isEmpty(value)) {
                return true;
            }

            // replace escaped sequences to enable/simplify regexp validation (\@ or "everythingInHereIsEsc@ped"
            value = value.replace(/\\.{1}/g, "replaced").replace(/".*?"/g, "replaced");

            return module.validationRegex.test(value);
        },

        _getValueAttr: function () {

            var value = this.inherited(arguments);

            if (this.addTel) {
                // make sure the hyper link has tel: prefix
                value = value ? lang.trim(value) : "";
                if (value && value.indexOf("tel:") !== 0) {
                    value = "tel:" + value;
                }
            }

            return value;
        },

        _setValueAttr: function (value) {
            value = value ? value.replace("tel:", "") : "";

            this.inherited(arguments, [value]);
        }
    });

    // Simple and incomplete test for phone number likeness
    // only trying to stop the most common mistakes
    module.validationRegex = /^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d+))?$/i;

    return module;

});

You'll also need to update the WidgetType when you add this to the providers:

providers.Add(new
{
    Name = "Phone Number",
    Title = "Phone Number",
    DisplayName = "Phone Number",
    WidgetType = "scripts/PhoneValidationTextBox",
});

Finally, you'll need to add the following line to your module.config (or create one if it doesn't exist):

<?xml version="1.0" encoding="utf-8"?>
<module>
  <dojo>
    <paths>
      <add name="scripts" path="Scripts" />
    </paths>
  </dojo>
</module>

As you probably guessesd, the path above should align with the path you saved the JavaScript to (the above would actually be ClientResources/Scripts).

I haven't tested this, but I'm pretty confident it should work and give you the correct formatting.

#221523
Edited, Apr 28, 2020 22:22
Marcelo - Apr 21, 2020 10:46
Hey Jake Jones

We are almost there, your suggestion has helped a lot!!!
It is working fine to add new phone number links, but when I try to edit it, so the value is displayed on External Link.
Do you have any idea why it is happening?
Vote:
 

Glad we nearly solved this!

Since this is pretty useful functionality I took the liberty of spinning it off into a blog post: https://jakejon.es/blog/adding-a-telephone-link-option-to-the-episerver-link-editor

You need to do 2 small things, both of which I explained (+ gave an example of) in the post:

  1. Insert the phone link before the external link
  2. Update the validationRegex to start with an optional "tel:" token: (tel:)?

The alternative is that you need to do some more customization in the front-end which I was trying to avoid.

Let me know how it goes.

#221578
Apr 21, 2020 22:33
Marcelo - Apr 22, 2020 14:18
Thanks Jake Jones. It is working perfectly now.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.