Monday, May 18, 2009

Xpages: How to create a view picklist!!

So i finally figured it out, by piecing many sources of code from around the internet.


Updated to say go get the custom control on Openntf.org!!!
It is much easier to use and set up.  It is also reusable.


Step 1. create a custom control.

Create a custom control and put your view on it, and put a search bar and a select button above it like this, make the first column have a check box option


Configure this for searching.... click here if you do not know how to do this.

On the select button "on click" event put this code in, it gets the selected documents, then it gets a value from the document and then adds it to the field on my main form. I got this code form the developer wiki

function printToLog(stuff) {
_dump("\r\nPRINT START\r\n");
_dump(stuff);
_dump("\r\nPRINT END\r\n");
}

var database = session.getDatabase("notes1", "applications\\viewpoint.nsf")
var viewPanel=getComponent("viewPanel1"); //get the componet of viewPanel
var docIDArray=viewPanel.getSelectedIds(); //get the array of document ids
printToLog('got ids')

for(i=0;
i  <  docIDArray.length;
i++){
var docId=docIDArray[i];
printToLog(docId)
var doc=database.getDocumentByID(docId);
printToLog(doc)
if(doc != null){
var pickthis1 = doc.getItemValueString("projectnum")
printToLog(pickthis1)
}
}

if(pickthis1 != null){
dominoDocument1.replaceItemValue("job", pickthis1)
}


On the client side of the select button js on click event, enter this in
dijit.byId('Dialog3').hide();


This closes the dialog we will create in a moment. Save and close that custom control.

On your main form you need to add this client side javascript function, i found this on the forum, unless you use this you can not click any buttons on your dialog or search or update.
/**
* Creates a dijit dialog box based on a div content
* @param id div identifier
*/

function dialog_create(id, title1) {
var dialogWidget = dijit.byId(id);
if( dialogWidget )
dialogWidget.destroyRecursive(true);
dialogWidget = new dijit.Dialog(
{ title: title1, duration:600},
dojo.byId(id));

var dialog = dojo.byId(id);
dialog.parentNode.removeChild(dialog);

var form = document.forms[0];
form.appendChild(dialog);
dialogWidget.startup();
}


Next add this to the source of your page, notice the<> is the picklist custom control we just created



At the top of the XPage in source view, you need to add the onload function to call the function to create the dialog

Then we create a button to show the dialog with client side javascript.
dijit.byId('Dialog3').show()

Then you will have something that works like a picklist, once you do it once it gets much easier.

moz-screenshot

example

28 comments:

John Mackey said...

Very nice Mark. Thanks for sharing. I'll have to borrow this...

-John

Mark Hughes said...

Seems to work well with multiple dialogs per page as well, still loads fast.

@John I put it here so others could borrow it, i had not seen it anywhere else, so either people had not done this before or had not shared it. The lack of resources and documentation makes this a little harder than i thought, of course thanks to those who wrote the code i borrowed i have made it past all of the hurdles!

Fifteen August said...

Hi Mark,

I am so happy to see this example.

Actually I am looking for the way how to do dialog in Xpage.

But in codes, i have a error at this line.
for(i=0; i <> i++)

:(

Plz,

Anonymous said...

Hi mark,

I tried your picklist. But

I got an error "Object doesn't support this property or method". :-(

Plz help

Jerry Shelley said...

Thanks Matt, but for all those XPage novices out there like myself, here's some extra info from my reserach how to get this to work ...

http://www-10.lotus.com/ldd/ddwiki.nsf/dx/Client_Side_JavaScript_Libraries_in_XPages.htm
(why can't I paste into this field?)

I had to add a semi-colon after the ++ in the "for(i=0; i <> i++) statement.

More to come perhaps, because it's not working for me yet.

Jerry

Jerry Shelley said...

Sorry Mark - I was close with "Matt".
An embarrassed Jerry.

Mark Hughes said...

Jerry have you downloaded the example database?

Mark Hughes said...

Link to example database

http://mhughes.focul.co.uk/Picklist%20Example.zip

Jerry Shelley said...

And here's a link to the setting up a Search XPage tutorial which is hidden deep in the depths of the 8.5 Dom Designer Help...

http://publib.boulder.ibm.com/infocenter/domhelp/v8r0/index.jsp?topic=/com.ibm.designer.domino.xpages_ug.doc/wpd_tutorial_enhancing.html

(Still can't get the Dialog to work - I'm not getting past the dialog_create JS function loading - it's saying dialog is null.

Jerry Shelley said...

No Mark, I hadn't, but have now and am avidly interrogating it. Thanks muchly. Jerry.

Mark Hughes said...

i recopied the js code in a code snipit above in Windows live writer, it is much better than just using blogger.

Unknown said...

Sweet way of doing it. Pointing people to help files without giving specific information where to find stuff, although is less helpful. I was not able to rebuild the search within the dojo dialog. But then, maybe it's just me not getting it.

Mark Hughes said...

@CharNode, i just updated it with a link to the topic in the help database, which is full text indexed by the way. Jerry also posted it here in the comments.

Mitch said...

Hey Mark,

thanks for your article, works fine, but...

... the submit button forces my page to save and validate its fields.

If I select the "Do not validate and update" option, the button type changes back to "button" and it doesnt work anymore.

Any way to work around that? I dont want my page to be saved just because I add some values via dialogbox.

Mark Hughes said...

@ mitch is it set to refresh the underlying document or field?

Mitch said...

Err, I'm sorry, I was that fixed to my problem that I forgot to mention: I'm talking about the searching-part of the dialogbox, as described in the designer help.

Dialogbox is working fine, but if I want to filter the dialogbox's content, the submit button of the search part submits the whole page.

It's set to a partial update of itself.

Mark Hughes said...

refreshes the viewpanel only? set to button, not submit?

Mitch said...

It's set to "Submit", because that's the only way I can get the search in the dialogbox to work. I tried various versions of the partial update, like the whole dialogbox element or just the view panel. But it always submits & saves the page/document the dialogbox was called from.

Melissa Snell said...

Got it to work - thanks!

However needed to do 2 additional bits that you don't mention here:

1) Follow the instructions here:
http://www-10.lotus.com/ldd/ddwiki.nsf/dx/Client_Side_JavaScript_Libraries_in_XPages.htm
to tell the Xpage about Dojo module dijit.Dialog

2)Change the JavaScript call at the top of the Xpage source to include the title arguement on the function call like this:


XSP.addOnLoad(function(){dialog_create('Dialog3','Title')});


3) Put the javascript function into a javascript script library and then added as a resource to the xpage.

Thanks!

John Smart said...

Odd... I tried downloading from http://mhughes.focul.co.uk/Picklist%20Example.zip and it doesn't work. Firefox 3.5.7 with Firebug, running off local Domino Designer:

"failed loading /domjs/dojo-1.3.2/dojo/../dijit/_base/popup.js with error: SyntaxError: illegal character"

Anyone else have/overcome this problem?

John Smart said...

I figured it out. My problem was my Kaspersky web anti-virus!!!

When I disabled it, or added a rule to trust */dijit/_base/popup.js then it started working.

Joy said...

Hi,

I followed everything said here..but I am stuck at an error 'parentNode' is null or not an object, while the xpage loads.

I am new to Xpage, please help me...

Paul Cable said...

Hi,

Is it possible to limit the user to only select ONE document from the view?

I was thinking along the lines of an onClick event triggering some javascript to deselect all other checked items?

Cheers
Paul

Patpicos said...

Hi Paul

Instead of using a view container control, you could use a data table. This requires a little bit more work. Also, in the first column, you cannot use the radio button object directly because a name= will be generated for each entry and therefore they will not become part of a radio group. What i've done is use the <input name="myGrp" type="radio>put a computed field here for</input>

Then the javascript code from the select button needs to be modified to find the selected radio button.

Another caveat is that if your list is greater than the max item per page, a selection will be wiped if you navigate using the pager

Mark Hughes said...

If you make a datatable, then make a button instead of a checkbox or radii button, get the row value and set your field value

Patpicos said...

Good point. No point in wasting time finding which one the user selected. Just make them click the button and use that row!

Patpicos said...

Hi Mark,
In terms of best practice, do you return an object from your dialog instead of tightly coupling the dialog code to modifying the backend directly? (Im starting in Xpages and Im trying to think 2 steps ahead)

For example, I've used this tutorial to create a dialog box allowing an admin to change the department for an employee. Based on the selection, I change 3 fields on the employee document (dept_code, dept_title, and cost_centre). Right now, the buttons in the dialog directly act on the form by doing getComponent("xxx").setValue(rowEntry.getDocument.getItemValueString("dept_code");

Instead of coupling like this, I thought of creating a department object with the appropriate getters. However, I am not sure how to pass that back to the calling Xpages. At first, I thought to save the object in a sessionScope variable, but i find this would polute the global space. Another option would be to save the selected department object in a custom control variable (compositeData). What do you think?

Mark Hughes said...

Using a viewscope or sessionscope would seem the set way to do this, global objects exist for a reason, sometimes they need to be used.

Post a Comment