NumericTextBox with 4 decimal places - kendo-ui

I'm guessing that with the impending changes to the way Kendo's forums work (only paid customers) there's going to be little chance of getting a question answered on there, so I'll try here instead...
I've setup an editable grid that's using custom validators for two numeric fields. The validators use an ajax query obtain valid parameters (but I don't think that's important).
This is all working, but I need the NumericTextBoxes to support 4 decimal places, which they don't by default.
I've created custom Grid editors for these fields and this allows me to enter 4 decimal places, but it breaks the custom validation.
How can I get the NumericTextBoxes to support 4 decimal places in edit mode AND allow custom validation rules?
Thanks in advance
Here's the field definition, with validator that I'm using:
end: { type: 'number', validation: {
end: function(input){
if (input.attr('name')=='end' && $('input[name=lookup]').val()!=''){
$.ajax({
type: 'post',
url: '/ajax/lookupParams',
data: { lookup:$('input[name=lookup]').val(), csrf_token: token },
success: function(data) {
start = data.start;
end = data.end
},
dataType: 'json',
async: false
});
input.attr('data-end-msg', 'End must be between '+start+' and '+end);
return (input.val() >= start && input.val() <= end);
}
return true;
}
}
This bit works -- ajax is used to retrieve valid start and end values, based on the current value of the lookup field. It just stops working if I use a custom editor to support 4 decimal places.

KendoUI NumericTextBoxes supports 4 decimal and validations:
Having the following HTML:
<input id="num" value="123.456789"
data-format="n4"
data-decimals="4"
data-step="0.0001"
data-role="numerictextbox"/>
and the following initialization:
$("#num").kendoValidator({
rules :{
custom:function (input) {
var val = Math.floor(input.val() * 10000);
return val % 2;
}
},
messages:{
custom:"Your number * 10000 needs to be odd"
}
});
kendo.init($("#num"));
This defines a NumericTextBox with four digits -both in visualization and edition mode- and with a custom Validator that check that the last digit of your decimal number is odd.
And by the way, Welcome to KendoUI on Stack Overflow!!

Related

How I can choose conditionally parameter from multiple dependent combo boxes in SpagoBI

How I can choose conditionally parameter from multiple dependent combo boxes with subqueries and send it to a report?
I have a BIRT report which use a stored procedure which expect parameter #category_id
The input should come from one of three combo boxes:
Combo with categories level 1
Combo with categories level 2
Combo with categories level 3
When you select something in combo 1 combo 2 is populated executing subquery which depends on value from combo 1.
When you select something in combo 2 combo 3 is populated executing subquery which depends on value from combo 2.
If combo 3 has a selected value this is sent for parameter #category_id
If combo 3 has not a selected value and combo 2 has selected value this is sent for parameter #category_id
If combo 2 and 3 are not selected combo 1 is sent for parameter #category_id
Any idea how to do it?
this is ruff code hope it will helps you :
$("#combobox1").change(function(){
var selval1=$(this).val();
var dataString="combo1data="+selval1;// get data from ajax related to this value from ajax
$.ajax({
url: "somepage",
type: "POST",
data: dataString,
success: function(cbdata2){
fillcombo2(cbdata2);
}
});
)};
$("#combobox2").change(function(){
var selval2=$(this).val();
var dataString="combo2data="+selval2;// get data from ajax related to this value from ajax
$.ajax({
url: "somepage",
type: "POST",
data: dataString,
success: function(cbdata3){
fillcombo3(cbdata3);
}
});
)};
$("#submitbutton).click(function(){
var val3=$("#combobox3 option:selected").val();
if(val3=="")
{
var val2=$("#combobox2 option:selected").val();
if(val2=="")
{
var val1=$("#combobox2 option:selected").val();
if(val2=="")
{
var val1=$("#combobox1 option:selected").val();
}
else
{
//use val1
}
}
else
{
//use val2
}
}
else
{
//use val3
}
});
You are going to want to use cascading parameters.
Set the default value to % (wild card)
Use a like Statement in your SQL Query, if 2 and 3 remain % then it searches for everything. If they are populated is searches for the specific value.

KendoUI grid minlength not working

can KendoUI grid enforce minlength validation. I have some troubles with it. Look at the screenshot.
I have set minlength and maxlength. It doesn't allow me to enter more than 10 letters, however, I can enter less than 2 letters and update the entry in grid.
Is this Kendo issue?
As mentioned in my comments, minlength doesn't work because that attribute doesn't exist in HTML5 whereas maxlength does.
Instead, you have to use custom validation, or use the pattern attribute.
Pattern Attribute
my_name {
validation: {
required: true,
pattern:'.{2,10}'
}
},
This means that my_name must be between 2 to 10 characters. It will allow you to type less or more, but will throw invalid message when you try to update.
Custom Validation:
my_name {
validation: {
required: true,
lengthRule: function (input) {
if (input.is("[name='DirectionName']") && input.val() !== "") {
input.attr("data-lengthRule-msg", "My Name must be between 2 to 10 characters.");
return (input.val().length<=10 && input.val().length>=2);
}
return true;
},
}
},
With the latter method, there is a known bug, so I am not to keen on using the latter method.
Custom Valiation Bug FYI: Validation is not always triggered when editing with backspace

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;
}
}

Using jQGrid and jQUery tabs how to oprimize the number of grids

I have 3 different tabs where i am displaying data using jQGrids(each tab contain one grid).
But i just thought that my grids are completely the same, only the difference is that they using different url to get data.
So I have three similar girds on each tab only with different urls:
First: url: '/Home/GetData?id=1' Second: url: '/Home/GetData?id=2' and Third: url: '/Home/GetData?id=3'
So i was thinking that may be i may declare grid only once and than on each tab click a can pass the url to load data? So on each tab click jQGrid will be populating from the new url.
May be some one may have any ideas about that?
Or may be some one may have better ideas how to reduce "jQGrid copy-paste" in that case?
UPDATE 0:
Nearly get it work i mean it is working but there is one small problem,
When i am switching tabs the header of the grid getting lost...and some jqgrid formatting as well.
here is my code:
$("#tabs").tabs({
show: function (event, ui) {
if (ui.index == 0) {
//$("#Grid1").appendTo("#tab1");
//$("#Grid1Pager").appendTo("#tab1");
//When Appending only pager and grid div, header getting lost so i've append the whole grid html instead
$("#gbox_Grid1").appendTo("#tab1");
changeGrid("#Grid1", 1);
}
else if (ui.index == 1) {
//$("#Grid1").appendTo("#tab2");
//$("#Grid1Pager").appendTo("#tab2");
$("#gbox_Grid1").appendTo("#tab2");
changeGrid("#Grid1", 2);
}
else if (ui.index == 2) {
//$("#Grid1").appendTo("#tab3");
//$("#Grid1Pager").appendTo("#tab3");
$("#gbox_Grid1").appendTo("#tab3");
changeGrid("#Grid1", 3);
}
}
});
function changeGrid(grid, id) {
$(grid).jqGrid('setGridParam', {
url: '/Home/GetData?id=' + id
});
$(grid).trigger('reloadGrid');
}
UPDATE 1
All right, i've changed the code to append the whole grid instead of appending grid div and pager only. So it is working like that.
You can basically make the tabs as regular buttons that will call some function which sets new URL parameter to the grid and reloads it.
The function should be something like this:
function changeGrid(grid, id) {
$(grid).jqGrid('setGridParam', {
url: '/Home/GetData?id=' + id, page: 1
});
$(grid).trigger('reloadGrid');
}
Note that I set the page to 1. Keep in mind that you might need to set the default sorting column or something similar depending on your solution.
UPDATE
If you really want to go with the tabs, the 'show' event handler can be simplified.
Try this:
$("#tabs").tabs({
show: function (event, ui) {
var id = ui.index + 1;
$("#gbox_Grid1").appendTo("#tab" + id);
$("#Grid1").jqGrid('setGridParam', {
url: '/Home/GetData?id=' + id
});
$("#Grid1").trigger('reloadGrid');
}
});

Spring MVC: Auto-save functionality (jQuery, Ajax...)

I'd like to implement a "auto-save" functionality on my page. I don't really know how to start though. I got one object (with a list of tasks). I'd like to submit the form every 20 seconds, so the users won't lose their data. It doesn't have to be exactly like that. After every submit the submit-button should be disabled as long as there are no changes.
I'm using Spring MVC. I did some research but I'm not an expert in jQuery, Spring... So it's all pretty complicated for me. A tip, or a working example would help me a lot.
It's a pretty complex form (a timesheet). There are +/- 50 textboxes on one page (minimum, depends on the number of tasks available)
Thanks.
I don't know what spring mvc is, but in ASP.NET MVC I would do the following:
I assume all your data is in a form, you give the form an ID, then post it:
$(function () {
var timer = 0;
$(this).mousemove(function(e){
timer = 0;
});
$(this).keypress(function() {
timer = 0;
});
window.setInterval(function () {
timer++;
if (timer == 20) {
$('#form').submit(function() {
});
}
}, 1000);
});
Checks for mousemove, keypress, if this isnt done in 20 seconds then it saves the form.
Edit: What you could also do maybe is, after every textbox they fill in, post the data: as followed:
http://api.jquery.com/change/
$('.textbox').change(function() {
$.ajax({
url: '/Save/Textbox',
data: 'TextBoxId=' + $(this).id + '&TextValue=' + $(this).value
});
});
In this example, you make a controller called Save, action called Textbox, you give the textbox the ID of data that it has to save, and on change (after un focussing the textbox), it posts the textbox id, and the value of the box.
then in the controller you retrieve it:
public void SaveText(string TextBoxId, string TextValue) {
// SAVE
}
Below Js script will help you to make ajax call when ever form field changes.
<script>
$(document).ready($('.form-control').change(function() {
$.ajax({
type : "post",
url : "http://localhost:8521/SpringExamples/autosave/save.htm",
cache : false,
data : $('#employeeForm').serialize(),
success : function(response) {
var obj = JSON.parse(response);
$("#alert").text(JSON.stringify(obj));
$("#alert").addClass("alert-success");
},
error : function() {
alert('Error while request..');
}
});
}));
</script>

Resources