Brian - Friday, August 7, 2009 12:53 AM:
Hi All,
I am trying to work out how to get to data on one tab while on another.
Example. I have an item type (Document Distriubtion) with three relationships.
- Document
- Recipient
- File
From the File tab I want to be able to access all of the listed Documents on the Document tab.
It is likely that the Item will not be saved when I want to do this so I can't just retrieve the AML from the server and get to the data this way.
Can anyone help with how to get at this data?
Thanks,
Brian.
SamsAn - Friday, August 7, 2009 1:17 AM:
Try javascript like below
var q = parent.thisItem.newItem("Document Distriubtion Document","get");
q.setProperty("source_id", parent.thisItem.getAttribute("id"));
q.setAttribute("select","*");
var r = q.apply(); //now r contains required data
SamsAn.
Original Mind Any Level Innovator Solutions Free-Lancer, http://sites.google.com/site/caraacc
Brian - Tuesday, August 11, 2009 9:21 PM:
Thanks SamsAn,
This doesn't work in the current case because
"parent.thisItem" is null or undefined.
Also since the data is on the grid of the remote tab and may well not be saved on the server at this stage I can't use the "q.apply()" method since it will not always get me all of the data that I need.
I am making progress anyway using
document.frames[2].document.frames[0].document.grid
to access the current data in the grid that I am interested in from the user interface rather than from the server.
Brian.
SamsAn - Wednesday, August 12, 2009 11:38 AM:
Hi.
I just friendly remind that "document.frames[2].document.frames[0].document.grid" may be destroyed. For example, click File tab, click Save Item icon, click something to cause run your script. You will get null reference error on "document.frames[2].document.frames[0].document.grid" code line reaching Documents tab grid.
Concerning data from UI. I believe it is pretty strange design to take data from UI in like cases. Innovator standard client data are based on xml, and "thisItem" is a wrapper for it. By the way, thisItem contains unsaved data modified in the current form, but does not contain data retrieved from the server for "non-dirty" item.
Concerning parent.thisItem. It is well known that there is IOM.Item object "thisItem" attached to Instance frame document of TearOff window. So, depending of your script context your should call something like parent.thisItem or parent.parent.thisItem.
Hope it helps, SamsAn.
Original Mind Any Level Innovator Solutions Free-Lancer, http://sites.google.com/site/caraacc
Brian - Wednesday, August 12, 2009 6:59 PM:
Hi SamsAn,
Thanks for the response. I will admit to being quite frustrated by this process. XML is not my strong suit and the documentation that I am looking at for Innovator doesn't help as much as it could.
I am trying to implement a filtered item browser. I have an ItemType (Document Distriubtion) with three related ItemTypes (Distributed Document, Recipient and File Distribution).
The DocumentDistribution ItemType will capture general information about who a File is being distributed to outside the company. The user will select a number of Documents via the Distributed Document tab in the normal manner. When the user clicks on the File Distribution tab and selects to create a new relationship a method linked to the "onSearchDialog" event is called. It is in this context that I am trying to write the method.
So. I have attached a method to the onSearchDialog and it runs when the user selects to create a new Relationship of a File. Inside this method "parent.thisItem" and "parent.parent.thisItem" are both undefined. I have verified this through the debugger.
I would love to be able to access the new data entered but not yet saved in this manner but since I can't get to the "thisItem" object I can't do it.
Where is the documentation for "thisItem" since I can't find any reference to it online in the IOM.Item class
It appeared that I could access the grid of the "Distributed Document" tab through the "document.frames[2].document.frames[0].document.grid" call. This in fact works quite well, although if it can be easily destroyed by the user it is clearly not all that robust a method.
The second problem that I have is that even if I manage to find all of the File items which belong to the Distributed Document items I can't make the filter accept two or more of the same type of item. I want to be able to say "Limit the user to being able to pick idA, idB, idC or idD as the Files that are being distributed."
If you can help with a working example of the above situation then it would be great.
Thanks,
Brian.
SamsAn - Friday, August 14, 2009 6:29 AM:
OnSearchDialog has inArgs input parameter as you can see in a debugger:
var itm = inArgs.itemContext; //XmlElement. It represents main item concerned with the opened tear-off window.
var propValue = top.aras.getItemProperty(itm, "prop_name");//just an example
var dirtyRelships = itm.selectNodes("Relationships/Item[@type='Some RelshipType Name']"); //XmlNodeList
var idList = new Array();
for (var i=0; i<dirtyRelships.length; i++)
{
var relatedId = top.aras.getItemProperty(dirtyRelships[i], "related_id");
if (relatedId)
{
idList.push(relatedId);
}
}
//... Additional code
var idListStr = (idList.length>0 ? idList.join(",") : "this_string_should_not_be_empty");
inArgs.QryItem.item.setAttribute("idlist", idListStr); //To display necessary items only.
Hope it helps, SamsAn.
Original Mind Any Level Innovator Solutions Free-Lancer, http://sites.google.com/site/caraacc
dhenning - Friday, August 21, 2009 9:38 AM:
Brian:
I am new to this discussion, and just saw the interchange between you and SamsAn. There was not a final
reply from you to SamsAn last reply, and I was wondering if that approach was successful for you? I had
been trying to do a similar thing (actually trying to display a running total in the main window frame when someone
would add another item in one of the tabs in the bottom frame. What I was told by Peter Schroer was that
the frame reference number (e.g. document.frames[2]) varies by the order in which someone clicks on the tabs.
And he did not know of a way to query the frames to find out which one is which at any particular moment. I had
developed a process that worked with hard coding frame numbers, but it only work if I entered the window and
clicked tabs in a particular way and then called my method. And the second time I called the method it
did not work. So, my interest in whether you got your process to succeed.
Brian - Sunday, August 23, 2009 6:38 PM:
At this point I have been sidetracked and have not had a chance to put SamsAn's suggestion to the test.
I hope to get to it over the next week and will post the results when I have tried.
Cheers,
Brian.
Brian - Thursday, August 27, 2009 1:33 AM:
I guess that I am making slow progress on this. Sometimes it is a bit hard to tell.
The code that SamsAn posted works for retrieving the Item details in the tabs and I can use this to get to the lower level ID's that I need to get the actual Items that I want from the database. This means that I should be able to forget about the document.frames etc arrays which are not stable in the process.
However, I still can't figure out how to make the Search Dialog display the items of interest if there is more than one item.
If there is only one File then it is displayed after I click the "search" icon.
If there is more than one file then nothing is displayed.
After calling the following code to set the id list (as per SamsAn)
inArgs
.QryItem.item.setAttribute("id",filterFiles);
The XML in the inArgs.QryItem looks like this.
xml "<Item type="File" action="get" id="2EC723D658334CE098F0741EE17195DD,F2DBB3F5B4574AC6B174BA2F255843FB"/>
" String
Which does not seem to return anything.
After experimenting with the Nash script client I tried simply replacing the XML with a new construct which works in the Nash script. This time when I load it I get an XML load error advising that there can only be one Top item in the XML. the XML was of the form:
<Item type="File" action="get" id="010A3B5F3063448CB08F31BB19CFAA90"/>
<Item type="File" action="get" id="423AB835241646BF8BD5D6ED1918C737"/>
Which works in the Nash client but won't load using inArgs.QryItem.dom.loadXML( xmlString );
If I use this method and only supply one id then I can limit the user to one selection choice but this is not much use to me.
Can someone PLEASE tell me how to set up the xml in the inArgs for an onSearchDialog event to allow me to limit the selection to a list of ids?
Frustrated in Canberra.
Brian.
SamsAn - Thursday, August 27, 2009 3:11 AM:
Hi.
Just a friendly reminder. My original example contains "idlist" attribute, not "id". Idlist is one of special features in innovator. If it is not empty, then the search dialog blocks input criteria row and executes search automatically.
inArgs.QryItem.item.setAttribute("idlist", idListStr); //To display necessary items only.
Hope it helps, SamsAn.
Original Mind Any Level Innovator Solutions Free-Lancer, http://sites.google.com/site/caraacc
Brian - Thursday, August 27, 2009 8:12 AM:
Hi SamsAn.
Thank you. I would buy you a drink if I could.
I must have had something wrong when I first tested your code sample as it returned nothing.
With the idlist attribute it works just fine now.
I will clean the code up in the next day or so and post an example of the FilteredBrowser in the Wiki's.
Out of interest where is all of this "special" stuff that you mention documented? Is it in the standard documentation and I have just missed it or is there other documentation that you have access to?
Thanks again.
Brian.
Brian - Thursday, August 27, 2009 11:46 PM:
Pending a full example in the Wiki this is the code I am using in response to the onSearchGrid event.
Grrr. I hate the formatting on this forum for pasted text.
// Limit the available Files which can be selected by a user based on the Documents selected // in another Tab of the form. // Method is called from the onSearchGrid event of the "related_id" property of the // FileDistribution tab (relationship). // // This method implements a "Filtered Item Browser" which pre-defines the selections // that a user can make when they create a new Relationship. // // Context: Item = Document Distribution. // Relationships = Distribution Document (List of documents from which individual Files are being // distributed to external sources) // = File Distribution (list of actual files being distributed. Since each document // can hold more than one file we need to know the actual files). var myInnovator = this.NewInnovator(); var itm = inArgs.itemContext; //XmlElement. It represents main item concerned with the opened tear-off window. // retrieve all of the "Distribution Document" relationships. var distDocs = itm.selectNodes("Relationships/Item[@type='Distribution Document']"); //XmlNodeList var idList = new Array(); var amlString = ""; // loop through all of the Distribution Documents (listed Relationships in // Distribution Document tab) and retrieve the related_id. // Once we have the related_id we can build the AML to retrieve the // Document and finally the File that we want to offer to the user. for (var i=0; i<distDocs.length; i++) { var relatedId = top.aras.getItemProperty(distDocs[i], "related_id"); if (relatedId) { // for each ID in the grid retrieve the relationship Data and the related_id // information. // In this case relationshipItem is "Distribution Document" and related_id // type is "Document" // From "Document" we actually want to get the further related "File" items // to limit the available choices for the user in the search grid. //var distDoc = myInnovator.NewItem("Distribution Document", "get"); //distDoc.setId(IDs[i]); //var returnItem = distDoc.apply(); // use the related id to retrieve Document Items which include the Files that are // held by them. amlString = "<Item type='Document' action='get' id='" + relatedId + "'>"; amlString += "<Relationships><Item type='Document File' action='get'></Item></Relationships></Item>"; // Retrieve the File items related to this Document from the Server. // There is probably a more efficient way of doing this since I am // querying the server once for each document. // Can't just concatenate the AML as it gives a "The instance doesn't represent a single item" // exception if you do that. var distDoc = myInnovator.NewItem(); distDoc.loadAML(amlString); var returnItem = distDoc.apply(); if (returnItem.isError) { alert(returnItem); return returnItem; } var files = returnItem.getItemsByXPath("//Item[@type='File']"); var numFiles = files.getItemCount(); for (j = 0; j < files.getItemCount(); j++) { var fileId = files.getItemByIndex(j).getProperty("id"); if (fileId) { idList.push(fileId); } } } } var idListStr = (idList.length>0 ? idList.join(",") : "this_string_should_not_be_empty"); // Using setAttribute("idlist", list) causes the Search Dialog to perform an immediate search // and also allows you to specify a number of ids to be returned. // The "list" string should not be empty. inArgs.QryItem.item.setAttribute("idlist", idListStr); //To display necessary items only.
SamsAn - Friday, August 28, 2009 8:09 AM:
No problem.
I guess it is pretty difficult to document like tricks probably stubbing architectural mistakes. However i believe it is pretty difficult to support like tricks too.
I do not use any documentation due to it's not forbidden and pretty easy to read non-obfuscated client scripts and htmls. I guess any license agreements are not infringed in the case of reading.
In general, my opinion is it's enough existing documentation to implement a simple solution.
If a complex innovator solution is required then its customer should touch an experienced developer or aras (if they have human resources).
Hope it helps, SamsAn.
Original Mind Any Level Innovator Solutions Free-Lancer, http://sites.google.com/site/caraacc