contributte / live-form-validation

:no_entry: Nice client-side live form validation for Nette Forms.

Home Page:https://contributte.org/packages/contributte/live-form-validation.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Inconsistent error display when validating CheckboxList control

mcbmcb0 opened this issue · comments

The script does not reliably show the validation error for CheckboxList control. I've adapted the standard demonstration form, setRequired as follows:
$form->addCheckboxList('colors', 'Favorite colors:', [ 'red', 'green', 'blue', ])->setRequired("Enter your favourite colour");
only sometimes are the 'has error' class added to the parent div , and 'help-block text-danger' added to the message span.
i can sometimes get the error to show when I switch tabs, or when I complete other invalid items and again press submit. It appears to toggle the CheckboxList errors on and off each time I resubmit (with invalid data) when the data in other 'invalid' controls have been corrected.

the other control types show errors reliably/as they should.

If I remove 'live-form-validation.js' and use 'netteForms.js' the messages show reliably in the alert.
I'm using nette forms 2.4 (standalone) and jquery.min.js 1.10.2 on the page.

thanks for checking this.
Mike

i can't quite follow all the js but the error classes/messages are being added then removed when checckbox groups have names[] and there is more than one item. commenting out the following stops this removal:
if (!onlyCheck) { //LiveForm.removeError(elem);
I think its is because only the first checkbox in the array has a rule attached to it eg `data-nette-rules='[{"op":":filled","msg":"Enter your favourite colour"}]'
so the latter checkboxes aren't validated and any attached error classes are removed.

????

Could you try version 1.7.0 of this script? I think it worked correctly before. So I'm not sure if something was changed in Nette 2.4 or in new netteForms.js.

And please give me some live example - could be just jsfiddle with HTML form created with Nette and included live-form-validation script.

thanks for your reply. just tried 1.7.0 and the same result. if I'm right that section of the js is the same.
i'll set up a fiddle tomorrow (1am here)

try this: [(https://jsbin.com/juyamo/2/edit)] - all fields are required
(i couldn't get the github raw to load consistently so copied all into the js pane)
first - doesn't show 'favourite colours' or country errors. if you enter data for name and gender, then click submit a few times the favourite colours error will toggle
note the country select doesn't show errors at all even when blank entry (tho this may be nette?)

i'd love for you to tell me there's a different method for validating checkboxlists, but if not here's a hacky fix: [(https://jsbin.com/muluzi/11/edit)].
all its does is when the form validates it makes a unique array of all controls, then when each control is validated it stores a boolean so it won't re-validate the same control (and remove the previous errors). modified code is marked mb*****. i think this confirms that the problem is that nette ads the js validation rule to the first [0] checkbox so later ones in the same checkboxlist with no rules trigger removing any errors.

one glitch is when unchecking all checkboxes in a list they don't trigger a re validation (tho the form submit does). and an empty select is not marked as invalid

Thanks for fiddle and additional info.

About your country select problem - even clean netteForms.js won't show error and that's correct, because I think you have wrongly set the select values. You have specified "empty" value as <option value="0"></option> - note that you set value to 0. If you set it as <option value=""></option> it will be correctly validated as empty.

And I'm looking into the checkboxlist problem now...

thanks - good tip re options. this works:

$arr = array(
'' => Nette\Utils\Html::el('option')->setHtml(''),
'item_bing' => Nette\Utils\Html::el('option')->setHtml('bing'), //->disabled("disabled"),
'item_bong' => Nette\Utils\Html::el('option')->setHtml('bong'),
);
$form->addSelect('country3', 'Country3', $arr)->setRequired("choose an option please");

perhaps extending this approach, if we could set an attribute of the checkboxlist label then we could add the nette rule to each label before generating the form:
->setAttribute('data-nette-rules', '[{"op":":filled","msg":"choose an option please"}]')
but i only know how to add attributes to the checkbox, not its label....??

alternatively in Nette.validateControl get the rule of the first child element of the parent group of a checkbox control and test for that

You should use setPrompt() for creating your "empty" select item. See https://api.nette.org/2.4/source-Forms.Controls.SelectBox.php.html#40-49

this is tidier and works: [(https://jsbin.com/yoyoqot/edit)]
Nette.validateControl = function(elem, rules, onlyCheck, value, emptyOptional) {
var inputs = LiveForm.getGroupElement(elem).getElementsByTagName('input');
if(inputs.length>0 && inputs[0].type == "checkbox"){
elem = inputs[0]; // **** get the first checkbox and below process rules from that ****
} ...
again edits marked mb**** in the jsbin js pane

Good idea.
Your workaround won't work in situations where inputs are not enclosed in own "input group", so I improved the check:

EDIT: Final version:

// Fix for CheckboxList - always get the validation rules from first item
if (elem.name && elem.name.match(/\[\]$/) && elem.type.toLowerCase() == 'checkbox') {
    elem = elem.form.elements[elem.name].tagName ? elem : elem.form.elements[elem.name][0];
}

But it still feels like workaround and not proper fix.

great. that appears to work here when after my elem = inputs[0]; line.
(js is not my best language!)

I commited it: 80e6721

thanks - 1.8.1 works for me