xpages session scope AND document data binding - data-binding

I have a value that I get from a picklist. I set this value as a sessionScope variable.
I then want to use this value, do a lookup, and set the value of an input field - which is working.
However, I am doing the lookup code in the fields data binding section using SSJS, and as such am not too sure how to save this value (normally my data binding would just be document1.FIELDNAME)
I've tried setting the value as part of my code, but the change is not saved in the backend doc.
I've also tried doing the lookup code in the fields "Default value" property, but this always just returns nothing.
Does anyone know how I can display on the xpage the value from my lookup AND also save this value to the backend document?
I fear I am missing something simple and maybe getting tunnel vision!
The code I am using for my data binding value is below.
Thanks
try{
var key1 = sessionScope.PLProspectiveAssured;
var dbName:NotesDatabase = session.getDatabase(database.getServer(),"CIR2001.nsf");
if (key1==""){
returnVal = "Not found";
}else {
var vwOrgs:NotesView = dbName.getView("OrgDocID");
var doc:NotesDocument = vwOrgs.getDocumentByKey(key1);
returnVal = doc.getItemValueString("OrgCountry");
}
// set our field
var doc:NotesDocument = document1.getDocument();
doc.replaceItemValue("ProspectiveAssured", returnVal);
return returnVal;
}catch(e){
openLogBean.addError(e,this);
}

Use your datasource and set the value using .setValue(field, value). In your case:
// set our field
document1.setValue("ProspectiveAssured", returnVal);
Make sure that you save your datasource somewhere (else).

Related

Datasource Paging Issue (Revised Again)

See Datasource Paging Issue (Revised)
for the original question.
Markus, you were kind enough to help with out with the issue of incorporating a record count into a query using a calculated datasource. I have a search form with 15 widgets - a mix of date ranges, dropdowns, text values and ._contains, ._equals, ._greaterThanOrEquals, ._lessThanOrEquals, etc.
I have tested this extensively against mySQL SQL code and it works fine.
I have now added a 16th parameter PropertyNames, which is a list with binding #datasource.query.filters.Property.PropertyName._in and Options blank. The widget on the form is hidden because it is only used for additional filtering.
Logic such as the following is used, such that a particular logged-in user can only view their own properties. So if they perform a search and the Property is not specified we do:-
if (params.param_Property === null && canViewAllRecords === false) {
console.log(params.param_PropertyNames); // correct output
ds.filters.Property.PropertyName._in = params.param_PropertyNames;
}
The record count (records.length) is correct, and if I for loop through the array of records the record set is correct.
However, on the results page the table displays a larger resultset which omits the PropertyNames filter. So if I was to search on Status 'Open' (mySQL results 50) and then I add a single value ['Property Name London SW45'] for params.param_PropertyNames the record count is 6, the records array is 6 but the datasource display is 50. So the datasource is not filtering on the property array.
Initially I tried without adding the additional parameter and form widget and just using code such as
if (params.param_Property === null && canViewAllRecords === false) {
console.log(params.param_PropertyNames); // correct output
ds.filters.Property.PropertyName._in = properties; // an array of
properties to filter out
}
But this didn't work, hence the idea of adding a form widget and an additional parameter to the calculated recordcount datasource.
If I inspect at query.parameters then I see:-
"param_Status": "Open",
"param_PropertyNames": ["Property Name London SW45"],
If I inspect query.filters:-
name=param_Status, value=Open
name=param_PropertyNames, value=[]}]}
It looks as though the filter isn't set. Even hard coding
ds.filters.Property.PropertyName._in = ['Property Name London SW45'],
I get the same reuslt.
Have you got any idea what would be causing this issue and what I can do for a workaround ?
Using a server side solution I would suggest editing both your SQL datasource query script (server side) that is supposed to filter by this property list and including the same code in your server side script for your calculated Count datasource. The code would look something like this, not knowing your exact details:
var subquery = app.models.Directory.newQuery();
subquery.filters.PrimaryEmail._equals = Session.getActiveUser().getEmail();
subquery.prefetch.Property._add();
var results = subquery.run();
if(!results[0].CanViewAllRecords) {
query.filters.Property.PropertyName._in = results[0].Property.map(function(i) {return i.PropertyName;});
}
By adding this code you are filtering your directory by your current user and prefetching the Property relation table, then you set the filter only if your user canviewallRecords is false and use JS map function to create an array of the PropertyName field in the Property table. As I stated, your code may not be exactly the same depending on how you have to retrieve your user canviewallrecords property and then of course I don't know your relation between user and Property table either, is it one-to-many or other. But this should give you an idea how to implement this on server side.

Add objects to session

I need some clarity about session and how to add objects, because I think I do it the wrong way.
First I create a session to hold a list of Products:
Session["ShoppingCart"] = new List<Products>();
To add Products to the list, I do like this:
Session["ShoppingCart"] = new Products { ID = productId, Name = name };
I guess this isn't the right way?
I guess this isn't the right way?
Yes, this isn't the right way (please skip towards the last paragraph of my answer to know the correct way - which is not to use ASP.NET session at all). The correct way is to first get the object you stored inside the session by trying it to cast it to the same .NET type yo uhave stored inside the session:
var products = Session["ShoppingCart"] as List<Products>;
and then if this item is not null add the corresponding product to the list. We should of course make the necessary type check that the session actually contained a value with the specified key and that this value is of the expected type:
if (products != null)
{
var product = new Products { ID = productId, Name = name };
products.Add(product);
}
Of course we are using object references here which will only work if you are storing your session in-memory (sessionState mode = InProc) which of course is absolutely a terrible disaster and something you should never do in production. In a production environment you are probably persisting your session in a session server or even SQL server, aren't you? In this case it is more than obvious that working with object references is a recipe for disaster. So in this case once you have added the new product to the session you should of course set back the new list value to the session which will serialize the object instance to the corresponding data store:
if (products != null)
{
var product = new Products { ID = productId, Name = name };
products.Add(product);
Session["ShoppingCart"] = products;
}
Now, after all this being said I must admit that using ASP.NET Session is probably the huge mistake you would ever commit in a real world application. So basically every time you are using Session["xxx"] you are doing it wrong. Simply search the entire solution for the Session keyword and just get rid of it.
In order to add itens to an existing list on the Session, you must first retrieve the list then add the object to it. Here's an example:
Session["ShoppingCart"] = new List<Products>();
List<Products> productsList = (List<Products>)Session["ShoppingCart"];
productsList.add(new Products { ID = productId, Name = name });
Session["ShoppingCart"] = productsList;

meteor 0.5.7: how to handle/use Meteor.Collection.ObjectID?

I have updated my meteor yesterday and tried using the new Meteor.Collection.ObjectID.
But since with no success. First i updated my collections in this way:
myCollection = new Meteor.Collection('mycollection', {idGeneration: 'MONGO'}
Now, normal new inserts have an _id like Wi2RmR6CSapkmmdfn... (?)
Then i have a collection with an array included. I like to have an unique id for every object in this array. So i $push an object with a field like id: new Meteor.Collection.ObjectID() into my array. The result in the database is like this: ObjectId("5b5fc278305d406cc6c33756"). (This seems to be normal.)
But later i want to update my pushed object, if the id equals an id, which i stored as data attribute in an html tag before.
var equals = EJSON.equals(dbId, htmlId); (This results every time in false. So i logged the values dbId and htmlId into the console with console.log(typeof dbId, dbId);)
The values of this two variables is as follows:
object { _str: 'a86ce44f9a46b99bca1be7a9' } (dbId)
string ObjectID("a86ce44f9a46b99bca1be7a9") (htmlId; this seems to be correct, but why is a custom type a string?)
How to use the Meteor.Collection.ObjectID correct?
When placing your htmlId in your html you need to put it in as a string and not as an object, remember _id is an object now, handlebars is guessing and using toString() & thats why it shows up as ObjectID("...").
So if you're using {{_id}} in your html you now need to use {{_id.toHexString}} to properly extract the string part of it out
When you extract this html value with your javascript you need to make it back into an objectid:
js:
var valuefromhtml = "a86ce44f9a46b99bca1be7a9"; //Get with Jquery,DOM,etc
htmlId = new Meteor.Collection.ObjectID(valuefromhtml); //see: http://docs.meteor.com/#collection_object_id
EJSON.equals(htmlId, dbId); //Should be true this time

flex: drilling down into dataprovider arrays

I have an SQL Statement which I want to read the name fields from an SQL database. the code:
public function getAllGiberish():void {
var stmt:SQLStatement = new SQLStatement();
stmt.sqlConnection = sqlConnection;
stmt.text = "SELECT name FROM test3";
stmt.execute();
l.dataProvider = new ArrayCollection(stmt.getResult().data);
}
This will pull the data from the db. However, in the list item it shows everything up as [object Object]. Upon debugging I can see that the data provider shows:
data[0] > name
data[1] > name
data[2] > name
Where the info that I want is the name within each data object.
How do I easily access this? It is a problem I keep coming across and would like to work it out once and for all!
Cheers
You want to set the labelField property on the list (Assuming Flex 3 here). By default it's looking for a field called "label" not "name". Also look at the dataField and labelFunction properties of the list object for some more advanced options.
The result of the query returns an array of Object instances, while you might expect String, with their keys equal to the column names that you select. You will either need to alias the "name" column to "label" in your query (as the List control uses this as the default labelField as Chris metioned), or you need to set the labelField or a labelFunction on the List control.
Note that you can also return typed objects instead of plain Object instances by setting the itemClass property on the statement.
You could write a label function:
private function list_labelFunction(item:Object):String {
return item.columnName;
}
And make sure that your List has a label function set:
<s:List id="myList" labelFunction="list_labelFunction"/>
That's how I did it anyway!

How to update a table row with save button using .ajax

I have a table which has one row and only one cell will be editable. I have accomplished this with the following code.
$("td#effEndDate").click(function() {
if (!$(this).hasClass("edit")) {
var value = jQuery.trim($(this).html());
$(this).html("<input id=\"txtEdit\" type=\"text\" value=\"" + value + "\" />");
$(this).addClass("edit");
$("#txtEdit").focus();
}
});
Now this is the part where i'm stuck.
After the field is updated a save button must be clicked to call the proper .ajax method to update the database. But how can I compare the previous value to the current value on a button press? Since i'm not using the onblur property where I could have saved the old value and passed it to the update function.
There are two possibilities.
Pass the variable around in between functions
Make the variable global
if you want the variable global do not use the "var" keyword
Change:
var value = jQuery.trim($(this).html());
To this:
value = jQuery.trim($(this).html());
Edit
If the click function is getting hit more then once before a page refresh and assuming you want to keep a copy of the original table rows you can try this. Save a copy of the original table in a variable then you can query the original table for the html using the ID number. Here is a quick mock
first store the table in a variable upon the page loading. This will save an original copy of the table
//get a copy of the table
var GetCopyofOriginalTable = function() {
var TableToBeCopied = $('the appropriate selector');
CopyOfTable = JQuery.extend(true, {}, TableToBeCopied); //Notice no var, its global
}
//Now store the variale
GetCopyofOriginalTable();
var FindTableRowByID = function(trID) {
return $('table:has(tr#' + trID));
}
Now you can loop through the new table test its value agaisnt the old table. This methed make use alot of memory depending on how big the table is.
I would store the original value somewhere in a variable, and compare the two in the submission function before sending the .ajax call.

Resources