Jump to content

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


Juergen

Recommended Posts

I noticed all registered users have untitled-xxxx as name, it is possible to make it nicer, having a unique id generated instead or maybe using the email address as name or even better make it configurable in the settings? Thanks 😛

sorry wrong post

Link to comment
Share on other sites

I have a question about additional checks.

How can I organize custom checks on the database? For example, how can I prohibit duplication of e-mail value or participant's number or full namesake?

Link to comment
Share on other sites

Hello @Andy

Take a look at the custom rules. There are some ready-to-use validators which check against the database (fe. uniqueEmail to check if email is not registered inside the user table).

List of Custom rules

If you want to check against custom tables, you have to check it inside the isValid() method by your own. There is no possibility to create and add custom rules by yourself.

if ($form->isValid()) {

//make your custom check here (fe checking a form value against the database)
if(customcheck is valid){

	// go on with your code
} else {

	// set an error message at the top of the form
	$alert = $form->getAlert();
	$alert->setErrorMessage('Sorry, but there are errors inside the form');

	// set an error message on the inputfield itself (fe. an email input)
	$emailInput = $form->getFormElementByName('email);
	$emailInput->setErrorMessage('There is an error');
	
}

}

I have not tested the code above, but you got the idea such an issue could be solved.

The last option is to write an request on Github for a new validator and if it could be useful for others I will try to implement it 😉

Best regards

  • Like 1
Link to comment
Share on other sites

Hello @PWaddict

I have adapted the hook to change the form markup inside the readme file to get it working now.

The previous versions of hooks did not work, because the hooks will never be triggered. Instead you have to hook "Form::render" and change the markup there.

Here you can see the example of the readme file to change the markup of the asterisk on required fields.

Before:

1182071232_Screenshot2025-01-30at18-52-27MinimalSiteProfile.png.93d68059adf7879ac95e9a985383882b.png

After:

359520941_Screenshot2025-01-30at18-50-59MinimalSiteProfile.png.0e30d3cba6aa7daae3adcdd8c16eb30f.png

Hope this helps

Link to comment
Share on other sites

I tried the new hook on both init.php and ready.php but still not working.

wire()->addHookAfter('Form::render', function ($event) {
    $return = $event->return;
    $return = str_replace('<span class="asterisk">*</span>','<span class="myAsterisk">+</span>', $return);
    $event->return = $return;
});

 

Link to comment
Share on other sites

  On 1/30/2025 at 6:35 PM, Juergen said:

Could you please post the code of your init.php.

Expand  

I'm testing it on a brand new website and my init.php doesn't have any other hook. If I change the hook to Page::render it works so it seems it's not a PW issue.

<?php namespace ProcessWire;

if(!defined("PROCESSWIRE")) die();

/** @var ProcessWire $wire */

/**
 * ProcessWire Bootstrap Initialization
 * ====================================
 * This init.php file is called during ProcessWire bootstrap initialization process.
 * This occurs after all autoload modules have been initialized, but before the current page
 * has been determined. This is a good place to attach hooks. You may place whatever you'd
 * like in this file. For example:
 *
 * $wire->addHookAfter('Page::render', function($event) {
 *   $event->return = str_replace("</body>", "<p>Hello World</p></body>", $event->return);
 * });
 *
 */

wire()->addHookAfter('Form::render', function ($event) {
    $return = $event->return;
    $return = str_replace('<span class="asterisk">*</span>','<span class="myAsterisk">+</span>', $return);
    $event->return = $return;
});

 

Link to comment
Share on other sites

Hi @Juergen

Unfortunately, the suggested example doesn't work  18 hours ago, Juergen said:

if ($form->isValid()) {

//make your custom check here (fe checking a form value against the database)
if(customcheck is valid){

    // go on with your code
} else {

    // set an error message at the top of the form
    $alert = $form->getAlert();
    $alert->setErrorMessage('Sorry, but there are errors inside the form');

    // set an error message on the inputfield itself (fe. an email input)
    $emailInput = $form->getFormElementByName('email);
    $emailInput->setErrorMessage('There is an error');
    
}

}


First of all, I didn't find the setErrorMessage function in your code. But you have the setErrorMsg function. Here's the code I used:

if($form->isValid()) {

    $selector = $sanitizer->text($form->getValue('title'), $options = ['stripQuotes'=>true,'stripSpace'=>true]);
    $selector = preg_replace('/[^а-яё]/ui','', $selector);

    If(empty($selector)){
       // set an error message at the top of the form
        $e_msg = "The name must be in Cyrillic.";
        $alert0 = $form->getAlert();
        $alert0->setErrorMsg($e_msg);
    }
}


However, I get an error either way:

Exception: Method Alert::setErrorMsg does not exist or is not callable in this context (in  wire/core/Wire.php line 563)

Perhaps there is some other way to change the value of $form->isValid() to false?

Edited by Andy
Link to comment
Share on other sites

  On 1/31/2025 at 5:03 AM, Juergen said:

Hello @PWaddict

It seems that @Robin S has found the problem. Take a look here. I'll test it on mylocalhost and on the live site over the weekend and post my results here, but I'm sure this solves the problem.

Expand  

Yep, now this hook works:

$wire->addHookAfter('Label::renderAsterisk', function(HookEvent $event) {
    $event->return = '<span class="myAsterisk">+</span>';
});

Please fix Errormessage::render too.

  • Like 1
Link to comment
Share on other sites

Hi @Juergen

First of all, I didn't find the setErrorMessage function in your code. But you have the setErrorMsg function. Here's the code I used:

if($form->isValid()) {

    $selector = $sanitizer->text($form->getValue('title'), $options = ['stripQuotes'=>true,'stripSpace'=>true]);
    $selector = preg_replace('/[^а-яё]/ui','', $selector);

    If(empty($selector)){
       // set an error message at the top of the form
        $e_msg = "The name must be in Cyrillic.";
        $alert0 = $form->getAlert();
        $alert0->setErrorMsg($e_msg);
    }
}

However, I get an error either way:

Exception: Method Alert::setErrorMsg does not exist or is not callable in this context (in  wire/core/Wire.php line 563)

Perhaps there is some other way to change the value of $form->isValid() to false?

Link to comment
Share on other sites

Hi Juergen

First of all, I didn't find the setErrorMessage function in your code. But you have the setErrorMsg function. Here's the code I used:

if($form->isValid()) {

    $selector = $sanitizer->text($form->getValue('title'), $options = ['stripQuotes'=>true,'stripSpace'=>true]);
    $selector = preg_replace('/[^а-яё]/ui','', $selector);

    If(empty($selector)){
       // set an error message at the top of the form
        $e_msg = "The name must be in Cyrillic.";
        $alert0 = $form->getAlert();
        $alert0->setErrorMsg($e_msg);
    }
}

However, I get an error either way:

Exception: Method Alert::setErrorMsg does not exist or is not callable in this context (in  wire/core/Wire.php line 563)

Perhaps there is some other way to change the value of $form->isValid() to false?

Link to comment
Share on other sites

Hi @Juergen

Method:

$alert0 = $form->getAlert();
$alert0->setErrorMsg($e_msg);

Causes an error:

Exception: Method Alert::setErrorMsg does not exist or is not callable in this context

Is there any other method to set $form->isValid() to false?

Link to comment
Share on other sites

Try

$alert0 = $form->getAlert();
$alert0->setText($e_msg); 
$alert0->setCSSClass('alert_dangerClass'); // or alert_successClass or alert_warningClass

setErrorMsg() is a method of the form object

Link to comment
Share on other sites

Hi @Juergen

Thank you for your quick response. You are always helpful.

  On 1/31/2025 at 2:45 PM, Juergen said:
$alert0 = $form->getAlert();
$alert0->setText($e_msg); 
$alert0->setCSSClass('alert_dangerClass'); // or alert_successClass or alert_warningClass
Expand  

This code now works and shows an error message at the beginning of the form.

However, the problem is that despite the error, the variable $form->isValid() = true. And the form submittal happens.

Is there any way to tell the form that it is invalid? And make $form->isValid() = false.

That would solve all the problems with additional inspections.

 

 

Link to comment
Share on other sites

The form will be always submitted after pressing the send button 😉

  On 1/31/2025 at 3:54 PM, Andy said:

However, the problem is that despite the error, the variable $form->isValid() = true

Expand  

You have the choice, what should be done inside the isValid() function. This method returns always true if the "standard validation does not fail". It is up to you to make another validation inside the isValid() method, but there is no possibility to make isValid to false manually.

As I explained in the example some post before, you can do addtional checks inside the isValid() method. Depending on the results of your custom checks you can send fe an email or not. The only problem could be that the form will not be displayed after isValid() is true.

The code is not designed to handle such special cases, sorry!

  • Like 1
Link to comment
Share on other sites

I have updated FrontendForms to support hooks to customize the markup of certain elements. As written in a the blog post above there was a problem of using hooks, because they never fired. This should be solved now.

You will find a working example on this website.

If you press submit without filling out the form, all error messages will get an exclamation sign in front of the error message. This is done via the following hook inside the site/init.php:

$wire->addHookAfter('Errormessage::render', function(HookEvent $event) {
    $msg = $event->object;
    $errorText = $msg->getText();
    if($errorText){
        $fontAwesome = '&#9888; ';
        $event->return = $fontAwesome.$errorText;
    }
});

This is for demonstration puropose that it works now!

In addition I have added some other hook examples inside the Hooking section of the docs.

This bug fix includes the change of really a lot of files of FrontendForms, so please that care that everything works after the update as expected. Make a backup before you update the module!!!

Best regards

 

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