top of page

Building form smarts from scratch with Wix Velo

  • Writer: Wendy White
    Wendy White
  • May 9
  • 8 min read

Updated: May 18

I was recently given a new challenge by Twenty2 Collective: build a neat little tool that could assess someone’s skills across a variety of categories, then whip up a personalised report with tips and tools to help them improve.


This kind of thing is what Twenty2 Collective does best: matching businesses and individuals with the tools and knowledge they need to grow beyond their current capability. They do this wonderfully in-person, and lately they've been expanding their services to include tailored digital packages to help their clients continue their growth in a sustainable, on-demand way. It's thoughtful, user-focused, and highly scalable. Exactly the kind of thing that gets my brain fizzing.


The form needed to:

  • store submissions in a Wix Collection (CMS),

  • work well on both desktop and mobile views,

  • create dynamic scores based on 40+ questions,

  • generate a results chart, and

  • not overwhelm the person filling it out (considering the lengthy nature of the questions).


The resulting tool belongs to Twenty2 Collective as their product IP, so I won't be sharing my code, but I wanted to write up some lessons learned, and highlight some Wix Velo quirks. May this help someone else dipping their toes into the Wix Velo ocean 🙏


Originally, it wasn't going to be in Wix at all

Twenty2 Collective was already deep in the Microsoft 365 ecosystem, using SharePoint for all their internal documents and project management. Since they also wanted to improve how they handled knowledge sharing, my first instinct was to build a SharePoint subsite that could moonlight as a public-facing tool.


It seemed like a good fit: PowerAutomate for the form logic, PowerApps for user input, PowerBI for visualisation. I could even sprinkle in a bit of governance magic while I was at it.


But there was one thing that didn't quite fit. This tool wasn’t just for internal use. It was something my client wanted to offer as a value-add to their customers. That raised some thorny questions:


  • Who gets access?

  • For how long?

  • How do we manage that without drowning in admin?


Basically: how can I automate scaling their digital services long-term? SharePoint is many things, but out-of-the-box support for productised, paywalled tools isn’t really one of them. It's more a deep, dank castle library (this sounds like a criticism, but look, I'm all about ancient tomes) than a storefront.


That’s when I discovered they use Wix. And so a new path opened up before me.


Wix is built on the idea that their users will operate digital storefronts

Wix is a website development and hosting platform with built-in tools for creating private member areas, gated resources, online stores - all the kinds of digital bells and whistles small businesses love.


And while I can build a website from scratch (HTML, CSS, CMS templates - the whole shebang), I also use Wix for my own portfolio site. Why? Because when I’m deep in client projects, I don’t have the spare brain cycles to hand-code every tweak. Wix lets me focus on the important bits without falling into the dreaded perfectionist dev rabbit hole.


Now, that doesn’t mean I’m completely uncritical. I have… feelings… about some of their business decisions.


For instance: after years of encouraging users to move from static content to CMS-driven dynamic content, they recently slapped a limit on CMS item creation for even the highest-tier plans. Not ideal. Especially for a platform that is meant to be heavy on the customer-management side of things, not just the "make website pretty pls" bits.


That said, their dev team deserves a lot of credit. The editing interface is genuinely impressive... sleek, powerful, and miles ahead of some of the older platforms I’ve worked with. I do wish they had a tool to port sites from classic Wix into Wix Studio (and I have no idea why they have two totally separate versions of almost the exact same thing) but that’s a rant for another day (or blog post).


Despite those quibbles, Wix seemed to be the better fit for this project. It meant we could keep everything - from the public tool to client access - under one roof. And, when the time comes, automating paid access should a smoother process.


Problem: you can't build a dynamic results page with OotB Wix Forms

Wix has a form-creation "app" ([ancient cranky web dev voice]: everything's gotta be 'apps' these days).


Unfortunately, I couldn't use it.


The reason for this is subtle, and it actually took me an hour of butting my head against the wall to uncover it - there is actually no way, using Wix's default form "submit" functionality, to capture and display the results the user has just submitted. You cannot run extra "onClick" functions on a default Wix submit button that is connected to a dataset using the recommended Wix approach, basically.


Which meant I had to throw the idea on using out-of-the-box Wix forms (and their ability to innately link fields to CMS datasets) into the bin and build all of the submission smarts from scratch.


While that was honestly a pain at times, long term this is actually incredibly useful, because if Twenty2 Collective builds more web-based tools like this down the track, I've basically created a modular set of functions that they can build on. It was also a great learning experience for me when it comes to working in the Wix Velo environment, as previously I've only used Velo to tweak things that already worked - not totally sculpt a new tool.


Building the survey flow

With over 40 questions, putting everything on one screen would’ve overwhelmed users (and probably caused small screens to explode in protest). Instead, while the entire survey exists on a single page, I grouped questions by category into their own Wix Sections - all but the first collapsed at page load, and dynamically revealed/hidden as the user clicks the Next and Previous buttons.


This meant writing code to:


  1. Only show one section at a time.

  2. Prevent the user from skipping ahead.

  3. Validate that all questions in a section were answered before continuing.


To avoid repeating the same logic for eight sections, I created a reusable helper module to wire up all buttons using a single config array. I love this kind of abstraction; it will make my life much easier if I need to create a similar survey for my client later on - no hard-coded section IDs to search and replace. It also means the client can change the order of survey sections without my code breaking. And it means all my Previous and Next buttons share the same overall logic. The Submit button needed a few extra tweaks, but it also largely relies on the helper module.


Validation of child elements: a Wix tear-jerker

Wix page elements are arranged in a lovely little setup called "Layers" which in theory (cough, cough) means that you can have parent elements and child elements, and use Wix Velo to do neat things like generate an array of all child elements of a parent.


Which was kind of essential for my initial validation plan. Every time a user clicked "next" or "submit", I was going to run a function that:

  • gets the element ID of the current Wix Section,

  • creates an array populated with a list of all survey question child elements in that section,

  • loops through each element in the array to see if it is null (an unanswered question),

  • if it hits a null value, it stops the loop, and displays a validation error message to the user.


Nice and modular, right? No hard-coding required.


Unfortunately, Wix Velo crushed that dream. For some reason, while the whole Parent-Child element thing works in some contexts, apparently if you have onClick functionality that makes a call to a parent to see the list of its children, Wix just glares at you in response. Even though I could generate these lists in other contexts, any onClick call resulted in an empty array, even though I was definitely capturing the parent element ID correctly. Had the same issue with populating a page load.


Not gonna lie, this was the part of the project where I actually shed a tear. Or three. Maybe three thousand.


I was severely dehydrated, basically. Thanks Wix!


Here's the code that doesn't work - not used by my client in any way. Obviously.



So, learn from my suffering, and don't expect anything triggered by an onClick to be able to use section.children.filter.


I had so much momentum, and it was totally disrupted by this innate Wix functionality just not working in this specific use case. A function I thought would take at most a half-day to write and test expanded to a three day slog of attempted work-arounds, cajoling, and Wix support forum deep dives.


Eventually I had to give up, and hard-code an array of child elements for each parent. This is not tasty modular coding, I know, but it works. And hopefully future iterations of the Wix platform allow me to write cleaner code in future.


Displaying results

So, my results "page" is just another Wix Section on the survey page, which has two benefits:

  1. Doesn't eat further into my client's static page limits.

  2. I can store and post all the calculated scores within the same onClick action - nice and self-contained.


Wix doesn’t do fancy Power-BI-ish chart generation, but you can use an HTML Embed to run your own JavaScript. So, I dropped in Chart.js via CDN, then used window.addEventListener('message') to pass in the data from the form.


This meant:


  • Calculating average scores on the fly in the frontend.

  • Passing them into the <iframe> embed using postMessage().

  • Rendering a chart based on the received data.


This is where I learned that customising chart.js charts within a Wix HTML embed is a bit of a pain - lots of little CSS overrides and weird padding issues to deal with. This is another pain point where I briefly wished I was building everything entirely from scratch, rather than from within Wix, given a lot of the styling issues were exacerbated by having to use the Wix HTML embed. But it is what it is. Building a (highly secure, easy for non-devs to maintain) membership section from scratch would be much more intensive down the track, so I felt it was still worth fighting with the embed.


Debugging lessons learned

If you want to build something similar with Wix Velo, in addition to the issues I've outlined above, here's some other things to keep in mind:

  • Backend/frontend separation in Wix is strict. You cannot use $w() anywhere but page code.

  • Be sure your Wix Collection is set up with Write permissions for all relevant users.

  • Don't let chart.js load prior to the canvas coming into existence.

  • Add a brief (200ms was enough for this form) pause before calling backend functions while the page is loading. You may need a longer wait if the page is complex (lots of images, 100s of questions, embedded fonts, etc.)

  • Related to the last point - careful sequencing of async functions is essential to keep things flowing smoothly. I used a heck of a lot of console debug messages to work this out.


Final thoughts

This project turned out to be one of the most satisfying dev projects I’ve worked on in ages, even with the tears. Wix Velo is pretty flexible… if you’re willing to get your hands dirty. (And sometimes, a Wix Velo feature that should work, doesn't work in your very specific use case, and you just have to panic for a bit. Then work around it.)


Another thing this project did was remind me of what I love most about coding: once you figure something out, it doesn’t just solve one problem. It gives you a pattern. And patterns are powerful. Patterns are how my life works. (Of course, breaking out of patterns is also an important skill... but again, that's another blog post).


So, if you’re working in Wix Velo and wondering if you can make it do something that seems too complex: you probably can. Just be prepared to do a little creative problem-solving now and then, because some very reasonable ideas turn out to be things the Velo devs didn’t quite expect anyone to try.

  • RSS
  • LinkedIn
  • itchio-logo-textless-black
  • GitHub-Mark-120px-plus
  • RedBubble
  • youtube
bottom of page