I wonder, if someone has THE CLUE for me on one of my devel problem (sure you do ;-) ).
I try to use a "Dojo Tab Container" with dynamic Dojo Tab Panes.
<xp:div id="tabs">
<xe:djTabContainer id="djTabContainer1" tabPosition="top"
style="height:250px;width:500px" defaultTabContent="defTab">
<xp:this.facets>
<xe:djTabPane xp:key="defTab" id="myTab" partialEvents="true" closable="true">
<xp:panel>
<xp:label value="#{javascript:getComponent('myTab').getTitle()}"></xp:label>
</xp:panel>
</xe:djTabPane>
</xp:this.facets>
</xe:djTabContainer>
</xp:div>
Then there's a SSJS (button) event to add tabs (actually the action is more complex to calculate title etc., but this should explain):
var cont:com.ibm.xsp.extlib.component.dojo.layout.UIDojoTabContainer = getComponent('djTabContainer1');
cont.createTab({id:'tab1', tabUniqueKey:'tab1', tabTitle:'tab1'});
cont.createTab({id:'tab2', tabUniqueKey:'tab2', tabTitle:'tab2'});
cont.createTab({id:'tab3', tabUniqueKey:'tab3', tabTitle:'tab3'});
Now I want to programmatically switch (open) to another tab, or close a tab. It's quite difficult to find useful examples here.
I found out, that I can programmatically switch to another tab via cont.setSelectedTab('2') instead of cont.setSelectedTab('tab2') - as I would expect. For some reason the tabUniqueKey parameter is fully ignored, while the tabTitle parameter isn't. Even worse: it looks like all createTab()-parameters are ignored, except of tabTitle.
Is there an elegant way to get the tab pane component? getComponent('tab2') doesn't work. Neither "id:'tab2'" nor "tabUniqueKey:'tab2'" are taken in account. I can get a tab using getComponent('myTab'), but that's fully useless, if all tabs have the same id.
So, neither does
var cont:com.ibm.xsp.extlib.component.dojo.layout.UIDojoTabContainer = getComponent('djTabContainer1');
var tabSel:com.ibm.xsp.extlib.component.dojo.layout.UIDojoTabPane = comp.selectTab('tab2');
nor
var tabSel:com.ibm.xsp.extlib.component.dojo.layout.UIDojoTabPane = comp.setSelectedTab('tab2');
At least what I'm looking for is something similar to:
cont.closeTab('tab3'); // to close tab3
createTab() returns a UIDojoTabPane pane object and you can use it to select the created tab afterwards:
var cont:com.ibm.xsp.extlib.component.dojo.layout.UIDojoTabContainer = getComponent('djTabContainer1');
var paneTab1:com.ibm.xsp.extlib.component.dojo.layout.UIDojoTabPane = cont.createTab({id:'tab1', tabUniqueKey:'tab1', tabTitle:'tab1'});
...
cont.setSelectedTab(paneTab1.getTabUniqueKey());
You can use this pane object to close the tab too:
paneTab1.closeTab()
Related
I have a view that I am using to display people that have chosen to have a lunch (Mittagessen) or/and a snack (Jause). I want to display a tick (glyphicon-ok) if they have selected either one of the options. Previously I just displayed "Yes" - this was centered and looked fine in the view. As soon as I use the glyphicons the values are no longer centered, they are not in their respective columns (when both are selected) and the separating line is missing (that is not a mistake in the screenshot).
This is the code I am using for the view column values:
<xp:viewColumn columnName="Jause" id="viewColumn6" style="width:8%;text-align:center" displayAs="hidden">
<xp:this.facets>
<xp:viewColumnHeader value="Jause" xp:key="header" id="viewColumnHeader6"></xp:viewColumnHeader>
</xp:this.facets>
<xp:this.styleClass><![CDATA[#{javascript:var idx = viewEntry.getColumnValues().get(6);
if (idx == 1) {
return "glyphicon glyphicon-ok"
}}]]></xp:this.styleClass></xp:viewColumn>
I am assuming that the problem is that I am hiding the value of the column.
Any idea what I am doing wrong or how would this be done correctly using Bootstrap and the extlib? I did take a look at the examples in the ExtLib but couldn't find one in the ToDo.nsf app.
I wouldn't use the styling of the column cell itself but insert some HTML with a xp:text element:
<xp:text escape="false" styleClass="glyphicon glyphicon-ok">
<xp:this.value><![CDATA[#{javascript:"<i class='glyphicon glyphicon-ok'/>"}]]></xp:this.value>
<xp:this.rendered>
return viewEntry.getColumnValues().get(6) == 1
</xp:this.rendered>
</xp:text>
The at the end makes sure the cell is displayed and rendered even when the text (HTML) is not.
I'm using a listbox on an xpage which is using computed values
<xp:listBox id="listboxAutorInstitution"
styleClass="listBoxPicklist">
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:getValuesPicklist("authorRT")}]]></xp:this.value>
</xp:selectItems>
<xp:eventHandler event="ondblclick"
submit="true" refreshMode="partial" refreshId="ccAuthor">
<xp:this.action><![CDATA[#{javascript:view.postScript("console.log('" + getComponent("listboxAuthor").value +"')")}]]></xp:this.action>
</xp:eventHandler>
</xp:listBox>
The values come from a rich-text field on a profiledocument.
function getValuesPicklist(fieldName) {
var db: NotesDatabase = session.getCurrentDatabase();
var doc: NotesDocument = db.getProfileDocument("(Config)", "");
var list = #Trim(doc.getFirstItem(fieldName).getValueString().split("|"));
return list.sort(function(a, b) {
return a.toLowerCase().localeCompare(b.toLowerCase());
});
}
If I load the xpage on browser and clicking an element from listbox the console.log('') script is only run for some elements.
The trace log shows me the following error message:
Validation Error: Value is not valid
What could be the cause for this behaviour?
SOLVED:
I solved the problem by using
doc.getFirstItem(fieldName).getUnformattedText().split("|");
instead of
doc.getFirstItem(fieldName).getValueString().split("|");
Based on discussion:
1) You can disable validation: http://www-10.lotus.com/ldd/ddwiki.nsf/dx/XPagesNoDataValidation.htm
I am not sure it will help with listbox, though.
2) Seems, there is something wrong with that profile - my guess is "enter" or some invisible character somewhere at the beginning or end of some keywords (very common with copy/paste from other sources). Try to cut everything, paste to notepad, and copy/paste back.
By the way, it is pretty odd to use Rich Text field to keep keywords...
see my Update in the question post!
I am now getting my tabs in the Application Layout's TitleBar form a view, but it seems that managing the "selected" property is not wotking. Here is the code I have in my page:
<xe:this.titleBarTabs>
<xe:repeatTreeNode indexVar="1" var="tab">
<xe:this.children>
<xe:basicLeafNode label="# {tab.label}"
submitValue="#{tab.label}"
onClick="#{javascript:sessionScope.selectedTab = tab.label;}">
<xe:this.href><![CDATA[#{javascript:
"home.xsp?action=openDocument&documentId=" + tab.unid;}]]>
</xe:this.href>
<xe:this.selected>
<![CDATA[#{javascript:tab.label==sessionScope.selectedTab;}]]>
</xe:this.selected>
</xe:basicLeafNode>
</xe:this.children>
<xe:this.value><![CDATA[#{javascript:getTabs();}]]></xe:this.value>
</xe:repeatTreeNode>
</xe:this.titleBarTabs>
Can this be that hte Href and onClick cannot be there at the same time or I'm just missing something?
As usual, thanks a million for your help. Can't wait to give some back...
You have to decide what shall happen when user clicks a title bar tab:
open URL defined in href
OR
execute onClick event.
The help for onClick gives the hint:
So, you can't use onClick and a scope variable to appear a tab selected after user clicked on tab and new content shows up.
To accomplish this
add an URL parameter &tab= with the tab label tab.label to your href URL
return true in selected code if the current tab label is equal to the tab URL parameter
Your href and selected properties would look like this then:
<xe:this.href><![CDATA[#{javascript:
"home.xsp?action=openDocument&documentId=" + tab.unid + "&tab=" + tab.label}]]>
</xe:this.href>
<xe:this.selected>
<![CDATA[#{javascript:tab.label === param.tab}]]>
</xe:this.selected>
Don't forget to delete the onClick property in your code. You don't need it anymore.
Along the lines of what Knut is suggesting (I think) ... comment out the onClick property for the basicLeafNode and moves its function to the onItemClick for the xe:applicationLayout control.
The code for the onItemClick would be something like this...
var clickedTab = context.getSubmittedValue();
sessionScope.selectedTab = clickedTab;
I created on my previous applications a simple FTsearch module, displaying the results inside a viewPanel1.
But, now in other app it gives me a headache. The search code from the view:
var tmpArray = new Array("");
var cTerms = 0;
if (sessionScope.searchFurnizor) {
tmpArray[cTerms++] = "(Field txt_particontractcv_1 = \"*" + sessionScope.searchFurnizor + "*\")";
}
if (sessionScope.searchStare) {
tmpArray[cTerms++] = "(Field txt_stadiucontrcv = \"*" + sessionScope.searchStare + "*\")";
}
qstring = tmpArray.join(" AND ").trim();
sessionScope.queryString = qstring;
return qstring
The txt_particontractcv_1 is a simple inputText and txt_stadiucontrcv is a checkbox:
<xp:checkBoxGroup id="checkBoxGroup1" value="#{Contr.txt_stadiucontrcv}" defaultValue="In derulare">
<xp:selectItem itemLabel="In derulare" itemValue="In derulare"
id="selectItem1">
</xp:selectItem>
<xp:selectItem itemLabel="Finalizat" itemValue="Finalizat"
id="selectItem2">
</xp:selectItem>
</xp:checkBoxGroup>
The button which submits the search is doing a partial refresh to viewPanel1. Still, it returns 0 results even there are documents respecting the filter criteria inside the search.
LATER EDIT: After deleting one by one fields from the FTsearch module, I think I found the issue: the problem is at the fields which are comboboxes ( my case ) in the document content but also inside the FTsearch modulo. The code for the combobox from the FTsearch:
<xp:checkBoxGroup id="checkBoxGroup1" value="#{sessionScope.searchStare}">
<xp:selectItem itemLabel="In derulare" itemValue="In derulare" id="selectItem1">
</xp:selectItem>
<xp:selectItem itemLabel="Finalizat" itemValue="Finalizat" id="selectItem2">
</xp:selectItem>
</xp:checkBoxGroup>
Also, I noticed that the inputField(s) must be inputText, I try with some comoboboxes as input fields, but not working.
Are you refreshing the view in the partialrefresh or a panel outside of the view?
because if you are refreshing the view you probably never update the search query. If so add an xp:panel or xp:div out side of the view and do the partial refresh on that.
Whenever a full text search is not working how you expect it to, my recommendation is always to print out the search string. Then try performing the search in a view in the Notes Client.
If it doesn't work in the view in the client, trying to resolve it in your XPage will not get it working. The Notes Client will tell you why, usually "Query is not understandable" and you can troubleshoot why using the buttons in the search bar in Notes, which tells you which fields are available and what data type the UNK table thinks they are.
If it does work, there's a problem somewhere in your XPage.
As ever, break it down to try to identify where the problem is - in this case the full text search functionality or the implementation of it in XPages.
I'm trying to make a box that allows you to select some variables, and re-order the ones that are selected. So the LEFT box starts filled, the RIGHT box starts empty. You move items from the left to the right, and on the right you can re-arrange their order (with the up and down buttons). This lets you pick what items you want and in what order (for sorting purposes in another section of the program).
The layout I'm going for looks like of like this:
Unfortunately, it's coming out like... well... :-(
The functionality I'm looking for all works. Yay. I am just having a very hard time with the layout. I think if I can reach the following four primary objectives, I'll be set.
How can I get the OK and CANCEL buttons on the bottom instead of above the multis?
How can I get the multis to have a pre-set size (let's say... 10)
How can I get the arrow buttons to be stacked vertically instead of horizontally?
How can I get the arrow buttons to be between the two multis?
I figure each of these particular objectives are probably one-liners, perhaps a little bit of plumbing here and there...
On a side note, I'm using GridLayout - this might be a poor choice. Is there a better choice for something like this?
Without further ado, here's the code that generates this horrid mess...
#Override
protected Control createDialogArea(Composite parent) {
parent.getShell().setText("Multi-sort");
Composite dialogcomp = new Composite(parent, SWT.NONE);
dialogcomp.setLayout(new GridLayout(3, false));
available = new List(getShell(), SWT.BORDER | SWT.V_SCROLL);
for(String t : MultiSortDialog.availableNames) {
available.add(t);
}
used = new List(getShell(), SWT.BORDER | SWT.V_SCROLL);
for(String t : MultiSortDialog.usedNames) {
used.add(t);
}
createButton(parent, ADD, ">", false);
createButton(parent, REM, "<", false);
createButton(parent, UP, "^", false);
createButton(parent, DOWN, "V", false);
return dialogcomp;
}
I would suggest you simple use the Dialog's default OK and Cancel buttons and not trying to lay out your own. SWT has a nice system for placing them in the system default location (i.e., on Mac OS, the OK button will be on the right, which is the correct location.)
Don't use Dialog.createButton() to create buttons. This creates a button on your dialog which, although it sounds like what you want to do, actually isn't. This creates a button in the style of OK or Cancel buttons, expected to be placed in the button bar composite that the Dialog class owns and styled appropriately for the bottom row OK/Cancel buttons. You want to create a new Button in the composite you're creating. That is:
Button addButton = new Button(dialogcomp, SWT.PUSH);
addButton.setText(">");
addButton.addSelectionListener(...);
To stack the buttons vertically, create a new composite inside dialogcomp to contain them.
To put the arrow buttons between the Lists, you need to ensure that you add things in the correct order. With a GridLayout, you need to add widgets in the order that you want them to appear.
Other points:
Don't change the title of the dialog by calling Shell.setText(). Call setText() in your
Don't try to parent your Lists inside the parent shell. You're given a composite to put things in. This will wreak havoc on your layouts. You're basically hoisting widgets up into things you don't own and don't layout. Instead, put it in the Composite you created.
You may also wish to create buttons with the type SWT.ARROW | SWT.LEFT instead of simply drawing a < sign. It may be more visually appealing. Just something to investigate.
A simple rearrangement of your code, creating Buttons properly, and creating a new composite to hold the buttons, will get you much closer:
Composite dialogcomp = new Composite(parent, SWT.NONE);
dialogcomp.setLayout(new GridLayout(3, false));
available = new List(dialogcomp, SWT.BORDER | SWT.V_SCROLL);
for(String t : MultiSortDialog.availableNames) {
available.add(t);
}
Composite buttonComposite = new Composite(dialogcomp, SWT.NONE);
buttonComposite.setLayout(new GridLayout(1, false));
Button addButton = new Button(buttonComposite, SWT.PUSH);
addButton.setText(">");
Button removeButton = new Button(buttonComposite, SWT.PUSH);
removeButton.setText("<");
Button upButton = new Button(buttonComposite, SWT.PUSH);
upButton.setText("^");
Button downButton = new Button(buttonComposite, SWT.PUSH);
downButton.setText("v");
used = new List(dialogcomp, SWT.BORDER | SWT.V_SCROLL);
for(String t : MultiSortDialog.usedNames) {
used.add(t);
}
This will probably get you pretty close to what you want. However, you will probably want to apply GridDatas for each of your instances. For example, your two Lists will probably want to grab and fill horizontally and vertically to fill the layout as the Dialog is resized. But I'll leave that as an exercise for the reader.