XPages Extension Library Dialog control and updating "parent" document - xpages

I have an XPage with a Dialog control from the Extension Library.
The dialog works fine -- opens, does what it needs to do, however, when I try to update the "parent" document, it does not work.
I have the XPage data source as Domino Document called document1. I added this after reading:
When I save a document from an extension library dialog box some values are blank
<xp:this.data>
<xp:dominoDocument var="document1" formName="speakerReq"></xp:dominoDocument
</xp:this.data>
On the dialog control, I have a Search button which calls a servlet and returns JSON that is parsed and built into an HTML table. The first cell is a link which calls a function from a client side JavaScript library when it is clicked. The function is to update the "parent" document with values from the returned JSON as well as close the dialog.
It can call the function when I test with just an alert() statement in that function, however, when I try to update the "parent" document, it does not recognize that.
I have tried to pass the "document1" object but once I get to the dialog, it says it does not exist, so the link is failing.
Here is the code snippet where the link is built:
// Let's build the row...
cell = document.createElement("td");
resultLink = document.createElement("a");
resultLink.setAttribute("class", "linkText");
resultLink.setAttribute("href", "#");
resultLink.setAttribute("onclick", "javascript:updateDocument(document1, '" + bpName + "', '" + bpEmail + "', '" + bpPhone + "', '" + bpTitle + "', '" + bpCountry + "', '" + bpLoc + "');");
resultLink.appendChild(document.createTextNode(bpName));
cell.appendChild(resultLink);
row.appendChild(cell);
How do I get a handle on the document1 object on the client side so I can update those fields on the "parent" document as well as close the dialog?
Code:
function updateDocument(doc, name, email, phone, job, country, location) {
var thisField;
// Need to update the document with the selected values...
thisField = doc.getElementById("#{id:sr_Name1}");
thisField.value = name;
thisField = doc.getElementById("#{id:sr_Title1}");
thisField.value = email;
thisField = doc.getElementById("#{id:sr_Phone1}");
thisField.value = phone;
thisField = doc.getElementById("#{id:sr_Email1}");
thisField.value = job;
thisField = doc.getElementById("#{id:sr_Location1}");
thisField.value = location + " - " + country;
}
Thanks!

Seems you are mixing CSJS and SSJS up. The code snippet runs in the browser, but you try to execute server side code. This can't work. You need to post back your data to the server and handle the data there. The XPages Wiki has some ideas you might find useful.
Clarification:
Rule of thumb: anything that lands as JavaScript in your browser cannot have SSJS in it. So you can use anything DOM, but NO session, database, document1 etc. SSJS libraries are invisible to CSJS, so you can't call these methods. You can have a button in your page where you define both CSJS and SSJS. The client side would execute first and then do a refresh (partial or full).
Also your code above: getElementById is CSJS -> can't use that in a SSJS, while doc is as NotesDocumentDatasource -> doesn't have getElementById.
Furthermore: there is no "parent" element. The dialogbox is just another part of the local DOM (this is not NotesUIWorkspace.dialogbox). Check the XPagesWiki for samples

Related

XPages Extension Library Data View Control Confirm Count of Checkbox selection

I have an xpage with a data view control, that has show checkbox and show header checkbox enabled. I want to be able to provide confirmation with a count of selected documents to the user when they click the submit button.
Example
"Are you sure you want to submit x number of documents?"
My confirm action returns 0 regardless of how many documents I select. What am I doing wrong?
<xp:confirm>
<xp:this.message><![CDATA[#{javascript:var dataView1:com.ibm.xsp.extlib.component.data.UIDataView = getComponent("dataView1");
var val = dataView1.getSelectedIds();
var len = val.length;
return "Are you sure you want to submit " + len + " number of documents?";
}]]></xp:this.message>
</xp:confirm>
The immediate problem that you're running into is that the confirmation message is most likely being computed as the button is rendered the first time - which is to say, when no documents are checked.
Even beyond that, though, the getSelectedIds method is tricky: the selected documents are cleared after each request, so something that would do a request to the server to get the selected ID count would also have the side effect of clearing out the selections.
What may be the way to do here is to do the check client-side with something like this:
<xp:eventHandler ...>
<!-- other action stuff here -->
<xp:this.script><![CDATA[
var count = dojo.query("tbody input[type='checkbox']:checked", dojo.byId("#{id:yourDataViewId}")).length;
return XSP.confirm("Are you sure you want to submit " + count + " document" + (count == 1 ? "" : "s") + "?");
]]></xp:this.script>
</xp:eventHandler>
The Dojo query in there will search for all checked checkboxes inside the body part of the data view (to exclude the header checkbox), restricted to within the specific data view you want to search for. The XSP.confirm client-side method is the same idea as the <xp:confirm/> simple action, and returning the value from it will cancel the submit if the user says no.

Create an iconNote Document in a new database

This is a more explicite extension on my previous question.
From an button on an XPage I create a new database
targetDB = dir.createDatabase(fileName);
I then copy a bunch of stuff into the targetDB from the sourceDB. I then want to set the launch properties in the targetDB which is where the problem comes.
I know that I can get the iconNote = targetDB.getDocumentByID("FFFF0010") except there is no iconDoc in the target. Does anyone have a way to create this doc with the specific NoteID?
I tried copying the iconNote document from the sourceDB to the targetDB but that does not work. Changes the UNID and noteID. Can't find any database method to create an icon Note.
Found lots of stuff on how to change the settings in the iconNote, but nothing on how to create one if there is not one in the database.
Thanks to Jesse I took his code and changed it to SSJS and it works fine.
var dir:NotesDbDirectory = session.getDbDirectory("Development");
var newDB:NotesDatabase = dir.createDatabase("XPages/install/created.nsf");
var importer:NotesDxlImporter = session.createDxlImporter();
importer.setDesignImportOption(6);
var dxl:String = "<?xml version='1.0'?>\n" +
"<note default='true' class='icon'>\n" +
" <item name='$TITLE'>\n" +
" <text>Test Title</text>\n" +
" </item>\n" +
" <item name='$Flags'>\n" +
" <text>J7NZq?!</text>\n" +
" </item>\n" +
"</note>\n";
importer.importDxl(dxl, newDB);
var iconNote = newDB.getDocumentByID("FFFF0010");
iconNote.replaceItemValue("$DefaultXPage", "xpWFSDemo.xsp");
iconNote.replaceItemValue("$DefaultClientXPage", "xpWFSDemo.xsp");
iconNote.save();
dBar.info(iconNote.getItemValueString("$Flags"));
Something like this oughta do it:
DbDirectory dir = session.getDbDirectory(null);
Database newDB = dir.createDatabase("tests/created.nsf");
DxlImporter importer = session.createDxlImporter();
importer.setDesignImportOption(DxlImporter.DXLIMPORTOPTION_REPLACE_ELSE_CREATE);
String dxl = "<?xml version='1.0'?>\n" +
"<note default='true' class='icon'>\n" +
" <item name='$TITLE'>\n" +
" <text>Some DB Title</text>\n" +
" </item>\n" +
" <item name='$Flags'>\n" +
" <text>J7NZq?!</text>\n" +
" </item>\n" +
"</note>\n";
importer.importDxl(dxl, newDB);
That's with the two "open XPage" options set already - you could also include the two XPage name items the same way, and it may be a good idea to export the icon note from an existing DB (database.getDocumentByID("FFFF0010").generateXML()) and paste in the actual icon item as well, since this DXL will result in an icon-less database. Nonetheless, it seems to work in my testing as a basis.
And after that point, you'll be able to fetch the icon note using the usual "FFFF0010" pseudo-ID and replace item values the same way I mentioned before.

Hyperlink in Post entity's textfield

I'm creating a Post entity (Activity feed entity) within my custom C# code and I need to be able to add a hyperlink into its text field.
Creating a post entity
Entity post = new Entity();
post.LogicalName = "post";
I could simply write something like
post["text"] = "http://www.google.com"
and it would work as a hyperlink. I think there's jQuery (out of a box?) that handles formatting in that case.
But in my case I'd like to add a hyperlink with a custom title. Something similar to
Click
Is there a supported way to do this or do I need to write my own client side script for formatting purposes?
For your text box content to work as a hyperlink, the Format of the Textbox needs to be URL. If you can set the format of your textbox, then any text that you put in there ,provided it follows the rules of hyperlink, it will be displayed as one.
Are you creating the attribute, or is it an existing one that you're trying to fiddle with? If it's an existing one, you need to write your own javascript to render it on the form as a hyperlink; and this would be unsupported.
you can use hyperlink with custom title like this:
string link = "<a onclick='window.open(" + "http://localhost:49944/Default.aspx? surveyresponseid=" + SurveyResponseId.ToString() + "); ' href='" + "http://localhost:49944/Default.aspx?surveyresponseid=" + SurveyResponseId.ToString() + "' target='_blank' >click this</a>";
post["text"] = link;

Adding content control throws an exception dynamically

I am fairly new to Word Addin development. Fortunately I was able to do almost everything but stuck at some simple issue I belive.
I want to insert plain text controls dynamically at the selected range. For this I am using the following:
currentDocument = application.ActiveDocument;
foreach(var field in myFieldsList)
{
Microsoft.Office.Interop.Word.Range rng = currentDocument.ActiveWindow.Selection.Range;
object oRng = rng;
var contentControlPlain = application.ActiveDocument.ContentControls.Add(Microsoft.Office.Interop.Word.WdContentControlType.wdContentControlText, ref oRng);
contentControlPlain.Tag = formField.FormFieldId.ToString();
contentControlPlain.SetPlaceholderText(null, null, " <" + formField.FormFieldName + "> ");
contentControlPlain.LockContentControl = (formField.TypeName.Trim() == "Blank");
}
Code seems to be working fine but when I try to insert the second field it complains saying:
This method or property is not available because the current selection partially covers a plain text content control.
I understand that addin is trying to insert next content control into the previously inserted plain text control. But I tried giving some other range and could not fix it.
Any help is greatly appreciated.
Thanks.
After adding every content control use
Application.Selection.Start = lastControl.Range.End+1

How do I filter a dojo grid on an xpage?

How do we filter the dojo grid (extlib component) that gets its data from the REST service component? I have the grid loaded with data from the view correctly from the REST service component. I also have on the xpage a dropdown where users can select a value that's a dbcolumn of one of the columns in the same view. I've tried setting the REST service keys value to viewScope.filterCat01 (which is the variable for the combo box), and I've also tried setting the filter in a button (BY is the field/column name) but nothing seems to filter it. Any ideas? In the button when I check grid properties, it does work, so I know the grid object is valid - but the filter just doesn't seem to be doing anything. I've also tried doing a grid._refresh() as well as setting the Keys in the REST service component with no luck. Is there a special way to trigger the filter?
var filterValue = XSP.getElementById("#{id:comboBox2}").value;
var grid = dijit.byId("#{id:djxDataGrid1}");
grid.filter({ By: filterValue});
This is definitely one of those things that you need to piece together a thousand cryptic clues to work it out (Domino - never!). Anyway, I had to work this one out last year. Here's an example 'search' button:
var searchText = dojo.byId('#{id:searchText}').value.replace(/"/g, '|"');
if (searchText) {
var ftSearchText = '[Title] CONTAINS "' + searchText + '" OR [Description] CONTAINS "' + searchText + '" OR [URL] CONTAINS "' + searchText + '"';
dijit.byId('#{id:grid}').filter('?search=(' + ftSearchText + ')', false);
} else {
dojo.byId('#{id:reset}').click();
}
As you can see, it's doing an ft search when a filter is applied. The key is to put "?search=" on to the beginning of the filter string.
and here's the 'reset' button example:
dojo.byId('#{id:searchText}').value="";
var grid = dijit.byId('#{id:grid}');
grid.filter("",true);
grid.store.close();
grid._refresh();
This was developed with 8.5.2. There might be some cleaner ways to do things in 8.5.3 with dojo 1.6.1.
Enjoy!

Resources