How To: Add "placeholder" attribute to Text Field in Dynamic Forms

Orchard CMS is built on a powerful architecture that provide us rich ways to extend it, and to add some missing features as needed.

"PlaceHolder" Attribute

HTML 5, has a very useful attribute called "placeholder", it is used to display a watermark text on the input field when it's empty, but text field and text area elements in dynamic forms module don't have this attribute out of the box, and we will learn how to add such attribute in this post.

Add New Editor Form "PlaceHolderForm"

First thing we will do, implement a new editor form for "placeholder" attribute, to be able to attach it to text field and text area editors, this form will have a single tokenized input field, to enter the attribute value, as following:

public class PlaceHolderForm : Component, IFormProvider {
public void Describe(DescribeContext context) {
context.Form("PlaceHolder", factory => {
var shape = (dynamic)factory;
var form = shape.Fieldset(
Id: "PlaceHolder",
_Value: shape.Textbox(
Id: "PlaceHolder",
Name: "PlaceHolder",
Title: "PlaceHolder",
Classes: new[] { "text", "medium", "tokenized" },
Description: T("The value of placeholder attribute.")));
return form;

Implement New "TextFieldElementDriver"

Drivers in Orchard CMS used to transport data to a template for rendering, called "Shape", and we can implement multiple drivers for the same item to render more shapes from same data source in different zones.

Now, we will implement new driver for "TextField" element, called "TextFieldElementDriver", then override "OnBuildEditor" method to attach the form "PlaceHolderForm", which was created on the previous step to the output editor, and override "OnDisplaying" method to read attribute value from the element data property, then add a new attribute to the rendered element shape.

public class TextFieldElementDriver : FormsElementDriver<TextField> {
    private readonly ITokenizer _tokenizer;

    public TextFieldElementDriver(
IFormsBasedElementServices formsServices,
ITokenizer tokenizer) : base(formsServices) { _tokenizer = tokenizer; } protected override EditorResult OnBuildEditor(
TextField element,
ElementEditorContext context) { var placeholderEditor = BuildForm(context, "PlaceHolder"); return Editor(context, placeholderEditor); } protected override void OnDisplaying(
TextField element,
ElementDisplayingContext context) {
_tokenizer.Replace(element.Data["PlaceHolder"], context.GetTokenData())); } }

Then you can implement new driver for text area field to add the same attribute to it using same "PlaceHolder" form.


You must have noticed that we used the "ElementShape.ClientValidationAttributes" instead of "ElementShape.Attributes", which is the right way to add attributes to shapes in orchard, but we are currently forced to use this workaround because there is an issue in orchard, and you can see issue #6812 for more information.



Leave a comment


  • ramiassi

    Thank you for writing this article. I tried to follow the steps but I wasn't able to locate the newly created files. Could you give more details.

  • mdameer

    Hello Ramiassi, Thank you for your feedback, I added a new attachment to this post, which contains an Orchard module to add this feature, you can download and use it as is, or integrate it with your code.