Joomla 3 client side checkbox group validation - checkbox

I'm trying to use Joomla's (version 3.4.3) built in form validator: JHTML::_('behavior.formvalidator');
I'm trying to apply it for a dynamically generated form. It works fine for dropdown menus and textfields. But when (lets say) I have a group of 4 checkboxes and I want the user to select at least 1 of the 4 then I ran into a problem... The site asks the user to select ALL 4 checkboxes.
Here is the generated HTML code:
<label title="Checked out?" class="hasTooltip required" for="jform_checked-out_cbv_qwq4-473" id="checked-out_cbv_qwq4-473-lbl">Checked out? <span class="star">*</span></label>
<input type="checkbox" name="checked-out_cbv_qwq4-473[]" id="checked-out_cbv_qwq4-473" value="Yes" class="required" aria-required="true" required="required"> Yes
<input type="checkbox" name="checked-out_cbv_qwq4-473[]" id="checked-out_cbv_qwq4-473" value="No" class="required" aria-required="true" required="required"> No
<input type="checkbox" name="checked-out_cbv_qwq4-473[]" id="checked-out_cbv_qwq4-473" value="maybe" class="required" aria-required="true" required="required"> maybe
<input type="checkbox" name="checked-out_cbv_qwq4-473[]" id="checked-out_cbv_qwq4-473" value="of course not" class="required" aria-required="true" required="required"> of course not
When I try to submit the form I get these error messages:
Invalid field: Checked out?
Invalid field: Checked out?
Invalid field: Checked out?
Invalid field: Checked out?
What am I doing wrong here?

Each of your input elements has the same id, which is "checked-out_cbv_qwq4-473". id attribute should be unique.
Sample code of fieldset with checkboxes:
<div class="control-group">
<div class="control-label">
<label id="mycheckboxes-lbl" for="mycheckboxes" class="required">Checked out?<span class="star"> *</span></label>
</div>
<div class="controls">
<fieldset id="mycheckboxes" class="checkboxes required" required="required" aria-required="true">
<ul>
<li>
<input type="checkbox" id="checkbox_1" name="myform_checkboxes[]" value="Yes">
<label for="checkbox_1">Yes</label>
</li>
<li>
<input type="checkbox" id="checkbox_2" name="myform_checkboxes[]" value="No">
<label for="checkbox_2">No</label>
</li>
...
</ul>
</fieldset>
</div>

Related

Ensure at least one checkbox is selected in angular

I need to validate that at least one checkbox, in 3, has been selected. I can't use radio buttons because two of the options are can be selected and exclude the third. I'm not really sure if it's best to put these checkboxes into a model array, rather than binding them to separate models and creating a longer ng-required expression. The docs aren't particularly helpful in describing what 'best practise' is for this sort of thing...
Code:
<div class="form-inline form-group">
<div class="row">
<div class="col-xs-12">
<h4 class="card-title left test-list-header">Balcony</h4>
</div>
</div>
<fieldset class="form-group">
<input type="checkbox" id="balconyBalcony" ng-model="balcony">
<label for="balconyBalcony">Balcony</label>
</fieldset>
<fieldset class="form-group">
<input type="checkbox" id="patioBalcony" ng-model="patio">
<label for="patioBalcony">Patio</label>
</fieldset>
<fieldset class="form-group">
<input type="checkbox" id="noBalcony" ng-model="noBalcony" ng-disabled="balcony || patio">
<label for="noBalcony">No</label>
</fieldset>
<fieldset class="form-group" ng-show="noBalcony && !patio && !balcony">
<div class="md-form">
<input
type="text"
id="{{ Plot::FIELD_BALCONY_NOTES }}"
class="form-control"
name="{{ Plot::FIELD_BALCONY_NOTES }}"
inline-edit
inline-edit-callback="UpdateHandler()"
ng-model="Model.BalconyNotes.Value"
ng-class="{ invalid: createPlot.balconyNotes.$invalid && submitted, valid: createPlot.floor.$valid }"
ng-init="Model.BalconyNotes.Value = '{{ old(Plot::FIELD_BALCONY_NOTES) or $Model->BalconyNotes }}'" ng-required="noBalcony">
<label for="{{ Plot::FIELD_BALCONY_NOTES }}" data-error="#{{ Model.BalconyNotes.ValidationMessage }}" class="w-100">Comments</label>
<span class="help-block" ng-show="createPlot.balconyNotes.$invalid && submitted">As there is no balcony or patio, you must enter a comment</span>
</div>
</fieldset>
You could use ng-required built in directive to validate your form.
Like this:
<form novalidate name="myForm" ng-submit="mySubmitFunc()">
<label>Checkbox 1
<input ng-required="!(cb2 || cb3)" ng-model="cb1" type="checkbox">
</label>
<label>Checkbox 2
<input ng-required="!(cb1 || cb3)" ng-model="cb2" type="checkbox">
</label>
<label>Checkbox 3
<input ng-required="!(cb1 || cb2)" ng-model="cb3" type="checkbox">
</label>
<input type="submit" ng-disabled="myForm.$invalid" value="submit">
</form>
Here is a fiddle demonstrating how to handle such logic.
You could add a validation line:
<div ng-show="myForm.$submitted">
<p style="color: red" ng-show="!myForm.balcony && !myForm.patio && !myForm.noBalcony">You must select at least one of the options above.</p>
</div>
That div shows when the user tries to submit and the p shows when none are selected.
Your button will also need an ng-disabled directive with the same condition.

ng-disabled is not working

This might be a silly question. But I just started experimenting with AngularJS. Can someone point out what I'm doing wrong in validation. The button is not disabled even when the fields are invalid.
What's the difference between
ng-disabled="myForm.$invalid" and
ng-disabled="myForm.cuisine.$invalid || myForm.title.$invalid || myForm.description.$invalid || myForm.cost.$invalid"
I think using myForm.$invalid is a cleaner way of disabling the button. Any tips?
<form name="myForm">
<div class="form-group">
<select ng-required="true" name="cuisine" ng-model="model.food.cuisine" class="form-control" type="text">
<option ng-repeat="c in model.cuisines" value="{{c}}">{{c}}</option>
</select>
<p ng-show="myForm.cuisine.$invalid && myForm.cuisine.$touched">
Please select cuisine type.</p>
</div>
<div class="form-group">
<input ng-required="true" name="title" ng-minlength="4" ng-maxlength="25" ng-model="model.food.title"
type="text" class="form-control">
<p ng-show="myForm.title.$invalid && myForm.title.$touched">Please pick a valid title with atleast 4
characters.</p>
</div>
<div class="form-group">
<textarea ng-required="true" name="description" ng-minlength="10" ng-maxlength="255"
ng-model="model.food.description" type="text" class="form-control"></textarea>
<p ng-show="myForm.description.$valid && myForm.description.$touched">Please describe your food with 10 - 255
characters.</p>
</div>
<div class="form-group">
<input name="cost" ng-pattern="/0-9/" ng-required="true" min="1" ng-model="model.food.cost" type="number"
class="form-control" placeholder="Cost">
<p ng-show="myForm.cost.$error.pattern">Please enter a valid number</p>
<p ng-show="myForm.cost.$invalid && myForm.cost.$touched">Please enter cost of food item.</p>
</div>
<div class="form-group">
<button ng-disabled="myForm.$invalid" class="btn btn-success btn-block">Add Food</button>
</div>
</form>
Apparently, validations don't work if the form element is inside the body of a table.
It works fine if I moved the form tag outside the table.
Thanks everyone.

Use ng-model with condition

I am using angularjs in my project.
I have below code in my HTML:
<div class="MT10" ng-init="getPaymentDetailsById()">
<div class="panel">
<div class="form-group">
<label> Name:</label>
<span class="rightside">
<input type="text" value="" ng-model="singleGatewayDetails.name" >
</span>
</div>
<div class="form-group">
<label> APP :</label>
<span class="rightside">
<input type="text" value="" ng-model="paymentDetails.id" ng-disabled="appId">
</span>
</div>
<div class="form-group">
<label> APP KEY:</label>
<span class="rightside">
<input type="text" value="" ng-model="singleGatewayDetails.appKey" >
</span>
</div>
<div class="form-group">
<label> APP SECRET:</label>
<span class="rightside">
<input type="text" value="" ng-model="singleGatewayDetails.appSecret">
</span>
</div>
</div>
</div>
now
<span class="rightside">
<input type="text" value="" ng-model="paymentDetails.id" ng-disabled="appId">
</span>
This code displays some data in my textbox. And I want to display that data in textbox in both scenario, that is while editing and while posting new data to server. So it just displays it while editing but not when I want to post new data to server. Basically this textbox will always have some value pre-filled in it. So i am guessing I have to use some condition on that. So please help me how to achieve that.
I think I know what you are getting at. Without seeing your JS file it would be very hard to give you a good example, however using $scope.value in your JS and setting the text to {{value}} in your HTML should provide the desired result.
Now that I understand your question, you could do this:
<input type="text" ng-model="paymentDetails.id" ng-disabled="appId" ng-show="adding"/>
<span ng-hide="adding">{{paymentDetails.id}}</span>
And then in your controller you could control the variable:
$scope.adding = true
and set it to false based on some condition

AngularJS validation message is not displayed when the field is invalid

I'm using angularJs validation in my html form. I'm using the required validation on an input, and when I erase the value there the textbox gets highlighed in red and trying to submit the pops-out the error 'Please fill out this field' But my custom error message is not displayed. Following is the code.
<form id="settingsForm" ng-submit="vm.saveSettings()" class="form">
<td style="width:30%">
<input class="userInput" name="locationName" style="width:80%" type="text" maxlength="50" data-ng-model="vm.location.locationName" required />
<label class="validationErrorText" data-ng-show="locationSettingsForm.locationName.$error.required">Location Name Required</label>
</td>
</form>
Any idea why this happens? Attached is a screenshot of how its displayed when the field is not filled.
I have created a plunker which will help you.
http://plnkr.co/edit/GVAdjcjcYczmcmzoCqoF
<form role="form" name="signUpForm" class="form-horizontal">
<div class="form-group">
<label for="url" class="col-sm-4 control-label">URL</label>
<div class="col-sm-8">
<input type="text" class="form-control" name="url" id="url" placeholder="Enter last name"
ng-model="user.lastName" required="true" ng-pattern="/(https?:\/\/)(www)?[A-Za-z0-9.\-#_~]+\.[A-Za-z]{2,}(:[0-9]{2,5})?(\/[A-Za-z0-9\/_\-.~?&=]*)*/">
<span ng-show="signUpForm.url.$dirty && signUpForm.url.$error.required">
<small class="text-danger">Please enter valid URL.</small>
</span>
<span ng-show="signUpForm.url.$dirty && signUpForm.url.$error.pattern">
<small class="text-danger">URL should have 2 to 25 characters.</small>
</span>
</div>
</div>
</form>
You can use similar validation. The name attribute should match with the condition. Here it is url.
Add
name="locationSettingsForm"
to the <form> element

"select form" does not sync with model

This is my template:
<div class="form-group"
ng-repeat="recipeIngredient in recipes.currentRecipe._ingredients">
<label class="col-sm-2 control-label">Ingredient {{ $index + 1 }}</label>
<div class="col-sm-10 form-inline" role="form">
<input
type="text"
class="form-control"
placeholder="quantity"
ng-model="recipeIngredient.quantity"
>
<input
type="text"
class="form-control"
ng-model="recipeIngredient._unit"
>
<select
class="form-control"
ng-model="recipeIngredient._unit"
ng-options="unit._id for unit in units"
/>
<select
ng-model="recipeIngredient._ingredient"
class="form-control"
ng-model="recipeIngredient._ingredient"
ng-options="ingredient._id for ingredient in ingredients"
/>
<button
type="button"
class="btn btn-default btn-xs glyphicon glyphicon-remove"
ng-click="recipes.currentRecipe.removeRecipeIngredient($index)">
</button>
</div>
</div>
I want to display the ingredients listed in the currentRecipe
If I use:
<input type="text" class="form-control" ng-model="recipeIngredient._unit">
I can see the value of _unit showed
But why the select form does not show at all the current value of recipeIngredient._unit?
<select
class="form-control"
ng-model="recipeIngredient._unit"
ng-options="unit._id for unit in units"
/>
I've verified the the _unit is part of the list of units
If I change the value of the select box to some value, the input text show "Object", which means the real value of the model is the unit object and not the unit._id text
ng-options="unit._id for unit in units"`
Please tell me if you want additional code
I've found out that when I use:
ng-options="unit._id for unit in units"
The text showed in the drop box is unit._id, but the ng-model will be the object in unit and not the text showed!
To correct my problem I've written like this:
<select ng-model="recipeIngredient._unit" class="form-control">
<option ng-repeat="unit in getId(units, '_id')">{{unit}}</option>
</select>
the getId is the function that return a list of _id from units

Resources