dataitem.set not updating value in browser display kendo grid mvc - kendo-grid

I have a kendo grid mvc with few number columns. columns are A,B,Total.
my grid in incell edit mode.
if i modify A column cell value then i need to update value in Total column.
here my value is updating in javascript but its not displaying updated value in kendo grid browser view.
below is the code.
function onChange(e) {
if (e.action == "itemchange" && e.field != "HoursYTD") {
var editItemModelId = e.items[0].EmpNumber;
var grid = $("#Grid").data("kendoGrid");
var dataItem = grid.dataSource.get(editItemModelId);
CurrentEditCell = e.field;
var dataSource = $("#Grid").data("kendoGrid").dataSource;
var _flt = { field: "EmpNumber", operator: "eq", value: editItemModelId };
var copyDataSource = kendo.data.DataSource.create({
data: dataSource.data()
});
copyDataSource.filter(_flt);
const today = new Date();
var currentMonth = today.getMonth()+1;
var HoursYTD =
e.items[0].A +
+e.items[0].B;
dataItem.set("Total", HoursYTD);
}
columns.Bound(p => p.Total).Width(70).Filterable(false).Editable("function(dataItem) {return false;}").ClientFooterTemplate("#=kendo.toString(sum, '0,0')#").HtmlAttributes(new { style = "font-weight: bold; text-align: center;" }).HeaderHtmlAttributes(new { style = "white-space: normal; text-align: center;font-weight: bold;" });

Related

Tabulator - Dependent Select with Custom Editor

I need to show the list in the select box based on the another input.
On click on the SubCategory column, its showing the selected value in the dropdown. But its not showing in the table.
You can see the table in the below image. First image its not showing the data in the display, in the second image its showing the value selected
Anything missed. Any help please..
Attached the working code.
var comboEditor = function (cell, onRendered, success, cancel, editorParams) {
//Getting the other select value, based on the value this select need to show the list
let otherCellValue = cell.getData().ForumCourt;
cboData = []; //Store last values based on another cell value
var currentlyAdded = [];
var editor = document.createElement("select");
arrayOfValues2 = caselocationData.filter(function(r){return true;});
var filteredArrayOfValues = arrayOfValues2.filter(function(r){ return r[0]=== otherCellValue});
// addUniqueOptionsToDropdownList(select2_Sub, filteredArrayOfValues,1);
filteredArrayOfValues.forEach(function(r){
if(currentlyAdded.indexOf(r[0]) === -1) {
currentlyAdded.push(r[1]);
var item = {};
item.key = r;
item.name = r[1];
cboData.push(item);
}
});
for (var i = 0; i < cboData.length; i++) {
var opt = document.createElement('option');
opt.value = cboData[i].key;
opt.innerHTML = cboData[i].name;
editor.appendChild(opt);
}
editor.style.padding = "0px";
editor.style.width = "100%";
editor.style.boxSizing = "border-box";
editor.value = cell.getValue();
onRendered(function () {
editor.focus();
editor.style.css = "100%";
});
function successFunc() {
success(editor.value);
}
editor.addEventListener("change", successFunc);
editor.addEventListener("blur", successFunc);
return editor;
};

How can I parse html table inside a script respecting merged cells

This header is contained in a js file https://www.portaldefinancas.com/js-tx-ctb/th-cdib.js
document.write(""),document.write('</p></caption><thead><tr><th rowspan="4">Mês de<br>Referência</th><th colspan="7">Taxas - %</th></tr><tr> <th rowspan="3">Mensal</th><th colspan="4">Anualizada</th><th colspan="2">Acumulada</th></tr><tr> <th colspan="2">Ano de<br>252 dias<br> úteis</th><th colspan="2">Ano de<br>365/366 dias<br>corridos</th><th rowspan="2">No ano</th><th rowspan="2">Em <br>12 meses</th></tr><tr><th>Dias</th><th> Taxa</th><th>Dias</th><th> Taxa</th></tr></thead><tbody>');
How can I parse the headers respecting the merged rows and merged columns. The script I use today is
function getHeaders(url) {
var source = UrlFetchApp.fetch(url).getContentText()
source = source.split('document')[2]
var table = '<table><tr><th ' + source.match(/(?<=<th ).*(?=th>)/g) + 'th></tr></table>'
table=table.replace(/ê/g,'ê').replace(/ú/g,'ú').replace(/<br>/g,'\n')
var doc = XmlService.parse(table);
var rows = doc.getDescendants().filter(function(c) {
var element = c.asElement();
return element && element.getName() == "tr";
});
var data = rows.slice(0).map(function(row) {
return row.getChildren("th").map(function(cell) {
return cell.getValue();
});
});
return data;
}
but it doesn't respect merged areas. Thanks for any help !
Since intellectual exercises is my my drug of choice... I can't help it. Here is the possible solution. It works to a degree but it shows little the traits of lofty style of coding:
function main() {
var sheet = SpreadsheetApp.getActiveSheet();
var data = getHeaders();
data = handle_rowspans(data);
sheet.getRange(1, 1, data.length, data[0].length).setValues(data);
}
function getHeaders(url) {
// var source = UrlFetchApp.fetch(url).getContentText()
// source = source.split('document')[2]
var source = `<thead><tr><th rowspan="4">Mês de<br>Referência</th><th colspan="7">Taxas - %</th></tr><tr> <th rowspan="3">Mensal</th><th colspan="4">Anualizada</th><th colspan="2">Acumulada</th></tr><tr> <th colspan="2">Ano de<br>252 dias<br> úteis</th><th colspan="2">Ano de<br>365/366 dias<br>corridos</th><th rowspan="2">No ano</th><th rowspan="2">Em <br>12 meses</th></tr><tr><th>Dias</th><th> Taxa</th><th>Dias</th><th> Taxa</th></tr></thead><tbody>`;
source = handle_colspans(source);
table = '<table><tr><th ' + source.match(/(?<=<th ).*(?=th>)/g) + 'th></tr></table>';
table = table.replace(/ê/g, 'ê').replace(/ú/g, 'ú').replace(/<br>/g, '\n');
var doc = XmlService.parse(table);
var rows = doc.getDescendants().filter(function (c) {
var element = c.asElement();
return element && element.getName() == "tr";
});
var data = rows.slice(0).map(function (row) {
return row.getChildren("th").map(function (cell) {
return cell.getValue();
});
});
return data;
}
function handle_colspans(table) {
return table.split('</tr>').map(r => add_cells_in_row(r)).join('</tr>');
function add_cells_in_row(row) {
var cells = row.split('</th>');
for (var i in cells) {
if (/colspan/.test(cells[i])) {
var colspan = cells[i].replace(/.*colspan="(\d+).*/, '$1');
cells[i] += '{col' + colspan + '}';
cells[i] = [cells[i], ...(new Array(+colspan - 1).fill('<th>'))];
}
if (/rowspan/.test(cells[i])) {
var rowspan = cells[i].replace(/.*rowspan="(\d+).*/, '$1');
cells[i] += '{row' + rowspan + '}';
}
}
return cells.flat().join('</th>')
}
}
function handle_rowspans(array) {
for (var row in array) {
for (var col in array[row]) {
if (/\{row/.test(array[row][col])) {
var rowspan = array[row][col].replace(/.*\{row(\d+).*/s, '$1');
for (var r = 1; r < rowspan; r++) array[+row + r].splice(col, 0, '')
}
}
}
return array;
}
It will get you the table like this:
Whrere {row#} and {col#} means how many cells or rows to the left or to the bottom you need to join to the current cell to recreate the original design. It could be the next dose of the intellectual exercises. :)
A solution, example with url = https://www.portaldefinancas.com/js-tx-ctb/th-cdib.js
function getHeaders(url) {
var source = UrlFetchApp.fetch(url).getContentText()
source = source.split('document')[2]
var table = '<table><tr><th ' + source.match(/(?<=<th ).*(?=th>)/g) + 'th></tr></table>'
table=table.replace(/ê/g,'ê').replace(/ú/g,'ú').replace(/<br>/g,'\n')
var doc = XmlService.parse(table);
var rows = doc.getDescendants().filter(function(c) {
var element = c.asElement();
return element && element.getName() == "tr";
});
var n=0
var data=[]
rows.slice(0).map(function(row) {data[n++]=[]})
n=0
rows.slice(0).map(function(row) {
row.getChildren("th").map(function(cell) {
try{nbcols = cell.getAttribute('colspan').getValue()}catch(e){nbcols = 1}
try{nbrows = cell.getAttribute('rowspan').getValue()}catch(e){nbrows = 1}
var value = cell.getValue()
r=0
var free=0
while(r<nbrows*1){
c=0
while(c<nbcols*1){
while(data[n+r][free]!=null){free++}
data[n+r][free]=(value)
value=''
c++
}
r++
}
});
n++
});
return (data);
}

How to clear formatting on a selection in TLF?

I'm trying to remove the formatting of the selection and what I have so far only removes the formatting on a selection when the selection is inside a paragraph. If the selection extends to another paragraph the formatting is not removed.
Here is what I have so far:
var currentFormat:TextLayoutFormat;
var currentParagraphFormat:TextLayoutFormat;
var containerFormat:TextLayoutFormat;
var selectionStart:int;
var selectionEnd:int;
var operationState:SelectionState;
var editManager:IEditManager;
if (richEditableText.textFlow && richEditableText.textFlow.interactionManager is IEditManager) {
editManager = IEditManager(richEditableText.textFlow.interactionManager);
selectionStart = Math.min(richEditableText.selectionActivePosition, richEditableText.selectionAnchorPosition);
selectionEnd = Math.max(richEditableText.selectionActivePosition, richEditableText.selectionAnchorPosition);
if (operationState == null) {
operationState = new SelectionState(richEditableText.textFlow, selectionStart, selectionEnd);
}
currentFormat = editManager.getCommonCharacterFormat(operationState);
currentParagraphFormat = editManager.getCommonParagraphFormat(operationState);
containerFormat = editManager.getCommonContainerFormat(operationState);
editManager.clearFormat(currentFormat, currentParagraphFormat, containerFormat);
}
It seems that SelectionManager.getCommonCharacterFormat() doesn't quite do what I was thinking it was doing. I need to get the format of the characters that are selected and that function doesn't seem to do that.
If I get a ElementRange and then loop through it I can create a TextLayoutFormat that contains the formats on all the leaves in the element range.
var currentFormat:TextLayoutFormat;
var currentParagraphFormat:TextLayoutFormat;
var containerFormat:TextLayoutFormat;
var selectionStart:int;
var selectionEnd:int;
var operationState:SelectionState;
var editManager:IEditManager;
if (richEditableText.textFlow && richEditableText.textFlow.interactionManager is IEditManager) {
editManager = IEditManager(richEditableText.textFlow.interactionManager);
selectionStart = Math.min(richEditableText.selectionActivePosition, richEditableText.selectionAnchorPosition);
selectionEnd = Math.max(richEditableText.selectionActivePosition, richEditableText.selectionAnchorPosition);
if (operationState == null) {
operationState = new SelectionState(richEditableText.textFlow, selectionStart, selectionEnd);
}
// following lines were change
elementRange = ElementRange.createElementRange(richEditableText.textFlow, selectionStart, selectionEnd);
currentFormat = getElementRangeFormat(elementRange);
editManager.clearFormat(currentFormat, currentParagraphFormat, containerFormat);
}
// method to get format of the selected range
public static function getElementRangeFormat(elementRange:ElementRange):TextLayoutFormat {
var leaf:FlowLeafElement = elementRange.firstLeaf;
var attr:TextLayoutFormat = new TextLayoutFormat(leaf.computedFormat);
for (;;)
{
if (leaf == elementRange.lastLeaf)
break;
leaf = leaf.getNextLeaf();
attr.concatInheritOnly(leaf.computedFormat);
}
return Property.extractInCategory(TextLayoutFormat, TextLayoutFormat.description, attr, Category.CHARACTER, false) as TextLayoutFormat;
}

Kendo UI Grid Get Row Values

I am trying to get the row item values (name, email, age) but I'm only able to get the first item by using the code below.
How can I get other row text by changing tr:eq(1) code or is there any other way to get two items value?
$("#grid_").kendoDropTarget({
drop: function (e) {
var data = grid.dataItem("tr:eq(1)");
// I only get first row but I need to dynamically get any row items.
alert(data.name);
}
});
plz try this..
var entityGrid = $("#DataGrid").data("kendoGrid");
var data = entityGrid.dataSource.data();
var totalNumber = data.length;
for(var i = 0; i<totalNumber; i++) {
var currentDataItem = data[i];
VersionIdArray[i] = currentDataItem.VersionId;
}
Thanks Sanjay however I was looking to just select a row items and this is what I got:
//Selecting Grid
var gview = $("#grid").data("kendoGrid");
//Getting selected item
var selectedItem = gview.dataItem(gview.select());
//accessing selected rows data
alert(selectedItem.email);
So it worked out perfect.
if your grid is set to selectable: true, use the following:
var mygrid = $("#grid").kendoGrid({
selectable: true
});
mygrid.on("click", "tr", function() {
var datarowindex = mygrid.data("kendoGrid").items().index(mygrid.data("kendoGrid").select());
var datarowid = mygrid.data("kendoGrid").dataItem(mygrid.data("kendoGrid").select()).MyId;
alert("index: " + datarowindex + " | value: " + datarowid);
});
if your Kendo UI Grid is set to selectable: false, use the following:
var mygrid = $("#grid").kendoGrid({
selectable: false
});
mygrid.on("click", "tr", function() {
var datarowindex = mygrid.data("kendoGrid").items().index($(this));
var datarowid = mygrid.data("kendoGrid").dataItem($(this).closest("tr")).MyId;
alert("index: " + datarowindex + " | value: " + datarowid);
});
where MyId is the property you are looking for.
I usually use the model from the event. Sometimes, actually very rarely, the row gets deselected and so, the .select() will return a 0 length object which will throw error while trying to access undefined properties.
You might be safer using: e.model.name

How to move a popup window from a client handler?

I have a code that simulates a popup window (thanks to Waqar Ahmad) that is triggered by a client handler.
I would like to get this popup appear near the button that triggered it but with the script I have I see no way to move the window.
The code is below and the app is viewable here, if ever someone has an idea about how I should re-organise or change the script so that the popup window shows up near the button that fired the process ?
var choice = ['-','Choice 1','Choice 2','Choice 3','Choice 4']; // var definition
function doGet(){
var app = UiApp.createApplication().setStyleAttribute("background", "beige");
app.add(createMaskPanel_());//this is used to make popup panel modal
var mainPanel = app.createVerticalPanel().setStyleAttributes({'padding' : '15'});
app.add(mainPanel);
// idx holds the index value of the button that is pressed
var idx = app.createTextBox().setId('idx').setName('idx').setVisible(false);
mainPanel.add(idx);
//Make a panel for popup and add your popup elements
var popup = app.createVerticalPanel().setId('popup').setVisible(false)
.setStyleAttributes(
{'position': 'fixed',
'border' : '1px solid brown',
'padding' : '15',
'background' : 'beige',
'top' : '150PX',
'left' : '300PX',
'width' : '200',
'height':'120',
'zIndex' : '2'});
popup.add(app.createLabel('Select your choice').setId('label'));
var list = app.createListBox().setId('ppValue').setName('ppValue').setWidth('200')
.addItem(choice[0], '0').addItem(choice[1], '1').addItem(choice[2], '2').addItem(choice[3], '3').addItem(choice[4], '4');
popup.add(list);
var valHandler = app.createServerHandler('showVal').addCallbackElement(mainPanel).addCallbackElement(popup);;
popup.add(app.createButton('✖ Close / confirm').addClickHandler(valHandler));
app.add(popup);
var mask = app.getElementById('mask')
var ppHandler = app.createClientHandler().forTargets([popup,mask]).setVisible(true)
var flex = app.createFlexTable()
for(nn=1;nn<11;++nn){
flex.setText(nn,0,'Item nr '+nn)
var text = app.createTextBox().setHeight('26').setWidth('150').setId('val'+nn).setName('val'+nn)
flex.setWidget(nn,1,text);
var handler = app.createClientHandler().forTargets(idx).setText(nn).forTargets(text).setText('suggestion = ?');
flex.setWidget(nn,2,app.createButton('✐').setHeight('26').setId('btn'+nn).addClickHandler(handler).addClickHandler(ppHandler))
}
mainPanel.add(flex);
return app;
}
function createMaskPanel_(){ //Called when UI loads, initially it will be invisble. it needs to be made visible
var app = UiApp.getActiveApplication();
var mask = app.createVerticalPanel().setId('mask').setSize('100%', '100%') //maskPanel to mask the ui
.setStyleAttributes({
'backgroundColor' : '#F0F0F0',
'position' : 'fixed',
'top' : '0',
'left' : '0',
'zIndex' : '1',
'opacity' : '0.4'}).setVisible(false);
mask.add(app.createLabel('POPUP')
.setStyleAttribute('color', '#F0F0F0')
.setStyleAttribute('opacity', '0.6'));
return mask;
}
function showVal(e){
var app = UiApp.getActiveApplication();
var source = e.parameter.idx
var value = app.getElementById('val'+source)
value.setText('choice value = '+choice[e.parameter.ppValue])
var popup = app.getElementById('popup')
var mask = app.getElementById('mask')
popup.setVisible(false)
mask.setVisible(false)
return app
}
EDIT : Since the server handler seems to be the only way I gave it a try, the app is viewable here and the (final ?) code is below for info.
var choice = ['-','Choice 1','Choice 2','Choice 3','Choice 4','Choice 5','Choice 6','Last choice !'];//var definition
function doGet(){
var app = UiApp.createApplication().setStyleAttribute("background", "beige");
app.add(createMaskPanel_());//this is used to make popup panel modal
var top = '100PX'
var left = '265PX'
var mainPanel = app.createVerticalPanel().setStyleAttributes({'padding' : '15'});
app.add(mainPanel);
// item definitions
var idx = app.createTextBox().setId('idx').setName('idx').setVisible(false);
mainPanel.add(idx);
//Make a panel for popup and add your popup elements
var popup = app.createVerticalPanel().setId('popup').setVisible(false)
.setStyleAttributes(
{'position': 'fixed',
'border' : '1px solid brown',
'padding' : '10',
'background' : 'beige',
'top' : top,
'left' : left,
'width' : '200',
'height':'110',
'zIndex' : '2'});
popup.add(app.createLabel('Select your choice').setId('label'));
var list = app.createListBox().setId('ppValue').setName('ppValue').setWidth('160')
for(c in choice){list.addItem(choice[c], c)}
popup.add(list);
var valHandler = app.createServerHandler('showVal').addCallbackElement(mainPanel).addCallbackElement(popup);;
popup.add(app.createButton('✖ Close / confirm').addClickHandler(valHandler));
app.add(popup);
var idxHandler = app.createServerHandler('setidx').addCallbackElement(mainPanel)
var flex = app.createFlexTable()
for(nn=1;nn<11;++nn){
flex.setText(nn,0,'Item nr '+nn)
flex.setWidget(nn,1,app.createTextBox().setPixelSize(180,26).setId('val'+nn).setName('val'+nn));
flex.setWidget(nn,2,app.createButton('✐').setHeight('26').setId('btn'+nn).addClickHandler(idxHandler))
}
mainPanel.add(flex);
return app;
}
function setidx(e){
var app = UiApp.getActiveApplication();
var idx = app.getElementById('idx')
var idxval = Number(e.parameter.source.replace(/[a-z]/g,''))
idx.setValue(idxval);
var top = -30+38*idxval+'PX'
var left = '265PX'
var popup = app.getElementById('popup')
var mask = app.getElementById('mask')
var label = app.getElementById('label').setText('Select your choice (item '+idxval+')')
var value = app.getElementById('val'+idxval)
value.setText('suggestion = ?')
popup.setVisible(true)
mask.setVisible(true)
popup.setStyleAttributes(
{'top' : top,
'left' : left});
return app
}
function createMaskPanel_(){ //Called when UI loads, initially it will be invisble. it needs to be made visible
var app = UiApp.getActiveApplication();
var mask = app.createVerticalPanel().setId('mask').setSize('100%', '100%') //maskPanel to mask the ui
.setStyleAttributes({
'backgroundColor' : '#F0F0F0',
'position' : 'fixed',
'top' : '0',
'left' : '0',
'zIndex' : '1',
'opacity' : '0.6'}).setVisible(false);
mask.add(app.createLabel('POPUP')
.setStyleAttribute('color', '#F0F0F0')
.setStyleAttribute('opacity', '0.6'));
return mask;
}
function showVal(e){
var app = UiApp.getActiveApplication();
var source = e.parameter.idx
var value = app.getElementById('val'+source)
value.setText('choice value = '+e.parameter.ppValue+' ('+choice[Number(e.parameter.ppValue)]+')')
var popup = app.getElementById('popup')
var mask = app.getElementById('mask')
popup.setVisible(false)
mask.setVisible(false)
return app
}
Serge I did something simular using a dialogbox to get this kind of functionality.
In the proper function that shows the dialogbox I decide the position of the dialogbox.
I used it to enlarge a image so I just put the (entire) code I used for the dialogbox.
function showimg(e){
var app = UiApp.getActiveApplication();
//
// Style
//
var _showimg =
{
"position":"fixed",
"width":"200px", // here you can change size
"top":"100px", // and horizontal position maybe you can use your
"left":"100px", // your setidx function .
"opacity":"0.95",
"border":"none",
}
var _container =
{
"width":"90%",
"border":"none",
}
var _img= {
"background-color":"none",
"width":"90%",
"border":"4px solid f2f2f2",
}
var _btn= {
"background-color":"none",
"background":"none",
"width":"80px",
"height":"24px",
"border":"None",
"font-family":"hobo std",
"font-size":"0.9em",
"color":"3f3f3f",
"opacity":"1",
}
//
// aplication
//
var f = DocsList.find("YOURSPREADSHEET");
var id = f[0].getId();
var ss = SpreadsheetApp.openById(id);
var sheet = ss.getSheetByName("YOURSHEET");
var rows= sheet.getLastRow();
var cols = sheet.getLastColumn();
var dialogBox = app.createDialogBox(true, true).setId("dialogBox");
applyCSS(dialogBox, _showimg);
var cont = app.createAbsolutePanel().setId("cont").setVisible(true);
applyCSS(cont, _container);
var source = e.parameter.source;
for (var i = 1; i < rows ; i++) {
for (var j = 1; j <6 ; j++) {
if (source == "imgb"+[j]+[i]) {
if (j == 1) {
var img = app.createImage().setId('img').setUrl(sheet.getRange(i+1,[5]).getValue()).setVisible(true);
dialogBox.setText(sheet.getRange(i+1,[6]).getValue());
}
if (j == 2) {
var img = app.createImage().setId('img').setUrl(sheet.getRange(i+1,[7]).getValue()).setVisible(true);
dialogBox.setText(sheet.getRange(i+1,[8]).getValue());
}
}
app.getElementById( "imgb"+[j]+[i]).setEnabled(false);
//}
}
}
applyCSS(img,_img)
app.createImage().setId('img').setUrl("https://lh6.googleusercontent.com/-PTl6c-pfHoc/TzFvp1dteaI/AAAAAAAACTI/Mmx-7RU4i8g/s640/xxxxxxx.jpg").setVisible(true);
// applyCSS(img,_img)
var closeb = app.createButton("Close").setId("closeb").setTitle("close");
applyCSS(closeb,_btn);
var closeH = app.createServerClickHandler("closediag");
closeb.addClickHandler(closeH);
closeH.addCallbackElement(cont);
cont.add(img);
cont.add(closeb);
dialogBox.add(cont);
app.add(dialogBox);
return app;
}
The applyCss from James
function applyCSS(element, style){
for (var key in style){
element.setStyleAttribute(key, style[key]);
}
}
From what I've discovered so far using what I see in these replies, this methodology is positioning my widgets accordingly, but not the actual form itself. Unless, of course, I'm missing something, which is entirely possible. Thanks for the replies so far.