TotalResults count changed when page index changed FullTextQuery in sharepoint search - sharepoint

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/

Related

Row count in aggrid with 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

CodedUI "FindMatchingControls()" works 10% of the time but usually returns about half of the controls

Problem: I am using FindMatchingControls() to create a Collection of rows in a WPF table. I have written a loop that will set the ComboBox in each row to a given value. The whole thing works sometimes but more often than not, FindMatchingControls() actually finds about half of the rows. How can I configure timeouts or change settings to make it find all 50 controls every time or perhaps to find the first 10 and then to find the next 10 etc?
Background: I am testing a WPF window and on it, there's a table, each row in the table has a drop down list. There are 50 rows and in future there could be more so it is not feasible for me to record the setting of each one, my recorded test would be out of date with each new version (every month or so).
I have therefore recorded the setting of 1 ComboBox and then I used FindMatchingControls() to create a Collection. I loop through the Collection setting each ComboBox in that collection to the desired selection. The first 23 rows are shown on my current screen resolution. The only problem is that FindMatchingControls() sometimes returns 23, sometimes 26 , sometimes 34 and sometimes it returns all 50 rows! My question is, how do I fix the code below so that it always return all 50 rows (and possibly more in future).
You can see from the code that I found the Parent control twice so pseudo code is below.
Psuedo Code:
1) Find Parent Container (table)
2) Define a row (that is a child of the parent table)
3) Use FindMatchingControls to get a Collection of Rows
4) Loop through the Collection, finding the ComboBox in each row and setting it's selection to a value passed into the method.
CODE:
public void PlaceAnOrderScreen_SelectItems_List(String item /*Value to set all 50 ComboBoxes to*/)
{
WpfControl rowOfOrderItems = new WpfControl(this.UIOptimalOrderSystemClientShWindow.UIItemCustom22.UIListViewAutoID37Table);
rowOfOrderItems.SearchProperties[WpfControl.PropertyNames.ControlType] = "DataItem";
rowOfOrderItems.SearchProperties[WpfControl.PropertyNames.ClassName] = "Uia.ListViewItem";
rowOfOrderItems.WindowTitles.Add("Order Management System");
rowOfOrderItems.Find();
rowOfOrderItems.DrawHighlight(); //Visible diagnostic
//should get a collection of 50 controls ...
//... but this is dodgy, it sometimes finds 23, 26, 34 or ocassionaly all 50 controls.
//There are 23 visible controls and the rest, you have to scroll down to see.
UITestControlCollection itemRows = rowOfOrderItems.FindMatchingControls();
int c = 0;
int i = 1;
string label = String.Empty;
foreach (var auditSelectionBox in itemRows)
{
//After the top 15 drop down selections have been made, strat scrolling down.
//This is because setting the Value for a list box that is off the screen
//causes it to complain the control is blocked...
if (c >= 15)
{
if (i >= 3) //The scroll wheel moves 3 rows at a time, so only scroll once for every 3 rows...
{
Mouse.MoveScrollWheel(-1);
i = 0;
}
}
i++;
c++;
WpfCell auditDDL1 = new WpfCell(auditSelectionBox);
auditDDL1.SearchProperties[WpfCell.PropertyNames.ColumnHeader] = "Total";
auditDDL1.WindowTitles.Add("OrderSystem 5");
//Works but takes 5 - 16 seconds per drop down list
auditDDL1.Value = item;
}
}
Instead of trying to find matching controls based on another row, you could use a method that takes the parent (in your case the table) and returns all it's children in a recursive way. It digs all the way down until all available children have been found. It shouldn't matter how much row's your table has, it will try and get all of them. It's usable for any UITestControl.
public ParentControl GetChildControls(UITestControl parentControl)
{
ParentControl parent = new ParentControl();
if (parentControl != null)
{
List<ParentControl> children = new List<ParentControl>();
foreach (UITestControl childControl in parentControl.GetChildren())
{
children.Add(GetChildControls(childControl));
}
parent.Children = new KeyValuePair<UITestControl, List<ParentControl>>(parentControl, children);
}
return parent;
}
The parent class
public class ParentControl
{
public KeyValuePair<UITestControl, List<ParentControl>> Children { get; set; }
public string Value
{
get
{
return Children.Key.Name;
}
}
}
I just added the Value property for easy access to the name of UITestControl.
PixelPlex (above) has provided the best answer. All I had to add to PixelPlex's code was an If statement to set the ComboBox to a value when it was found. The foreach is therefore as below in my case ...
foreach (UITestControl childControl in parentControl.GetChildren())
{
children.Add(GetChildControls(childControl));
//Added below If statement to set ComboBox selected item to "Carrots"...
if (childControl.ClassName == "Uia.ComboBox")
{
WpfComboBox cb = (WpfComboBox)childControl;
cb.SelectedItem = "Carrots";
}
}
This selects Carrots from my ComboBox... Everything that does not satisfy my If statement is not relevant so I don't do anything with it.

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.

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>"

How to use content slide with RECORD objects in typoscript

On one of my sites, content (Videos) is inherited from the levels above if the content column is empty (in this case: colPos=3 / Border)
To create the output, I use
temp.myObject < styles.content.getBorder
temp.myObject {
slide = -1
}
Easy, because this is taken from a CONTENT object and slide is a built-in function.
Due to our system setup I need to do something similar with the RECORDS object. But the following typoscript doesn't work - it generates empty output:
temp.myObject = RECORDS
temp.myObject {
tables = tt_content
source.cObject = CONTENT
source.cObject {
slide = -1
table = tt_content
renderObj = TEXT
renderObj.field = uid
}
}
The same happens with this snippet:
temp.myObject = RECORDS
temp.myObject {
tables = tt_content
source.cObject = CONTENT
source.cObject {
table = tt_content
select {
pidInList.data = leveluid:-1,slide
}
renderObj = TEXT
renderObj.field = uid
}
}
[Note: The complicated source part above provides the ID of a content element from where we extract an image file from the flexform xml]
Can somebody help me to achieve a contentslide solution based on the RECORDS object?
If there are any problems understanding the questions, please ask.
CONTENT object doesn't have "slide" property.
Try simulate slide using stdWrap.ifEmpty.cObject.... for Your RECORDS object, as it could be done for slide simulation for TYPO3 3.8.x.
Example on TYPO3 wiki :
http://wiki.typo3.org/wiki/Content_Slide#Content_Sliding_in_TYPO3_3.8.x_by_TS_only

Resources