{"id":390429,"date":"2026-10-30T13:32:32","date_gmt":"2026-10-30T13:32:32","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/quoteform\/"},"modified":"2026-10-30T13:32:21","modified_gmt":"2026-10-30T13:32:21","slug":"quoteform","status":"publish","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/quoteform\/","author":23572895,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.1.2","stable_tag":"0.1.2","tested":"7.1.4","requires":"6.2","requires_php":"7.4","requires_plugins":null,"header_name":"Quoteform","header_author":"Murad Nasrullayev","header_description":"Multi-step quote calculator and conditional logic forms. Free, with no paid upgrade.","assets_banners_color":"2f5bea","last_updated":"2026-10-30 13:32:21","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/wordpress.org\/plugins\/quoteform\/","header_author_uri":"","rating":0,"author_block_rating":0,"active_installs":10,"downloads":41,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.1.2":{"tag":"0.1.2","author":"miratnasrullayev","date":"2026-10-30 13:32:21","revision":3775354}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3775393,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3775393,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3775393,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3775393,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.1.2"],"block_files":[],"assets_screenshots":[],"screenshots":[]},"plugin_section":[],"plugin_tags":[716,130308,30663,15432,56778],"plugin_category":[59],"plugin_contributors":[284765],"plugin_business_model":[],"class_list":["post-390429","plugin","type-plugin","status-publish","hentry","plugin_tags-calculator","plugin_tags-conditional-logic","plugin_tags-multi-step-form","plugin_tags-price-calculator","plugin_tags-quote-form","plugin_category-utilities-and-tools","plugin_contributors-miratnasrullayev","plugin_committers-miratnasrullayev"],"banners":{"banner":"https:\/\/ps.w.org\/quoteform\/assets\/banner-772x250.png?rev=3775393","banner_2x":"https:\/\/ps.w.org\/quoteform\/assets\/banner-1544x500.png?rev=3775393","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/quoteform\/assets\/icon-128x128.png?rev=3775393","icon_2x":"https:\/\/ps.w.org\/quoteform\/assets\/icon-256x256.png?rev=3775393","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Quoteform is a form builder for one job: working out a price. A visitor picks a\nconfiguration \u2014 three rooms, two bathrooms, express turnaround \u2014 and a quote\ncomes out of it. That is a different problem from a contact form, and Quoteform\nis built for it rather than around it.<\/p>\n\n<p>Conditional logic and multi-step forms are the two features that calculator\nplugins usually keep behind a paid upgrade. Here they are simply part of the\nplugin.<\/p>\n\n<h4>The builder<\/h4>\n\n<ul>\n<li><strong>Fields<\/strong> \u2014 number, slider, text, email, telephone, textarea, dropdown,\nradio, checkboxes, toggle, date, hidden and static HTML content.<\/li>\n<li><strong>Steps<\/strong> \u2014 split a long form into steps, and order both the steps and the\nfields inside them.<\/li>\n<li><strong>Calculations<\/strong> \u2014 named formulas such as <code>subtotal<\/code> and <code>total<\/code>. A\ncalculation may refer to another one, and Quoteform works out the order for\nyou.<\/li>\n<li><strong>Rules<\/strong> \u2014 conditional logic. Show or hide a field or a whole step, or make a\nfield required or optional, based on what has been answered. Conditions use\nequals, does not equal, greater than, greater than or equal, less than, less\nthan or equal, contains, does not contain, is empty and is not empty.<\/li>\n<li><strong>Settings<\/strong> \u2014 currency, currency position and the number of decimal places.<\/li>\n<\/ul>\n\n<h4>Showing a form to visitors<\/h4>\n\n<p>A saved form can be placed on the site in three ways, and all three draw exactly\nthe same form:<\/p>\n\n<ul>\n<li><strong>Shortcode<\/strong> \u2014 <code>[quoteform id=\"12\"]<\/code>, where <code>12<\/code> is the id shown in the form\nlist. It works in posts, pages and any widget or template that runs\nshortcodes.<\/li>\n<li><strong>Block<\/strong> \u2014 search the block inserter for <strong>Quote form<\/strong>, then pick the form\nfrom the dropdown in the block itself.<\/li>\n<li><strong>Elementor<\/strong> \u2014 the <strong>Quote form<\/strong> widget, under General. It appears only when\nElementor is installed.<\/li>\n<\/ul>\n\n<p>On the page, the visitor moves through the steps with Back and Next. The total\nupdates as they answer, fields and steps appear and disappear as the rules say\nthey should, and a required field they can see has to be filled in before Next\nwill move them on. On the last step the total is broken down into the\ncalculations that make it up.<\/p>\n\n<h4>Submissions and entries<\/h4>\n\n<p>On the last step the visitor submits the form. The server then works out the\nprice again from the answers alone. The browser never sends a total, so a\nvisitor cannot change the price that gets stored.<\/p>\n\n<ul>\n<li><strong>After a submission<\/strong> \u2014 show a message with the total and its breakdown, or\nredirect the visitor to a URL. You choose this per form.<\/li>\n<li><strong>Spam protection<\/strong> \u2014 a hidden honeypot field and a time check signed by the\nserver. No CAPTCHA and no external service.<\/li>\n<li><strong>Entries screen<\/strong> \u2014 every submission is stored in your WordPress database\nand listed under <strong>Quoteform \u2192 Entries<\/strong>. Filter by form, new or read, date\nand total. Open an entry to see each answer and the price breakdown.<\/li>\n<li><strong>Bulk actions<\/strong> \u2014 mark entries as read or unread, or delete them.<\/li>\n<li><strong>CSV export<\/strong> \u2014 export the entries that match the current filters.<\/li>\n<\/ul>\n\n<h4>What this version does not do<\/h4>\n\n<p>Quoteform does not send email notifications, does not take payments and does\nnot let a visitor save a form and come back to it later. Entries are only on\nthe Entries screen and in the CSV export.<\/p>\n\n<h4>Formulas, without writing code<\/h4>\n\n<p>Formulas are written in a small, deliberately limited expression language:<\/p>\n\n<pre><code>{room_count} * 50 + {bathrooms} * 120\n\nif({urgency} == \"express\", {subtotal} * 1.3, {subtotal})\n\nround(max({subtotal}, 99), 2)\n<\/code><\/pre>\n\n<p>The available functions are <code>if<\/code>, <code>min<\/code>, <code>max<\/code>, <code>sum<\/code>, <code>round<\/code>, <code>ceil<\/code>, <code>floor<\/code>,\n    abs, <code>contains<\/code> and <code>is_empty<\/code>. The formula editor checks each formula as you\ntype: it tells you where a formula is malformed, and when a formula refers to\nsomething the form does not have it says so \u2014 and if the name is close to one\nthat does exist, it asks whether that is what you meant.<\/p>\n\n<h4>Nothing is ever executed<\/h4>\n\n<p>The expression language is not JavaScript and it is not PHP. Formulas are read\nby Quoteform's own parser into a syntax tree and evaluated one node at a time.\nPHP's <code>eval()<\/code> and JavaScript's <code>eval()<\/code> and <code>Function()<\/code> are not used anywhere\nin this plugin. The JavaScript that ships is checked before every release for\nevery spelling of both \u2014 <code>eval()<\/code>, <code>Function()<\/code> and <code>new Function()<\/code> \u2014 so the\npromise is kept by a machine rather than by memory.<\/p>\n\n<p>Every form is validated again on the server when it is saved, no matter what the\nbrowser sent. Circular references between calculations are refused at save time\nrather than discovered later.<\/p>\n\n<h4>Light on the front end<\/h4>\n\n<p>The front-end script is under 10 KB gzipped and loads no framework: no React,\nno jQuery, no web fonts, no CDN. It is enqueued only on pages that actually\ncontain a form.<\/p>\n\n<h4>Free, and that is the whole plan<\/h4>\n\n<p>No pro version, no add-ons, no license key, no account and no hosted service.\nQuoteform sends no data anywhere: it makes no request to any external server,\nloads no fonts or scripts from a CDN, and collects no usage statistics.<\/p>\n\n<h4>Privacy<\/h4>\n\n<p>Submitted entries stay in your own WordPress database. Each entry stores the\nanswers, the calculated total and its breakdown, the date, the visitor's\nbrowser user agent and, if the visitor was logged in, their user ID. The\nvisitor's IP address is stored only if you turn on <strong>Store the visitor's IP\naddress with each entry<\/strong> in the form settings. It is off by default.<\/p>\n\n<p>The answers can contain personal data, such as a name or an email address,\nwhen your form asks for it. Mention this in your site's privacy policy.<\/p>\n\n<h3>Source code<\/h3>\n\n<p>The JavaScript and CSS in <code>build\/<\/code> are compiled. Their human-readable source\nlives in <code>admin-src\/<\/code> and <code>frontend-src\/<\/code> of the public repository:<\/p>\n\n<p>https:\/\/github.com\/muradNasrullayev\/quoteform<\/p>\n\n<p>To rebuild the assets from source:<\/p>\n\n<ol>\n<li><code>npm install<\/code><\/li>\n<li><code>npm run build<\/code><\/li>\n<\/ol>\n\n<p>PHP dependencies are installed with <code>composer install --no-dev<\/code>.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Install the plugin from the Plugins screen in WordPress, or upload the\n   quoteform folder to <code>wp-content\/plugins\/<\/code>.<\/li>\n<li>Activate it on the Plugins screen.<\/li>\n<li>Open <strong>Quoteform<\/strong> in the admin menu and create your first form.<\/li>\n<li>Put the form on a page with the <strong>Quote form<\/strong> block, the <code>[quoteform id=\"\u2026\"]<\/code>\nshortcode or the Elementor widget.<\/li>\n<\/ol>\n\n<p>Activating the plugin gives administrators three capabilities:<\/p>\n\n<ul>\n<li><code>qform_manage_forms<\/code> \u2014 create and edit forms, and delete entries.<\/li>\n<li><code>qform_view_entries<\/code> \u2014 see the Entries screen.<\/li>\n<li><code>qform_export_entries<\/code> \u2014 export entries to CSV.<\/li>\n<\/ul>\n\n<p>They are deliberately separate from <code>manage_options<\/code>, so you can grant them to\nanother role without handing over the rest of the site settings.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"is%20it%20really%20free%3F\"><h3>Is it really free?<\/h3><\/dt>\n<dd><p>Yes. There is no paid version to upgrade to, no add-ons to buy, no license key\nto enter and no account to create. Nothing in the plugin is locked.<\/p><\/dd>\n<dt id=\"can%20visitors%20submit%20the%20form%3F\"><h3>Can visitors submit the form?<\/h3><\/dt>\n<dd><p>Yes. The submission is stored as an entry in your WordPress database, and you\nsee it under <strong>Quoteform \u2192 Entries<\/strong>. The price is calculated again on the\nserver, so the stored total is always the one your formulas give.<\/p><\/dd>\n<dt id=\"will%20i%20get%20an%20email%20when%20someone%20submits%20a%20form%3F\"><h3>Will I get an email when someone submits a form?<\/h3><\/dt>\n<dd><p>Not in this version. Check the Entries screen, or export the entries to CSV.<\/p><\/dd>\n<dt id=\"do%20i%20need%20elementor%2C%20divi%20or%20a%20page%20builder%3F\"><h3>Do I need Elementor, Divi or a page builder?<\/h3><\/dt>\n<dd><p>No. The builder is an ordinary WordPress admin screen, and the shortcode and the\nblock need nothing beyond WordPress itself. The Elementor widget is there for\nsites that already use Elementor.<\/p><\/dd>\n<dt id=\"my%20form%20is%20loaded%20by%20a%20popup%20or%20by%20ajax%20and%20stays%20empty.%20what%20now%3F\"><h3>My form is loaded by a popup or by AJAX and stays empty. What now?<\/h3><\/dt>\n<dd><p>A form that arrives after the page has finished loading has to be started. Call\n    window.quoteform.boot() once the markup is in the page:<\/p>\n\n<pre><code>window.quoteform.boot();\n<\/code><\/pre>\n\n<p>Pass an element to limit it to that part of the page \u2014 <code>window.quoteform.boot(\ndocument.querySelector( '#my-popup' ) )<\/code>. Calling it again is safe: a form that\nis already running is left alone.<\/p><\/dd>\n<dt id=\"can%20a%20formula%20run%20arbitrary%20code%3F\"><h3>Can a formula run arbitrary code?<\/h3><\/dt>\n<dd><p>No. Formulas are written in Quoteform's own small expression language, which has\nnumbers, text, comparisons, arithmetic and ten named functions \u2014 and nothing\nelse. They are parsed into a syntax tree and evaluated by the plugin. <code>eval()<\/code> is\nnot used, in PHP or in JavaScript, anywhere in the plugin.<\/p><\/dd>\n<dt id=\"what%20happens%20to%20my%20forms%20if%20i%20deactivate%20the%20plugin%3F\"><h3>What happens to my forms if I deactivate the plugin?<\/h3><\/dt>\n<dd><p>Nothing is deleted. Forms are stored as WordPress posts, so they are still there\nwhen you activate the plugin again. Deactivating does not remove the\ncapabilities it granted either, so a site that is temporarily switched off comes\nback exactly as it was.<\/p><\/dd>\n<dt id=\"and%20if%20i%20delete%20the%20plugin%3F\"><h3>And if I delete the plugin?<\/h3><\/dt>\n<dd><p>Deleting is not the same as deactivating. <strong>Deleting Quoteform permanently\ndeletes every form you have made and every entry submitted to them<\/strong>, including\nforms in the trash, and removes\n    qform_manage_forms, <code>qform_view_entries<\/code> and <code>qform_export_entries<\/code> from every\nrole on the site. On a multisite network it does this on every site of the\nnetwork, because the forms and the roles live on each site separately. Nothing\nis recoverable afterwards, so export your entries to CSV and copy anything else\nyou want to keep before you click Delete.<\/p><\/dd>\n<dt id=\"who%20can%20create%20and%20edit%20forms%3F\"><h3>Who can create and edit forms?<\/h3><\/dt>\n<dd><p>Anyone with the <code>qform_manage_forms<\/code> capability, which administrators get when\nthe plugin is activated. The same capability is required by the REST endpoints\nunder <code>quoteform\/v1<\/code> that the builder uses, so there is no way around it.<\/p><\/dd>\n<dt id=\"which%20languages%20does%20it%20speak%3F\"><h3>Which languages does it speak?<\/h3><\/dt>\n<dd><p>The interface is written in English and is fully translatable \u2014 every string in\nboth the PHP and the JavaScript goes through WordPress's translation functions,\nand a <code>.pot<\/code> file ships in <code>languages\/<\/code>.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.1.2<\/h4>\n\n<ul>\n<li>The readme now describes submissions, the Entries screen, CSV export and the\ndata each entry stores.<\/li>\n<li>Removed the \"save and resume\" option from the form settings. The feature is\nnot implemented yet.<\/li>\n<\/ul>\n\n<h4>0.1.1<\/h4>\n\n<ul>\n<li>Fix: the entries table install no longer records its version when the table\ncould not be created, so it is retried on the next load.<\/li>\n<li>Fix: the entries table definition is compatible with MySQL versions before\n8.0.13.<\/li>\n<li>Security: the CSV export reads only the parameters it needs and sanitizes\neach one.<\/li>\n<li>The uninstall routine runs only when WordPress itself uninstalls the plugin.<\/li>\n<\/ul>\n\n<h4>0.1.0<\/h4>\n\n<ul>\n<li>First release.<\/li>\n<li>Form builder: fields, steps, calculations, conditional rules and form\nsettings.<\/li>\n<li>Expression language for pricing formulas, validated as you type in the editor\nand again on the server when the form is saved. The formula editor suggests\nthe name you probably meant when a reference is a near miss.<\/li>\n<li>Front-end renderer: multi-step navigation, conditional show and hide, a live\ntotal, a breakdown on the last step, and per-step validation of the fields the\nvisitor can actually see. No React and no jQuery.<\/li>\n<li>Three ways to place a form: the <code>[quoteform id=\"\u2026\"]<\/code> shortcode, the <strong>Quote\nform<\/strong> block and an Elementor widget. All three render the same form.<\/li>\n<li><code>window.quoteform.boot()<\/code> for forms that arrive after the page has loaded.<\/li>\n<li>REST API under <code>quoteform\/v1<\/code> for the builder, gated by the\n  qform_manage_forms capability.<\/li>\n<\/ul>","raw_excerpt":"Build multi-step quote and price calculator forms with conditional logic, and collect the quotes your visitors submit. Free, with no paid upgrade.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/390429","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=390429"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/miratnasrullayev"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=390429"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=390429"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=390429"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=390429"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=390429"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=390429"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}