PDA

View Full Version : How do I get the doc ID of a selected row in the grid?



Dominoble
27 Sep 2007, 9:15 AM
Since we don't have a selection column of checkboxes yet, what's the best way to get the doc IDs of the selected docs in the view?

galdaka
27 Sep 2007, 11:50 AM
1) In column render print a checkbox. Each checkbox id corresponds with a document ID.

2) Use selectionmodel for detect the selections of rows.

3) Create a global variable to store the ID

Dominoble
28 Sep 2007, 9:54 AM
Thank's for the response but that's quite a bit more than I was looking for. I shouldn't have to hand code all of my views in Ext just to get a doc id. I was hoping for something like:

var docs = document.getElementsByName('x-grid-row-selected') so I can loop through and get the id of each doc.

Anybody?

jratcliff
30 Sep 2007, 6:31 PM
We'll try and make it easier in a future release. In the meantime, try something like this:



var row = DemoApp.ui.uiView.grid.selModel.getSelected();
var node = row.node;
var unid = node.attributes.getNamedItem('unid');


where DemoApp is the global variable you've declared for your app and "ui" is defined like in the Ext.nd.SampleMain.html page of the Ext.nd db.

~Jack

Dominoble
2 Oct 2007, 10:58 AM
OK. So far so good. My action button in the view will show me the doc id of the selected doc. Of course the next logical step is to look at all selected docs. I can't seem to get the number of rows returned with the getSelections() method. Neither count nor length work. Length always returns 1. I also tried ...selections.getCount() and that didn't work.

//var row = SAPApp.ui.uiView.grid.selModel.getSelected();
//var node = row.node;
//var unid = node.attributes.getNamedItem('unid');
//alert(unid.value);

var rows = SAPApp.ui.uiView.grid.selModel.getSelections();
var i;
for(i=0 ; i < rows.count ; i++) {
var node = rows[i].node;
var unid = node.attributes.getNamedItem('unid');
alert(unid[i].value);
}
}

RWaters
8 Oct 2007, 6:51 AM
couple things, when possible everyone should try to use the get methods provdided by Ext instead of directly accessing properties. The selection model for example should be grid.getSelectionModel() instead of grid.selModel, this makes sure that the rowSelectionModel gets properly initialized.

length should return the proper number of elements in the javascript array. I would give this a shot:


var rows = SAPApp.ui.uiView.grid.getSelectionModel().getSelections();
for(var i = 0; i < rows.length ; i++) {
var record = rows[i].node;
var unid = node.attributes.getNamedItem('unid');
alert(unid);
}

After typing that out I noticed that one issue is that you're trying to call unid[i] and it doesn't appear that unid is an array. Also, there appears to be an extra } in your example...

Dominoble
10 Oct 2007, 5:28 AM
Thanks for the reply Rich. I know you're a busy guy but the posted code doesn't work.

var rows = SAPApp.ui.uiView.grid.getSelectionModel().getSelections();
alert(rows.length);
always returns 0 regardless of the number of docs selected. Assuming the number of rows was returned correctly, shouldn't the lines


var record = rows[i].node;
var unid = node.attributes.getNamedItem('unid');

actually read



var record = rows[i].node;
var unid = record.attributes.getNamedItem('unid');

Thanks again for the help.

tarikonen
10 Oct 2007, 5:32 AM
Hi Dominoble i have tested Rich code



var rows = GesProBankApp.ui.uiView.grid.getSelectionModel().getSelections();
for(var i = 0; i < rows.length ; i++) {
var node = rows[i].node;
var unid = node.attributes.getNamedItem('unid');
alert(unid.value);
}

and it work perfectly. You must pay attention to application name (in my case GesProBankApp)

Bye

RWaters
10 Oct 2007, 5:51 AM
Yeah, sorry about the silly record/node mistake. Honestly I was writing the code from memory, and I haven't fully tested it. Thanks for checking it out Tarikonen, I'll try to find some time as well to make sure.

Dominoble
10 Oct 2007, 10:22 AM
I'm testing in both IE7 and FF2 with Firebug. The code is in an action button and the application is specified correctly. When I use tarikonen's code with the app name changed absolutely nothing happened in either browser. It wasn't until I changed the default viewName in UIView to be the view with the action that it started working. To verify this I switched it back and the action stopped working. I then reset it and it works again. The results are not consistent though. Sometimes it will return only one doc ID when several are selected and sometimes it will continue to return the same ID not matter what is selected. I'll keep testing and report back.

tarikonen
16 Oct 2007, 2:27 AM
Hi Dominoble, i have now realized that you have reason, also I have the problem that the first time that I load the view the selection correctly happens when I reload it beginning to have the behavior that signals you (I always get the same UNID).
is there someone who has some idea of the problem or that it has a solution that does it work?

Thanks in advance

chernomorez
18 Oct 2007, 1:20 PM
How would you perform the check for selected items in 2.0b1 with either RowSelectionModel or CheckboxSelectionModel?

Thanks

tarikonen
22 Oct 2007, 2:34 AM
Is there someone who has succeeded in resolving the problem or that has found a different way to resolve the problem of the selection of the documents in a view?

Thank's in advance

abmcr
22 Oct 2007, 7:03 AM
I use the versione 2 of the EXT.
I have set a grid with

var sm = new xg.CheckboxSelectionModel();
var cm = new xg.ColumnModel([
new xg.RowNumberer(),
sm,
{
id: 'name',
header: "Name",
dataIndex: 'employee_name',
width: 100
},{
header: "Title",
dataIndex: 'title',
width: 170
},{
id: 'note',
header: "Note",
dataIndex: 'note',
width: 50
}]);
// by default columns are sortable
cm.defaultSortable = true;

var grid = new xg.GridPanel({
// var grid = new Ext.grid.GridPanel({
el:'grid-paging',
sm: sm,
width:700,
height:500,
title:'ExtJS.com - Browse Forums',
autoExpandColumn: 'note',
store: ds,
cm: cm,
frame:true,
trackMouseOver:true,
bbar: new Ext.PagingToolbar({
pageSize: 8,
store: ds,
displayInfo: true,
displayMsg: 'Records visualizzati {0} - {1} di {2}',
emptyMsg: "Nessun dato",
items:[
'-', {
pressed: true,
enableToggle:true,
text: 'Elimina',
cls: '',
toggleHandler: doDel
}]
})
});
and i want to get the id of selected rows with


function doDel(){
var m = grid.getSelections();
if(m.length > 0)
{
Ext.MessageBox.confirm('Message', 'Do you really want to delete it?' , doDel2);
}
else
{
Ext.MessageBox.alert('Message', 'Please select at least one item to delete');
}
}
function doDel2(btn)
{
if(btn == 'yes')
{
var m = grid.getSelections();
//alert(m.length);
var jsonData = "[";
for(var i = 0, len = m.length; i < len; i++){
var ss = "{\"id\":\"" + m[i].get("name") + "\"}";
alert(ss);...........


But the alert get an indefined for aech rows selected. What is wrong? Thank you
PS.: please excuse me , i am begginer with the EXT....(:|

gogglehead
30 Jul 2008, 4:57 PM
Hi

Any progress with this issue? The problem I have is that ExtndApp.ui.uiView returns the initial view and not the current view selected from the outline. This means when you get the selected documents you always get the document that were selected in the initial view. How do I get the current uiView from the application or panel?

Jan K
12 Aug 2008, 10:49 PM
A possible solution to get the selection to work in all views is to extend the Ext.nd.UIOutline class, so it update the ExtndApp.ui.uiView variable every time a new view is opened.

ExtndApp.ui.uiView = this.uiView; //Updates the global variable, so it's possible to get a handle to the current viewHere's a code example snippet from Ext.nd.UIOutline, with the required extra line which accomplies this. I've implemented this succesfully in a working solution


var viewUrl = (extndHref.indexOf('?') > 0) ? extndHref.split('?')[0] : extndHref.split('!')[0];
// now create our new view/folder
this.uiView = new Ext.nd.UIView({
viewport: this.viewport,
tabPanel: this.tabPanel,
container: this.uiView.container,
statusPanel: this.statusPanel,
showActionBar: false,
toolbar: false,
viewUrl: viewUrl
});
ExtndApp.ui.uiView = this.uiView; //Updates the global variable, so it's possible to get a handle to the current view
this.tabPanel.setActiveTab(this.uiView.container);

Hopefully this could be of help

Zakaroonikov
13 Aug 2008, 2:24 PM
Hi

Any progress with this issue? The problem I have is that ExtndApp.ui.uiView returns the initial view and not the current view selected from the outline. This means when you get the selected documents you always get the document that were selected in the initial view. How do I get the current uiView from the application or panel?

Just a though could you do access the current view like:

ExtndApp.ui.uiOutline.uiView

Looking through the code it appears as if uiOutline assigns the latest opened view to its uiView property

gogglehead
13 Aug 2008, 6:11 PM
Thanks guys. Tested both those suggestions and they both were exactly what I was looking for.

I was thinking along the lines of the solution from Jan myself but was wondering about the reference to the global variable and thought there must be somewhere to get the current uiView from. I now see there is (the uiOutline)!

So you can get the currently selected docIDs from:




var rows = ExtndApp.ui.uiOutline.uiView.grid.getSelectionModel().getSelections();

var selnum = rows.length;
var arrUnid =new Array(selnum);
for (var i =0; i < selnum; i++) {


arrUnid [i]= rows[i].node.attributes.getNamedItem('unid').value;
}





Thanks again, hopefully this will help others starting out with this issue.
&gh

jasontj
23 Dec 2008, 3:41 PM
OK, I'm still learning this stuff. I need to loop this 1 to many documents and run some function to set a field on each one. I took the example below, and pasted it into a view "Action". I think this will build the array. I changed the first line to be "Demo", which is the name I defined for my application. However, any time I push the button I get 'Demo' is undefined. After this works, then I need to call some function to archive them (set a field on each doc), and refresh the view.


var rows = Demo.ui.uiOutline.uiView.grid.getSelectionModel().getSelections();
var selnum = rows.length;
var arrUnid =new Array(selnum);
for (var i =0; i < selnum; i++) {
arrUnid [i]= rows[i].node.attributes.getNamedItem('unid').value; }

I have this code in my header, which works great for creating my 3 grids. It seems like I need something defined globally. I'm sure this is something very simple, but I'm just a newbie at this.


thisWebDbName := @WebDbName;
extndDbWebPath := "/extnd/template.nsf/";
extUrl := extndDbWebPath + "ext/2x/";
extndUrl := extndDbWebPath + "extnd/2x/";
viewName := "f1";
outlineName := "mainOL";
mode := @If(@UrlQueryString("debug") = "true"; "-debug"; "");
unid := @If(@IsNewDoc;"";@Text(@DocumentUniqueID));
editMode := @If(@IsDocBeingEdited;"true";"false");
"<!-- Ext JS library -->" + @NewLine +
"<script type='text/javascript' src='" + extUrl + "adapter/ext/ext-base.js'></script>" + @NewLine +
"<script type='text/javascript' src='" + extUrl + "ext-all" + mode + ".js'></script>" + @NewLine +
"<!-- Ext.nd JS library -->" + @NewLine +
"<script type='text/javascript' src='" + extndUrl + "extnd-all" + mode + ".js'></script>" + @NewLine +
"<script type='text/javascript' src='" + extndUrl + "Session.js?OpenAgent&db=" + thisWebDbName + "'></script>" + @NewLine +
"<script type='text/javascript' src='" + extndUrl + "UIDocument.js?OpenAgent&db=" + thisWebDbName + "&unid=" + unid + "&editmode=" + editMode + "'></script>" + @NewLine +
"<script type='text/javascript'>" + @NewLine +
" Ext.nd.init({extndUrl : '" + extndUrl + "', extUrl : '" + extUrl + "'});" + @NewLine +
" var ExtndApp = function() {
return {
init : function(){
this.ui = new Ext.nd.DominoUI({
uiOutline : {outlineName: '" + outlineName + "'},
uiView : {viewName: '" + viewName + "'}
});
} // init
} // return
}();" + @NewLine +
" Ext.onReady(ExtndApp.init, ExtndApp, true); " + @NewLine +
"</script>" + @NewLine +
"<link rel='stylesheet' type='text/css' href='" + extUrl + "resources/css/ext-all.css' />" + @NewLine +
"<link rel='stylesheet' type='text/css' href='" + extUrl + "resources/css/xtheme-gray.css' />" + @NewLine +
"<link rel='stylesheet' type='text/css' href='" + extndUrl + "resources/css/domino.css' />"

Thanks,
Jason

jasontj
23 Dec 2008, 4:51 PM
Actually, the code below creates my grids....

var myViews = function(){
var showBtn, dialog;

return {
init : function() {

var view1 = new Ext.nd.UIView({
viewName : 'ClientPendingWeb',
gridConfig: {
renderTo : 'view1',
width : 700,
height : 300
}
});

// Completed searches below
var view2 = new Ext.nd.UIView({
viewName : 'ClientCompletedWeb',
gridConfig: {
renderTo : 'view2',
width:700,
height:300
}
});

// Invoices view below
var view2 = new Ext.nd.UIView({
viewName : 'My Invoices',
gridConfig: {
renderTo : 'view3',
width:700,
height:150
}
});
}// end init
};// end 'return'
}();
Ext.onReady(myViews.init, myViews, true);

jratcliff
25 Dec 2008, 11:02 AM
...I changed the first line to be "Demo", which is the name I defined for my application. However, any time I push the button I get 'Demo' is undefined.

Where do you define "Demo"?




...


" var ExtndApp = function() {
return {
init : function(){
this.ui = new Ext.nd.DominoUI({
uiOutline : {outlineName: '" + outlineName + "'},
uiView : {viewName: '" + viewName + "'}
});
} // init
} // return
}();" + @NewLine +
" Ext.onReady(ExtndApp.init, ExtndApp, true); " + @NewLine +

...


The above code snippet of what you posted defines "ExtndApp" instead of "Demo". Why not try changing it to Demo and see if it then works.

P.S. Rich and I have Beta 2 coming real soon (hopefully right after the new year and definitely before LS09) that should make tasks like these even easier.

Jack

jasontj
25 Dec 2008, 11:38 AM
OK, I obviously don't quite get this yet. I did figure out that I simply only needed 1 line of code to build my grids and action bars. So, I have my header now only reading this:



@Eval(@DbLookup("";"":"extnd/template.nsf";"($configurations)";"12329226E915C8468625751B005CABCF";"HTMLHeadForm";[FailSilent]))



And then I build my 3 grids with the code below. I want to be able to select multiple docs and archive them. So, I think I'm defining "view1", "view2" and "view3" in the below code. How do I reference these view names in the looping code for selected docs? Also, once I get the unids into the array "arrUnid", do I then have to loop again to archive my docs? If so, I might as well just do them as I'm gathering them, right? Thanks.

------------------------------
my code to define views (grids)
------------------------------


var myViews = function(){
var showBtn, dialog;

return {
init : function() {

var view1 = new Ext.nd.UIView({
viewName : 'ClientPendingWeb',
gridConfig: {
renderTo : 'view1',
width : 700,
height : 300
// frame : true
}
});
// Completed searches below
var view2 = new Ext.nd.UIView({
viewName : 'ClientCompletedWeb',
gridConfig: {
renderTo : 'view2',
width:700,
height:300
}
});

// Invoices view below
var view3 = new Ext.nd.UIView({
viewName : 'My Invoices',
gridConfig: {
renderTo : 'view3',
width:700,
height:150
}
});
}// end init
};// end 'return'
}();
Ext.onReady(myViews.init, myViews, true);



------------------------
looping code
------------------------



var rows = ExtndApp.ui.uiOutline.uiView.grid.getSelectionModel().getSelections();
var selnum = rows.length;
var arrUnid =new Array(selnum);
for (var i =0; i < selnum; i++) {
arrUnid [i]= rows[i].node.attributes.getNamedItem('unid').value;
}

jratcliff
25 Dec 2008, 6:45 PM
OK, I think I follow a little of what you are trying to do. It looks like you just have 3 views defined on a page or form and you are not using the Ext.nd.DominoUI class that builds a basic 2 pane style app with an outline on the left and a view to the right.

So, based on this code:



@Eval(@DbLookup("";"":"extnd/template.nsf";"($configurations)";"12329226E915C8468625751B005CABCF";"HTMLHeadForm";[FailSilent]))


The "HTMLHeadForm" lookup field that is return load the needed js/css and calls the code to convert any form fields and the actionbar on the page/form.

From here, I'm guessing you have 3 divs with the ids of 'view1', 'view2', and 'view3' and the below code is what you are using to load views into these divs.



var myViews = function(){

var showBtn, dialog;

return {

init : function() {

var view1 = new Ext.nd.UIView({
viewName : 'ClientPendingWeb',
gridConfig: {
renderTo : 'view1',
width : 700,
height : 300
}
});

// Completed searches below
var view2 = new Ext.nd.UIView({
viewName : 'ClientCompletedWeb',
gridConfig: {
renderTo : 'view2',
width:700,
height:300
}
});

// Invoices view below
var view3 = new Ext.nd.UIView({
viewName : 'My Invoices',
gridConfig: {
renderTo : 'view3',
width:700,
height:150
}
});
}// end init
};// end 'return'
}();
Ext.onReady(myViews.init, myViews, true);


So then your question is:


How do I reference these view names in the looping code for selected docs? Also, once I get the unids into the array "arrUnid", do I then have to loop again to archive my docs? If so, I might as well just do them as I'm gathering them, right? Thanks.



Because this code doesn't work:



var rows = ExtndApp.ui.uiOutline.uiView.grid.getSelectionModel().getSelections();
var selnum = rows.length;
var arrUnid =new Array(selnum);
for (var i =0; i < selnum; i++) {
arrUnid [i]= rows[i].node.attributes.getNamedItem('unid').value;
}


The reason this code doesn't work is because you are not using Ext.nd.DominoUI so throw this code out.

Ok, now I'm guessing that you want to trigger this code from an action button and probably the easiest way to do this is to first change your 'view code' to not use 'local' variables since you probably want to put your action button code in the JavaScript section section within Domino Designer and therefore your code wont be able to "see" these local variables. So let's make them instance variables that you can then access from your action button code by changing each "var viewn" to "this.viewn" (where 'n' is 1, 2, or 3 in your case)




var myViews = function(){

var showBtn, dialog;

return {

init : function() {

this.view1 = new Ext.nd.UIView({
viewName : 'ClientPendingWeb',
gridConfig: {
renderTo : 'view1',
width : 700,
height : 300
}
});

// Completed searches below
this.view2 = new Ext.nd.UIView({
viewName : 'ClientCompletedWeb',
gridConfig: {
renderTo : 'view2',
width:700,
height:300
}
});

// Invoices view below
this.view3 = new Ext.nd.UIView({
viewName : 'My Invoices',
gridConfig: {
renderTo : 'view3',
width:700,
height:150
}
});
}// end init
};// end 'return'
}();
Ext.onReady(myViews.init, myViews, true);


Now, let's write the code for each view action button. Since view1, view2, and view3 are now instance variables of 'myViews', you can now access and thus I've changed the first line of your 'var rows'.



var rows = myViews.view1.grid.getSelectionModel().getSelections();
var selnum = rows.length;
var arrUnid = new Array(selnum);
for (var i =0; i < selnum; i++) {
arrUnid[i]= rows[i].node.attributes.getNamedItem('unid').value;
}


So for each action button just replace 'view1' with 'view2', 'view3' and so on for how many ever views you have.

Now, as for processing this server side you could just make an Ajax call to an agent posting your array of UNIDs and have your agent return to the caller whether it was successful or not.

Now, with all of this said, the major downside to this is that you now have action buttons in your views that are now dependent on their views being named view1, view2, or view3 in your myViews class. This isn't ideal and what we should have ready by Beta 2 is for an easier and more generic way to do this that is also portable so that your view can be placed anywhere and your action button code will just know how to work with the view that it is on. So stayed tuned for that....

jasontj
25 Dec 2008, 8:17 PM
That works perfectly! Thanks for working on Christmas to help solve this. I don't know where you live, but I owe you a beer, or two. I wish I could make LS09, but I doubt I will.

For now I'm ok with hard coding the view names in my code and I understand why it's not the best solution, but it will work for now. I will master this beast before it's over and I'll be on here helping you answer questions like mine :).

I'll write my Ajax call and all will be done. I also found out how to refresh the view at the end by adding the following line after my loop:

myViews.view2.refresh({params:{options: ''}});


Thanks again for the help! Maybe someone else can use this too.

Jason

jratcliff
25 Dec 2008, 8:57 PM
No problem. I'm glad I could help. I was working on Ext.nd anyway getting ready for my presentation with Lance Spellman in Battle of the IBM Lotus Domino JavaScript Toolkits (https://www-950.ibm.com/events/wwe/lotus/lsph2009.nsf/sessionabstract?openform&sessionid=BP103) which is basically Ext.nd vs Dojomino.

Oh, and I just tested out the new code that will be in beta2 that allows you to write this for your action button on a view:



var selections = this.uiView.getDocuments();
for (var i=0; i<selections.length; i++) {
alert(selections[i].unid);
}


And for those who are used to the NotesUIView.Documents LotusScript property, we have a "documents" property that returns the same value as the "getDocuments()" method.



var selections3 = this.uiView.documents;
for (var i=0; i<selections.length; i++) {
alert(selections[i].unid);
}


So, as you can see this code if written in an action button will now be portable since the view isn't hardcoded but instead referenced by 'this.uiView' and the 'documents' property and 'getDocuments()' method will provide an easy way (and familiar way to LotusScript developers) to get a handle to the documents.

jasontj
28 Dec 2008, 3:34 PM
I can't wait to see the results of the battle! I hope those of us that cannot attend will be able to see a video. I'm sure Ext.nd will prove to be the superior product. Good luck!

Jason