Jump to content

FrontendForms - A module for creating and validating forms on the frontend


Juergen

Recommended Posts

I have created a fresh install with the beginner theme, but I am not able to reproduce your errors.

1820091749_Screenshot2022-05-11at16-40-35About.thumb.png.55cefaf8a659705053c148031fa420c8.png

I have integrated the code inside the basic-page and as you can see the form is still there and it works.

Here is the complete code of the basic page (templates/basic-page.php):

<?php

namespace ProcessWire;

/** @var Page $page */

include('./_head.php'); // include header markup ?>

    <div id='content'><?php

        // output 'headline' if available, otherwise 'title'
        echo "<h1>" . $page->get('headline|title') . "</h1>";


        $form = new \FrontendForms\Form('contactform');

    $gender = new \FrontendForms\Select('gender');
    $gender->setLabel('Gender');
    $gender->addOption('Mister', 'Mister');
    $gender->addOption('Miss', 'Miss');
    $form->add($gender);

    $surname = new \FrontendForms\InputText('surname');
    $surname->setLabel('Surname');
    $surname->setRule('required');
    $form->add($surname);

    $name = new \FrontendForms\InputText('lastname');
    $name->setLabel('Last Name');
    $name->setRule('required');
    $form->add($name);

    $email = new \FrontendForms\InputText('email');
    $email->setLabel('E-Mail');
    $email->setRule('required');
    $email->setRule('email');
    $form->add($email);

    $subject = new \FrontendForms\InputText('subject');
    $subject->setLabel('Subject');
    $subject->setRule('required');
    $form->add($subject);

    $message = new \FrontendForms\Textarea('message');
    $message->setLabel('Message');
    $message->setRule('required');
    $form->add($message);

    $privacy = new \FrontendForms\InputCheckbox('privacy');
    $privacy->setLabel('I accept the privacy policy');
    $privacy->setRule('required')->setCustomMessage('You have to accept our privacy policy');
    $form->add($privacy);

    $button = new \FrontendForms\Button('submit');
    $button->setAttribute('value', 'Send');
    $form->add($button);

    if ($form->isValid()) {
        print_r($form->getValues());
      // do what you want
    }

// render the form
    echo $form->render();

        // output bodycopy
        echo $page->get('body');

        // render navigation to child pages
        renderNav($page->children);

        // TIP: Notice that this <div id='content'> section is
        // identical between home.php and basic-page.php. You may
        // want to move this to a separate file, like _content.php
        // and then include('./_content.php'); here instead, on both
        // the home.php and basic-page.php template files. Then when
        // you make yet more templates that need the same thing, you
        // can simply include() it from them.

    ?></div><!-- end content -->

    <aside id='sidebar'><?php

        // rootParent is the parent page closest to the homepage
        // you can think of this as the "section" that the user is in
        // so we'll assign it to a $section variable for clarity
        $section = $page->rootParent;

        // if there's more than 1 page in this section...
    if ($section->hasChildren > 1) {
        // output sidebar navigation
        // see _init.php for the renderNavTree function
        renderNavTree($section);
    }

        // output sidebar text if the page has it
        echo $page->get('sidebar');

    ?></aside><!-- end sidebar -->

<?php include('./_foot.php'); // include footer markup ?>

You do not need to integrate something inside the init.php to make it work. I have only integrated the following 2 lines inside the init.php. Here is the complete code of my init.php (templates/_init.php)

<?php

namespace ProcessWire;

/**
 * Initialization file for template files
 *
 * This file is automatically included as a result of $config->prependTemplateFile
 * option specified in your /site/config.php.
 *
 * You can initialize anything you want to here. In the case of this beginner profile,
 * we are using it just to include another file with shared functions.
 *
 */

include_once("./_func.php"); // include our shared functions

$frontendforms = new FrontendForms();
$frontendforms->setLang('de');

I use these 2 lines only to make the error messages in german for all pages -> nothing more, but the module works also without these 2 lines.

Please check my code against yours and let me know.

Best regards

Link to comment
Share on other sites

Hello Jurgen,
Thank you for testing.
But I get the exact same errors as before.
It doesn't matter if I take the code template from you or just insert the relevant part.

Then I tried PHP versions 7.2.34 - 8.0.8.
From version 8 the error message is longer. See pictures.
It runs under Mamp Pro on a Mac. But haven't had any problems so far.


I think it has something to do with how you access paths with your module. (#1 on error message)
Did you also use the latest PW Dev 3.0.199 version?
Have you possibly made another setting that differs from the normal PW installation? Possibly in the config?

Regards,
Christian

Bildschirmfoto 2022-05-12 um 10.46.35.png

Bildschirmfoto 2022-05-12 um 10.46.44.png

Link to comment
Share on other sites

Hello!

I have replaced my own class loader with the ProcessWire classLoader, which handles namespaces better and here on my windows system and XAMPP it works. Could you please reinstall the module with the new version 2.0.3 and let me know if the problem is gone now.

Best regards.

Link to comment
Share on other sites

Hello,
unfortunately the same error comes up. ?  But I think you are on the right path to the solution.

(I downloaded your new version as a zip from GitHub and completely uninstalled the old one in PW first. Then unpacked the new one and renamed the folder according to your specifications. Then I reinstalled and activated it in PW…)

I looked for it on the web, maybe this will help:

https://dev.to/dechamp/php---how-to-fix-class--not-found-error-1gp9

 Upper and lower case seems to be a problem with the classes. Probably also on the Mac with file names and paths...

Maybe you have another idea...

 

Best regards
Christian

Link to comment
Share on other sites

Hello Juergen,

This is sp1ke (for some unknown reason, I cannot login with my old name in forums). Some remarks that might help you:

1. Your module worked fine on my local server (windows PC with XAMPP). The problem arise when I transfer the site to a live server. I have already tested in 2 different servers and the error message was the same in both of them.

2. Yesterday using module's version 2.0.2, I comment out the line 121 in Forms.php (where there is the error):
// $this->alert = new Alert();
After doing that the same error message was for line 128:
$this->requiredHint = new RequiredTextHint();

Maybe these info is useful for you.

Best regards

Link to comment
Share on other sites

Maybe there could be a problem with new instances without the namespace. I have only tested this module locally and and never on live servers. Thats why I did not recognize that there could be a problem with namespaces.

Anyway: I have added the namespace to every new instance of a FrontendForms class on every file inside the module (I hope I have not overlooked a new instance ?).

A lot of files were modified - so please download the module once more. I have not bumped up the version number.

BTW: I could not find different spellings on the namespaces inside the files. If you have discovered that I have written it in different ways please let me know where.

Best regards

Link to comment
Share on other sites

Hello Jurgen,
sorry for the late reply.
Unfortunately the same error comes again.

I'd love to help you, but unfortunately my PHP OOP knowledge isn't good enough for that.

I looked again and found this in the PW forum. Maybe that can help a bit:

And this:

https://processwire.com/blog/posts/processwire-3.0-alpha-2-and-2.6.22-rc1/#compiled-template-files

And this:

 

It works for you and sp1key on Windows XAMP and not on Mac-Mamp and Linux-Server. I would tap on a spelling problem with paths.
Maybe a sanitizer changes a bit too much on a path....?

Many greetings,
Christian

Link to comment
Share on other sites

Hello Juergen,

In Form.php 
...
in line 346:
public function getAlert(): Alert 

 return $this->alert; 
}
and in line 307:
public function getRequiredText(): RequiredTextHint 

 return $this->requiredHint; 
}

Both functions return an object (Alert & RequiredTextHint), but these objects are not declared anywhere in the code. Maybe this is the issue that causes the error message?

Best regards

Link to comment
Share on other sites

Hello,

What I meant in my previous message is that system accepts (understands) the command:

... = new FrontendForms ();

But doesn't accept (understand) the command:

... = new Alert();

Perhaphs is an issue with module's directories or too many directories or files that cause an issue with the memory allocated in a live server?

Link to comment
Share on other sites

23 hours ago, sp1key said:

Both functions return an object (Alert & RequiredTextHint), but these objects are not declared anywhere in the code. Maybe this is the issue that causes the error message?

Hi sp1key!

The objects are declared at the top of the file (take a look at line 94 and below of the Form.php).

// Classes
    protected $alert;
    protected $requiredHint;

 

20 hours ago, sp1key said:

Perhaphs is an issue with module's directories or too many directories or files that cause an issue with the memory allocated in a live server?

I do not think so, because the classes will (should) be loaded on demand and not all at once, but you are right: it is strange that it makes differences between classes. I will take a closer look today on the issue especially on the autoloader and the paths.

I guess the amount of directories should not cause this issue.

Best regards

Link to comment
Share on other sites

Hi,

I have added a new autoloader function. I have tested it and only the classes which are used in the template will be loaded and nothing more. So there could not be an overhead by loading all classes.

You do not need to replace the complete module. Please replace only the code of the FrontendForms.module file and let me know if it works now.

Thanks

Link to comment
Share on other sites

Hello Juergen,

The form is working now in live server (I have not yet test if emails can be sent). 

The issue is that if in the site/config.php the debug is true:
$config->debug = true;
There is an error both in back-end (admin) and the front-end of the site. I attached the error message picture. Especially this error line is keep coming in the page (many lines) so especially in admin it's not easy to work.
If $config->debug = false; no error message.


Also another question:
I declare the 
$frontendforms = new FrontendForms();
into the template file(s). 
In the site I have 2 different forms; a contact form and a kind of simple reservation form. The contact form page, as I said, is working fine but the reservation form page shows an error saying:

Compile Error: Cannot declare class FrontendForms\Form, because the name is already in use (line 0 of site/modules/FrontendForms/Formelements/Form.php)

Any idea about these 2 issues?

Best regards

forntendforms-loading-error.jpg

Link to comment
Share on other sites

48 minutes ago, sp1key said:

Also another question:
I declare the 
$frontendforms = new FrontendForms();
into the template file(s). 
In the site I have 2 different forms; a contact form and a kind of simple reservation form. The contact form page, as I said, is working fine but the reservation form page shows an error saying:

Compile Error: Cannot declare class FrontendForms\Form, because the name is already in use (line 0 of site/modules/FrontendForms/Formelements/Form.php)

 

I already fixed this 2nd issue. 

Best regards

Link to comment
Share on other sites

Hello sp1key,

glad to hear that ?

11 hours ago, sp1key said:

I have not yet test if emails can be sent

Sending emails is not part of this module, so its up to the mailer class of PW. If you set it up correctly, it will work.

11 hours ago, sp1key said:

There is an error both in back-end (admin) and the front-end of the site. I attached the error message picture. Especially this error line is keep coming in the page (many lines) so especially in admin it's not easy to work.

I have corrected this notice - so please download FrontendForms.module once more and replace it with the new one.

Best regards

 

Link to comment
Share on other sites

Hi Juergen, I reinstalled the updated module.

Unfortunately the problem still exists.

Without changes to your theme example above, an internal server error will now occur.

If I remove "\FrontendForms\..." I get the error message with the class at alarm...

Greetings Christian

Link to comment
Share on other sites

On 5/16/2022 at 9:04 PM, Juergen said:

Hello sp1key,

glad to hear that ?

Sending emails is not part of this module, so its up to the mailer class of PW. If you set it up correctly, it will work.

I have corrected this notice - so please download FrontendForms.module once more and replace it with the new one.

Best regards

 

Hello Juergen,

I uploaded the new FrontendForms.module and everthing is fine now. No warnings in back-end or front-end.

This is a very handy and helpful module for building forms. I just miss the examples you have included in the previous versions of the module - they were very informative; it's a pity I didn't kept them after the updates.

You have done a very good job. Thank you for your efforts and hard trying.

Best regards,
Constantine

  • Thanks 1
Link to comment
Share on other sites

Hello Chris

Please do the following: Go to the FrontendForms.module file, find the method classLoader (at line 163) and insert the following print command before the include function at line 183

print_r($dir . $file); // add this line
include $dir . $file;

Load the page on the frontend and make a screenshot of the paths like I did in the image below.

1288685879_Screenshot2022-05-21at08-22-45About.thumb.png.77fe4191c80a5b098c87e97f1488dd0c.png

Let us see if there are differences in the paths between mine and yours. I am excited!

Best regards Jürgen

Link to comment
Share on other sites

  • 1 month later...

Hi,

Is there a way to insert <div> inside <form></form>? I need to wrap all input fields, but addFieldwrapper() or $form->prepend() does not fit here. It works with str_replace, but then $tmp=form->render() doubles output.

Edited by Anonimas
Link to comment
Share on other sites

Hi Anonimax

Yes it is possible, but instead of adding the divs to the form element itself you have to add the opening div to the first form element and the closing div to the last form element. Please take a look at the example code below:

$form = new \FrontendForms\Form('testform');

$surname = new \FrontendForms\InputText('surname');
$surname->setLabel('Surname');
$surname->setRule('required');
$surname->getFieldWrapper()->prepend('<div>');
$form->add($surname);

$email = new \FrontendForms\InputText('email');
$email->setLabel('E-Mail');
$email->setRule('required');
$email->setRule('email');
$form->add($email);

$button = new \FrontendForms\Button('submit');
$button->setAttribute('value', 'Send');
$button->append('</div>');
$form->add($button);

if($form->isValid()){

    print_r($form->getValues());
    // do what you want

}

// render the form
echo $form->render();

The first input field in the form is the text input "surname". Grab the field wrapper object and prepend the div there:

$surname->getFieldWrapper()->prepend('<div>');

The last element in this form is the button element -> so append the closing div there:

$button->append('</div>');

It always depends on the structure of your form.

Hidden fields are excluded in this case from beeing wrapped with the div, but I guess this should not be a problem.

If you have problems, please post your form code here.

Best regards

 

Link to comment
Share on other sites

Hi Anonimas

Inspired by your question I have added a new method to add the wrapper div over all form fields (including hidden fields too).

$form->setFormElementsWrapper()->setAttribute('class', 'mycustomclass');

By default a unique CSS id will be added, but as you can see in the example above, you can also add a class attribute (or other attributes) too.

  <form>
    <div id="formelementswrapper" class="mycustomclass">
        ....
    </div>
  </form>

To use this method, please download version 2.0.9 from GitHub. Alternatively replace the Form.php. This file includes all the changes and additions.

BTW could you please tell me, what is the intention for you to wrap all form fields in an extra div?

Best regards Jürgen

  • Like 1
Link to comment
Share on other sites

9 hours ago, Juergen said:

BTW could you please tell me, what is the intention for you to wrap all form fields in an extra div?

Hi,

I'm using https://html5up.net/story template and want to use unmodified css file. It wraps all form fields for inline fields alignment (name and email in example) and css use "form > .fields > .field ". If Div with class "fields" is outside form, then it don't works.

I tested with new version and it works! Thank you for update!

Also it would be useful to add something like setRequiredText(), because now I disabled default and added my text manually before form. Something like setErrorMsg() and setSuccessMsg(). 

  • Like 1
Link to comment
Share on other sites

Great idea @Anonimas

I have integrated both.

You can change/customize the text for the required fields with setRequiredText() method.

$form->setRequiredText('This is my customized text, that you have to fill out all required fields.')

I have also added EOT for better readability.

Please download and install the module once more.

Thanks for your ideas.

 

  • Like 1
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...