zofe / rapyd-laravel

deprecated rewritten in rapyd-livewire
MIT License
866 stars 298 forks source link

Passing a validator instance to the dataform / dataedit wrong error messages #298

Open TBarina opened 8 years ago

TBarina commented 8 years ago

I tried and moved rules to a validator instance like this:

public function anyEdit() {
    $edit = \DataEdit::source(new RoleType());
    $edit->link("role-types","Role types", "TR")->back();

    $edit->validator = \Validator::make(\Input::all(), [
        'name' => 'required',
    ]);

    $edit->add('name','Name', 'text')
    //->rule('required')
    ;
    $edit->add('description','Description', 'summernote')->options(array('height' => 150));
    return $edit->view("roleTypes.edit", compact('edit'));
}

When I edit or show the model in the blade view (using {!! $edit !!}) a red message "The name field is required." always appears just below the name field input box (which shows in red as well).

tacone commented 8 years ago

You should not validate before the form is sent. Use the validator only on POST.

TBarina commented 8 years ago

I saw that custom validator should be set after setting \DataEdit::source(...) (see [https://github.com/zofe/rapyd-laravel/issues/145]). I thought the inted place was the controller's anyEdit method.

How should I do that instead? I'm confused. I think that rapyd should load messages only when appropriate. Thanks

tacone commented 8 years ago

After a quick look to the source it seems you're right and it should behave the way you said. I suggest trying to dump a backtrace inside DataForm::isValid() and trying to understand why it gets triggered.

TBarina commented 8 years ago

I think the problem orginates in the way DataForm's buildField() method loads messages from Validator and set the has_error property. In fact, by enclosing the loading in a conditional, I could circumvent the problem. I'm not sure though wheather this is the right way:

protected function buildFields()
{
    $messages = (isset($this->validator)) ? $this->validator->messages() : false;

    foreach ($this->fields as $field) {
        $field->status = $this->status;
        $field->orientation = $this->orientation;
        $field->has_label = $this->has_labels;
        $field->has_placeholder = $this->has_placeholders;

       **if (($this->status == 'create' && $this->action == 'insert') || 
            ($this->status == 'modify' && $this->action == 'update'))** {

          if ($messages and $messages->has($field->name)) {
              $field->messages = $messages->get($field->name);
              $field->has_error = " has-error";
          }

        }
        $field->build();
    }
}

Thanks again

tacone commented 8 years ago

Not sure what's going on, and the project mantainer (@zofe) is pretty busy at the moment. I suggest you to put the conditional in your controller method so that you only pass in the validator when the request method is POST. Not a clean solution, but it can work for now.