I have a extJS grid with four column. On third column I am modifying the value by button and able to display. In Fourth column I am getting empty string "" as data. I am giving some input and trying to save this in store but it not happening. How to save value in extjs grid store.
var grid = Ext.getCmp('gridID');
var gridstore = grid.getStore();
var modify = gridstore.modified;
for (var i = 0; i < modify.length; i++) {
modifyRec[i].data.S = "Hello";
}
S is dataIndex of the column.
Better way is to use set, than changing property directly.
var grid = Ext.getCmp('gridID');
var gridstore = grid.getStore();
var modify = gridstore.modified;
for (var i = 0; i < modify.length; i++) {
modifyRec[i].set('S', "Hello");
}
Edit:
In Ext-data-AbstractStore afterEdit fires update event. Which is being called from Model set
I prepared some fiddle for you. Hope it will help you:
https://fiddle.sencha.com/#fiddle/1f56
To get modiified records i used getModifiedRecords() fuction.
Related
For some hours now I'm trying to get the model data of selected rows of a tree table.
I used this example: https://openui5.hana.ondemand.com/#/sample/sap.ui.table.sample.TreeTable.JSONTreeBinding/preview
Additionally, I added sortProperty and filterProperty to the columns. Until now everything works.
What I want to do is to submit the json data via ajax of all selected rows. for this, I need to get the json data of the selected rows.
What I tried:
var oTable = this.getView().byId("tableName").getSelectedIndicies()
and then
for(var i=0; i<=oTable.length; i++) {
this.getView().byId("tableName").getModel().getData().jobs[oTable[i]]
}
it seems that when I use the sorter and filter function, the indicies are not correct anymore. The indicies keys won't change.
any idea how to solve my request? thx in advance!
There is a small change you can do to get the right data in your for loop.
Get the bindingContext of the item which is selected as per the indices information.
var sPath = TreeTable.getRows()[0].getBindingContext()
Get the data from the model as:
oTreeTable.getModel().getProperty(sPath)
this is how I solved it:
var oJSON = {};
var aData = [];
var oTable = this.getView().byId("TreeTable");
var aIndicies = oTable.getSelectedIndices();
var oSelect = this.getView().byId("selectStandort").getSelectedKey();
for (var i=0; i<aIndicies.length; i++) {
var oTableContext = oTable.getContextByIndex(aIndicies[i]);
var rowData = oTable.getModel("jobs").getProperty(oTableContext.getPath());
aData.push(rowData);
}
oJSON.jobs = aData;
oJSON.standort = oSelect;
I'm having an issue pulling the correct values out of a for loop in Google Sheets.
Here's my code:
Note: this is a snippet from a larger function
function sendEmails() {
var trackOriginSheet = SpreadsheetApp.getActiveSpreadsheet().getName();
var getMirSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Miranda");
//Set a new object to hold conditional data
var holdingData = new Object();
//Create function to get values from origin sheet
var returnedValues = function (trackOriginSheet) {
//Load dynamic variables into an object via returnedValues()
if (trackOriginSheet === getMirSheet) {
var startMirRow = 2; // First row of data to process
var numRowsMir = 506; // Number of rows to process
// Fetch the range of cells A2:Z506
var dataRangeMir = getMirSheet.getRange(startMirRow, 1, numRowsMir, 26);
// Fetch values for each cell in the Range.
var dataMir = dataRangeMir.getValues();
for (var k in dataMir) {
var secondRowMir = dataMir[k];
var intRefDescMir = secondRowMir[3];
var intAdminActionsMir = secondRowMir[4];
//Push returned data to holdingData Object
holdingData.selectedData = secondRowMir;
holdingData.refDesc = intRefDescMir;
holdingData.adminActions = intAdminActionsMir;
}
}
}
Here's a copy of the sheet I'm working on
What I need to have happened here first, is track the origin sheet, then create an object to hold data returned from the returnedValues() function. Later, I'll call the properties of this object into a send email function.
The problem is that I need to be able to pull data from the selected sheet dynamically (the "Miranda" sheet in this case.) In other words, when a user selects the "Yes" option in column I of the Miranda sheet, the first thing this script needs to do is pull the values of the variables at the top of the for loop within the same row that the user selected "Yes." Then, I'm pushing that data to a custom object to be called later.
It's apparent to me, that I'm doing it wrong. There's, at least, something wrong with my loop. What have I done? :)
EDIT:
After reviewing the suggestion by VyTautas, here's my attempt at a working loop:
for (var k = 0; k < dataMir.length; k++) {
var mirColI = dataMir[k][8];
var mirRefDesc = dataMir[k][2];
var mirAdminActions = dataMir[k][3];
var mirDates = dataMir[k][4];
if (mirColI === "Yes") {
var activeRowMir = mirColI.getActiveSelection.getRowIndex();
//Pull selected values from the active row when Yes is selected
var mirRefDescRange = getMirSheet.getRange(activeRowMir, mirRefDesc);
var mirRefDescValues = mirRefDescRange.getValues();
var mirAdminActionsRange = getMirSheet.getRange(activeRowMir, mirAdminActions);
var mirAdminActionsValues = mirAdminActionsRange.getValues();
var mirDatesRange = getMirSheet.getRange(activeRowMir, mirDates);
var mirDatesValues = mirAdminActionsRange.getValues();
var mirHoldingArray = [mirRefDescValues, mirAdminActionsValues, mirDatesValues];
//Push mirHoldingArray values to holdingData
holdingData.refDesc = mirHoldingArray[0];
holdingData.adminActions = mirHoldingArray[1];
holdingData.dates = mirHoldingArray[2];
}
}
Where did all that whitespace go in the actual script editor? :D
You already correctly use .getValues() to pull the entire table into an array. What you need to do now is have a for loop go through dataMir[k][8] and simply fetch the data if dataMir[k][8] === 'Yes'. I also feel that it's not quite necessary to use for (var k in dataMir) as for (var k = 0; k < dataMir.length; k++) is a lot cleaner and you have a for loop that guarantees control (though that's probably more a preference thing).
You can also reduce the number of variables you use by having
holdingData.selectedData = mirData[k]
holdingData.refDesc = mirData[k][2] //I assume you want the 3rd column for this variable, not the 4th
holdingData.adminActions = mirData[k][3] //same as above
remember, that the array starts with 0, so if you mirData[k][0] is column A, mirData[k][1] is column B and so on.
EDIT: what you wrote in your edits seems like doubling down on the code. You already have the data, but you are trying to pull it again and some variables you use should give you an error. I will cut the code from the if, although I don't really see why you need to both get the active sheet and sheet by name. If you know the name will be constant, then just always get the correct sheet by name (or index) thus eliminating the possibility of working with the wrong sheet.
var titleMirRows = 1; // First row of data to process
var numRowsMir = getMirSheet.getLastRow(); // Number of rows to process
// Fetch the range of cells A2:Z506
var dataRangeMir = getMirSheet.getRange(titleMirRows + 1, 1, numRowsMir - titleMirRows, 26); // might need adjusting but now it will only get as many rows as there is data, you can do the same for columns too
// Fetch values for each cell in the Range.
var dataMir = dataRangeMir.getValues();
for (var k = 0; k < dataMir.length; k++) {
if (dataMir[k][7] === 'Yes') { //I assume you meant column i
holdingData.refDesc = dataMir[k] //this will store the entire row
holdingData.adminActions = dataMir[k][3] //this stores column D
holdingData.dates = dataMir[k][4] //stores column E
}
}
Double check if the columns I have added to those variables are what you want. As I understood the object stores the entire row array, the value in column called Administrative Actions and the value in column Dates/Periods if Applicable. If not please adjust accordingly, but as you can see, we minimize the work we do with the sheet itself by simply manipulating the entire data array. Always make as few calls to Google Services as possible.
this is What have so far.
function GetHighest () {
var arrayData = [];
var data = $("#QuarterlyBucketsGrid").data("kendoGrid").dataSource.data();
for (i = 0; i < data.length; i++) {
arrayData.push(data[i].max);
}
return arrayData;
};
I want to get the Highest value from the grid , and set my kendo text box default value to highest value from kendo grid. please help me
Two suggestions
1) Apply sorting from server side and get highest value of column on top.
OR
2) You have to sort your "data" variable on a specific dataset attribute. Also note kendo already have compare() functions that you can use.
I have a grid for which Cell editing plugin has been activated.
Once I updated few of the columns, I press Save button and all of the updated records (Row) are sent back with following code:
var grid = Ext.ComponentQuery.query('#CheckGrid')[0];
var store = Ext.data.StoreManager.lookup('CheckStore');
var modifieds = grid.getStore().getUpdatedRecords();
var id_check = [];
var ds_check_list = [];
var id_check_type = [];
var id_version = [];
console.log(modifieds);
if (modifieds.length > 0)
{
for(var i = 0; i < modifieds.length; i++) {
id_check.push(modifieds[i].get('ID_CHECK'));
ds_check_list.push(modifieds[i].get('DS_CHECK_LIST'));
id_check_type.push(modifieds[i].get('ID_CHECK_TYPE'));
id_version.push(modifieds[i].get('ID_VERSION'));
}
}
Ext.Ajax.request({
url: 'URL',
method: 'POST',
params: {
'Param.1': 'Check',
'Param.2': id_check.toString(),
'Param.3': ds_check.toString(),
'Param.4': id_type.toString(),
'Param.5': id_version.toString()
}
This works fine. But I want to know and send also the column name which got updated and its previous value.
When I see the console for console.log(modifieds); , I can spot following:
So how do I access this previousValue object in my code? I want to know previous value as well as column name both.
Kindly advise !
ds_check_list.push(modifieds[i].getPrevious('DS_CHECK_LIST'));
id_check_type.push(modifieds[i].getPrevious('ID_CHECK_TYPE'));
Ext.data.Model.getPrevious(fieldname) : Object
This method returns the value of a field given its name prior to its most recent change.
The Store.getUpdatedRecords() function returns an Ext.data.Model instance, which in turn has a getPrevious method.
It usually helps a lot to take a look at the API docs of ExtJS and then just navigating through the methods and return values used.
The getUpdatedRecords() method is documented over here: http://docs.sencha.com/extjs/5.0/5.0.1-apidocs/#!/api/Ext.data.Model-method-getPrevious
I am working on a kendo grid with remote data, and currently when updating my grid, I use the dataItem.set() method to manually sync the grid with the data. This works fine, but unfortunately the aggregates in the footer are not refreshed. They refresh only when calling dataSource.fetch(), which hangs up the application for about 10 seconds. The users however, would like more excel-like responsiveness where every change they make is immediately reflected in the total, but also persisted to the database. Is this possible using the kendo api? Or do I have to do this manually with jQuery?
Edit: doesn't look like there's a built-in way so I fixed manually w/ jQuery.
Edit 2: Here's the code I used, generalized a bit and taking out some application specific quirks.
Kendo Grid Configuration:
$(gridId).kendoGrid({
columns: [
{
field: fieldToUpdate,
editor: customEditor,
//add 'data-field' attribute to footer/group footer
footerAttributes: { 'data-field': fieldToUpdate },
groupFooterAttributes: { 'data-field': fieldToUpdate }
},
//other fields...
],
//other config...
});
Custom Editor:
function customEditor(data) {
//store original and new value
//append textbox
//call custom update passing td and data w/ original/new values
}
Find Affected Aggregate Cells:
//Gets all affected aggregate cells after an update
function getTotalsCells($container, updatedField) {
var groups = $('#grid').data('kendoGrid').dataSource.group(),
$totals = $('.k-footer-template>td[data-field="' + updatedField + '"]'),
$row = $container.parent('tr');
for (var i = 0; i < groups.length; i++) {
var $groupTotal = $row.nextAll('.k-group-footer')
.eq(i)
.find('[data-field="..."]');
$totals = $totals.add($groupTotal);
}
return $totals;
}
Update Totals
$.fn.updateTotal = function (delta) {
this.each(function () {
var $container = $(this);
var origTotal = parseFloat($container.text() || 0);
var total = origTotal + delta;
$container.text(total);
});
};
Custom Update:
function updateGrid($container, data) {
var difference, field;
//get difference and updatedField
var $totals = getTotalsCells($container);
$totals.updateTotal(difference);
}
I feel like there must be a better way to do this, but the aggregate model doesn't seem to update.
My solution was to define a function that manually calculates the results and call this from within the footer template. Whenever the grid is refreshed the footer is also updated.
Client Template: #: sumDebits() #
function sumDebits() {
var $grid = $('#GridId');
var kendo = $grid.data().kendoGrid;
var data = kendo.dataSource.data();
var total = 0;
for (var i = 0; i < data.length; i++) {
var debit = parseFloat(data[i].Form.debit);
if (debit == NaN) {
debit = 0;
}
total = total + debit;
}
return total;
}
I had almost similar problem. I had a KendoGrid which i needed to refresh the row only (update HTML and Data) and update the groupFooterTemplateand and the footerTemplate after a modal close (which it had the edit cells i needed to update to the grid). I had "#progress/kendo-ui": "^2019.2.626". I know that is uses set but in this version set updates everything.
Bellow is the Code where you update groupFooterTemplateand ,footerTemplate , Html(row) and also excel is updated withoute Total Refresh of the Grid.
let grid = $('#grid').getKendoGrid(); // Kendo Grid
let dataItem = grid.dataItem(tr); // tr: JQuery (selected Row)
let index= grid.items().index(grid.select()); // or the selected Row
dataItem = data.length > 0 && data.length === 1 ? data : dataItem; // data is the new item with the same properties as the item datasource of the Grid. You can update all properties like below or just set one property.
dataItem.dirty = true;
let rowItem = grid.dataSource.at(index);
for (let [key, value] of Object.entries(dataItem )) {
rowItem.set(key, value); //
}
var grid = $("#gridName").data('kendoGrid');
var aggregateSum = grid.dataSource._aggregateResult;
//below code give you current aggregate value.
var sum = aggregateSum.<your_aggregate_columnname_here>.sum;
//assuming my Grid Column name is 'Amount'
var sum = aggregateSum.Amount.sum;
To change the aggregate value without refreshing page or without fetching the datasource, follow below steps
// Set the current aggregate value to 0
aggregateSum.<your_aggregate_columnname_here>.sum = 0;
// i.e. aggregateSum.Amount.sum = 0;
// Loop trough Grid data row by row
var gridData = grid.dataSource.data();
for (var i = 0; i < gridData.length; i++) {
var dataRow = gridData[i];
// to set the aggregate sum value
aggregateSum.Amount.sum += value;
// to set the cell value for that particular row
dataRow.set(ColumnName, value);
}
Note : Make Sure Call the Set() function in the end after updating the aggregate sum. If you will call Set function before setting aggregate sum, you will not be able to see the last iteration changes, as the changes will only reflect after set() function will get executed