Jump to content

How to show the custom error message below the Inputfileds?


SIERRA
 Share

Recommended Posts

 Hi

We tried using this hook method "$this->addHookAfter('Inputfield::processInput', $this, 'validateCustomField');", Using this we can able to show the error messages in the repeater field.

However, we need to show the error message below the respective inputfield in the Repeater. Is there any hook methods to achieve this?

Thanks for the support and we will avoid duplicate questions.

Link to comment
Share on other sites

Hi,

How to add custom validation to the field 'Test name' (inside the repeater) and display its error message similar to 'Title' field.

Please find the screenshot and suggest.

Thank you.

Screenshot_61.png

Link to comment
Share on other sites

I don't how to do this, but by exploring HTML source of the repeater items in admin page (browser dev tools), looking InputfieldWrapper API and InputfieldRepeater API, and var_dumping things in a hook, I found a way.

image.thumb.png.7d052acd0f4a2363fc2e322787982a13.png

 

self::addHookAfter("Inputfield(name=championshipRoundRepeater)::processInput", function (HookEvent $event) {
    /** @var InputfieldRepeater $inputfieldRepeater */
    $inputfieldRepeater = $event->object;

    /** @var InputfieldWrapper $wrapper */
    foreach ($inputfieldRepeater->getWrappers() as $repeaterItemId => $wrapper) {
        /** @var Inputfield $itemField */
        $itemField = $wrapper->getByName("title_repeater$repeaterItemId");
        $itemField->error('this is an error');
    }
});

image.thumb.png.eee3c64299c9d1d81061446e558ff9ce.png

  • Like 1
Link to comment
Share on other sites

Hi,

Thank you for your suggestion.

We have tried your code, and it is working well for the repeater fields.

However, one issue we are facing is that if a repeater item has an error, it should be opened by default at page loading. Unfortunately, it is not opening, and we need to manually open and view the error.

Please find the screenshot attached and our coding .Could you please possibilities to fix this?

Thank you.


Code in ready.php file
$wire->addHookAfter("Inputfield(name=test1_repeater)::processInput", function (HookEvent $event) {
    /** @var InputfieldRepeater $inputfieldRepeater */
    $inputfieldRepeater = $event->object;

    /** @var InputfieldWrapper $wrapper */
    foreach ($inputfieldRepeater->getWrappers() as $repeaterItemId => $wrapper) {
        /** @var Inputfield $itemField */
        $itemField = $wrapper->getByName("test_name_repeater$repeaterItemId");
       
        if($itemField && $itemField->value == ''){
            $itemField->error('Custom Message');            
        }
    }
 
});

Screenshot_67.thumb.png.a8c0daeaef568751600083e3c0e7f22b.pngScreenshot_68.thumb.png.92551cb91ec6e6a6724a7291eba0e995.png

Link to comment
Share on other sites

If you look into InputfieldRepeater.module, in method ___processInput() :

if($numErrors || $numRequiredEmpty) {
  $this->error(sprintf($this->_('Errors in “%s” item %d'), $this->label, $key + 1));
  if(!$page->hasStatus(Page::statusUnpublished)) $this->numRequiredEmpty += $numRequiredEmpty;
  $openIDs[$page->id] = $page->id; // force item with error to be open on next request
} else if(isset($openIDs[$page->id])) {
  unset($openIDs[$page->id]);
}

It opens items with an error, but our hook is executed after this, so this code doesn't know at this time that this item has an error (and "before" hook is not working at all).

You see that $openIDs is used to remember which items to open, and at bottom of this function it stores it in session:

if($_openIDs !== $openIDs) $this->wire()->session->setFor($this, 'openIDs', $openIDs); 

So it looks like there's at least a way to achieve your goal by directly updating this session variable:

wire()->addHookAfter("Inputfield(name=championshipRoundRepeater)::processInput", function (HookEvent $event) {
    /** @var InputfieldRepeater $inputfieldRepeater */
    $inputfieldRepeater = $event->object;
    $openIDs = wire()->session->getFor($inputfieldRepeater, 'openIDs') ?? [];

    /** @var InputfieldWrapper $wrapper */
    foreach ($inputfieldRepeater->getWrappers() as $repeaterItemId => $wrapper) {
        /** @var Inputfield $itemField */
        $itemField = $wrapper->getByName("title_repeater$repeaterItemId");
        $itemField->error('this is an error');
        $openIDs[$repeaterItemId] = $repeaterItemId;
    }
    wire()->session->setFor($inputfieldRepeater, 'openIDs', $openIDs);
});

I don't like this solution because it is strongly dependent of a the ___processInput() private implementation. Maybe there's a cleaner way to work with this, I don't know... If no, maybe it would be a good idea to add a hookable method ___checkForItemErrors(InputfieldWrapper $repeaterItem):void, called from ___processInput()?  @ryan

Link to comment
Share on other sites

Hi @da²

Thank you very much for your inputs.

I used a session variable and updated it as you suggested.

It works as expected.

If we find an alternative solution to resolve this, it would be greatly appreciated.

Thank you

 

  • 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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...