Row count in aggrid with pagination - pagination

I am using aggrid with pagination(client side).
I need to get the count of rows present in current page.
When i use the below apis it always gives me count of all rows present in all pages.
gridApi.paginationGetRowCount()
gridApi.getDisplayedRowCount()
gridApi.paginationProxy.masterRowCount

The one you need is GridApi.paginationGetPageSize().
GridApi.paginationGetRowCount() returns total number of rows in all pages.
GridApi.getDisplayedRowCount() returns total number of rows in all pages, plus all expanded rows (when using Row Grouping or Master Detail).
GridApi.paginationProxy is a private property and should not be used.
If you want to get the number of rows in current page. You can calculate the startResult and endResult of that page yourself. The number of rows in the page is endResult - startResult + 1
const printPagination = () => {
const currentPage = gridApi.paginationGetCurrentPage();
const totalPage = gridApi.paginationGetTotalPages();
const totalResults = gridApi.paginationGetRowCount();
const pageSize = gridApi.paginationGetPageSize();
const startResult = currentPage * pageSize + 1;
const endResult = Math.min(startResult + pageSize - 1, totalResults);
console.log();
console.log("Page size:", pageSize);
console.log("Current page:", currentPage);
console.log("Total pages:", totalPage);
console.log("Total results:", totalResults);
console.log("Start-end:", startResult, endResult);
console.log("Number of rows in this page:", endResult - startResult + 1);
};
Live Example
The live example below uses React but it should be trivial to convert that code to angular

Related

Highlight dates closer than 3 months away

I have a simple spreadsheet listing certificates and expiry dates. Before we moved this to sharepoint online we had a macro than on opening the spreadsheet would check dates in a range of cells and highlight those within three months. It was intended to highlight anything up for renewal before it expired.
I appreciate macros are not an option in Excel online. Can this (or something very similar) be achieved in Office Scripting?
It should be possible to create an Office Script that highlights cells with a date that is within three months of the present.
Something Like:
function main(workbook: ExcelScript.Workbook)
{
// highlight all days between today and the next number of days out
// Number of days to look ahead
const daysOut = 90;
// Excel by default stores dates as the number of days after January 1, 1900
const dayMin = currentDaysSince1900();
const dayMax = dayMin + daysOut;
// Need to target the column to look at and how far down the column
const columnToLookAt = "A";
const rowStart = 1;
const rowEnd = 4;
const rangeAddress = `${columnToLookAt}${rowStart}:${columnToLookAt}${rowEnd}`;
const sheet = workbook.getActiveWorksheet();
// get range column
const range = sheet.getRange("A1:A3");
const values = range.getValues();
// iterate through the rows of values
for (let i =0 ; i < values.length; i++) {
const value = values[i][0];
console.log(value);
if (typeof value === "number") {
// only look at numbers
if (value >= dayMin && value <=dayMax ) {
// highlight
const rangeAddress = `${columnToLookAt}${rowStart +i}`;
const range = sheet.getRange(rangeAddress);
range.getFormat().getFill().setColor("yellow");
}
}
}
}
/**
* Current Days since Jan 1 1900
* Equivalent to number of current excel day
*/
function currentDaysSince1900() {
// method returns the number of milliseconds elapsed since January 1, 1970
const nowMilliseconds = Date.now();
const millisecondsPerDay = 24 * 60 * 60 * 1000 ;
const nowDays = Math.floor(nowMilliseconds / millisecondsPerDay);
const daysBetween1900And1970 = 25567;
const elapsed = nowDays + daysBetween1900And1970 +2; // add two to include both jan 1s
return elapsed;
}
In terms of triggering the script:
Office Script does not currently support running a script on opening a workbook.
You can manually trigger the script whenever you like.
You can also create a Microsoft Power Automate flow to run the script every day to keep the workbook updated.
More Office Script resources:
Official Microsoft Office Script Date Example
Official Microsoft Office Script Examples
wandyezj office script examples

How can I match exact text in a particular column and output the entire row of information?

I have been attempting to create a Telegram bot that searches a preexisting database and outputs information based on search query, essentially I want the bot to just receive a text via Telegram that contains an invoice number and output all relevant information regarding that order (The entire row of information).
Since I am dealing with invoice numbers and tracking numbers, sometimes the bot is exporting incorrect information given the current script is not matching exact text or a specific column.
For instance, rather than searching and finding invoice number it picks up a partial match of tracking number and outputs the wrong information.
I would like to set it up to search a specific column, ie. Column 3 - "Invoice #" and then output the entire row of information.
Thanks in advance!
I have been working in Google App Script:
var token = "";
var telegramUrl = "https://api.telegram.org/bot" + token;
var webAppUrl = "";
var ssId = "";
function getMe() {
var url = telegramUrl + "/getMe";
var response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
}
function setWebhook() {
var url = telegramUrl + "/setWebhook?url=" + webAppUrl;
var response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
}
function sendText(id,text) {
var url = telegramUrl + "/sendMessage?chat_id=" + id + "&text=" + text;
var response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
}
function doGet(e) {
return HtmlService.createHtmlOutput("Hi there");
}
function doPost(e) {
var data = JSON.parse(e.postData.contents);
var text = data.message.text;
var id = data.message.chat.id;
var name = data.message.chat.first_name + " " + data.message.chat.last_name;
var answer = "Hi " + name + ", please enter invoice number.";
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Orders");
var search_string = text
var textFinder = sheet.createTextFinder(search_string)
var search_row = textFinder.findNext().getRow();
var value = SpreadsheetApp.getActiveSheet().getRange("F"+search_row).getValues();
var value_a = SpreadsheetApp.getActiveSheet().getRange("G"+search_row).getValues();
sendText(id,value+" "+ value_a)
}
You want to find rows where the content in column 3 is exactly equal to your variable "text"
Modify your function doPost as following:
function doPost(e) {
var data = JSON.parse(e.postData.contents);
var text = data.message.text;
var id = data.message.chat.id;
var name = data.message.chat.first_name + " " + data.message.chat.last_name;
var answer = "Hi " + name + ", please enter invoice number.";
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Orders");
var range = sheet.getRange(1,1, sheet.getLastRow(), sheet.getLastColumn());
var values = range.getValues();
for (var i=0; i< values.length; i++){
var column3Value = values[i][2];
if(column3Value == text){
var rowValues = values[i].toString();
sendText(id,rowValues)
}
}
}
Explanations
The for loop iterates through all rows and compares the values in column 3 (array element[2] against the value of text
The operator == makes sure that only exact matches are found (indexOf() would also retrieve partial matches)
In case a match is found, the values from the whole row are converted to a comma separated string with toString() (You can procced the values differntly if desired)
Every row with a match will be sent to the function sendText() (you could alternatively push all rows with matches into an array / string and call sendText() only once, after exiting the for loop
I hope this answer helps you to solve your problem and adapt the provided code snippet to your needs!
I would look for a specific column where the order number is stored.
I`m not sure if it is the best way from performance side, but I think it should work.
function orderInformation(orderNumber){
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Orders");
//Gets last row in Orders sheet
var lastRow = sheet.getLastRow();
//Here you can change column where is order number stored
var orderNumberRange = sheet.getRange("A1:A" + lastRow);
//Gets all order number values
var orderNumbers = orderNumberRange.getValues();
//You can use indexOf to find which row has information about requested order
var orderLocation = orderNumbers.indexOf(orderNumber);
//Now get row with order data, lets suppose that your order information is from column A to Z
var orderData = sheet.getRange("A" + (orderLocation + 1) + ":Z" + (orderLocation + 1)).getValues();
//Now you have all data in array, where you can loop through and generate response text for a customer.
}
Sorry, I have not tested it, at the moment I don`t have time to make a test sheet, but this is the way I would do it and I think it should work.
I will test it maybe later when I will be able to make a test sheet.

Conditional Formatting for items created in the last 5 minutes in SharePoint 2010

All,
I've been looking all day and have tried numerous solutions, but just can't get it to work. Our team projects a list that is constantly updated and we want to highlight only newly created items for 5 minutes. After 5 minutes, the row would return to normal. (FYI- the list is projected on a display and updated using AJAX asynchronous update every 15 seconds)
Basically, I want to set conditional formatting on list items created in the last 5 minutes. If the item was created in the last 5 minutes, the row will be highlighted. After the 5 minutes are up, the row would return to normal.
I tried SharePoint Designer conditional formatting by creating a calculated column in Date/Time format called "Created + 5" and tried to set an expression where the formatting is applied (row is highlighted) when "Created + 5" is greater than or equal to current date. So after 5 minutes, the row will no longer be highlighted (because the current date/time will exceed the "Created + 5" value)
Here is the expression from the SPD Advanced Condition Builder:
ddwrt:DateTimeTick(ddwrt:GenDisplayName(string($thisNode/#Created_x0020__x002b__x0020_5_x))) >=
ddwrt:DateTimeTick(ddwrt:GenDisplayName(string($Today)))
I think the problem is that the [Current Date] option ($Today in the expression builder) only accounts for date and not time. It looks like it just ends up highlighting everything that was created today, which is not very useful.
Any thoughts or help!? I have never messed with the advanced conditions because usually the basic stuff works fine for me! If anyone has any other ideas too like JavaScript or anything else that would work, I am open to that too as long as it will continuously update!
Thanks all!!!!
[Today] actually doesn't work properly in 2010, there are some workarounds though, e.g. https://abstractspaces.wordpress.com/2008/05/19/use-today-and-me-in-calculated-column/.
You can also use the approach with calculated column: https://blog.splibrarian.com/2012/06/06/using-calculated-columns-to-add-color-coding-to-your-sharepoint-lists/
Since you want this to update automatically without requiring someone to manually refresh the page, JavaScript is your best bet. You can have a function run repeatedly on a specified interval, checking the current date against the values in a date column.
Something like the following code would work, though you may need to tweak the CSS selectors specified in the calls to document.querySelector and querySelectorAll to match your particular HTML.
<script>
formatCell();
function formatCell(){
var frequencyToCheck = 2 /* num seconds between updates */
var minutes = 5; /* num minutes back to highlight */
var targetColumn = "Display name of the column you want to check";
var formatting = "background-color:darkred;color:red;font-weight:bold;";
var comparisonDate = new Date();
comparisonDate.setHours(comparisonDate.getHours() - minutes);
var tables = document.querySelectorAll("table.ms-listviewtable"); /* should get all list view web parts on the page */
var t_i = 0;
while(t_i < tables.length){
var headings = tables[t_i].rows[0].cells;
var columnIndex = null;
var h_i = 0;
while(h_i < headings.length){
var heading = headings[h_i].querySelector("div:first-child");
if(heading != null){
var displayName = heading.DisplayName ? heading.DisplayName : (heading.innerText ? heading.innerText : heading.textContent);
displayName = displayName.replace(/^\s+|\s+$/g,''); /* removes leading and trailing whitespace */
if(displayName === targetColumn){
columnIndex = h_i;
break;
}
}
h_i += 1;
}
if(columnIndex != null){ /* we found a matching heading */
var rows = tables[t_i].rows;
for(var i = (rows.length > 0 ? 1 : 0); i < rows.length; i++){
var cells = rows[i].children;
if(cells.length <= columnIndex){continue;}
var valueToEval = cells[columnIndex].innerText ? cells[columnIndex].innerText : cells[columnIndex].textContent;
if(typeof valueToEval == "undefined"){valueToEval = "";}
valueToEval = new Date(valueToEval);
if(valueToEval > comparisonDate){
cells[columnIndex].setAttribute("style",formatting);
}else{
cells[columnIndex].setAttribute("style","");
}
}
}
t_i +=1;
}
setTimeout(formatCell,frequencyToCheck * 1000);
}
</script>
One potential pitfall is that while this approach will "age" records appropriately based on their displayed values (causing them to stop being highlighted as they grow stale), it won't automatically pick up new changes to the list; you'd need to refresh the page (or at least refresh the view in the web part) whenever you want to see updated information.

TotalResults count changed when page index changed FullTextQuery in sharepoint search

I create custom search for SharePoint search.
if i search it wit page size 10 and page index (0 or 1 or 2) total result count will be 55 when actual result 40, else if page size 10 and page index 4 total result count will be 50 and no rows returned else if page size 10 and page index 3 total result count will be 40,
else if page size 100 and page index 0 total result count will be 40.
My Code:
private static DataTable ExecuteSearchQuery(SPWeb web, int pageNumber, int pageSize, ref long totalRecords)
{
FullTextSqlQuery query = new FullTextSqlQuery(web.Site);
query.StartRow = pageSize * (pageNumber - 1);
query.RowLimit = pageSize;
query.TrimDuplicates = true;
query.ResultTypes = ResultType.RelevantResults;
query.QueryText = #"SELECT ID, Title, Modified ,URL FROM Scope() WHERE (CONTAINS(Url, '/lists/Comments') AND FREETEXT(Title,'*any*'))";
ResultTableCollection results = query.Execute();
DataTable searchResults = results[ResultType.RelevantResults].Table;
totalRecords = query.QueryInfo.TotalResults;
return searchResults;
}
the problem is caused by the paging web part. If you modify it to show all the pages, the statistic total results number will be always the same. For example, from the paging web part properties, change the number of pages before and after current page to 1000, then you will see that your problem will not exist anymore!! This is a bit ugly if you have many pages!!!
Check out this: http://kamilmka.wordpress.com/2012/04/14/customize-sharepoint-search-results-paging/

Getting total View entries including categories - performance issue

I'm using a custom footer on my View Control; there I have for example:
Displaying 1 - 25 of 34200
My underlying View is Categorized so the total of entries should include categories as well.
So far the only way I'm able to find the total of entries including categories is using NotesViewNavigator; however, performance is not acceptable since it's taking around 27 seconds to compute this piece of code.
I'm sure the issue is with line var nav:NotesViewNavigator = view1.createViewNav(); because I added some debugger info:
start = new Date().getTime();
var viewPanel1:com.ibm.xsp.component.xp.XspViewPanel = getComponent("dataView1");
var nav:NotesViewNavigator = view1.createViewNav();
if (viewScope.VendorSrch == "" || viewScope.VendorSrch == null){
var total = nav.getCount();
}else{
var total = viewPanel1.getRowCount();// View can be filtered by user as well (using categoryFilter property)
}
var from =(viewPanel1.getFirst() < total? (viewPanel1.getFirst() + 1 ) : total);
var tmpTo = viewPanel1.getFirst() + viewPanel1.getRows();
var to = (tmpTo < total? tmpTo : total);
var elapsed = new Date().getTime() - start;
print(elapsed + " ms");
"</b>Displaying <b>"+ from +"</b> - <b>"+ to + "</b> of " + "<b>"+total+"</b>"
Does anyone know how can I improve this piece of code?
Please note documents in this View have Readers fields as well which may be impacting the
performance of this operation.
You are trapped in performance hell. Read access protection is only and only stored inside the document. So when you ask your view navigator to get the count its only option is to open all involved documents - hence the poor performance. Read protection and performance are natural enemies (just imagine: you have an office where every door is locked and to move around you have to check all your keys every time if you have one with the matching lock number).
The way out of reader field introduced performance hell is to read only the entries you actually need (as outlined). It could be a little tricky if a user has access to documents based on name, group-membership and role (that would make one read per access), but it is still very much feasible. In this case you would use a repeat control and a object data source or managed bean, so the multiple passes happen in the background.
Bonus trick: if you add a column with the formula 1 (just the number) and add it up, while categorizing it, then you can just jump from naventry to next sibling (that would be the next category) and add the numbers --> much less reads involved and NO documents opened.
To stress again: nav.count needs to open all documents and is a BAD idea, anything that requires read access to be checked is a bad idea, so using one (or more) viewNav based on access rights that actually only read documents the user can read is the way to go.
Let me know if you need more hints
I tried several approaches and using this loop reduced the time from 27 seconds average to 2.7 seconds:
start = new Date().getTime();
var viewPanel1:com.ibm.xsp.component.xp.XspViewPanel = getComponent("dataView1");
var nav:NotesViewNavigator = view1.createViewNav();
nav.setEntryOptions(NotesViewNavigator.VN_ENTRYOPT_NOCOLUMNVALUES);
// disable autoupdate
view1.setAutoUpdate(false);
if (viewScope.VendorSrch == "" || viewScope.VendorSrch == null){
nav.setBufferMaxEntries(400);
//var total = nav.getCount(); // This works but slow
// peform lookup
var vwentry:NotesViewEntry = nav.getFirst();
var vwentrytmp:NotesViewEntry = null;
count = 0;
while (vwentry != null){
count = count + 1;
// Get entry and go recycle
vwentrytmp = nav.getNext(vwentry);
vwentry.recycle();
vwentry = vwentrytmp;
}
total = count;
}else{
var total = viewPanel1.getRowCount();
}
var from =(viewPanel1.getFirst() < total? (viewPanel1.getFirst() + 1 ) : total);
var tmpTo = viewPanel1.getFirst() + viewPanel1.getRows();
var to = (tmpTo < total? tmpTo : total);
var elapsed = new Date().getTime() - start;
print(elapsed + " ms");
"</b>Displaying <b>"+ from +"</b> - <b>"+ to + "</b> of " + "<b>" + total + "</b>"

Resources