Content Editor

To choose what options users will have while using your widget, you need to add certain content types. These will be presented as options for taking inputs from the user. Duda defines what the UX is on it, you get to choose which input types you'd like and the order to arrange them in.

Each content input allows you to set the variable of that input. This variable must be unique among all other input types and will be accessible in the handlebars output of the widget and in the javascript. It's important to make these variable names descriptive to make selecting them easier while writing widgets.

The image above shows the Content options for Duda's Twitter feed widget. The user can enter their Twitter username as a text input. The dropdown allows them to specify which type of feed they want to display. The toggle input labeled Show header and footer enables the widget to make a slight design change based on the toggle being on or off.

We will review all the input types below.

Input Options

Below you will see a list of the common input options that can be set for any input type while building a widget. It also includes the best practices for each option for building user-friendly widgets.

Name

Description

Variable

The variable name of how this input value will be accessed inside of the widget output. This is required for all inputs

Descriptive Label

This is a free text field that you should use to tell the user exactly is being asked to input. This should be short, but give the user an idea of what is expected

Default Value

Give the input a default value. This will be visible to end users who add the widget to the website

Placeholder Text

The descriptive text in the background of the input. If you have a value added to the input, this will not be visible to the user. It's recommended to place a valid example of what you are expecting. For example, if you need an email address to be input, then place [email protected] as the placeholder text

Tooltip Text

This will be added as a '?' at the top right of the input (next to the label). This can be used to give more detailed instructions or tell users why you need this. This should be used if you are asking for something very specific and need to give details about how the user can get the value you're requesting

Required

A checkbox to make sure that the user inputs this value. By default, it is disabled. We recommend using this for any required input to make your widget function correctly

Checkbox

A checkbox returns a boolean value, depending on the input. This is usually used to define conditions of how the widget will work. You can use the checkbox combined with the handlebars if helper statement to change the way the widget works:

{{#if checkbox}}
    <p>Checkbox is selected / true</p>
{{else}}
    <p>Checkbox is not selected / false</p>
{{/if}}
if( data.config.checkbox ){
 // do something 
}

Date

Allow the user to choose a day on a calendar. The user can only choose a day and not a specific time of day. The calendar will output a timestamp in standard universal full date/time format. It is recommended that you only interact with the date format in JavaScript, as outputting the date via handlebars will produce a long digit.

<p>{{dateVariable}}</p>
<!--Outputs: <p>2018-01-12T01:14:55.241Z</p> -->
var d = new Date(data.config.dateVariable);
console.log(d.getFullYear());

Description

The description is not actually an input type. It allows you to add text directly into the widget content settings. This can be used to help tell the user what they should input below and what they can expect it to do. We recommend keeping it succinct, short and direct. Below you will see an example of what the description looks like.

📘

You can insert standard HTML into the description, to include links, bolding, etc.

Divider

Like the description, a divider is not a real input type. It allows you to section off different parts of the widget settings. It adds a simple horizontal divider line in the widget editor.

Dropdown

You can use a drop-down to define multiple values for a user to select from. The value of the drop down can be accessed by placing the variable name of the input down.

This is great for defining a class name to be used within the HTML. You can also use the drop down in conjunction with the decode and equals handlebars helper, for more advanced usage.

<div class="{{dropDown1}}">
    Change text color based on drop down.
</div>
switch (data.config.dropDown1) {
  case 'favorites':
    console.log('Use twitter favorites');
    break;
  case 'retweets':
    console.log('Use twitter retweets');
    break;
  case 'profile':
  default:
    console.log('Use profile feed');
}

Group

Using an input type of Group helps organize all the widget's inputs. A group creates a submenu with a subset of inputs. The image below shows how to take a set of input types and organize them into a group.

This produces this type of submenu in the Duda editor.

📘

There are 4 different layouts for a group. The above example shows the Side Menu layout. Try out all the options and see what works best for you.

Icon

Allow the user to choose an icon from Duda's library of SVG icons. This library is maintained by Duda and can't be added to. Duda will output the SVG HTML directly into the markup. It is required to use the triple curly bracket, as the output should be unescaped.

To style the SVG icon, you can use the CSS slider, color, and background to set the size, color and background of the icon. It's recommended to place the icon within a div or span, depending if you want it to be inline or block styled.

<div class="icon">{{{icon}}}</div>
console.log(data.config.icon);

/* 
// outputs
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<g>
    <path d="M75.4,23.9H24.6c-2.7,0-4.9,2.2-4.9,4.9v31.3c0,2.7,2.2,4.9,4.9,4.9h34.8l11.2,11.2V65h4.9c2.7,0,4.9-2.2,4.9-4.9V28.8&#10;&#9;&#9;C80.3,26.1,78.1,23.9,75.4,23.9z M78.4,60.1c0,1.6-1.3,2.9-2.9,2.9h-6.8v8.4L60.2,63H24.6c-1.6,0-2.9-1.3-2.9-2.9V28.8&#10;&#9;&#9;c0-1.6,1.3-2.9,2.9-2.9h50.9c1.6,0,2.9,1.3,2.9,2.9V60.1z"/>
    <rect x="35.3" y="43.4" width="29.3" height="2"/>
    <rect x="35.3" y="33.7" width="29.3" height="2"/>
    <rect x="35.3" y="53.2" width="19.6" height="2"/>
</g>
</svg>
*/

Image

The image input asks users to choose an image from the site image gallery. Duda will return an absolute URL to the image. This URL should not be altered in any way, as Duda often dynamically replaces this image source with device specific images for optimization purposes.

Duda recommends that whenever you are going to output an <img> tag into markup, you also ask the user for an alt text value of this image and place it as the alt attribute on the image (shown below). This is a best practice for SEO, as it gives search engines an indicator about the content of the image.

<img src="{{imageSourceVar}}" alt="{{imageAltText}}" />

Duda also recommends providing a default image in the event one is not provided by the user. Doing this removes the potential of a poor user experience if an image is not provided.

Large Text

Large text should be used to accept bigger blocks of text, such as descriptions and paragraphs.

There is an option for large text to enable a 'rich text editing' capability. This gives the user an easy way to define text styles such as bold, italics, lists and more.

If you use 'rich text editing', you must prevent handlebars from escaping the content as this input produces raw formatted HTML and should be output as such. Preventing handlebars from escaping the content can be done with the triple handlebars mustache {{{largeText}}}. Learn more here.

<p>{{{largeText}}}</p> <!-- this is not escaped -->

<p>{{largeText}}</p> <!-- this is escaped -->
console.log( data.config.largeText );

Link

The link input will display a list of link options available on the website. This allows users to link to other pages of the website, external websites, popups and more.

To output a link, the handlebar custom_link must be used. This will ensure that Duda handles the anchor correctly.

{{#custom_link linkVariableName}}
    <span>Click here</span>
{{/custom_link}}

<!-- produces this markup for a Website URL of http://duda.co -->
<a value="http://duda.co" type="url" href="http://duda.co" raw_url="http://duda.co"> 
    <span>Click here</span> 
</a>

List

You can allow users to define multiple types of inputs. For example, if you want to have a list of events, or questions in an FAQ, etc. The list allows users to enter as many items as they might need. A list is stored as an array and can have as many inputs as needed.

The example above allows the user to enter as many products and services as they'd like. Each product and service has a name and description. These properties of a list item can be accessed by the each helper. This will loop through each item of the list and give you access to each inner input.

{{#each product_list}}
    <h1>{{product_name}}</h1>
    <p>{{product_description}}</p>
{{/each}}
data.config.product_list.forEach(function(item,index) { 
    console.log(item.product_name);
    console.log(item.product_description);
});

Radio Buttons

<h2>{{radio1}}</h2>
switch (data.config.radio1) {
  case 'favorites':
    console.log('Use twitter favorites');
    break;
  case 'retweets':
    console.log('Use twitter retweets');
    break;
  case 'profile':
  default:
    console.log('Use profile feed');
}

Slider

Shows the user a slider which can be used for inputting selecting a number on a scale. Very similar to CSS slider, but but instead outputs to an integer. This number can then be accessed via JavaScript or handlebars output.

This is great for any time you need a user to select a number. Rather than requiring they input something into text, you can use a slider. For example, you might want to use this with an image slider that changes images every x seconds or a hover effect that takes place after a few seconds.

<div class="slider" data-slider-speed="{{sliderVar}}"></div>
for (var i = 0; i < data.config.sliderVar; i++)
{
    console.log(i);
}

Text

The text is the most basic input that you will want to output into your HTML. You’ll use the standard double curly brackets surrounding the variable that you want to output. This can also be used to collect numbers and other, short, inputs from the user.

For example, if you had a text input called buttonText, then the code below would print the text input.

<p class="first-button">{{buttonText}}</p>

📘

The Text input type supports regular expression validation. Learn more about that here.

Toggle

Similar to a checkbox, a toggle returns a true or false value. This can be used to decide upon the core functionality of the widget. The toggle is generally a better choice than the checkbox unless there are multiple true/false statements from the user that need to be selected at once.

{{#if toggle1}}
    <p>Toggle is enabled</p>
{{else}}
    <p>Toggle is disabled</p>
{{/if}}
if (data.config.toggle){
    // do something 
}

Video

The video input type allows your users to upload video directly to the Duda CDN, or provide a URL to a Youtube, Vimeo or Dailymotion page.

The input provides an object with the following properties for use within a widgets HTML or JS:

Property

Description

type

Value describing the source of the video: youtube, vimeo, dailymotion or cdn.

poster

URL pointing to a poster frame (image) for the video.

videoUrl

URL to the video or hosted video web page. For Youtube, Vimeo or Dailymotion videos, this will be the site URL the user entered, not the URL to use directly in the embed code.

🚧

Hosted Video Embeds

If a user entered a hosted video link (Youtube, Vimeo or Dailymotion) instead of directly uploading the video, you must convert the value to the embed URL. See the JavaScript example below, for an example on how to handle all video types.

<!-- responsive video container, see CSS and JavaScript tabs -->
<div class="wb-innerVideo"></div>
.wb-innerVideo {
    width: 100%;
    height: 100%;
    position: relative;
    padding-top: 30px;
    padding-bottom: 56.25%;
    overflow: hidden;
}

.wb-innerVideo iframe,
.wb-innerVideo video {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
}
function buildFrame (src) {
    var iframe = document.createElement('iframe');
    iframe.frameBorder = 0;
    iframe.allowFullScreen = true;
    iframe.src = src
    return iframe;
}

function hostedVideo (url, type) {
    var domain = sources[type];
    if (!domain) return console.error('Unknown video source.');
    
    var id = url.pathname.split('/').pop();
    var src = domain + id;
    var iframe = buildFrame(src);
    container.appendChild(iframe);
}

function cdnVideo (url) {
    var video = document.createElement('video');
    video.src = url;
    video.controls = true;
    container.appendChild(video);
}

var sources = {
    youtube: 'https://youtube.com/embed/',
    vimeo: 'https://player.vimeo.com/video/',
    dailymotion: 'https://www.dailymotion.com/embed/video/'
};

var container = element.querySelector('.wb-innerVideo');
var type = data.config.video.type;
var url = new URL(data.config.video.videoUrl);

if (type === 'cdn')
    return cdnVideo(url);
    
hostedVideo(url, type);

📘

Responsive Video CSS

The example CSS above provides one solution to rendering responsive video content. The responsive video container ensures the player doesn't interfere with the rest of your site layout, no matter the user's viewport dimensions.

Connected Data

To use custom widgets with Connected Data, make sure the "Enable binding to Connected Data" toggle is on for the input type that you're adding. This toggle is only available for input types that support Connected Data.

Other

Regular Expressions

The text input type allows for regular expression validation. For example, if you only want to accept digits in a text input, then you can set the regular expression validation string to ^\d+$. This is using standard regular expression string validation in JavaScript.

Additionally a validation error message can be set to display when invalid text is entered.

Updated 2 months ago


What's Next

Design Editor

Content Editor


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.