How can I refresh value kendo numerictextbox? - kendo-ui

I have a kendoNumericTextBox. I have code that sets the value of the input element associated with the kendoNumericTextBox. For example, the code calls:
$('#myId').val('test');
Unfortunately, the kendo numeric text box doesn't automatically reflect the value. How can I tell the kendoNumericTextBox to update its value? I know there's a method on kendoNumericTextBox as follows:
$('#myId').data('kendoNumericTextBox').value('test');
However, I'm populating many fields and not exactly sure which ones will be kendoNumericTextBox fields. So, I prefer to call something like I do with the chosen plugin to refresh the value based on the underlying component. For example, with the chosen plugin, I can call:
$('.chosen').trigger('liszt:updated');
to update all values based on the underlying select component's value.

var numerictextbox = $("#paymentAmount_" + id).data("kendoNumericTextBox");
numerictextbox.value("0.00");
This works for me. Store the element in a variable and the set the value using double quotes. Also I was not able to put a word in like 'test' in a numericTextBox...I am assuming you meant that as test data. But this should work for you as well.

i was having trouble with this same thing, I However got it working without the quotes...
all that i can say is that it seems to work for now....
calCalories: function (e) {
var totalCals = 0;
totalCals = totalCals + ($("#Carbs").val() * 4);
totalCals = totalCals + ($("#Protein").val() * 4);
totalCals = totalCals + ($("#Fat").val() * 9);
var numerictextbox = $("#Calories").data("kendoNumericTextBox");
numerictextbox.value(totalCals);
},
note:
one could obviously use the below line of code to get the value from the event
e.sender.value()

Just trigger change event for kendo numeric textbox
$('#myId').data('kendoNumericTextBox').trigger('change');

Related

HandsonTable not rendering all rows

HandsonTable is not rendering all rows - it loads only part of all rows. But when I do Ctrl+A and paste into Excel I see all the rows. Why is Handsontable not displaying all the rows?
<hot-table col-headers="true" row-headers="true" datarows="data" context-menu width="1080">
<hot-column ng-repeat="column in columns" data="{{column.data}}"></hot-column>
</hot-table>
To render all rows, just set renderAllRows: true
The current answer does not answer the original question.
Handsontable does not render all cells at once because it is designed to be efficient for very large data sets. It does this using virtual rendering, dynamically modifying the DOM to include only the cells at the scroll position.
The rows virtual rendering can be disabled by setting renderAllRows: true, as described in the docs: "If typed true then virtual rendering mechanism for handsontable will be disabled." Although it will then not be as efficient for large data sets.
You can also change the number of pre-rendered rows and columns instead of rendering them all. From the performance tips,
You can explicitly specify the number of rows and columns to be rendered outside of the visible part of the table. In some cases you can achieve better results by setting a lower number (as less elements get rendered), but sometimes setting a larger number may also work well (as less operations are being made on each scroll event). Tweaking these settings and finding the sweet spot may improve the feeling of your Handsontable implementation.
This is done by setting viewportRowRenderingOffset and viewportColumnRenderingOffset in the handsontable options. These are by default set to auto which lets handsontable try to find the best value, but may be provided an integer value (e.g. viewportRowRenderingOffset: 70, viewportColumnRenderingOffset: 70).
I had the same problem (using HandsOnTable 6.2.1 and the old AngularJS) and customers would start complaining about not being sure if they were at the end of the table or not.
I was able to create two buttons linked to the functions 'scrollToBeginning' and 'scrollToEnd'. This way the user is sure to be at the last line. Three things specific about my answer:
I expose the functions to the DOM using $scope;
I have an object 'goToLine' holding 3 properties (scrollingToEnd: boolean, row: number, col: number), it is used in other functions not posted here;
I have a list of ID referencing HandsOnTable objects stored in $scope.hots.
Here is my raw solution, feel free to adapt / enhance:
$scope.stopScrollingToEnd = function () {
$scope.goToLine.scrollingToEnd = false;
};
$scope.scrollToBeginning = function (goToLine) {
$scope.stopScrollingToEnd();
const hot = $scope.hots[goToLine.id];
hot.scrollViewportTo(0, 0);
};
/**
* Scroll to the end of the List Element.
* We need this functionality because of a bug in HandsOnTable related to its Virtualization process.
* In some cases (complex table), when manually scrolling, the max row is wrong, hence causing major confusion for the user.
* #param {*} goToLine
* #returns
*/
$scope.scrollToEnd = function (goToLine) {
// We scroll to the first line before going to the last to avoid the bug and being sure we get to the last line
$scope.scrollToBeginning(goToLine);
const hot = $scope.hots[goToLine.id];
var numberOfRows = hot.countRows();
// This variable is used to repeat the scrollViewportTo command.
// It is built using the length of `numberOfRows`.
var repeat = numberOfRows ? 1 * Math.ceil(Math.log10(numberOfRows + 1)) : 1;
// Used in other goTo function to avoid conflict.
$scope.goToLine.scrollingToEnd = true;
// FIXME : not supposed to call scrollViewportTo several times... => fixed in recent versions of HandsOnTable ?
for (let n = 0; n < repeat; n++) {
if (!$scope.goToLine.scrollingToEnd) {
return;
}
setTimeout(function () {
if (!$scope.goToLine.scrollingToEnd) {
return;
}
hot.scrollViewportTo(numberOfRows - 1, 0);
}, 500);
}
};

Copy/paste data validation in Google Spreadsheets

I feel a bit silly not being able to figure this out. So this is the data validation I have set up:
Cell Range: Journal!J2
Criteria: List from a range - Journal!W2:X2
Cell Range: Journal!M2
Criteria: List from a range - Journal!Y2:AA2
This is great in my first row. I create another row and I'd like it to update all of the '2' to '3'. The cell range updates correctly, but the criteria does not, and I can't figure out an easy solution other than going in and updating it manually.
I've tried copy/paste as well as paste special -> data validation.
I know something like $Y$2 would fix the row/col but that's the opposite of what I want. I guess I'm wanting to maintain the relative formula vs it being an absolute formula?
Indeed, the "list from a range" type of validation treats the reference to the list as absolute rather than relative. I know two workarounds:
Custom formula
Validation based on the custom formula
=not(isna(match(J2, W2:X2, 0)))
is equivalent to "value must be from the range W2:X2", and it will be copied down correctly, the reference to W2:X2 being relative.
Drawback: you don't get an in-cell dropdown list with custom formula validation.
Script
One can use an Apps Script to manage data validation rules. The following script sets data validation rules in each cell of the range J2:J100, where the value is required to be from W:X of the same row.
function validate() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("J2:J100");
var valuesColumn = 23; // begins in W
var valuesLength = 2; // has length 2, so W:X
var firstRow = range.getRow();
for (var i = 0; i < range.getHeight(); i++) {
var rule = SpreadsheetApp.newDataValidation()
.requireValueInRange(sheet.getRange(firstRow + i, valuesColumn, 1, valuesLength), true)
.setAllowInvalid(false)
.build();
range.offset(i, 0, 1, 1).setDataValidation(rule);
}
}

Programatically updating underlying data in Slickgrid

I have 6 textboxes at the top of the screen that update an entire column(one textbox per column) based on any changes. I was selecting the columns based on their class (.l#). Here is the code (issues to follow):
function UpdateField() {
var ctrl = this;
var id = parseInt(ctrl.id.replace("item", ""), 10) - 1;
var bound = [".l1", ".l7", ".l8", ".l9"];
var fields = $(bound[id]);
for (var i = 0; i < fields.length; i++)
{
fields[i].innerHTML = $(ctrl).val();
}
};
which is bound to the keyup event for the text areas. Issues are:
1) initially fields.length was -1 as I didn't want to put data in the "add new
row" section at the bottom. However, when running it, I noticed the
final "real" record wasn't being populated. Also, when stepping through, I
noticed that the "new row" field was before the "last row" field.
2) when doing it this way, it is purely superficial: if I double click the field,
the real data hasn't been changed.
so in the grand scheme of things, I know that I was doing it wrong. I'm assuming it involves updating the data and then forcing a render, but I'm not certain.
Figured out how to do it. Modified the original code this way:
function UpdateField() {
var ctrl = this;
var id = parseInt(ctrl.id.replace("item", ""), 10) - 1;
var bound = ['title1', 'title2', 'title3', 'title4'];
var field = bound[id];
for (var i = 0; i < dataView.getLength(); i++)
{
var item = dataView.getItem(i);
item[field] = $(ctrl).val();
dataView.updateItem(i, item);
}
grid.invalidate();
};
I have 6 textboxes (item1-item6) that "bind" to fields in the sense that if I change data in a textbox, it updates all of the rows and any new rows added also have this data.
Parts where the two issues can be explained this way:
1) to work around that, though still it would be a presentational fix and not a real updating of the underlying data, one could force it to ignore if it had the active class attached. Extra work, and not in the "real" direction one is going for (masking the field).
2) It was pretty obvious with the original implementation (though it was all I could figure out via Chrome Dev Tools that I could modify at the time) that it was merely updating a div's content and not actually interacting with the data underneath. Would look nice, and perhaps one could just pull data from the item1-item6 boxes in place of the column if it is submitted, but if someone attempts to modify the cell, they'll be looking at the real data again.

How to select a row in kendo grid by data item ID?

I need to select a specific row in kendoGrid but NOT by data-uid (as data-uid is changed when the grid dataSource is loaded again) but by the row itemID. I saw posts but they only select the row by uid which is not what I needed, I actually need to restart the HTML5 application and when grid is loaded, a specific item should be selected. This is what I've been seeing
Demo: jsfiddle.net/rusev/qvKRk/3/
e.g. the object has OrderID as ID, and every time the grid is loaded, it will be the same, unlike uid, I want to know how will I be able to select a row with OrderID, instead of uid.
You cam mix row itemID and data.uid, I guess.
var grid = $("#Grid").data("kendoGrid");
var dataItem = $("#Grid").data("kendoGrid").dataSource.get(itemID);
var row = $("#Grid").data("kendoGrid").tbody.find("tr[data-uid='" + dataItem.uid + "']");
Going along with what umais has mentioned, the better approach, since there is no built in functionality for this as of yet, would be to iterate through all the records to find the one you need. The function that I built will work even if there are pages of data. The only other way that I can think of doing this would be do do a secondary ajax call; But this works well. Note that i haven't tested it with more than 2000 records.
var dataGrid = $("#GATIPS").data("kendoGrid").dataSource;
var numOfRows = dataGrid.total();
var currentPageSize = dataGrid.pageSize();
dataGrid.pageSize(numOfRows);
var dataGridData = dataGrid.data();
for (var i = 0; i < numOfRows; i++) {
if (dataGridData[i].uid == e)
return dataGridData[i];
}
dataGrid.pageSize(currentPageSize); // reset the view
e is the UID. However this can be substituted for what ever variable you need just replace the check.
a work around that I managed to have, was to go through all rows and check which row model has that ID equal to the parameter, and then get that row data-uid and select the item through data-uid. It's working fine for me, since there were no suggestion, it's the better answer for now.
Well, accordingly to what I have done (and worked for me), and even though the work around isn't the prettiest, set one more Column, with your model id and with ClientTemplate then create any html object (div in my case) inside it give it a html id of your id, so when ever you need it, you just have to go and look with something like:
grid.dataItem($("td div#id").closest("tr"));
Because remember that the dataItem method is waiting for a selector then you get your selectedItem as regular one.
EDIT:
I forgot to say, that you should (or could) use the style property
display:none
If you don't want to display that col.

jqGrid cell editing need to position the error message dialog

I'm using jqGrid with cell editing. I have setup the colModel properties using the editrules option. Everything works fine in that if I edit a cell and try to save an invalid value the grid displays an error dialog, but I need to know how to position the error message dialog that comes up because in the case of my layout it ends up behind a video. I'm not quite sure how to hook into this and there don't seem to be any obvious options on how to do it.
In this case the dialog I would be trying to manipulate is the one with ID of info_dialog.
Also I'm using the clientArray option for cellsubmit.
I realize this is rather old but upon searching I didn't find any indication this might have been added since, so I figured now that I've figured it out I'd let everyone know how I solved the positioning of mine.
$(document).ready(function ()
{
$.jgrid.jqModal = $.extend($.jgrid.jqModal || {}, {
beforeOpen: centerInfoDialog
});
});
function centerInfoDialog()
{
var $infoDlg = $("#info_dialog");
var $parentDiv = $infoDlg.parent();
var dlgWidth = $infoDlg.width();
var parentWidth = $parentDiv.width();
$infoDlg[0].style.left = Math.round((parentWidth - dlgWidth) / 2) + "px";
}
From what I could find in the jqGrid source code, you can add a beforeOpen and an afterOpen. In my case I'd rather position the thing before it's displayed (duh!). Would be nice if there was a parameter to hook it up in the grid declaration, but this does the trick in the mean time.
I hope this helps someone! I spent most of my afternoon on this!
Default value of zIndex parameter of info_dialog is 1000. The function info_dialog from grid.common.js part of jqGrid will be called from grid.celledit.js without usage a 4-th parameter which can change the option.
So the best pragmatical way which I could recomend you is to decrease zIndex value of your div with the video so that it will be less then 1000.

Resources