How to check if one list menu have a value greater than zero in jquery form validation? - jquery-validate

I have more select menus, named menu1, menu2, menu3 etc...
All of them have values from 0 to 10. By default all are on 0.
How do I check with jquery validation plugin that at least one of the menus have a greater than zero value? Because each has a different name (I can give same class, but I do not see how this helps in validation plugin, because I can validate rules against form names not classes).

One solution is to create a custom rule.
I have adapted this answer and added a custom rule called mulitselect. This adds an error to the first dropdown list if none have a value > 0. Check the demo on jsfiddle.
note1 This currently is applied to every select list in the form, change the selector to limit it to certain select lists by class or otherwise.
note2 I added the onclick function after an invalid form has been submitted as adding it in the options resulted in validation that was a little too 'eager'.
js is as follows
$(function () {
$.validator.addMethod("multiselect", function (value, element) {
var countValid = $('select').filter(function () {
return $(this).val() > 0;
}).length;
if (countValid === 0 && $('select:first')[0] === element) {
return false;
}
else {
return true;
}
}, "please select at least one of the menus");
$('select').addClass("multiselect");
$('form').bind("invalid-form", function () {
$('form').validate().settings.onclick = function () { $("form").valid() };
}).validate({
debug: true
});
});

Related

bootstrap-multiselect rebuild/refresh not working

I have 2 bootstrap-multiselect boxes. I want to refresh the items in one based on the selections made in the other via an Ajax call.
Everything work except that the that the multiselect uses to disoplay the options is not being populated by either 'rebuild' or 'refresh'.
Code:
Decalring the multiselect"
$('#Groups').multiselect({
onChange: function (option, checked) {
//get all of the selected tiems
var values = $('#Groups option:selected');
var selected = "";
$(values).each(function (index, value) {
selected += $(value).prop('value') + ",";
});
selected = selected.substring(0, selected.length - 1);
//update hidden field with comma delimited string for state persistance
$("#Hidden_Groups").val(selected);
},
includeSelectAllOption: true
});
Updating the options list:
$('#JobCodes').multiselect({
onDropdownHide: function(event) {
console.log("start");
var option = $("#Groups");
//clear out old consolidations
option.empty();
console.log("emptied");
////get consolidation and append to select options list
$.getJSON("/Reports/GetGroups/", { options: $("#Hidden_JobCodes").val() }, function (result) {
$.each(result, function (index, item) {
console.log(item.text);
option.append($("<option />").val(item.id).text(item.text));
});
});
option.multiselect('destroy');
option.multiselect('rebuild');
option.multiselect('refresh');
},
Have left the destroy, rebuild and refresh in just as an example things i have tried. Have used all of these in every order and combination and no luck.
Destroy will "change" my multiselect back to a standard select but no matter what I do after that I cannot get the multiselect to come back with the new list of options, including using the full multiselect call wiht the onchange event present. Its either empty of has the old list. The select list has the correct options present when I make the refresh/rebuild calls.
Thanks in advance.
T
Totally my fault!!
The call to /destroy/refresh/rebuild was outside of the ajax call. so the were executing before my new list had been returned, hence no list to rebuild at that time.
Solution:
////get consolidation and append to select options list
$.getJSON("/Reports/GetGroups/", { options: $("#Hidden_JobCodes").val() }, function (result) {
$.each(result, function (index, item) {
console.log(item.text);
option.append($("<option />").val(item.id).text(item.text));
});
option.multiselect('rebuild')
});

Kendo grid enable editing during insert, disable during edit(applicable to only one column)

I have a scenario where I have a Kendo dropdown, Kendo Datepicker as couple of columns in the grid.
On Add new record, the dropdown should be editable, on Edit mode, this drop down should be non Editable.
I have declared Grid to be Editable in declaration using
.Editable()
model.Field(p => p.CountryName).Editable(true); // where CountryName is kendo dropdown
I am trying to do on Edit this way,
function OnEdit(e) {
if (e.model.isNew() == false) {
e.model.fields["CountryName"].editable = false
}
THe behaviour I observe is Initially on load, Editable is set to true (due to cshtml declaration). When I click on Edit too, the drop down is Editable because of the page load flag that is set.
Even though OnEditmethod is executed and editable is set to false, the grid seems to have loaded before this code execution, hence editable =false is not reflected.
If I click on Edit second time, now the editable is set to false due to the previous call, Hence the dropdown is non editable as expected.
In Summary, the flag setting is not effective for the current action, but for the immediate next action. I am not sure if I have made it clear. Can you guys help?
Update - The other option I tried, during databind to the grid, I tried explicitly settign editable to false to all the grid data. My assumption here was only the loaded rows will have this field set to false. But in this case even the add new record takes Editable false.
var grid2 = $("#Gridprepayment").data("kendoGrid").dataSource.data(requiredData);
$.each(requiredData, function (i, row) {
var model = $("#Gridprepayment").data("kendoGrid").dataSource.at(i);
if (model) {
model.fields["CountryName"].editable = false;
}
});
The best way is to make the column editable .
e.g.
model.Field(d => d.CountryName).Editable(true);
and Onedit function, replace the inner html like mentioned below, for just to display it as label.
function OnEdit(e) {
e.container[0].childNodes['0'].innerHTML = e.model.CountryName;
}
Try disabling the kendo dropdown in the following manner:
function OnEdit(e) {
if (e.model.isNew() == false) {
$("#CountryName").data("kendoDropDownList").enable(false);
}
}
You can try this if you want to show the dropdownList as label in edit mode
function OnEdit(e) {
if(e.container.find("input").attr("id") === 'CountryName') {
this.closeCell();
}
}
Note: The above code was written considering "CountryName" as the id of the dropdown. Please change if the id is different.
I tried this which worked.
It's only a work around :
function OnEdit(e) {
if (e.model.isNew() == false) {
if (e.container.find("input").attr("id") === 'CountryName') {
e.container.find("td:eq(0)").html($("#CountryName").val());
}
}
}

Kendo AutoComplete - force users to make valid selection

I've got a few Kendo AutoComplete fields linked to remote data (hundreds of possibilities, so DropDownList is not an option).
How can I force users to make a selection from the displayed list?
I'm also retrieving the additional data that's returned from the data source, e.g.
$("#station").kendoAutoComplete({
dataSource: stationData,
minLength: 2,
dataTextField: 'name',
select: function(e){
var dataItem = this.dataItem(e.item.index());
console.dir(dataItem);
}
});
I'm doing additional stuff with the data in dataItem and it needs to be a valid selection.
Thanks
SOLVED:
I think I was possibly over-complicating things. The answer is pretty simple and is posted below.
var valid;
$("#staton").kendoAutoComplete({
minLength: 2,
dataTextField: "name",
open: function(e) {
valid = false;
},
select: function(e){
valid = true;
},
close: function(e){
// if no valid selection - clear input
if (!valid) this.value('');
},
dataSource: datasource
});
This method allows users to type whatever they like into the AutoComplete if list not opens. There are two corrections to fix this:
initialize variable valid as false:
var valid = false;
Check if no valid selection in change event, but not in close:
...
change: function(e){ if (!valid) this.value(''); }
The answer the OP posted, in addition to the answer suggested by #Rock'n'muse are definitely good propositions, but both miss an important and desired functional aspect.
When utilizing the solution given by #Mat and implementing the change-vice-close suggestion from #Rock'n'muse, the typed-in value indeed clears from the widget if no selection is made from the filtered data source. This is great; however, if the user types in something valid and selects a value from the filtered list, then places the cursor at the end of the value and types something which now invalidates the value (doesn't return any valid selections from the data source), the typed-in value is not cleared from the widget.
What's happening is that the isValid value remains true if the previously typed-in (and valid) value should be altered. The solution to this is to set isValid to false as soon as the filtering event is triggered. When the user changes the typed-in value, the widget attempts to filter the data source in search of the typed-in value. Setting isValid to false as soon as the filter event is triggered ensures a "clean slate" for the change event as suggested by the solution from #Rock'n'muse.
Because we're setting isValid to false as soon as the filtering event is triggered, we do not need to do so in the open event (as data source filtering must occur before the user will ever see an option to select). Because of this, the open event binding was removed from #Mat's solution. This also means the initial assignment of false upon declaration of isValid is superfluous, but variable assignment upon declaration is always a good idea.
Below is the solution from #Mat along with the suggestions from #Rock'n'muse and with the filtering implementation applied:
var isValid = false;
$("#staton").kendoAutoComplete({
minLength: 2,
dataTextField: "name",
select: function () {
valid = true;
},
change: function (e) {
// if no valid selection - clear input
if (!valid) {
e.sender.value("");
}
},
filtering: function () {
valid = false;
},
dataSource: datasource
});
As an addendum, using the select event binding to set and evaluate a simple boolean value as #Mat proposes is much cleaner, simpler and faster than using a jQuery $.each(...) on the data source in order to make sure the typed-in value matches an actual item of the data source within the change event. This was my first thought at working a solution before I found the solution from #Mat (this page) and such is my reasoning for up-voting his solution and his question.
Perhaps, can you make your own validation by using the blur event :
$("#station").blur(function() {
var data = stationData,
nbData = data.length,
found = false;
for(var iData = 0; iData < nbData; iData++) {
if(this.value === data[iData].yourfieldname) // replace "yourfieldname" by the corresponding one if needed
found = true;
}
console.log(found);
});
You can check this fiddle.
You most likely need some custom logic which to intercept each key stroke after the min length of two symbols is surpassed, and prevent the option to enter a character which makes the user string not match any of the items from the autocomplete list.
For this purpose intercept the change event of the Kendo autocomplete and compare the current input value from the user against the items from the filtered list.
Hope this helps,
$("#autocomplete_id").val("");
$("#autocomplete").kendoAutoComplete({
dataSource: datasource,
minLength: 1,
dataTextField: "catname",
dataValueField:"id",
select: function(e) {
var dataItem = this.dataItem(e.item.index());
$("#autocomplete_id").val(dataItem.id);
},
dataBound: function(e){
$("#autocomplete_id").val("");
}
});
FYI, autocomplete_id is a hidden field to store the value of the autocomplete. - Sometimes, we would like to have the dataValueField other than dataTextField. So, it serves its purpose.
In this you can get the value of the autocomplete "id" from the element autocomplete_id - which is dataValueField from serverside.
In databound, its values is set to null, and on select, it is assigned the "id" value.
Although the accepted answer works, it is not the best solution.
The solution provided doesn't take into account if the user enters a value before even the kendo AutoComplete widget triggers the open event. In result, the value entered is not forced and therefore, the entry/selection is invalid.
My approach assumes that the application is running in MVC and the array is passed in ViewData. But this can be changed to suit your environment.
My approach:
var validSelect, isSelected;
$("#staton").kendoAutoComplete({
minLength: 2,
filter: "startswith",
dataTextField: "name",
filtering: function(e) {
validSelect = false;
dataArr = #Html.Raw(Json.Encode(ViewData["allStatons"]));
// for loop within the ViewData array to find for matching ID
for (var i = 0; i < dataArr .length; i++){
if (dataArr[i].ID.toString().match("^" + $("#staton").val())) {
validSelect = true;
break;
}
}
// if value entered was not found in array - clear input
if (!validSelect) $("#staton").val("");
},
select: function(e){
isSelected = true;
},
close: function(e){
// if selection is invalid or not selected from the list - clear input
if (!validSelect || !isSelected) $("#staton").val("");
},
dataSource: datasource
});
As you can see, this approach requires the array from the server side on load so that it can match during the filtering event of the widget.
I found this on Telerik's site by just using the change event. For me this works best. I added the "value === ''" check. This will catch when the user "clears" the selection.
Here's the link to the full article.
$("#countries").kendoAutoComplete({
dataSource: data,
filter: "startswith",
placeholder: "Select country...",
change: function() {
var value = this.value();
if (value === '') return;
var found = false;
var data = this.dataSource.view();
for(var idx = 0, length = data.length; idx < length; idx++) {
if (data[idx] === value) {
found = true;
break;
}
}
if (!found) {
this.value("");
alert("Custom values are not allowed");
}
}
});
In my AutoComplete Change event I check for a selected item and clear the cell if not selected.
function myAutoComplete_OnChange(e)
{
if (this.dataItem())
{
// Don't use filtered value as display, instead use this value.
e.sender.element[0].value = this.dataItem().WidgetNumber;
}
else
{
var grid = $("#grid").data("kendoGrid");
grid.dataItems()[grid.select().index()].WidgetKey = null;
grid.dataItems()[grid.select().index()].WidgetNumber = null;
}
}

Jquery validator is not un-highlighting "chosen" select box

I am using Chosen with jquery valodation.
you can see this example: http://jsfiddle.net/hfdBF/9/
if you click submit, you see that the validation is working for combo and input.
if you put one letter in the input box you will get an alert that the letter un-highlighted, as it suppose to be.
BUT, if you choose in the select box a value, it wont be alert as un-highlighted.
do you have any idea how to get that to work?
$(function() {
var $form = $("#form1");
$(".chzn-select").chosen({no_results_text: "No results matched"});
$form.validate({
errorLabelContainer: $("#form1 div.error"),
wrapper: 'div',
});
var settings = $.data($form[0], 'validator').settings;
settings.ignore += ':not(.chzn-done)';
settings.unhighlight= function(el){
alert(el.name + " hit unhighlight")
}
});​​
Thanks
You don't need to do the validation manually. You can bind a function to the change event handler that will check if the specific select is valid. This will also clear the error if the select is valid.
$('.chzn-select').change(function () {
$(this).valid();
});
You need to reset the jQuery validation manually:
$(".chzn-select").chosen().change(function () {
var value = $('#UserCompanyIds').val(); // the select element
if (value != "") {
$('.field-validation-error').each(function () {
if ($(this).attr('data-valmsg-for') == 'UserCompanyIds') {
$(this).html("");
$(this).removeClass("field-validation-error").addClass("field-validation-valid");
}
});
}
});
I hope this helps!

Jquery form :input

Is there a "simple" way to ensure that ALL the inputs in a form have "an entry". I need/want to disable the submit button unless all inputs have a value they are all input type=text. I assume it is something like for each but I am not very good at the for each in JQuery. Possible problem is that the inputs are "dynamically" generated by sortables? All I need to know is is there a value in every input field. The "real" validation is done elsewhere.
So is it something like:
$j('#button').click(function (){
each(function(:input){
//check the length in here?
});
});
Is this post useful http://forum.jquery.com/topic/enable-disable-submit-depending-on-filled-out-form?
$("#button").click(function(event) {
var valid = true;
$(":input").each(function(index) {
if ($(this).val().length == 0) {
valid = false;
}
});
if (!valid) {
event.preventDefault();
}
});
Should work.
First part grabs the element with id of button, then assigns a function to the onclick event. Second part grabs all input fields, and run a function on each of them. Then you get the length of the value for each.
The $(this) works since the function is being applied to a specific element on the page, and will always get you the current element.

Resources