bootstrapvalidator for checkbox - angularjs

I have a checkbox control which is dynamically filled. There are 3 checkboxes in the group. I am trying to check if at least one checkbox is selected, when user clicks on submit button. I have tried the below code, but I am not getting the error, and the page is getting saved. Below is the UI code
<input type="checkbox" id="{{method.id}}" value="{{method.value}}"
name="deliveryMethod[]" ng-model="method.selected"
ng-click="toggleSelection(method.value)"
ng-required="value.length==0"> {{method.value}}
In the js file, i tried as below:
jQuery("#createForm").bootstrapValidator({
framework: 'bootstrap',
excluded: [':disabled', ':hidden', ':not(:visible)'],
icon: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
fields: {
TypeSelect: {
validators: {
callback: {
message: 'Please select the type',
callback: function (value, validator, $field) {
var options = validator.getFieldElements('testTypeSelect').val();
return (options != null && options.length >= 1);
}
}
}
},
testName: {
validators: {
notEmpty: {
message: 'name required.'
}
}
},
"deliveryMethod[]": {
validators: {
required: true,
minlength: 1,
maxlength: 3,
message: 'Delivery Type is Mandatory.'
}
},
}
How to make at least one checkbox is checked, if not show the message.
Thanks

Related

How to make a dynamic watch()/usewatch() with react-hook-forms

I am having an issue were I need to generate a form from a schema and have fields dependent on each other such as enabled/disable show/hide etc.
my schema looks something like this.
contractorInformation: {
title: "ContractorInformation",
type: "object",
properties: {
contractorName: {
title: "Contractor Name",
type: "string",
ui: "input",
constraints: {
required: true
}
},
contractorFavouriteAnimal: {
title: "Contractor Favourite Animal",
type: "string",
ui: "input",
constraints: {},
dependencies: {
disabled: true,
watching: "contractorName"
// //disabled={!fullName || fullName.length === 0 || errors.fullName}
}
},
contractorEmail: {
title: "Contractor Email",
type: "string",
ui: "input",
constraints: {
common: 10
}
}
}
},
agencyInformation: {
title: "ContractorInformation",
type: "object",
properties: {
contractorName: {
title: "Contractor Name",
type: "string",
ui: "input",
constraints: {
required: true,
minLength: 3,
maxLength: 5
},
dependencies: {
disabled: true,
watching: "agencyName"
}
}
}
}
}
const watchThese = watch()
would allow me to watch everything but if I wanted to change this field from disabled to enabled I could use
<input disabled={!watchThese || watchThese.length === 0 || watchThese.fullName}/>
which works but is obviously triggered by every field.
How could I generate a dynamic watch()/useWatch() from a schema and be able to access the specific dependencies I need to enable/disable the input.
Any help would be gratefully received.
For future reference I solved it by using
export const FormField = () =>
{Object.entries(schema?.actions ?? {}).forEach(([key, value]) => value(watch(key)));
return (<div></div>)}
and update schema to match.

FormValidation.io with bootstrap select

I'm using Boost strap 4 and the bootstrap select jQuery plugin.
Im trying to integrate FormValidation.io with my forms. I have got everything working with normal input fields but cant figure out how to integrate it with the select field.
I would like it to be a required field and display the tick icon once a selection has been made.
my FormValidation.io code :
document.addEventListener('DOMContentLoaded', function(e) {
const mydropzone = document.getElementById('mydropzone');
const RoleIdField = jQuery(mydropzone.querySelector('[name="roleId"]'));
const fv = FormValidation.formValidation(mydropzone, {
fields: {
first_name: {
validators: {
notEmpty: {
message: 'First Name is required'
},
regexp: {
regexp: /^[a-zA-Z]+$/,
message: 'First Name can only consist of alphabetical characters'
}
}
},
last_name: {
validators: {
notEmpty: {
message: 'Last Name is required'
},
regexp: {
regexp: /^[a-zA-Z]+$/,
message: 'First Name can only consist of alphabetical characters'
}
}
},
roleId: {
validators: {
notEmpty: {
message: 'Please select a Role'
},
}
},
},
plugins: {
trigger: new FormValidation.plugins.Trigger(),
bootstrap: new FormValidation.plugins.Bootstrap(),
submitButton: new FormValidation.plugins.SubmitButton(),
icon: new FormValidation.plugins.Icon({
valid: 'fa fa-check',
invalid: 'fa fa-times',
validating: 'fa fa-refresh'
}),
}
}
);
});
$('#roleId').on('changed.bs.select', function (e, clickedIndex, isSelected, previousValue) {
// Revalidate the color field when an option is chosen
fv.revalidateField('roelId');
});
My form ID is 'mydropzone' and my select name and id are 'roleId'
Any help appreciated.
Thanks to the developers who answered my email, anyone else that needs to know how this is done:
add this to your css file :
.bootstrap-select i.fv-plugins-icon {
right: -38px !important;
then configure your js like this :
<script>
document.addEventListener('DOMContentLoaded', function(e) {
$('#gender').selectpicker();
const demoForm = document.getElementById('demoForm');
FormValidation.formValidation(demoForm, {
fields: {
gender: {
validators: {
notEmpty: {
message: 'The gender is required'
}
}
},
},
plugins: {
trigger: new FormValidation.plugins.Trigger(),
submitButton: new FormValidation.plugins.SubmitButton(),
bootstrap: new FormValidation.plugins.Bootstrap(),
icon: new FormValidation.plugins.Icon({
valid: 'fa fa-check',
invalid: 'fa fa-times',
validating: 'fa fa-refresh'
}),
}
});
});
</script>

read the Form component from #fluentui/react-northstar#0.48.0

There is a nice looking schema-based Form component on fluentui
import React from 'react';
import { Form, Button } from '#fluentui/react-northstar';
const fields = [
{
label: 'First name',
name: 'firstName',
id: 'first-name-shorthand',
key: 'first-name',
required: true,
},
{
label: 'Last name',
name: 'lastName',
id: 'last-name-shorthand',
key: 'last-name',
required: true,
},
{
label: 'I agree to the Terms and Conditions',
control: {
as: 'input',
},
type: 'checkbox',
id: 'conditions-shorthand',
key: 'conditions',
},
{
control: {
as: Button,
content: 'Submit',
},
key: 'submit',
},
];
const FormExample = () => (
<Form
onSubmit={() => {
alert('Form submitted');
}}
fields={fields}
/>
);
export default FormExample;
But they don't offer any method/example to collect the data from what I can tell. (at least not in the documentation).
I can collect most values from the onSubmit event but it get's hacky because not all html components are necessarily input elements that have the value attribute. I also don't think this is the intended way to do it. Anyone can enlighten me please? I think you must be able to feed the onChange function to it somehow. Or am i supposed to add the onChange function in each field-object?
I ended up combing through the library components (Forms Input and Checkbox) to see what makes them tick.
This is what I ended up with. Please feel free to improve on it should anyone else stumble on this in the future.
Note the use of the attributes defaultValue and defaultChecked to set the initial value of the Input and Checkbox components respectively. As well as the onChange event passing the name and value parameters for the Input component and name and checked for the Checkbox component.
The Checkbox label must be inside the Control if you wish it to appear next to the checkbox, otherwise it will appear above the checkbox.
import React, { Component } from 'react';
import { Form, Button, Checkbox, Input } from '#fluentui/react-northstar';
class Login extends Component {
constructor(props) {
super(props);
this.handleSubmit.bind(this)
}
state = {
email: "",
password: "",
remember_me: true
}
fields = [
{
label: 'Email',
name: 'email',
id: 'email-inline-shorthand',
key: 'email',
required: true,
inline: true,
type: 'email',
control: {
as: Input,
defaultValue: this.state.email,
onChange: (e, { name, value }) => this.setState({ ...this.state, [name]: value })
}
},
{
label: 'Password',
name: 'password',
id: 'password-inline-shorthand',
key: 'password',
required: true,
inline: true,
type: 'password',
control: {
defaultValue: this.state.password,
onChange: (e, { name, value }) => this.setState({ ...this.state, [name]: value }),
as: Input,
}
},
{
name: "remember_me",
key: 'remember_me',
id: 'remember_me-inline-shorthand',
type: 'boolean',
control: {
label: 'Remember me',
as: Checkbox,
defaultChecked: !!this.state.remember_me,
onChange: (e, { name, checked }) => { this.setState({ ...this.state, [name]: checked }) }
},
},
{
control: {
as: Button,
content: 'Submit',
},
key: 'submit',
},
]
handleSubmit = (e) => {
console.log("submitting these values", this.state)
}
render() {
return (
<Form
onSubmit={this.handleSubmit}
fields={this.fields}
/>
)
}
};
export default Login;

AngularJS Kendo UI grid with row filters behaviour

I am using Kendo UI Grid with row filters. i am facing filters options issue. I am using Filterbale.cell.template for filters to display kendo autoComplete.
Issue is as displayed in image autocomplete options are not updating on selecting of one of the filters.
Below is my html
<div ng-controller="VehiclesController" class="my-grid" >
<kendo-grid options="vehiclesGridOption">
</kendo-grid>
</div>
Below is my Controller
$scope.vehiclesGridOption = {
dataSource: {
schema: {
id: "_id",
model: {
fields: {
make: {type: "string"},
model: {type: "string"},
year: {type: "number"}
}
}
},
transport: {
read: function (e) {
vehicleService.vehicles().then(function (response) {
e.success(response);
console.log(response.length);
}).then(function () {
console.log("error happened");
})
}
},
pageSize: 12,
pageSizes: false,
},
sortable: {
mode: "multiple",
allowUnsort: true
},
filterable: {
mode: "row"
},
pageable: {
buttonCount: 5
},
columns: [
{
title: "",
template: '',
width: "3%" // ACTS AS SPACER
},
{
field: "make",
title: "Make",
filterable: {
cell: {
operator: "contains",
template: function (args) {
args.element.kendoAutoComplete({
dataSource: args.dataSource,
dataTextField: "make",
dataValueField: "make",
valuePrimitive: true,
placeholder: "Make",
});
}
}
},
width: "29%",
}, {
field: "model",
filterable: {
cell: {
operator: "contains",
template: function (args) {
console.log(args);
args.element.kendoAutoComplete({
dataSource: args.dataSource,
dataTextField: "model",
dataValueField: "model",
valuePrimitive: true,
placeholder: "Model",
});
}
}
},
title: "Model",
width: "29%",
}, {
field: "year",
title: "Year",
filterable: {
cell: {
template: function (args) {
args.element.kendoAutoComplete({
dataSource: args.dataSource,
dataTextField: "year",
dataValueField: "year",
placeholder: "Year",
suggest: true,
ignoreCase: true,
filter: "gte"
});
}
}
},
width: "29%",
},
{
field: "",
title: "Edit",
template: '<a class=\"k-link text-center grid-edit-btn vehicle-grid-edit-btn\" ui-sref="vehicleDetails({\'id\': \'#=_id #\' })"><span class=\"icon-editpencil icon-grid\"></span></a>',
width: "10%",
}],
};
Below is the Issue if user selects the Make in the first column filter then Model filter should display only selected make models like Honda (make)-> Accord , Civic ..etc but its displaying all unique values irrespective of model filter..
Kendo filter row uses the same dataSource from the grid component, just providing unique values. Since the autocomplete components are initialized when the grid dataSource is empty, they always show all the values.
You can manually filter based on current filter row values.
Firstly, add ids for your coresponding autocomplete components i.e. inside template functions:
args.element.attr('id', 'make');
//<...>
args.element.attr('id', 'model');
//<...>
args.element.attr('id', 'year');
Then add a data bound event to the grid (since autocomplete components do not fire change events when filters are cleared).
$scope.vehiclesGridOption = {
//...
dataBound : function(e) {
setTimeout(function() { //timeout is to make sure value() is already updated
var make = $('#make').data('kendoAutoComplete').value();
if (make) {
$('#model').data('kendoAutoComplete').dataSource.filter({field: 'make', operator: 'eq', value: make });
} else {
$('#model').data('kendoAutoComplete').dataSource.filter({});
}
});
}
}
Or if you also want to filter by "Year" column, it could go like this:
$scope.vehiclesGridOption = {
//...
dataBound: function(e) {
setTimeout(function() { //timeout is to make sure value() is already updated
var make = $('#make').data('kendoAutoComplete').value();
var model = $('#model').data('kendoAutoComplete').value();
if (make) {
$('#model').data('kendoAutoComplete').dataSource.filter({field: 'make', operator: 'eq', value: make });
} else {
$('#model').data('kendoAutoComplete').dataSource.filter({});
}
var yearFilter = {filters: [], logic: 'and'};
if (make) {
yearFilter.filters.push({field: 'make', operator: 'eq', value: make });
}
if (model) {
yearFilter.filters.push({field: 'model', operator: 'eq', value: model });
}
$('#year').data('kendoAutoComplete').dataSource.filter(yearFilter.filters.length ? yearFilter : null);
});
}
}

KendoUI Grid' DataSource parametermap's data.sort array becomes undefined on 3rd column sort click

I've got a datagrid configured as follows:
<script>
angular.module("KendoDemos", [ "kendo.directives" ]);
function MyCtrl($scope) {
$scope.mainGridOptions = {
dataSource: {
transport: {
read: {
url: "http://localhost:8090/rest/mycodeapi/Salesman?app_name=mycode&fields=FirstName%2C%20LastName&include_count=true",
dataType : 'jsonp',
type: 'GET',
beforeSend: function (req) {
req.setRequestHeader('Authorization', 'b3pilsnuhsppon2qmcmsf7uvj6')
}
},
parameterMap: function(data, type) {
if (type == "read") {
// send take as "$top" and skip as "$skip"
return {
order: data.sort[0]['field'] + ' ' + data.sort[0]['dir'],
limit: data.pageSize,
offset: data.skip
};
}
}
},
schema: {
data : 'record',
total: 'meta.count'
},
pageSize: 5,
serverPaging: true,
serverSorting: true,
sort: { field: "SalesmanID", dir: "asc" }
},
sortable: true,
pageable: true,
mobile: 'phone',
columns: [{
field: "FirstName",
title: "First Name"
},{
field: "LastName",
title: "Last Name"
}]
};
}
</script>
Problem is: on 1st click of the any column, say FirstName, it sorts by ascending order which is fine.
On 2nd click it sorts by descending: still the expected behaviour.
On the 3rd click however, nothing happens and the console reveals "Uncaught TypeError: Cannot read property 'field' of undefined ". This means something happens to the data.sort array after the 2nd consecutive click.
Would appreciate any pointers.
On third click the sorting is removed. You can modify your script like following:
if (type == "read") {
var params = {
limit: data.pageSize,
offset: data.skip
};
if (data.sort && data.sort.length > 0)
params.order = data.sort[0]['field'] + ' ' + data.sort[0]['dir'];
return params;
}
I know this is a bit late, but I was facing the same challenge, and this is what I did to resolve the issue.
Change
sortable: true,
to
sortable: {
allowUnsort: false
},

Resources