Jump to content

Developer centric form processor


Mike Rockett

Recommended Posts

New Commit: Non-AJAX implementation

Version: 0.5.0

This commit adds support for users without JavaScript enabled, or developers who choose to not use AJAX. Of course, the implementation of non-AJAX forms is different, as the template needs to handle things. The following is a simple example of how to go about using non-AJAX forms:

<?php $response = $simpleForms->response;?>
<?php $old = $simpleForms->oldData;?>

<?php if ($simpleForms->successful): ?>

    <p class="formSuccess message"><?=$response->success;?></p>

<?php else: ?>

    <form data-simpleforms="contact" action="<?=$simpleForms->actionFor('contact');?>" method="POST">
        <?=$simpleForms->csrfToken();?>
        <div data-simpleforms-formerror><?=$response->error;?></div>
        <div class="inputField text">
            <input type="text" name="name" id="name" placeholder="Your name (required)" value="<?=$old->name;?>">
            <div data-simpleforms-fielderror="name"><?=$response->errors->name;?></div>
        </div>
        <div class="inputField text">
            <input type="text" name="email" id="email" placeholder="Your email address (required)" value="<?=$old->email;?>">
            <div data-simpleforms-fielderror="email"><?=$response->errors->email;?></div>
        </div>
        <div class="inputField text">
            <input type="text" name="company" id="company" placeholder="Company name (optional)" value="<?=$old->company;?>">
            <div data-simpleforms-fielderror="company"><?=$response->errors->company;?></div>
        </div>
        <div class="inputField text">
            <input type="text" name="contact" id="contact" placeholder="Contact number (optional)" value="<?=$old->contact;?>">
            <div data-simpleforms-fielderror="contact"><?=$response->errors->contact;?></div>
        </div>
        <div class="inputField textarea">
            <textarea name="message" id="message" cols="30" rows="10"><?=$old->message;?></textarea>
            <div data-simpleforms-fielderror="message"><?=$response->errors->message;?></div>
        </div>
        <div class="inputField submit">
            <input type="submit" data-value="Submit Form">
        </div>
    </form>
    
<?php endif;?>

Of course, there are other things that need to still be taken into account here. For example, using this specific method keeps form error tags visible at all times. The JS module actually hides these when they are not needed (a CSS rule is also needed to hide them when the page loads). However, when not using AJAX, these fields are always available. As such, if you style them (with padding and colour, for example), you'll see them when the page loads. A simple isset() should do the trick.

A suggestion is to always use the above implementation along with the JS one so that both work.

Link to comment
Share on other sites

I'm busy finalising the file upload part, but it appears that the $_FILES global is an empty array when not using AJAX. It works perfectly when AJAX is used, however.

For some context: the front-end plugin now uses JS FormData instead of serialising the data - this adds support for file uploads, and PHP puts these in the $_FILES global as expected. However, if I turn offthe AJAX side of things, the file does get sent (request headers show this), but the global is empty. I need the $_FILES array so that I may only proceed with a WireUpload if files were uploaded (and provided they are allowed).

Any idea what may cause this?

Ah, I do apologise - I left out the enctype="multipart/form-data"

Link to comment
Share on other sites

File upload support is now ready - albeit a few possible oversights. You can grab the latest update from here.

As part of this new feature, several things have changed. Most notably, the template form output now uses $simpleForms for fetching previous input as well as responses. This prevents warnings when using debug mode, and generally looks a lot cleaner and easier to understand. (This is shown at the bottom of the post.)

Of course, the big part of this is that file uploads now work. As described in my previous (greyed out) post, the front-end module now uses FormData, as opposed to simply serialising the form on submission. This allows for AJAX file uploads.

If you'd like to make use of a file field, it needs to be defined in config.json. However, it should not be defined in the "fields" array, as validation etc is handled differently, mostly due to WireUpload, and internal checking to see if the field is actually required.

As can be seen in the config file included in the repo, defining a file is as simple as:

"files": {
    "file": {
        "required": "You need to upload a file",
        "validExtensions": ["pdf", "docx"],
        "maxSize": 4096000
    }
},

Each file field can be declared with a name - the same name used on the HTML form itself - and should be declared with the above rules in place. Of course, the required rule is not necessary if the upload is not required. The maxSize rule is measured in bytes, per the WireUpload standard.

Each field may only take one file for the time being - WireUpload will throw an error otherwise. Will be looking to support multiple files in the future, but this will involve quite a few changes (off the top of my head, I can see it being a little overboard - I could be wrong).

If the uploads are valid, they will be saved in a UID directory in the uploads directory for the form. For example:

site/modules/SimpleForms/forms/contact/uploads/{random_uid}/filename

(Keep in mind that the storage location for form configuration, templates, and uploads will change to the assets directory when the module is ready for production use. Currently, any module upgrades overwrite the forms directory.)

These will then be made available to each of the email templates as linkable downloads through {files.{field}.name} and {files.{field}.url}. See the template examples to see how they can be used.

Lastly, as mentioned at the beginning of this post, there is a new method for declring forms, should you wish to allow them to work without AJAX. I don't think any explanation is required here, so here's the template file example (this is not included in the repo - you'll need to add it to a template yourself).

Documentation

I'm still working on the docs, but won't finish them until such time as the module has reached feature-parity and is mostly stable.

Naming

Have decided to stick with SimpleForms. I still quite like QuickForms, and so the chance of me renaming the module is not lost forver. ;-)

Edited by Mike Rockett
  • Like 2
Link to comment
Share on other sites

SimpleForms Alpha bumped to 0.7.0, with a few chages.
 
Firstly, SimpleForms is now ready for translation. If anyone is willing to translate the module, please go ahead - your contributions are most welcome. Side note: there isn't much to translate at this point, and some messages may change as I go along.
 
Next, template stylesheets are now automatically prepended to each HTML template if found. The way in which this works is simple. If you have a CSS file with the same name as the form being worked with, that stylesheet will be prepended to every HTML template for that form. Of course, if you're not using HTML templates (these are indeed optional), then stylesheets will simply not work. I am considering the possibility of being able to define for each template whether or not it should have the form stylesheet prepended - some templates will not require such a stylesheet. (Input here is also most welcome.)
 
I've also made a few changes (additions, rather) with regards to using forms without AJAX. A few new methods have been added for the rendering of errors. Before, you would simply wrap $simpleForms->fieldError('name') inside a <div data-simpleforms-fielderror="name"/>. The problem that this brings about is that if no error is present, and you have added padding to the error block, it would always be visible. Now, you can use a renderer-method or a has-method to assist. Either of the below will work:


<!-- Render the default field error markup -->
<!-- Result: <div data-sf-fielderror="name">This field is required.</div>

<?= $simpleForms->renderFieldError('name'); ?>

<!-- Or render it yourself, if you want to style the div. -->
<!-- The data-sf-fielderror is completely optional if you wish to not use AJAX. -->

<?php if ($simpleForms->hasFieldError('name'): ?>
    <div data-sf-fielderror="name" ><?= $simpleForms->fieldError('name'); ?></div>
<?php endif; ?>

The same applies for $simpleForms->formError(), where you can use hasFormError() and renderFormError();
 
Note: This change is only for those who specifically choose not to use AJAX, and does not support the dual-approach, where AJAX is enabled, but the visitor does not have JS enabled. If you want to use AJAX (always recommended), then you should always render the error blocks, even if they're empty. Remember that they are used by the front-end module, which hides them when they are not needed, including when the page is loaded.
 
You'll also notice from the above example that the data attributes have been renamed. Instead of the full data-simpleforms-*, simply use data-sf-*.
 
Next on the todo-list: Two major things coming up are support for multi-language form messages (form and field errors, success message) as well as module configuration, which entails being able to set module-wide defaults that affect all forms.
 
@teppo: Thanks for the mention on ProcessWire Weekly today - much appreciated, as always. :)

  • Like 3
Link to comment
Share on other sites

Hi!

I haven't looked into your project in detail yet - but as far as I can tell there is no function to generate the forms in the repository, yet? I had a similar idea today when I was building this module: https://processwire.com/talk/topic/11160-textformattervideoembedoptions/

I don't know if this could actually be helpful for you - also, maybe you can have a look and say what you think if you like to. But Iguess my implementation is pretty simple ... 

I wonder if it makes sense to separate this functionality (to generate forms out of JSON-descriptions) into an standalone module?

cheers,

Steffen

Link to comment
Share on other sites

Hi!

I haven't looked into your project in detail yet - but as far as I can tell there is no function to generate the forms in the repository, yet? I had a similar idea today when I was building this module: https://processwire.com/talk/topic/11160-textformattervideoembedoptions/

I don't know if this could actually be helpful for you - also, maybe you can have a look and say what you think if you like to. But Iguess my implementation is pretty simple ... 

I wonder if it makes sense to separate this functionality (to generate forms out of JSON-descriptions) into an standalone module?

cheers,

Steffen

Hi blynx,

Presently, the module simply processes forms using their config.json files. I have a few things I'd like to do (mentioned previously) before I get to the rendering/generating of the forms. In case you did not see any the previous posts, form rendereing will have support for PW Inputfields, Bootstrap, and Foundation (I may include support for more frameworks - not so sure yet), but the rendering process will be very simple. As this is a developer-centric module, the idea is to leave the form-building side up to the developer/designer.

I have had a look at your question regarding JSON-form-building. SimpleForms (or whatever it is named in future, based on poll results) is really designed for use in front-end templates. I have not given any consideration as yet to allowing other modules to make use of it. Will give it some thought, though.

:)

You could actually have created a poll for this topic using the forum, although that's not obvious at all. Check the "more reply options" button.

Thanks - I only just realised that polls are associated with topics. So "More Reply Options" doesn't do it for me. I have to go to the first post and "Use Full Editor". As I've already created the polls and people have already started voting, I'll just stick with PollMaker for this one. Will use the forum-polls in future.

  • Like 1
Link to comment
Share on other sites

Results for the YAML poll indicate that the most preference is given to its implementation in addition to JSON (with six votes of the ten votes already cast). Will get cracking on this now. It'll work by auto-detecting what is in use, and will give preference to JSON, if both formats are provided for a form. That poll is now closed.

Shortly after, will get to work on multi-language support for validation and other messages.

Then, I'll begin work on the renderer, which may take a while (guess I need to do a bit of research). Anyone with ideas on how to go about it and/or what the config structure should be is more than welcome to contribute them. :)

  • Like 1
Link to comment
Share on other sites

SimpleForms Alpha bumped to 0.8.0, featuring support for YAML configuration (proudly powered by symfony/yaml), in addition to JSON.

You can now use a config.yaml file instead of config.json. Note that that JSON is preferred over YAML in the case that both files exist. An example YAML config file is in the default-forms directory.

As you just noticed, the form directory is no longer named "forms" - it is now named "default-forms". When you install the module, the contents of this directory is copied to site/assets/forms. To me, this seems to be best-practice, considering the fact that the previous directory was wiped out on module upgrade.

Lastly, you may find that, in some situations, selected fields need to be disabled when the form is rendered. For example, a "subject" field may need to be pre-populated based on a GET parameter and, therefor, read only. Often, the readonly attribute is enough, but I think disabled is better. Previously, such a field would be re-enabled after the form was processed and validation errors occurred (you may have noticed that the entire form is disabled when the form is processing). Now, these state of these fields persist by adding data-sf-disabled when the form is prepared by the front-end plugin. This makes the behaviour consistent with the intention.

  • Like 9
Link to comment
Share on other sites

Nice work @Mike Rockett !

I am using my own FormBuilder generally, a config file based form builder :) Six months ago i created a git repo uploaded files but can't finalize it.

If you interest and want to check it maybe you can use some useful things : https://github.com/trk/AvbFormBuilder

It has a validation library and google re-captcha support.

Some of features :

- Form generation

- Mail send

- Validation

- Re-captcha support

- Template support for custom input elements

- etc.. :)

Its working on my side but need to make it better.

  • Like 2
Link to comment
Share on other sites

  • 4 weeks later...
  • 1 month later...

Hi Mr. Rockettman,

is there an estimate when this module will be ready for production? I would love to use it for my projects. It looks very promising.

Hi jmartsch,

Unfortunately, I haven't given this much attention of late, but will be getting back into it in January.

At the moment, I'm busy moving both modules over to their new homes on Github, and publishing the new documentation site for Jumplinks.

Hoping to get the forms module done soon - sorry for the delay.

:)

  • Like 2
Link to comment
Share on other sites

  • 8 months later...
1 hour ago, Joynal said:

@Mike Rockett So your JSON/YML configuration based  form functionality is not ready yet?

Very sorry, but this module was placed on the mantleshelf, but I'll be able to get back into it soon. It does need a complete refactor as well. However, Jumplinks 2 is the priority at the moment.

That said, the basic fundamentals of the module do work, so it is possible to use it. However, I don't recommend using an incomplete module, even if it is functional enough.

Will update the thread when I get back to this.

  • Like 1
Link to comment
Share on other sites

  • 11 months later...

Wanted to continue developing this today, but it appears I've lost the latest source for it. After removing it from GH (can't remember why I did that), I kept a local copy and can't seem to locate it. Will continue looking and re-commit to GH.

I don't want to call it RockettForms anymore (I know we voted). As the module is dev-centric, I'd like to use an apt name, like DevForms or something. Not keen on keeping it as SimpleForms due to possible confusion between Simple Contact Form.

Will update you all when I find the source (it has to be somewhere, right? ?).

Update: I appear to have found it! Will need to do some work on it before I commit a newer version.

  • Like 1
Link to comment
Share on other sites

1 hour ago, Mike Rockett said:

I don't want to call it RockettForms anymore (I know we voted). As the module is dev-centric, I'd like to use an apt name, like DevForms or something. Not keen on keeping it as SimpleForms due to possible confusion between Simple Contact Form.

How about FormCrafter for ProcessWire?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...