Learn More





DNN Community Blog

The Community Blog is a personal opinion of community members and by no means the official standpoint of DNN Corp or DNN Platform. This is a place to express personal thoughts about DNNPlatform, the community and its ecosystem. Do you have useful information that you would like to share with the DNN Community in a featured article or blog? If so, please contact .

The use of the Community Blog is covered by our Community Blog Guidelines - please read before commenting or posting.

Advanced Dynamic Data / Content - Custom Input Type (300)

There are loads of reasons why to create a custom input type. Maybe you want to create a color-picker or you want to create a dropdown which provides options based on a JSON-feed. No matter what you want - here's how to do it.

Note that in this tutorial we're not creating a custom data-type, but a custom input type. This may be confusing at first, so here goes:

Difference between a custom Data-Type and a custom Input-Type

Basically a custom input type is just a different UI to add a string, number, date, etc. while a custom data-type could store something completely new. So a custom data-type would store neither a string nor a number, but maybe a combination of numbers - like GPS-coordinates which needs two numbers. This blog is about custom input-types, custom data-types come later…

There's an App for that

Just fyi - I created an App to demonstrate everything I explain here. So You should still read this, but check out the settings etc. in the demo app which should help you understand it better.

The Overview

Basically we'll go through the following steps to set this up

  1. Register this input-type in the system so it becomes available
  2. Create the necessary javascript which will create the UI for the content-type

Registering the Input-Type

All input-types are registered in the system as entities of the type ContentType-InputType. All predefined input-types are registered in the central list but the content-type is available as Ghost-Content-Type in every App. If you need to know more about Ghost-Content-Types please read this blog.

So let's start

  1. In the data / content administration, change scopes to see all the content-types in the System-Scope the short version I'll explain here, but you may want to read more about it here:
    1. Open the admin-dialog and change to advanced mode using ctrl+click
    2. Hit the scope button (the round one) and enter System - you should now see the system content-types
  2. Create a new entity of the type ContentType-InputType registering your type

You you can see what I configured in my demo input for numbers, providing a dropdown showing fibonacci-numbers.

The Fields when Registering your Input-Type

  1. The Type of your input-type is very important.
    1.  It must begin with the data-type and a "-" and continue with something of your choice.
    2. Note that you should NOT create a "string-colorpicker" because maybe one day the system will also provide a "string-colorpicker" - so you should always make it unique - ideally using your company name like "string-yourcompany-colorpicker" or similar
    3. Also note that the name MUST be in lower-case
  2. The Label is the information shown later on in the drop-down. Remember that this value is shown after the user picked the data-type - so you don't have to write "this is a string…" since that was already selected.
  3. The Description be shown in the tool-tip as an additional help
  4. Assets is a multi-line field containing all the additional files which must be loaded for this content-type. It could just be some CSS (in which case you would only inject some styiling) but in most cases it would be some javascripts.

Recommendation For Assets

Basically you could include a long list of assets - like some libraries, some JS and some CSS - but you shouldn't. Too many assets slow down the UI and degrade the user experience. The best implementation has as few assets as possible, ideally just one. Modern development paradigms using Grunt will help you achieve this.

Creating the JavaScript

Assuming you have some JS - and you should, unless your buliding upon the data-type empty (like creating an empty-yourcompany-make-it-all-red) then you should do the following things

  1. You must register the type in the form-engine (Angular-Formly)
  2. You must tell the engine what an input-field looks like - this can be a simple "hello, nothing to do here"

Just to keep things simple - please take a look at the sample-app. Since most DNN developers are not versed with Javascript, AngularJS or Formly, this may feel a bit scary till you see the sample code.

More Background: AngularJS and AngularFormly

So to get started it's important to know that our dynamic UI is built using AngularJS and Angurlar-Formly. This is a very advanced framework for forms and is fairly easy to use once you know what you're doing :). But to help you start I would like to tell you a few more things

  1. Angular Parts are called modules. If you see code which says angular.module("…", […]) this creates a new module - which is exactly what we'll do.
  2. Each module contains things like initialization (run), configuration (config), view-controllers which initialize a view (controller), services (factory) and more. The syntax is always [module].thing, usually abbreviated into a chain of angular.module("name", [dependencies]).config(…).run(…).controller(…) etc.
  3. The order of things is important - run will be executed once at the beginning, config even before that. If you want to know more about this you should read [todo]
  4. We just want to start by telling Formly that our new code handles our input-type - which we'll do at config-level. Look at the code examples is the app
  5. Then we want to ensure that the data-binding works. For trivial cases we'll just use the ng-model="value.Value". If you stick to this, most cases will just work automatically including multi-language editing.

Power Tip: Advanced Wrappers

Angular-Formly uses a concept called wrappers which are html-fragments which will wrap your input-component. Each wrapper should do one thing and one thing only - so the current default wrappers (2sxc 8.0) contain these four wrappers:

  1. Error-message
  2. Label
  3. Multi-Language
  4. Show-Hide if disabled

We'll add more wrappers as functionality increases, and in most cases you'll want to stick to the default wrappers using the config-method shown in the demo-app.

But there are cases where you will want to deviate from this - like if you input-type does not support disabling. I won't document the details here but if you really need this I'm sure you'll figure it out.

Tip: Avoid jQuery if possible

We worked hard to create a dynamic input dialog which does NOT need jQuery because it slows down the UI, has bad programming style and bad side effects (see [todo]). Very often you may be tempted to quickly use a component which needs jQuery - and if necessary you can (just remember to include jQuery in your JS). But try to avoid it - because there is no real reason to and you'll regret it some day in the future. Almost all JS plugins developed today also exist in a non-jQuery edition, so we really recommend to use those.

Tip: Advanced Functionality and Data-Binding

The simple case just binds the value.Value in a 1-to-1 fashion. You can do much, much more if you want to - but you'll need to dive deeper into AngularJS and Angular-Formly to do that. So you can do everything, but of course you'll need to learn these frameworks.

Love from Switzerland,

Daniel Mettler grew up in the jungles of Indonesia and is founder and CEO of 2sic internet solutions in Switzerland and Liechtenstein, an 20-head web specialist with over 800 DNN projects since 1999. He is also chief architect of 2sxc (see forge), an open source module for creating attractive content and DNN Apps.

Read more posts by Daniel Mettler


kurt wilby
Dear Mr. Mettler,

Please, could you develop, if you already haven´t one, a dnn dev template incorporating all the ideas/technologies (grunt OR gulp, especially ANGULARJS, Formly OR AngularUI, ...). This would be a great boost for the community. Could you please give your ideas on this subject.

kurt wilby Wednesday, November 25, 2015 4:19 AM (link)
kurt wilby
Dear Mr. Mettler,

Because I think you are the most knowledgeable dnn-ng developer, I ask you to develop, if you already haven´t one, a dnn dev template incorporating all the ideas/technologies (grunt OR gulp, especially ANGULARJS, Formly OR AngularUI, ...). This would be a great boost for the community. Could you please give your ideas on this subject (start a new github project OR ...).

kurt wilby Wednesday, November 25, 2015 4:27 AM (link)
2sic Daniel Mettler
@kurt I'm constantly creating demo apps which do most of this. I simply find the 2sxc-app model more appropriate for the web as it is today, so I'm not focused on the dnn-model with server controls and all that. That's why all my demos are also 2sxc based.

I'm also currently working on some grunt samples - but most tutorials need a very simple setup (so people get it), while real life then needs a bit more power :).

BTW: 2sxc includes a special nodejs feature to ensure that you can work with npm/grunt and it still won't package the large node_xxx folders into your published app :).
2sic Daniel Mettler Tuesday, December 01, 2015 9:40 AM (link)

Comment Form

Only registered users may post comments.


2sic Daniel Mettler (125)
Aderson Oliveira (15)
Alec Whittington (11)
Alex Shirley (10)
Andrew Nurse (30)
Anthony Glenwright (5)
Antonio Chagoury (28)
Ash Prasad (22)
Ben Schmidt (1)
Benjamin Hermann (25)
Benoit Sarton (9)
Beth Firebaugh (12)
Bill Walker (36)
Bob Kruger (5)
Brian Dukes (2)
Brice Snow (1)
Bruce Chapman (20)
Bryan Andrews (1)
cathal connolly (55)
Charles Nurse (163)
Chris Hammond (203)
Chris Paterra (55)
Clinton Patterson (28)
Cuong Dang (21)
Daniel Bartholomew (2)
Dave Buckner (2)
David Poindexter (3)
David Rodriguez (2)
Doug Howell (11)
Erik van Ballegoij (30)
Ernst Peter Tamminga (74)
Geoff Barlow (6)
Gifford Watkins (3)
Gilles Le Pigocher (3)
Ian Robinson (7)
Israel Martinez (17)
Jan Blomquist (2)
Jan Jonas (3)
Jaspreet Bhatia (1)
Jenni Merrifield (6)
Joe Brinkman (270)
John Mitchell (1)
Jon Henning (14)
Jonathan Sheely (4)
Jordan Coopersmith (1)
Joseph Craig (2)
Kan Ma (1)
Keivan Beigi (3)
Ken Grierson (10)
Kevin Schreiner (6)
Leigh Pointer (31)
Lorraine Young (60)
Malik Khan (1)
Matthias Schlomann (15)
Mauricio Márquez (5)
Michael Doxsey (7)
Michael Tobisch (3)
Michael Washington (202)
Mike Horton (19)
Mitchel Sellers (28)
Nathan Rover (3)
Navin V Nagiah (14)
Néstor Sánchez (31)
Nik Kalyani (14)
Peter Donker (52)
Philip Beadle (135)
Philipp Becker (4)
Richard Dumas (22)
Robert J Collins (5)
Roger Selwyn (8)
Ruben Lopez (1)
Ryan Martinez (1)
Salar Golestanian (4)
Sanjay Mehrotra (9)
Scott McCulloch (1)
Scott S (11)
Scott Wilkinson (3)
Scott Willhite (97)
Sebastian Leupold (80)
Shaun Walker (237)
Shawn Mehaffie (17)
Stefan Cullmann (12)
Stefan Kamphuis (12)
Steve Fabian (31)
Timo Breumelhof (24)
Tony Henrich (3)
Torsten Weggen (2)
Vicenç Masanas (27)
Vincent Nguyen (3)
Vitaly Kozadayev (6)
Will Morgenweck (37)
Will Strohl (163)
William Severance (5)
Try Evoq
For Free
Start Free Trial
a Demo
See Evoq Live
Need More Information?