Sitecore iframe field type basics

A few days ago I implemented a custom field which should have 2 dropdowns which are depending on each other (here you can find the whole implementation, in this example I will just show you a simple text field).

So I checked all possible solutions and I decided to use the IFrame type for that. This is a default field provided by Sitecore. So in the source input on the template you need to provide the url for your iframe. In my case it will be a Controller:

Capture

To make this path work I need to map this route:

using Sitecore.Pipelines;
using System.Web.Mvc;
using System.Web.Routing;
namespace MyProject.Pipelines
{
public class RegisterRoutes
{
public void Process(PipelineArgs args)
{
RouteTable.Routes.MapRoute("SimpleField", "myFields/SimpleField/Render", new { controller = "SimpleField", action = "Render" });
}
}
}

Let’s create our Controller and View:

using Sitecore.Configuration;
using Sitecore.Data;
using System.Web.Mvc;
namespace MyProject.Controllers
{
public class SimpleFieldController : Controller
{
public ActionResult Render()
{
return View("~/Views/SimpleField/Render.cshtml");
}
}
}

<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,300italic,400italic,600italic,700italic,300,600,700,800" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="/sitecore/shell/themes/standard/default/Default.css" />
<link rel="stylesheet" type="text/css" href="/sitecore/shell/themes/standard/default/Content Manager.css" />
<style>
#ll-fields {
padding: 10px 10px 10px 10px;
}
</style>
<div id="ll-fields" class="scEditorSections">
<div class="scEditorFieldMarker">
<div class="scEditorFieldLabel">Text:</div>
<div>
<input type="text" id="ll-text" class="scContentControl scCombobox" />
</div>
</div>
</div>
<script type="text/javascript" src="/scripts/field/field-base.js"></script>
<script type="text/javascript" src="/scripts/field/text-field.js"></script>
<script>
textField.getValue();
document.getElementById('ll-text').onchange = function () {
textField.setValue();
};
textField.updateIframeDisplaySettings();
</script>
view raw Render.cshtml hosted with ❤ by GitHub

As you can see in the View it contains 2 important JS references, they are doing the dirty job:

function fieldBase () {}
fieldBase.getParentIframe = function () {
var iframes = window.parent.document.getElementsByTagName('iframe');
var parent;
Array.prototype.forEach.call(iframes, function (el, i) {
if (fieldBase.getIframeDocument(el) === window.document) {
parent = el;
return;
}
});
return parent;
};
fieldBase.getIframeDocument = function (iframe) {
return iframe.contentDocument || iframe.contentWindow.document;
};
view raw field-base.js hosted with ❤ by GitHub

function textField() { }
textField.setValue = function () {
fieldBase.getParentIframe().setAttribute('sc_value', document.getElementById('ll-text').value);
}
textField.getValue = function () {
document.getElementById('ll-text').value = fieldBase.getParentIframe().getAttribute('sc_value');
}
textField.updateIframeDisplaySettings = function () {
var parentIframe = fieldBase.getParentIframe();
parentIframe.style = "height: 87px";
parentIframe.scrolling = "no";
}
view raw text-field.js hosted with ❤ by GitHub

At the end the result is this:

Capture

Conclusion

After the base functions are created easy to use this because you have the whole control of your field (design, behaviour). I would suggest this solution if you need a complex field (like you have more fields depend on each other). So I already mentioned at the beginning you can find here a more complex field resolved by iframe: https://github.com/ALLWIN-Informatics/Allwin.Sitecore.Modules.LiveList

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s