SurveyJS is out of Beta

Written by surveyjs | Published 2017/12/11
Tech Story Tags: web-development | javascript | vuejs | reactjs | angularjs

TLDRvia the TL;DR App

SurveyJS - an open-source JavaScript Survey library with versions for Angular 2+, React, Vue, Knockout and jQuery - is out of Beta.

We first released a public version on September 25, 2015 - over two years ago. By April 2017, when we published “Meet SurveyJS”, the library was already feature-competitive and stable, we only needed a bit more feedback from the field before we could call it a version 1.0 release.

Between April and now, we kept learning from our user’s surveys, forms, and quizzes striving to improve the API, introduce new functionality and, of course, fix bugs and usability issues.

Here’s what’s new.

Panels: Somewhere Between Questions and Pages

Consider a simple conditional flow shown in the following image:

Since survey tools usually limit you to two types of entities — Questions and Pages — the obvious options are:

  • Move partner-related questions to a separate, conditionally-visible page. The downside is bad UX caused by excessive navigation and separation of related information into multiple pages.
  • Use a single page with conditionally-visible questions. This is better from UX standpoint, but requires “code duplication”.

SurveyJS now offers a third, somewhat in-between option: put questions into a conditionally-visible Panel. As we see from many customer surveys, this Panel concept is being used quite extensively.

Here’s a live example. A Panel with additional questions pops up if you pick 3 or less on the product satisfaction scale. In this example, there is a nested collapsed Panel as well.

SurveyJS Panel example

Panels enable an elegant solution for yet another common task. Consider the following survey page:

If a phone number is required, and any of three fields can be populated, no complicated logic is necessary with SurveyJS. You simply group the fields into a Panel with isRequired property set to true.

See how it works in the following live sample:

SurveyJS Panel.isRequired = true

And, if you’re wondering about flexibility, SurveyJS supports an unlimited number of nested Panels. For example, the “Phone Numbers” panel can nest within a conditionally visible “Address” panel, and so on.

Custom Functions in “visibleIf” and “enableIf” Expressions

The simplest type of SurveyJS expression will use static values and question answers. Here’s an example:

That’s as straightforward as it gets in any survey tool: easy enough to construct for a user without programming experience.

What might have caught your attention is the unlikely use of {age}. Chances are you’re not going to ask for age, but instead will ask for a birth date and then try to figure out the age based on that.

Back in April 2017, if you were to ask us how to do this, we’d recommend handling the onValueChanged event (fires on every change in survey answers) to calculate the age and store it into a variable. The variable can then be used within the expression.

This only works, however, if the survey is created by you, a developer. But if you’re building an in-house survey engine using SurveyJS Library and SurveyJS Editor, questionnaires will be constructed by users without the expertise required to handle events in JavaScript.

To work around this limitation, we now allow you to register custom functions. The code below implements the “figure out the age based on birth date” function (one of the functions that ship with the library):

// The age() function accepts a birth date// and returns the number of full years

function age(params: any[]): any {if (!params && params.length < 1) return -1;var birthDay = new Date(params[0]);var ageDifMs = Date.now() — birthDay.getTime();var ageDate = new Date(ageDifMs); // miliseconds from epochreturn Math.abs(ageDate.getUTCFullYear() — 1970);}

// Register the function for use in SurveyJS expressionsSurvey.FunctionFactory.Instance.register(“age”, age);

With that function available, we’re back to something simple that system admins can handle:

Here’s a live sample to demonstrate:

Using age function example

Since we mentioned that certain functions ship with SurveyJS, we need to note that we don’t provide an extensive function library à la Excel just yet. We will, however, mention a couple more useful functions later in this article, in the section on Expressions and Totals.

Dynamic Panel: Dealing with List Data

Lists must be the worst type of data for surveys, yet examples are numerous: children list, countries visited in the last five years, most recent addresses, jobs past and current, and so on.

And if you have survey construction experience, the nesting list flow in the wireframe below must spell horror to you:

Using the standard means survey software provides, you can implement the left-hand side somewhat easily. Simply use a Matrix widget. Although it will awkwardly arrange fields into rows, so if you have more than three fields per entry, then be prepared for horizontal scrolling, i.e. bad UX.

But what about the right-hand side: the second-level list with every sibling’s children? You cannot put a matrix into a matrix… For that, we would normally recommend running a separate survey for each of the Sibling objects, which, as you might imagine, requires coding.

These complications are now a thing of the past. With the Dynamic Panel widget newly implemented in SurveyJS, you can build lists with any item layout, embed nested lists, and even edit list objects across multiple pages. Just as shown in the diagram above — you can start by filling out basic information on one page and add more information on another.

Now take a look at an example and we’ll discuss the most interesting parts below.

Dynamic Panel Example

As you see, both pages edit the same employer information: the second page will display the same list you’ve started building on the first page. In technical terms, these two pages contain Dynamic Panel widgets both connected to the same list source. Notice the following repeated code lines:

// Two dynamic panels on different pages// connected to the same list source

"pages": [{"name": "page1"..."elements": [{..."type": "paneldynamic","valueName": "employers"...}]}, {"name": "page2"..."elements": [{..."type": "paneldynamic","valueName": "employers"...}]}]

Another interesting part is that on the first page list entries are stacked one under another, while on the second page you navigate between individual employers inline. This is controlled by the dynamic panel’s renderMode property that can be set to:

  • list” (default value, used on the first page)
  • progressTop” (explicitly assigned on the second page)
  • progressBottom”, “progressTopBottom” (try them in JSFiddle)

..."renderMode": "progressTop"...

Expressions, Summaries, and Totals

Dynamic Panels were a hit and the interest snowballed into more user requests. Having such a simple list management tool at their disposal, our customers started creating more complex layouts, including invoices. SurveyJS could easily handle the layout, but we were getting and increasing number of requests for automatic totals calculation.

Once again, that wasn’t a limitation if you were a developer. But as time went on and we kept responding to customers with a standard onValueChanged event handler suggestion, we realized that those cases aren’t isolated and we need a simpler mechanism that everyone can use.

The solution: an Expression widget whose simplest usage is illustrated in the image below:

The “expression” property can accept:

  • constants
  • math operators
  • survey question values
  • custom functions discussed earlier in this article

Speaking of custom functions, one predefined function you’ll find useful with totals is “iif”. Here’s how to use it to apply a 20% discount to purchases of 10 or more items:

"iif({quantity} < 10, {quantity}*{price}, {quantity}*{price}*0.8)"

Another noteworthy function - “sumInArray”- can be used to calculate a total against all items in a Dynamic Panel or a Dynamic Matrix:

// summarize 'quantity' question values// in the 'invoiceItems' panel/matrix

"sumInArray('invoiceItems', 'quantity')"

Here’s a simple invoice form implemented with SurveyJS. It’s got a bit of everything: a custom function, summaries calculated for each invoice entry, and grand totals.

Invoice example

A GitHub Repository with Custom Widgets

SurveyJS, being a programming library first, lets you to integrate any JavaScript widget into your surveys. Our customers surely like to take advantage of that, but of course it comes with a price — a few lines of code.

Being somewhat naive, we expected to reduce the support load if we polished the integration API and documented it thoroughly. The questions never stopped though. Every widget had it quirks. Every SurveyJS user wanted nothing better than to find an existing code to copy. So we caved and ended up supporting integration code for all highly-requested widgets, treating that as part of the project.

To review the widgets we support now, check out the dedicated GitHub repository. Here’s the list:

And if you have ideas on what we should add next, by all means let us know.

Timed Quiz Functionality

SurveyJS has been used to create timed quizzes since we first published the library. But until now, a few features needed to be coded in manually:

  • A title page used to display instructions and a Start button. This page does not count as part of the quiz/survey progress.
  • Time management for the entire survey and individual pages. Quizzes usually need to display the time remaining on a page and/or in the survey and need to automatically skip forward when the time is up.
  • The notion of a correct answer to a question and the ability to obtain answer statistics.

You can review a simple quiz example that takes advantage of these new features.

Even if you are not developing a quiz, you may still use this functionality to find out how much time your users spend filling out the entire survey or each individual page.

Bootstrap 4 Support and In-House Themes

We were going to wait until Bootstrap 4 is officially released before working on integration, but yet again, the volume of requests was overwhelming and we had no choice but to roll up the sleeves and proceed right away. So enjoy Bootstrap 4 Beta with SurveyJS, but be advised that when the Bootstrap team publishes an update, it usually takes us a few days to bring our code in sync.

Everything that’s easy imposes certain boundaries. So is the case with applying Bootstrap themes. The website needs to be built with that framework in mind, and not every site is like that. This meant to us that Bootstrap themes could not be the only option we provide. Another option was manual CSS customization — something we allowed since day one. And while it allows complete look and feel control, it also requires the most effort.

We realized that a big part of our customer base wanted something in between — ready-to-use and easily customizable themes without the Bootstrap dependency. That’s one of the reasons we have a full-time designer on the team now. With several large surveys as a reference point, she created seven themes: “green” (default), “orange”, “darkblue”, “darkrose”, “stone”, “winter”, and “winterstone”.

To apply a theme, use the following code line:

Survey.StylesManager.applyTheme("stone");

The sample below shows you how to apply built-in themes and how to modify one of them if you need a different color palette. Use the combo box in the live sample to try out the options.

You can easily switch themes using root marker CSS class

Support for Web Content Accessibility Guidelines (WCAG) 2.0

WCAG is guidance for some developers, a strict requirement for others, and of course a necessity for users with disabilities. We always knew SurveyJS would have to support this and so it’s done.

A New Boolean Widget

A simple, yet useful check box widget that helps you improve survey UI:

Boolean Question example

Learn More about Project SurveyJS

Project SurveyJS includes three products:

  • A JavaScript library that enables you to run surveys on your websites (open-source and free).
  • A cloud service that allows you to create and store surveys, download and analyze their results (currently free for use).
  • An embeddable JavaScript-based survey editor UI (free non-commercial and paid commercial-use licenses are available).

This article reviewed the latest new features we have implemented in SurveyJS Library. To learn more about functionality provided by Project SurveyJS, to review documentation with live samples, or to contact us with questions, visit our about website at https://SurveyJS.io.


Published by HackerNoon on 2017/12/11