How do I use FTSearchSorted to filter a view in XPages? - full-text-search

I'm working on my Excel exporting using Apache POI. I want to be able to include a query string to limit the exported contents, but I either end up getting 0 documents or getting a couple of documents.
When I get a couple of document, it's unclear if the view object is actually modified. It still responds to getEntryCount with 13 documents, but exports just 2 and doesn't print the columnValues for those two. If I don't use the search, it exports the entire view flawlessly.
The server-side javascript has these few relevant lines.
function createWorkbookStreamWithLabels(workbookName,sheetName,fieldList,dbName,viewName,colLabels,totalLabels,queryString){
...a bunch of other code to get a handle to the view...
postValidationError(control,"Entries: " + view.getEntryCount());
var docCount = view.FTSearchSorted(queryString);
postValidationError(control,"Query: " + queryString);
postValidationError(control,"Query count: " + docCount);
if ( docCount == 0) return;
...code that walks the view and prints the contents...
}
My 0 hit queries include:
FIELD lastname CONTAINS e
and
[state] CONTAINS V
The one that gets two hits is simple:
VA
The view is sorted and now the database is full-text indexed. The column containing State is now sorted and click to sort, ascending.
Just for reference, here's the function that displays my status messages.
function postValidationError(control, msg) {
if ((typeof msg) != "string")
return;
var msgObj = new javax.faces.application.FacesMessage(javax.faces.application.FacesMessage.SEVERITY_ERROR, msg, msg);
facesContext.addMessage(control.getClientId(facesContext), msgObj);
control.setValid(false);
}
What have I done wrong?
Update: the problem with my search queries is solved, but my code also seems to have a terrific tendency to crash HTTP or the server.

Related

Redirect to Zoho matched Customer Record with Deluge function

I'm trying to embed a Zoho CRM by iframe into an application that knows only a phone number.
(Ramble: Originally I intended to call the Zoho api to lookup the Contact by phone number and redirect to or load the Contact's Zoho page - but the hosting app doesn't seem to support enough features to accommodate Zoho's OAuth2-only authentication - so I think I'm stuck with Zoho Deluge which I'm finding to be an ATROCIOUS language)
I'm hoping to GET navigate to this Zoho Function with the phone number as a parameter, have it find the unique match, and redirect to the customer details.
response = zoho.crm.searchRecords(
"Contacts",
"", // no criteria - I hope the later parameter
// normalizes better than this would?
1, // first page
2, // of two max results - just to verify uniqueness
"{ phone: '" + phoneNumber + "'}"); // Docs are terrible. Is this the format?
// I also tried "phone:equal:..."
//if (1 < response.size()) { // script errors show up on nonsense line
// return "[Ambiguous]"; // numbers, but this seems to work until later
//} // lines are included - then errors point here
return response; // Works, but useless string output
return response.firstName; // "Invalid collection object found" - but not expected to work
return response.get(0); // 'TEXT' can not be cast to '[KEY-VALUE, TEXT, LIST]' for the function 'get'
return response.get('firstName'); // 'TEXT' can not be cast to '[KEY-VALUE, TEXT, LIST]' for the function 'get'
return response.get(0).firstName; // Improper Statement Error might be due to missing ';' at end of the line or incomplete expression
// openUrl( <string>, <window_type> ); // hoping to get here
I've also tried variations on returning from inside a for each element loop, no luck.
I THINK I've successfully found the user by phone number because I think I indeed get one match, but I can't verify it and I don't know how to derive the url of the customer detail page for the openUrl() call. Do you know how to make progress on this?
The criteria is malformed, and function searchRecords returns a list of maps.
To access the first element of al list you must use .get(0) and get an element of a map .get("First_Name")
The fields are malformed, you must get the API name of the field form crm.zoho.com->setup->API->API names->Contacts
You can use info to debug the response (info response;)
Zoho CRM API Search records
toReturn = "";
response = zoho.crm.searchRecords("Contacts", "Phone:equals:" + phoneNumber, 1, 2);
if (1 < response.size()) {
toReturn = "[Ambiguous]";
} else if (0 == response.size()) {//error triggered if use get(0) of emty list
toReturn = "[None]";
}else {
toReturn = reponse.get(0).get("First_Name");
openUrl("https://crm.zoho.com/crm/org[yourOrgID]/tab/Contacts/" + reponse.get(0).get("id"), "new window");
}
return toReturn;

Dexie.js - table.delete(id) not working for per-row deletion

i'm just starting out with Dexie, and I seem to be coming unstuck.
I have a small database (less than 1000 rows), and i'm trying to delete each row one-by-one once I know that the row has been sent to a remote API.
I can also successfully save to the table (which is defined by an ID and a column storing a serialised object)
here's my code:
if (online) {
//we query the db and send each event
database.open()
let allEvents = database.events.toCollection()
let total = allEvents.count(function (count) {
console.log(count + ' events in total')
//a simple test to ensure we're seeing the right number of records
})
allEvents.each(function(thisEvent){
//push to remote API
console.log('deleting ' + thisEvent.id)
database.events.delete(thisEvent.id) //<= this doesn't seem to be working
})
}
All of this with the exception of the final delete statement.
Any ideas on how I should fix this? the important thing for me is to delete on a per-row basis.
thanks in advance!
I was experiencing the same problem, and the answer from Eugenia Pais wasn't working for me. So after some tests, I saw the trouble was with the type of the variable: I was using a string, but a number is needed, so this is how I solved it:
function removeRow (primaryKey) {
primaryKey = parseInt(primaryKey);
databaseName.tableName.where('primaryKey').equals(primaryKey).delete().then(function(deleteCount) {
console.log ("Deleted " + deleteCount + " rows");
}).catch(function(error) {
console.error ("Error: " + error);
});
So be aware you are using a number as argument.
The correct way to delete each row should be selecting the specific row and delete it:
database.tableName.where(indexId).equals(indexValue).delete();
The data type of the key is not a problem you could verify it in my example here: example
db.example.where('key').equals('one').delete();
Maybe you are trying to delete by a property that not is an index.

Parse query returning objects based on parameter string length (not the parameter I filter by though)

This has me stumped and I'm pulling my hair out here.
The simple query below finds speeches for the current user:
var _debug = function(cb) {
console.log('_debug')
var DebugParseObject = Parse.Object.extend("Speech");
var debugQuery = new Parse.Query(DebugParseObject);
debugQuery.equalTo("user", _getCurrentUser()); // Incorrect results only occurs when I set the user with this line
debugQuery.find({
success: function(results) {
console.log("Successfully retrieved " + results.length + " scores.");
cb(results);
},
error: function(error) {
console.log("Error: " + error.code + " " + error.message);
}
});
};
The speech object class has the following extra columns
title
body
speech_id
user (pointer)
Here is the weird part: The query will only return the speeches whose body is a string less than about 1000 characters.
As in, I can have Speech A, with a 500 character string in the body field. It will be returned as one of the speeches. BUT if I increase Speech A's body string to about 1500 characters, it will NOT be returned any longer.
I can't understand why.
Some further points
It's only when I filter by the user. If I search for all speeches or query by a different parameter (e.g. title), then the correct amount is returned
This used to work fine yesterday and before
I manually deleted a user earlier (removed the row from the table), while their linked speeches still existed
I changed those speeches' users value from the deleted user id to a new users id
The speeches appear to have the correct user
I tried re-saving the user object on the speech's user property and it didn't do anything
Any help will be great! I feel like I've corrupted the user class when I deleted the user row. But I can't prove it.
The query syntax looks solid and you should be well within the storage limitations of Parse. In case you're curious, there's no explicit limit on string length, but Parse Objects are limited to 128k (except for Parse Files of course).
My guess is that something has gone awry when copying over a different user in place of the one you deleted. Manually changing data and pointers within the browser is always risky and prone to errors.

Error! Unknown op code for conditional

I am using Aspose.Words to do the MailMerge. But after merge for a merge field, It is showing Error! Unknown op code for conditional in document itself. This error may be due to incorrectly formed merged field. But my requirement is to detect/catch such error through code. Because, in our case user themselves creates the word template and upload into system. I have written very simple code to read do the mail merge.
doc.MailMerge.Execute(this.DataSource.Rows[rowIndex];
Can we detect such error in code? I tried to find online, but nothing useful could find.
No exception will be thrown in this scenario, but you can catch using the result of field after merging. Try the below sample code
// Load the document
Aspose.Words.Document doc = new Aspose.Words.Document(src);
// Do processing and mail merge etc
// Select all field start nodes so we can find the merge fields.
NodeCollection fieldStarts = doc.GetChildNodes(NodeType.FieldStart, true);
foreach (FieldStart fieldStart in fieldStarts)
{
// Get the next sibling
Run fieldResult = (Run)fieldStart.NextSibling;
// Match the error code with the result
if (fieldResult.NextSibling.NextSibling.GetText().Equals("Error! Unknown op code for conditional.", StringComparison.CurrentCultureIgnoreCase))
{
// Find the page number, where the field is present
LayoutCollector collector = new LayoutCollector(doc);
int pageNumber = collector.GetStartPageIndex(fieldStart);
Console.WriteLine("Error in field at Page: " + pageNumber + ". Field text: " + fieldResult.GetText());
}
}

HandsOnTable manualRowMove not updating the DOM

The manualRowMove works fine visually but the underlying dom is not getting updated. After manualRowMove the HOT.getData() is showing the old sequence of data and not the latest sequence after row swap.
Please advise what I am doing wrong or is it a bug.
Turning on manualRowMove and moving rows around does not affect the original data source. HOT.getData() returns the original data source, which is not what the current state of the table is.
Plugins like manualRowMove, manualColMove, columnSorting are just abstractions that sit on top of the data layer. They maintain state on the handsontable object (ie the sortIndex attribute) which basically act as lookup tables from what the authors call "logical index" to "physical index". Read more about it here: https://github.com/handsontable/handsontable/wiki/Understanding-column-sorting-plugin
It seems like you are trying to allow users to sort the order of the table then save that order. You'll have to roll your own func to walk the table and use a method like getDataAtRow() to get data in table order.
the way I fixed this was to use a PHP script to push the new order to the database on the server (there needs to be some < / > swap logic, it isn't that easy in PHP land, but it is doable), in theory you could recollect the grid and "refresh" it but I didn't feel it was necessary. Obviously the original json from my database is listed by the order
afterRowMove: function (oldIndex, newIndex){
$.post('../ajax/partsOrder.php?id=212&new_parts_order=' + newIndex + '&old_parts_order=' + oldIndex, function(data) {
var msg = '';
if (data.err!=0 || data.url==0) {
msg = 'Error: ' + data.err;
}
else {
msg = 'Success: ' + data.msg;
}
console.log('partsOrder.php says: '+msg);
},"json");
}
PS: I think this is a major omission from handontable, I was not impressed that the getData() doesn't simply represent the gui. In fact it's borderline criminal that they even worked on the gui at all without this

Resources