DEV Community

Cover image for FormEngine Alternative: A Comprehensive Comparison with SurveyJS
Gavin Henderson
Gavin Henderson

Posted on

FormEngine Alternative: A Comprehensive Comparison with SurveyJS

Forms sit at the heart of every good web application. As soon as you enter a web application you are filling out a form, from sign up all the way to completing a checkout flow.

The more businesses go online the first thing they do is set up online forms to help them reduce manual paperwork. Often times these forms can be complex and people expect complex validation and the form to adapt as its filled in.

It can be very hard to build good experiences with forms and they can go wrong in many many ways. At first forms seem like a simple thing to build but as you add more fields and forms the edge cases grow exponentially.

This article will compare two survey software tools, SurveyJS and FormEngine, and outline the pros and cons of each.

Intro to SurveyJS

SurveyJS is a suite of products that all compliment each other to make building, publishing and managing forms easy.

SurveyJS takes a 'front-end only' approach to forms, which makes sense given that forms only exist on the front end, everything after that is just standard data handling.

Once the data reaches the backend you are free to save the data any way you like. This means that you can save it into your custom backend with ease and take advantage of all that great authentication you have already built. It also means that you don't have to worry about another third party handling your data.

Image description

The diagram above shows the design ethos of SurveyJS excellently. Everything in the 'client' section is within the domain of SurveyJS and they build those for you. Everything on the 'server' section is totally up to you, so it will seamlessly integrate with your existing backend.

The downside is, if you want to build and publish a single form you are going to have to build up your own backend for that.

FormEngine

Next up lets take a look at FormEngine, which is a set of tools to help you build and deploy your forms within your React apps. FormEngine is built by Optimajet who have been in the form business for a while now, they originally developed FormBuilder, which was a React based form designer and viewer. FormEngine is the next generation of their form designer and form viewer, built from the modern web.

FormEngine is distributed as a React package that you can install in your existing application. The two main components they give you are a Form Builder component and a Form Viewer component.

FormEngine also takes a 'front-end' only approach to managing forms, leaving you to store and manage the data any way you want. In respect to data storage, SurveyJS and FormEngine have the same set of trade-offs.

Form Building

The place that you are likely to spend the most time is the form builder, so its important that you find it easy to use and that it lets you do everything you need.

Lets start with SurveyJS. To get access to the form creator you are going to have to integrate it into your existing UI. Alternatively, you can use their hosted MySurvey tool, which serves as a full-featured form builder demo. It allows you to try out the form builder UI and build form JSON files without having to integrate the form builder into your application.

SurveyJS provides support for every common front-end framework that you could imagine, and even the ones you couldn't. They support:

  • Angular

  • Vue

  • React

  • Knockout

  • jQuery

Its really straight forward to integrate the form creator into your existing application. For example to add it your Angular application all you need is:

import { Component, OnInit } from '@angular/core';
import { SurveyCreatorModel } from "survey-creator-core";

@Component({
  selector: 'survey-creator-component',
  templateUrl: './survey-creator.component.html',
  styleUrls: ['./survey-creator.component.css']
})
export class SurveyCreatorComponent implements OnInit {
  surveyCreatorModel: SurveyCreatorModel;
  ngOnInit() {
    const creator = new SurveyCreatorModel({
        showLogicTab: true,
        isAutoSave: true
    });
    this.surveyCreatorModel = creator;
  }
}
Enter fullscreen mode Exit fullscreen mode

The output of the form builder in SurveyJS is a JSON object which we will use later with the form rendering library.

Image description

The form creator itself is a very nice modern UI that is extremely interactive and feels very snappy. You can drag and drop questions about without thinking about it and everything is intuitively where you would expect it to be, which is a tough job when there are so many settings. It even works pretty well on a mobile device which is pretty incredible.

Image description

It has all the field types that you would expect from a form builder. It has standard text inputs, checkboxes, radio groups (including matrixes) and drop-downs. There is a few drop-downs that you might not expect but could be very handy. There is a ranking field allowing users to rank a set options top to bottom.

They also have a grouping feature, that allows a respondent to answer a set of questions multiple times if they need to. For example, they can add multiple contact people and fill in each of their details separately. An image picker, allowing a user to select from a group of images. Lastly it even has the ability to accept signatures which is a nice addition.

If you find you that you are missing a field type you can add your own type. They have a nice example in the documentation about how to go about doing that.

When it comes to logic it allows you to do everything you could possibly imagine using a dedicated GUI. You can hide questions, answer questions and reset answers. You can do this by defining as many 'rules' as you want, by setting a condition and an action depending on the condition. To developers this will feel familiar as it presents as a giant if statement.

It might take a while for a novice users to get around all the options, but once they figure out where everything in they will quickly find themselves setting up form logic with the intuitive logic options.

Once you have the form built with all the fields and logic you want you can add translations to each question. You can add all the languages you want to support and input all your translations for the strings in each page. This makes it a breeze to translate large forms with complicated logic. They even provide an API that lets you use machine translation, for example Microsoft Translator, to quickly translate lots of strings and allows you to then manually correct any mistakes.

Image description

Next up lets take a look at FormEngine. Similar to SurveyJS you need to render the form builder into an application to use. Its worth noting that they only support React so if you want to integrate with any other framework you won't be able to use FormEngine.

Rendering the builder is slightly more involved inside FormEngine but they give you many options to customise how you integrate it into your React app. Here is an example piece of code to render a basic form designer in FormEngine:

export const Designer = () => {
  return (
    <FormBuilder
      view={builderView}
      getForm={getFormFn}
      formName={formName}
      initialData={({})}
      formStorage={formStorage}
      localize={localizeFn}
      onFormDataChange={({data, errors}) => {
        console.log('onFormDataChange', {data, errors})
      }}
      viewerRef={setRef}
      validators={customValidators}
      actions={{
        logEventArgs: e => console.log(e),
        assertArgs: ActionDefinition.functionalAction((e, args) => {
          console.log(e, args)
        }, {
          p1: 'string',
          p2: 'boolean',
          p3: 'number'
        })
      }}
    />
  )
}
Enter fullscreen mode Exit fullscreen mode

Once you have rendered the form builder you can then start using it to build your forms. Like SurveyJS is uses a drag and drop interface, allow you to place the fields anywhere inside the form. They provide all the standard field types, including what they call 'pattern format' which allows you to create grids which are commonly used to rate an experience on a scale.

Image description

You can edit the style of each field individually. It gives you the basic options in a user interface but it also lets you enter CSS for the field directly inside of the designer. I would like to see a way to edit all the field styles at once, so that you can apply a theme.

The form designer lets you customise the behaviour of the form via rules, actions and the 'render when' property. The 'render when' property is what you would use to show or hide a question based on the answers given in other questions. Its not particularly easy to use as you have to programmatically reference other questions, there is no user interface to it. The rules section lets you set validation rules to for the form field, it has a lot of really nice default validation rules you can use on most fields and it also has a nice custom mode where you define the validation yourself.

Lastly, there is an 'Actions' section that shows you all the different triggers every field has, for example 'onChange', and lets you decide what action to do when the event happens. For example you can force a field to validate after a given action.

Overall the drag and drop editor in FormEngine is nice to use if you just want to put fields in your form and change what they look like. However, if you want to show and hide fields based on rules then its really difficult and poorly documented. This is a really basic feature that every form editor needs to have so its surprising that its as good as the rest of the editor.

Someone who is not technical would struggle to use anything more than the basic form fields inside of FormEngine. The fact that you need to understand basic code to show or hide fields locks many people out of using it. The 'actions' tab is also clearly built for developers as it references functions like 'onChange', which will be very familiar to a developer but won't be much help to a non technical person.

Form Viewing

First up is SurveyJS and its form filling experience. To render the form you simply pass JSON object the form creator gives you into the survey component the like so:

function Survey() {
    const survey = new Survey.Model(json);

    survey.applyTheme(themeJson);

    survey.onComplete.add((sender, options) => {
        console.log("Form filled!");
    });

    return (
        <SurveyReact.Survey model={survey} />
    );
}
Enter fullscreen mode Exit fullscreen mode

The default form filling UI is simple and clean and its responsive and feels like a top tier form.

SurveyJS lets you do an exceptional amount customisation. You can change every single colour that is shown on the form using a fully integrated CSS Theme Editors with a panel of UI controls.

FormEngine also has a top tier FormView which is rendered in a similar way to SurveyJS via their React library. All of their components are based on the popular component library RSuite components which makes them great to use and they look great. The UI of the forms is responsive and gives users great feedback.

Overall, both display forms as you would expect them to and are very responsive.

Form Results

After users have submitted their form you probably want a way to access the results and view them. FormEngine provides no solution for this, after the user submits the data you are totally on your own to deal with the data and visualising it.

Its worth noting the Optimajet also sell a a product called 'WorkflowEngine', which you can use to process your data. That being said there is no native integration between WorkflowEngine and FormEngine and it is a separate product with an additional cost which is why I have not included it in this comparison.

On the other hand SurveyJS provides a 'Dashboard' library to allow you to analyse your results in a meaningful way.

Image description

You get access to just about any visualisation graph that you could think of. As with the rest of SurveyJS the customisation is pretty much unlimited. Its a really great way to get a high level overview of the results of your forms.

The great thing with SurveyJS is that you can actually view the data however you want because you fully own it and control it. You can be syncing it to a Google Sheet if you wanted and view it there. You can view it in your companies existing business insights platform if you want.

Custom Components

Both platforms have a great variety of form components to choose from, but there will always be cases where you want to create a custom component. When you do create a custom component you will want to access it within the form builder and the form viewer. Both platforms let you create custom components, so lets take a look at how you do it and which is easier and more flexible to use.

First lets take a look at SurveyJS and how to add a custom component using their React library, although you can do it in all the frameworks they support. To add a custom component to your form stack in SurveyJS you have to extend their existing Question class and define your own custom properties. The code below defines a color picker model and then sets two custom properties that you can use.

import { Question } from "survey-core";

const CUSTOM_TYPE = "color-picker";

export class QuestionColorPickerModel extends Question {
  getType() {
    return CUSTOM_TYPE;
  }
  get colorPickerType() {
    return this.getPropertyValue("colorPickerType");
  }
  set colorPickerType(val) {
    this.setPropertyValue("colorPickerType", val);
  }

  get disableAlpha() {
    return this.getPropertyValue("disableAlpha");
  }
  set disableAlpha(val) {
    this.setPropertyValue("disableAlpha", val);
  }
}
Enter fullscreen mode Exit fullscreen mode

Once you have created the model you must register it as follows:

ElementFactory.Instance.registerElement(CUSTOM_TYPE, (name) => {
    return new QuestionColorPickerModel(name);
});
Enter fullscreen mode Exit fullscreen mode

SurveyJS heavily relies on JSON to store the models of the surveys, because of this we have to setup how we want our new question to be serialised. The code below hooks into the existing serializer to define how to serialize the new question type to JSON.

Serializer.addClass(
  CUSTOM_TYPE,
  [{
    name: "colorPickerType",
    default: "Slider",
    choices: ["Slider", "Sketch", "Compact"],
    category: "general",
    visibleIndex: 2 
  }, {
    name: "disableAlpha:boolean",
    dependsOn: "colorPickerType",
    visibleIf: function (obj) {
      return obj.colorPickerType === "Sketch";
    },
    category: "general",
    visibleIndex: 3 // Place after the Name, Title, and Color Picker Type
  }],
  function () {
    return new QuestionColorPickerModel("");
  },
  "question"
);
Enter fullscreen mode Exit fullscreen mode

After we have fully setup the model we need to move onto setting up the component that is going to be rendered. Again we do this by extending a SurveyJS class and defining the parts that are specific to our custom component. The code below defines the ColorPicker question which tells SurveyJS how to render the colour picker component given the fields defined by the model we created earlier.

export class SurveyQuestionColorPicker extends SurveyQuestionElementBase {
  constructor(props) {
    super(props);
    this.state = { value: this.question.value };
  }
  get question() {
    return this.questionBase;
  }
  get value() {
    return this.question.value;
  }
  get disableAlpha() {
    return this.question.disableAlpha;
  }
  get type() {
    return this.question.colorPickerType;
  }
  handleColorChange = (data) => {
    this.question.value = data.hex;
  };

  // Support the read-only and design modes
  get style() {
    return this.question.getPropertyValue("readOnly")
      || this.question.isDesignMode ? { pointerEvents: "none" } : undefined;
  }

  renderColorPicker(type) {
    switch (type) {
      case "Slider": {
        return (
          <SliderPicker color={this.value} onChange={this.handleColorChange} />
        );
      }
      case "Sketch": {
        return (
          <SketchPicker color={this.value} onChange={this.handleColorChange} disableAlpha={this.disableAlpha} />
        );
      }
      case "Compact": {
        return (
          <CompactPicker color={this.value} onChange={this.handleColorChange} />
        );
      }
      default:
        return <div>Unknown type</div>;
    }
  }

  renderElement() {
    return (
      <div style={this.style}>
        {this.renderColorPicker(this.type)}
      </div>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Lastly, you have to register the component using ReactQuestionFactory.Instance.registerQuestion. There is lots of other things you can do with SurveyJS custom components that I haven't shown, like specify the icon to use or captions. If you want to know more you can read the documentation on how to change other parts of the custom component here.

Next lets take a look at how to add a custom component in FormEngine. The first step is to define a component using the constants they give to you. The below example creates a basic button custom component, this means you can have a totally custom designed button.

import {Button} from '@mui/material'
import {boolean, define, oneOf, string, event} from '@react-form-builder/core'

export const newButton = define(Button, 'NewButton')
  .name('Button')
  .props({
    children: string.named('Caption').default('Button'),
    color: oneOf('inherit', 'primary', 'secondary', 'success', 'error', 'info', 'warning'),
    disabled: boolean,
    onClick: event,
  })
Enter fullscreen mode Exit fullscreen mode

Once you have created the component and designed it you need to pass it into the builder when you render it as well as the form view renderer so it can also render the custom component whenever its used. The code below describes how to connect it to the builder and to the form viewer.

const builderView = new BuilderView([newButton.build()])
const view = createView([newButton.build().model])
Enter fullscreen mode Exit fullscreen mode

After you have done all of those steps you will be able to access your custom component in both the editor and the viewer with all the options that you have specified.

Pricing

When it comes to pricing its not straight forward to compare these two as they have multiple pieces to them.

First up lets take a look at the pricing for FormEngine. They provide two ways of paying, you can either buy a perpetual license or you can pay for a subscription.

The cheapest perpetual license ~£702 for the 'Startup' license, which gets you access to pretty much the whole product. It comes with 6 months worth of updates and 2 months of support, because it is a perpetual license you can choose to use the same version forever at no extra cost. The other perpetual licenses cost more and they give you more support or updates as well as permission to use your license on more subdomains. They also offer additional support packages that you can pick from.

As well as the perpetual licenses you can choose to pay for a subscription to FormEngine. Their cheapest subscription is ~£1171 per year, which give you access to FormEngine on all your subdomains as well as access to updates for as long as you pay the subscription. They have a lot of pricing options so if you want to learn more its worth reaching out to them to get access to their pricing options.

SurveyJS on the other hand takes a totally different approach to pricing. The publish all of their libraries on Github for you to install and try out entirely for free. However, if you want to use their products for any commercial uses then you have to look into buying a commercial license. Their core survey rendering library is MIT licensed which means its free to use even for commercial uses. If you want to use the Survey Creator then you have to buy a 'Basic' license for ~£422. If you want the Survey Creator, Dashboard and PDF Generator then you need a 'Pro' license for ~£760.

The commercial licenses are perpetual meaning that you can use the software for the entirety of your lifetime, but to access updates and support you will have to renew your license every 12 months. SurveyJS license key can be used with a specific domain or group of domains and it will also work for subdomains within the specified domain or group without additional payment.

Accessibility

When publishing forms you need to make sure they are accessible for everyone, including users who rely on assistive technology. To measure this we can rely on the WCAG guidelines which describe how a website can be accessible.

SurveyJS published an Accessibility Statement outlining the commitment to accessibility and talks about all the standards they meet. This is something that is missing from FormEngine.

SurveyJS is entirely keyboard accessible which means it can be accessed using alternative access methods.

However, SurveyJS falls short in a few minor ways. For example it has some contrast issues in a few places as well as missing or incorrect labeling on elements.

If we take a look at accessibility within FormEngine we can see its something they have worked very hard on. Their entire UI is also keyboard accessible but they have also taken the time to carefully markup their entire application using aria labels. This means that anyone using a screen reader can access the document fully.

Both platforms will meet the needs of most users of assistive technology users but if its something that you have a specific need for its best to try out with your own assistive technology.

Conclusion

Overall, both SurveyJS and FormEngine are good options to help you build forms and display them to users. They are both really intuitive and easy to use.

The main draw back with FormEngine is that it is only available for React so if you have any other framework within your existing system you won't be able to integrate with FormEngine. Overall, their UI has a really nice 'feel' to it, especially when adding in fields or designing the look of the form. However, when it comes to using it for larger forms if you are not a developer you will struggle to use it because of the language and paradigms used throughout.

If you want to have the option to have visualisations then SurveyJS will be your only option as FormEngine doesn't give you any. You can build you own though based on the data, but that will be more work.

I would encourage you to give them both a try and pick what works best for your needs!

Thanks for reading!

Top comments (0)