COS WP Woo
Back to blog

Drag-and-drop form builder: tickets and surveys without Contact Form 7

Contact Form 7 + five addons for one form? I’ll tell you how we built a visual form designer with drag-and-drop, conditional logic and application storage directly into the WooCommerce plugin.

Last week I was counting plugins on one of my client sites. An ordinary WooCommerce store, industrial equipment, nothing exotic. And so I look at the list of active plugins - and there is Contact Form 7 for one feedback form, Conditional Fields, Flamingo for storing applications, File Upload for uploading files, and the cherry on the cake - some kind of paid add-on for beautiful design, because the standard CF7 forms look like they were made up in 1998. Five plugins. Five potential points of failure. Five update sources, each of which can break something. And all this so that the client can write “I want to know the price of hydraulic oil, here is my phone number.”

Then I thought - why did this happen? Why is the WordPress community accustomed to the fact that to solve one problem you need to assemble a constructor from five or six different plugins, each of which is written by a different author, updated at different times and compatible with others only as long as no one has updated anything? After all, a feedback form is seemingly one of the most basic things on the Internet. The person filled out the fields, pressed a button, and the data was sent to the manager. What's so difficult about it? But if you dig a little deeper - add conditional logic, file loading, storing requests in the database, normal notifications - and a simple task turns into an engineering project for integrating a zoo of extensions.

It was this experience that pushed us to create our own form builder inside COS WP Woo. Not just another plugin for forms - the world has seen enough of them - but a built-in module that solves the problem entirely. With a visual drag-and-drop builder, conditional logic, application storage, email notifications and insertion via shortcode. All in one, no dependencies, no version conflicts, no annual subscriptions for each addon separately. And today I want to tell you how it works from the inside, why we made these decisions and how our approach differs from what everyone is used to.

But before we dive into the technical details, let's be honest about what's wrong with existing solutions. Not to offend anyone - Contact Form 7 has done a great job for the WordPress ecosystem and deserves respect. But it is understanding the problems that helps to assess why an alternative is needed at all.

Contact Form 7 is a plugin that was released in 2007. Nineteen years ago. Since then, it has been downloaded more than 340 million times and is used on millions of sites. But here's the thing - its architecture has remained essentially the same. Forms are described using text templates with tags like [text* your-name] and [email* your-email]. No visual editor. No preview. You write the form code in the text field, save it, go to the page and see whether it looks like what you wanted or not. And so on in a circle. For a developer this is tolerable. For a manager or marketer who wants to change a form on a website, this is a wall. An impenetrable wall of square brackets and incomprehensible parameters.

And this is just the beginning. Do you want one field to show depending on the selection in another? Set Conditional Fields. Do you want applications to be stored in a database and not just sent to the post office? Put Flamingo. Do you want the client to be able to attach a PDF or photo? Set File Upload. Do you want normal styles? Install CF7 Skins or write CSS manually. Each of these tasks is a separate plugin with a separate author, a separate update cycle and a separate license. On one project, I counted seven plugins related to Contact Form 7. Seven. And the project manager complained that after updating WordPress to 6.5, three forms stopped working because one of the addons was incompatible. Is this a familiar story?

Of course, there are paid alternatives - WPForms, Gravity Forms, Formidable Forms. They solve many of the problems of CF7: visual editor, conditional logic, application storage - all in one package. But they ask for money for this. WPForms Pro - $199/year. Gravity Forms - $259. And this is for one site. If you have ten projects, multiply them. And if at the same time you also need WooCommerce extensions for B2B, search, delivery, security - the budget for plugins begins to look indecent. I worked with a company that paid a total of more than fifteen hundred dollars a year just for plugins. And the forms were far from the most expensive item.

Why build forms inside a WooCommerce plugin

To be honest, when we were planning the forms module for COS WP Woo, there were disputes within the team. The argument against it sounded something like this: “Forms are a separate universe, why drag them into an e-commerce plugin?” And the argument was not without meaning. Forms are a really complex topic, they have their own UX patterns, their own security requirements (CSRF, XSS, validation), and their own data storage nuances. But the more I worked with real WooCommerce stores, the clearer it became: forms are an integral part of an online store. Not something external, bolted on the side, but an organic element.

Think for yourself. CP Request Form - Where should it lead? In the CRM of a sales manager, which is tied to WooCommerce. Application form for selection of an analogue - she must know about the product catalog. Callback form - it should appear in the context of the product page. Satisfaction survey form - it is tied to the order. All these are not abstract “forms on the website”, but elements of the trading process. And when they live in a separate plugin, you lose context. The manager sees the request in Flamingo, but does not see which page it came from or what product the client was looking at. Or he sees it, but through crutches - hidden fields, UTM tags, passing parameters via URL. It all works as long as it works. And then it breaks, and no one understands why.

So we decided: forms are part of the platform. Not an addon, not an integration, but a built-in module that knows everything about the WooCommerce context. Which stores data in the same custom tables as other modules. Which sends email through the same SMTP module that is already configured in the plugin. Which is controlled through the same React interface that the administrator is used to. This decision determined the architecture of everything that came next.

Now let's talk about how this works in practice. Because architectural solutions are great, but something else is more important to the site administrator: how quickly he can create a form, publish it on the page and start receiving applications.

When you open the Forms module in the COS WP Woo admin (path: Store - Forms), you see a list of all forms. This is a table with names, number of fields, status and number of applications received. Everything is simple and clear. Click “Create Form” and you will be taken to the full-screen designer. And this is where the fun begins.

Full screen mode is a conscious decision. We experimented for a long time with different approaches: a built-in editor in the sidebar, a modal window, a separate page in the standard WordPress layout. And we came to the conclusion that the form designer should occupy the entire screen. Why? Because you are building a visual object. You need to see what the shape will look like in actual scale. You need space to drag fields, to set conditions, to preview. The builder squeezed into the WordPress sidebar is like painting a picture through a keyhole. It's possible, but why?

Fullscreen canvas and dragging fields

The designer is divided into three zones. On the left is a panel of available field types. In the center is the form canvas, where the fields are located in the order in which the user will see them. On the right is the settings panel for the selected field. This three-column layout is familiar to anyone who has worked with Figma, Canva or even PowerPoint. This is an intuitive pattern that does not require training.

The available field types cover almost all scenarios that I have encountered in real projects. Text field - for name, subject of appeal, free comment. Numeric field - for quantity, volume, budget. Email - with automatic format validation. Phone - with an input mask so that the number is received in a uniform format. Textarea - for expanded messages. Drop-down list (Select) - when you need to limit the choice to specific options: type of equipment, delivery region, communication method. Checkboxes for multiple selection: services of interest, desired characteristics. Radio buttons - when you need to select exactly one option. Date - with a calendar to select the desired delivery or consultation date. File upload - for drawings, technical specifications, photographs. And even a signature field - for mobile users who can sign with their finger directly on the screen. This, by the way, turned out to be unexpectedly in demand in the forms of acceptance certificates and applications for warranty repairs.

Each field is a React component that is rendered on the canvas exactly as a site visitor will see it. No “preview in a new tab” - you see the result right as you work. We dragged the field from the left panel onto the canvas and it appeared. Click on it and the settings open on the right: label, placeholder, mandatory, width (full or half for two-column layouts), default value, tooltip text. All this changes in real time - we adjusted the label on the right, and it was immediately updated on the canvas.

To implement drag-and-drop, we use the @hello-pangea/dnd library - this is a fork of @hello-pangea, which itself is a continuation of react-beautiful-dnd from Atlassian. The choice is not random. We tried several options: react-dnd, dnd-kit, Sortable.js with a React wrapper. Each had its advantages, but @hello-pangea/dnd won based on a combination of factors. It provides excellent tactile feedback - the element “takes off” from the panel, follows the cursor, and a placeholder appears on the canvas, showing where the element will go. It works correctly with touch screens - which is important because more and more people are managing websites from tablets. And it does not require writing your own collision algorithms, which would have to be configured manually in dnd-kit.

But the visual designer is only the external part. Under the hood, each form is a JSON structure that stores a description of all fields, their order, settings and validation rules. When you save the form, this JSON is saved to the wpaic_forms table. When a visitor opens a page with a form, the PHP code on the backend reads the JSON and generates HTML with the correct markup, validation, and JavaScript handlers. This means that the form works even if the React part of the plugin is not loaded - it is completely server-side on the front end. No rendering delays, no SEO issues.

And here I want to touch on a point that many form creators ignore. Live preview is more than just a convenience. This is error prevention. When a manager builds a form in text mode, as in CF7, he does not see the result. He's guessing. And then he is surprised that the “Comment” field appears before the “Name” field, or that the checkboxes are arranged in a column instead of a row, or that on mobile the form looks like a long sheet. With a visual designer, these mistakes are impossible - you see exactly what the client will see. And it saves hours. I know because I spent those hours myself fiddling with CF7 templates and refreshing the page in the browser over and over again.

Now let's talk about what makes forms truly powerful - conditional logic. Submit an application form for oil selection. First question: “Equipment type” - drop-down list: Automobiles, Industrial equipment, Hydraulics, Other. If the customer selects "Cars", the "Make" and "Model" fields appear. If you select “Industrial equipment”, “Mechanism type” and “Operating conditions” appear. If "Other" is a text field for a free description. Without conditional logic, you would have to show all the fields at once, and the form would turn into a two-page questionnaire, which the client will run away without filling out.

In Contact Form 7, this requires a separate Conditional Fields plugin, which works through CSS hacks and JavaScript handlers, which often conflict with other scripts on the page. We built conditional logic directly into the constructor. In the settings of each field there is a section “Display conditions”. You simply select: “Show this field if the [Equipment Type] field is [Vehicles].” Or “Hide this field if the [Budget] field is less than 10000.” You can combine several conditions using “AND” or “OR”. The interface for this is a visual rule builder, similar to the one we use for custom fields in the CF module. No code, no text formulas.

Conditional logic is handled client-side via JavaScript, which is automatically generated from the JSON form description. This means that fields appear and disappear instantly, without reloading the page, without AJAX requests. The user selected an option in the list, and the required fields smoothly appeared. I chose another one - the previous ones disappeared, new ones appeared. This creates the feeling of an interactive interface rather than a static HTML form. And, importantly, hidden fields do not participate in validation - if a field is hidden by a condition, it will not be considered required, even if it is marked as required. This is a subtle point where many implementations stumble.

I remember a project where we were using WPForms with conditional logic, and we encountered a bug: a hidden required field was blocking the form from submitting because its validation was triggered even when the field was invisible. The client could not submit the form and left. We lost applications until we figured it out and wrote a crutch in JavaScript. This is one of those lessons that stays with you for a long time. Therefore, in our implementation, hidden fields are excluded from validation at the architectural level - this is not a bug fix, but a fundamental rule.

Applications - not to mail, but to database

Now we come to a topic that, in my opinion, is the main weak point of Contact Form 7 and similar free solutions. Where do the applications go? In CF7 the answer is simple - by email. The application arrived and I sent an email to the manager. Dot. No email - no application. And email servers tend to lose letters. Spam filters tend to block notifications from WordPress, especially if the server is not configured perfectly - no SPF record, no DKIM, no DMARC. I personally know of three cases where a business lost applications for weeks because notifications from Contact Form 7 ended up in spam on the mail server. And no one knew about it until clients started calling with complaints: “I left a request, why didn’t anyone call back?”

Flamingo solves this problem - it stores tickets in a WordPress database. But this is a separate plugin, with its own interface, its own storage logic and its own limitations. Applications are stored as custom posts (post_type), which creates a load on the wp_posts table, which is already bloated on large sites. On one of our projects with 16 thousand products, the wp_postmeta table weighs 937 megabytes - and adding requests from forms there would be madness.

We went a different route. All applications are stored in a custom table wpaic_form_entries. This is a dedicated table with an optimal structure: record ID, form ID, request data in JSON format, creation date, status (new, read, in progress, closed), sender IP address, User-Agent, user ID (if authorized). A custom table is not a whim, it is a conscious architectural decision. It doesn't clog wp_posts, has the right indexes for quick searching and filtering, and scales linearly—ten thousand submissions are as fast as ten.

In the administrative interface, requests are displayed in a convenient table with the ability to filter by form, status, date, and full-text search. You can find all applications containing the word "hydraulics", or all applications from the past week, or all unread applications for a specific form. You can open each application, see all the data in a beautiful format, download attached files, change the status, and add an internal comment.

And, of course, export. Forms without export are like CRM without reports. No use. We support export to CSV with field selection, filtering by date and status. We uploaded the CSV, opened it in Excel or Google Sheets, and analyzed which products are requested more often, which regions applications come from, which forms convert better. This is the data you lose when applications only live in the mail.

There is another nuance that is rarely talked about. When applications are stored in a database, you have auditing. You know exactly how many applications have been received. Not “approximately”, not “judging by the mail”, but exactly. The manager cannot say “there was no application” - it is recorded in the system with date, time, IP address and all the data. This is especially important for B2B companies, where each application can cost hundreds of thousands of rubles. Losing such an application due to a spam filter is not just an inconvenience, it is a direct loss.

But let's be honest - email notifications are needed too. Not all managers will log into the WordPress admin every hour to check for new applications. Therefore, we have implemented a double system: the application is always saved in the database (this is a guarantee), and at the same time an email notification is sent (this is efficiency). Moreover, the email is sent through the built-in SMTP module COS WP Woo, which you configure once in the Email Settings section. No separate SMTP plugins, no WP Mail SMTP for $49/year. One SMTP module for everything - order notifications, application notifications, security notifications.

Email notifications are customizable. For each form, you define: who to send the notification to the manager (several addresses are possible), what template to use, what data to include. And separately - a notification to the client: “Thank you, your application has been accepted, we will contact you within 24 hours.” The client notification is sent to the email specified in the “Email” type field - the plugin automatically determines which field contains the recipient’s address. Email templates - HTML with placeholders: {{field_name}}, {{form_title}}, {{submission_date}}. You can customize the appearance, add a company logo and contact information. We did not write a universal template engine, but a target tool for a specific task - therefore it works predictably and does not break due to non-standard designs.

I’ll tell you about another technical solution that may seem like a small thing, but in practice it saves nerves. Uploading files. In Contact Form 7 with the File Upload plugin, files are attached to emails as attachments. This works until someone sends a 25 megabyte file that your email server won't let through. Or by 50 megabytes - then PHP will crash with a memory limit error. With us, files are uploaded to a protected directory on the server (outside public access so that robots do not download client documents) and are linked to the application record by ID. You will receive a download link in your email, which only works for authorized administrators. It is safer, more reliable and does not depend on mail server restrictions. The client can attach a 50 megabyte drawing - and the manager will receive it, guaranteed.

Now - shortcodes. It would seem, what is there to discuss here? [wpaic_form id="42"] - and the form appeared on the page. But the devil, as always, is in the details. A shortcode can be inserted into a post, a page, a widget, a pop-up plugin, a theme template, even a WooCommerce product description. The form adapts to the container - if the container is narrow (sidebar or popup), the form switches to single-column mode. If wide (full screen page), fields set to half width will appear in two columns. This is responsive behavior that works out of the box. You don't have to worry about CSS media queries—the designer takes care of it.

You know what always annoyed me about CF7's approach to shortcodes? There, the shortcode is the only way to insert it. No Gutenberg block, no Elementor widget. Shortcode and that's it. In 2026. We also started with a shortcode - this is the most universal WordPress mechanism that works everywhere. But our shortcode is smart: it accepts parameters to customize the appearance. You can set a theme (light, dark, transparent), you can hide the form title, you can set custom text for the submit button. And all this without a single line of CSS - through shortcode attributes.

Fair comparison: us, WPForms, Gravity Forms and CF7

I promised an honest comparison, so let's do it without marketing nods. Each solution has its own strengths, and I'm not going to pretend that our builder is perfect.

Contact Form 7 - free, lightweight, time-tested. If you need one simple form without conditional logic and without storing applications, CF7 can handle it. All WordPress developers know it, thousands of guides have been written for it. But as soon as the task becomes a little more complicated “name-email-message”, the zoo of plugins begins. And the cost of this zoo in supporting and debugging conflicts often exceeds the cost of any paid solution.

WPForms is a great plugin with a great visual editor. Their drag-and-drop is one of the best on the market. Conditional logic, application storage, integration with CRM - everything is there. But WPForms is a separate plugin that solves only the problem of forms. It doesn't know about your WooCommerce catalog, isn't integrated with your shipping system, and doesn't use your SMTP module. He exists in his own bubble. And it costs $199 per year for the Pro version, which is needed for conditional logic and file uploading. Over 5 years - a thousand dollars just for forms.

Gravity Forms is perhaps the most powerful form builder for WordPress. Multi-step forms, calculations, integrations with payment systems, Webhooks, an amazing ecosystem of addons. But this power comes at a price—both in dollars (259 per year for an Elite license) and in complexity. Gravity Forms can do it all, but setting it all up takes time and expertise. For simple feedback forms, it's like shooting sparrows from a cannon.

Our form builder in COS WP Woo is the golden mean. It is not intended to replace Gravity Forms in scenarios with complex calculations or multi-step surveys with hundreds of questions. But it covers the real needs of a WooCommerce store one hundred percent. Feedback forms, selection requests, CP requests, satisfaction surveys, questionnaires for B2B registration - all this is built in minutes in a visual constructor. Moreover, the forms are part of a single platform. They use common SMTP, are stored in optimized custom tables, and are managed from the same interface as all other modules. And they don't cost extra money - they are included in the COS WP Woo license.

Let me give you a concrete example from practice. The client is a distributor of industrial oils. He needs three forms. The first is “Request price” on product pages: name, company, phone, email, drop-down list “Batch volume” (from 20 to 200 liters, from 200 to 1000, from 1000), comment. The second is “Selection of an analogue” on the catalog page: equipment type (conditional logic for additional fields), current oil (text), desired characteristics (checkboxes), file upload (TOR or equipment passport). The third is “Become a partner” on the “Cooperation” page: company details, TIN (with length validation), region, volume of purchases, uploading constituent documents.

With Contact Form 7, this project would have taken: CF7 + Conditional Fields + Flamingo + File Upload + styling = 5 plugins and at least 3 hours of customization (including CSS editing). With WPForms Pro - 1 plugin, $199 per year, and about an hour of setup. With our builder - 0 additional plugins, 0 additional costs, and about 40 minutes in the visual builder. Moreover, all three forms are immediately integrated with SMTP, applications are stored in a single database with search and export, and the manager sees them in the same interface where he manages everything else.

I want to talk about one more aspect that is often missed when comparing. Performance. Contact Form 7 loads its styles and scripts on every page of the site, even if there is no form on it. This is a known problem that can be solved either by additional plugins (Asset CleanUp, Perfmatters) or by manually editing the code. WPForms only loads assets on form pages, but its JavaScript bundle weighs 60-80 KB when minified. Our forms are rendered on the server as pure HTML with minimal JavaScript for conditional logic and validation. CSS forms - 5 KB, JavaScript - 8 KB. And they only load on pages where the form shortcode is actually present. For a store with 16 thousand product pages, the difference is noticeable - every extra kilobyte of CSS and JS is multiplied by thousands of pages in the cache, by parsing time in the browser, by Core Web Vitals.

I would also like to mention security. Forms are an entry point for attackers. SQL injections through input fields, XSS through text fields, CSRF attacks through form substitution, spam bots that flood thousands of applications per minute. We process all data through WordPress sanitization functions: sanitize_text_field(), sanitize_email(), wp_kses_post() for HTML fields. Each form is protected by a nonce token. Uploaded files are checked by MIME type and extension - you won't be able to upload a PHP file even if you rename it to .jpg. And if you have the Security module activated in COS WP Woo, then WAF additionally checks all incoming data for patterns of SQL injections and XSS attacks. This is an integration that is not possible when forms and security are different plugins from different authors.

And the last thing I want to say about the technical device. The architecture of the forms module follows the same pattern as all other COS WP Woo modules: PHP service (FormService) for business logic, REST controller (FormController) for the API, React page (FormBuilder) for the interface. The service is registered in class-plugin.php, endpoints work through namespace wpaic/v1, data is stored in custom tables. If you are familiar with the architecture of our plugin, you already know how the forms work. If not, forms are a great entry point because they show the pattern in its purest form: from the JSON description of the form via the REST API to rendering on the front end.

When our constructor is not enough

I don't want to end this article on the marketing note of "our solution is the best." It wouldn't be fair. There are scenarios for which our form builder is not the best choice.

If you need multi-step forms with dozens of steps, a progress bar and saving intermediate results, take a look at Gravity Forms. They have implemented this maturely and reliably. If you need integration with a CRM like HubSpot, Salesforce or AmoCRM out of the box, WPForms and Gravity Forms have ready-made addons, but we will have to use Webhooks or write a custom integration. If you need payment forms with Stripe or PayPal integration directly in the form, this is not our scenario; for this we have a full-fledged WooCommerce checkout with a payment module. If you are building a complex questionnaire with 100 questions with branching and scoring, you need a specialized tool like Typeform or Google Forms.

But if you are the owner or administrator of a WooCommerce store and you need working forms for feedback, tickets, CP requests, surveys with conditional logic, file uploads and database storage - our form builder will do it faster, more reliable and cheaper than any combination of CF7 + addons or an annual subscription to WPForms Pro.

And do you know what was the most convincing proof for me that we are on the right path? Not technical metrics, not the number of field types, not comparison tables with competitors. And that moment when the manager of a client project - a person who was afraid to “get into the code” all his life - put together an application form with conditional logic in twenty minutes, inserted it onto three pages via a shortcode, and the next day came with the question: “Can I make another form for a survey? I already roughly understand how.” This is a real indicator of the quality of the tool - when a person does not need instructions, does not need a developer, and does not need five plugins for one form.

Try COS WP Woo and build your first form in five minutes. The Forms module is available in the Store - Forms section. Drag and drop fields, set up conditions, insert a shortcode on the page - and start receiving applications that are guaranteed to reach the manager.