I add search suggestions to my search box like so...
var s = document.querySelector(".win-searchbox");
s.addEventListener("suggestionsrequested", function (e) {
e.detail.searchSuggestionCollection.appendQuerySuggestions(["one", "two", "three"]);
});
But when I run the app and use the search field too quickly, it throws one of two exceptions deep in the ui.js file having to do with adding to and removing from the suggestions list. I assume that the async script is trying to access list items that are taken out of existence already (because I'm navigating quickly... search, enter, type a new search, enter, etc.).
I can't figure out how to debug this or find a way around it. Is there a null check or something that I need to put somewhere? Thanks.
The problem was the page was navigating back to itself when the query was submitted, so I searched too quickly it tried to do navigations overlapped somehow and threw the exception. The fix was to simply replace the filter function on the ListView when the query was submitted. Obviously, this is the better way to do it anyway and the performance was dramatically improved.
I had an issue similar to this with the search box control if I searched rapidly to navigate to the search results page. My suggestions are ranked values from a 40K of JSON objects, and the result returns within 100ms. I made a global variable to hold the search promise and canceled it in my navigation onnav event.
Related
I'm curious if anyone has come across this question before.
I've been asked a few times if there is a way to emulate the Global Search functionality into another field.
I'm guessing Inline HTML, potentially triggered by Client Script, but I don't know where to start.
Anyone worked with the Global Search before?
N/search has a search.global method that returns a search result with columns: name, result, info1, info2 (and id and recordType) It has a promise method that allows use in a client script.
It's all up to you how you display the results though.
depending on what you are trying to do another search like operation but more focused is the field.getSelectOptions method. This lets you do a contains, is or startswith search for a matching value for a field. Great if are trying to script a transaction field where the normal select list could be 100k long.
TypeAhead works fine If you don't have so many documents. If i delete lots of them typeAhead works. I think there is a limitation #DbColumn() in typeahead option.
How to solve this problem? It's like a 64k size problem but any suggestion is important
Thanks in advance
C.A.
Are you using #DBColumn() or #DBLookup() to populate your typeahead? They do have 64K limits. (I'm not sure as I read your question, so I ask for clarification).
If so, you might want to consider looking at links like this Can typeahead results be returned from a java function,
I've recently done one with a massive number of documents (millions). I used this, but since it was taking a lot of time to return, I changed it to get the first selected entry in the view (based on the value from the AJAX typeahead), created a ViewNavigator from that entry, and used the setBufferMaxEntires property to restrict the size of the returned ViewNavigator. This lets the process go quite fast.
Brian
UPDATE:
As requested. I started with using results like I linked above, then I added
ViewEntry startEntry = canQLView.getEntryByKey(searchValue, false);
allObjects.addElement(startEntry);
if (startEntry != null) {
ViewNavigator matchingEntries = canQLView.createViewNavFrom(startEntry);
matchingEntries.setBufferMaxEntries(10);
ViewEntry entry = matchingEntries.getFirst();
You can see I get a single entry rather than a ViewEntryCollection, start my ViewNavigator from that entry, and the setBufferMaxEntries property restricts how much is fetched - you can change it, but a low number is sensible since it's a typeahead.
Cheers,
Brian
Correct, there is the 64Kb limit on #DbColumn(), it's not an XPages-specific limitation and various blog posts confirm it. Ensure typeahead is only provided once the user has entered an appropriate number of characters that can restrict. After all, the typeahead should return a small number of entries for the user to select from, otherwise it's not much use. Then use #DbLookup with "[PARTIALMATCH]" or getAllEntriesbyKey. There are a number of blog posts available that give code samples.
I'm trying to read the contents of a "list view" using automation. The first time I navigate to it, I'm able to go from item to item, getting the correct text for each list item. However, when I display a different screen (which is apparently reusing this display object), the text on the screen is different, but automation gets the same text as the first set. From then on I can only get the text for the first view I looked at. It's like the text is being cached and I'm only able to look at the cached view. UISpy, however, seems to grab the right values every time, and if I use it while my automation is paused, I end up getting the right values.
In my automation, I use Find to grab the header, and walk the tree to the List View and get the text for each element. I thought if you used the Current property, you got the live data. Apparently I was mistaken. How do I either refresh the tree or get the REAL data?
Yes, the Current property on a certain AutomationElement will return its current, 'live', value. UIA will not cache anything automatically, you'll have to declare it yourself and explicitly access the Cached properties.
What's probably happening is that the new tree items you're seeing after selecting a different screen, are actually re-created (and that actually makes sense, UI-wise), not just updated. You could easily determine if this is the problem by selecting the first screen and writing down the tree items' RuntimeId property (you can see it in UI Spy). Then, select the second screen and check if the RuntimeId has changed. If it has, then it's just not the same object instance.
If this is the case, all you need to do is get the items again. It'll be easier to do this using AutomationElement.FindAll with a ClassName property condition.
I have a fairly straightforward and common use case. A panel, in which resides a repeat control. The repeat control gets its content from a view lookup by key. Below that repeat control is another panel. This panel has a data binding to a new notesdocument. The panel has a couple of fields on it for the new document and a submit button.
It all works, however after submit (presumably in the "postSaveDocument()" event) I want to call back up to the repeat control and have it re-perform its lookup and refresh its content.
I'm looking to understand syntactically, how I can reference the repeat control and its properties and methods from elsewhere on the document -- and secondarily (though I can look this up once I get the first part figured out) what the refresh() method would be for that that repeat control.
Ideally, I think its something like: xp:page.repeatcontrolname.refresh() -- though I know that isn't right.
I'm sure once I see an example, it will apply to a myriad of other things.
Update :
I discovered that the repeated elements were actually refreshing but I wasn't seeing a new entry added to the list. The reason, ultimately, turned out to be that to add another entry to the repeat list I needed a new "control" -- but I'd checked that box (on the repeat control) that said "Create Controls at Page Creation". It was preventing my XPage from creating another entry for the new document to display!
This article explains the syntax for doing what you describe:
http://avatar.red-pill.mobi/tim/blog.nsf/d6plinks/TTRY-84B6VP
I have a feeling that this one captures the actual use case.
http://www-10.lotus.com/ldd/ddwiki.nsf/dx/Create_and_display_responses
The key setting that people tend to miss is "ignoreRequestParams".
Andrew,
The 'XSP.PartialRefreshGet' call was broken in Domino release 8.5.3 which results in the '_c9 is undefined' error.
Have a look at the article posted by Tommy Valand:
http://dontpanic82.blogspot.com.au/2012/03/patch-for-bug-in-xsppartialrefreshget.html
Basically to work around the problem a second argument is required to be passed to the call, for example:
XSP.partialRefreshGet("#{id:ExistingDevicesList}", "")
What's a good way to paginate a list that is constantly growing?
For example, a user may open page 2 of some listing, keep looking at it for a while and then open page 3. Meanwhile, new records have been added to the beginning of the list (page 1) and caused page 3 to contain items that could have been on page 2 previously.
Should such a list be paginated from the other end? Then how to deal with the front page and the fact that it would, without special attention, contain TOTAL NUMBER OF ITEMS % PAGE SIZE items (ie. not constant)?
Assuming you have a fixed page size, some specified ordering, and the user is specifying the page they wish to view, I would simply fetch the data accordingly. Trying to do anything more complicated than that will just end up causing you unnecessary headache and confuse the user.
I think the element you're missing here is the ordering. If you specify an ordering then the user will intuitively understand. Also, that's how the majority of pagination is done, so you're not deviating from what you're user really expects.
I'd add a warning to advise the user that new items have come in and allow them to refresh the list. If they choose not to then maintain list in the state it was in when they clicked on the "Page 2" button. You can use a timestamp on the URL to determine which version of the list to serve to which user.
I do not think it's a good idea to page through a growing list. You'd better recalculate items that should be displayed on a page everytime user performs an action.