adamwathan / bootforms

Rapid form generation with Bootstrap 3 and Laravel.
MIT License
417 stars 103 forks source link

Using with named error bags #99

Open LeRoyJulian opened 8 years ago

LeRoyJulian commented 8 years ago

Hi,

Is there any way to use BootForms with named error bags ? If not, add the possibility of attaching a custom error bag to a form could be a nice improvement.

adamwathan commented 8 years ago

I've never actually used the named error bags, can you give an example of how it works and how you'd like to use it?

LeRoyJulian commented 8 years ago

Sure ! It's useful when you have multiple forms on one page and you want to get errors for a specific form.

For example, we assume that for some reason you want to have your login and signup form on the same page. Both should have an 'email' field, right ? If you want to catch and display errors for this field, without named error bags, the error will be returned to both forms, instead of only the one which was filled by the user.

So, adding a parameter in the form declaration to attach it to a named error bag could be a nice improvement !

Documentation : https://laravel.com/docs/5.2/validation#other-validation-approaches

Tell me if it's not clear, my english is not perfect !

adamwathan commented 8 years ago

Got it, cool feature! I can't promise I'll get to this any time soon and it'll be a bit tricky since this package isn't Laravel specific, so we would be forcing any other implementations of the ErrorStore to support this behavior as well. Feel free to experiment with a PR if you like, would be happy to merge if we land on a good approach. In the mean time it's probably easiest to add your own namespacing to field names using some sort of conventional prefix like login_email and signup_email. Not as pretty but will work.

ghost commented 8 years ago

Hello guys, i need this in my project, so I decided to fix it by myself.

My solution was extend the IlluminateErrorStore from Adam's Form Package (the base package for this one) and override two methods. See below:

<?php

namespace App\Services\Form\ErrorStore;

use AdamWathan\Form\ErrorStore\IlluminateErrorStore;

class CustomIlluminateErrorStore extends IlluminateErrorStore
{
    private $bagName = null;

    public function hasError($key)
    {
        if (! $this->hasErrors()) {
            return false;
        }

        $key = $this->transformKey($key);

        // handle multiple bags
        if (is_array($this->getErrors()->getBag($this->bagName))) {
            $flag = false;

            foreach ($this->getErrors()->getBag($this->bagName) as $bag) {
                /**
                 * @var \Illuminate\Support\MessageBag $bag
                 */
                $flag = $bag->has($key) || $flag;
            }

            return $flag;
        }

        return $this->getErrors()->getBag($this->bagName)->has($key);
    }

    public function getError($key)
    {
        if (! $this->hasError($key)) {
            return null;
        }

        $key = $this->transformKey($key);

        // handle multiple bags
        if (is_array($this->getErrors()->getBag($this->bagName))) {
            $first = '';

            foreach ($this->getErrors()->getBag($this->bagName) as $bag) {
                /**
                 * @var \Illuminate\Support\MessageBag $bag
                 */
                $first = empty($bag->first($key)) ? $first : $bag->first($key);
            }

            return $first;
        }

        return $this->getErrors()->getBag($this->bagName)->first($key);
    }
}

@adamwathan, please take a look, i think this will clarify the idea behind supporting NamedBags. Also, verify my approach, lets make it better if possible.

ana-lisboa commented 7 years ago

Has this worked for you? Can you pelase explain how you overrid it, i.e. where you placed it to be called instead of the original class?

ghost commented 7 years ago

@anaisabel19886, do it according to your software architecture.

In my case, i remember to create some folder at "app" level, then all my custom classes resided on it.

I don't remember if was needed to config the autoload for those files, since Laravel already autoload a lot of things for us...

jesseleite commented 7 years ago

You'd need to extend laravel's error bag to support namespacing, wouldn't you?

That said, @adamwathan I had that PR for form namespacing in the base form package, which namespaces a form builder instance for separating form binding behaviour.

Maybe it's worth looking at building off of that functionality somehow with error bag?

ana-lisboa commented 7 years ago

@ricardovigatti I had tried that, and added it on app.config but there where some errors on Laravel due to received classes on some functions being different than what they where supposed to. Probably due to using 5.3 and this solution being mentioned previous to this release, idk.