Repeat Control - Tabindex - xpages

I use Repeat Controls to register data. Based on some tests, I want the cursor to move to different fields. When I set a tabindex for a field in a Repeat Control, the tab order changes. The cursor now moves through all the fields in the column with the lowest tabindex and after that all the fields in the next column.
Is there a way to change the tab order so that the cursor moves "row"-wise? If I have to programmaticly mananage the cursor movements, what is the easiest way to get the cursor position in the Repeat Control?

If you're on Domino 8.5.3, you can create a tabindex custom attribute and use the indexVar to prefix the tabindex so that you get row by row tabbing. Custom attributes can be created under all properties - attrs.
I think you have to use a custom attribute as the standard attribute can only be calculated on page load, and it looks like indexVar isn't available on page load.
E.g.
<xp:inputText>
<xp:this.attrs>
<xp:attr name="tabindex" value="#{javascript:return rowIndex + '1';}" />
</xp:this.attrs>
</xp:inputText>

It looks like you will be best off with a client side script. Use dojo.query to get all the fields and then sort them out.

Related

Force user to select only one value from filter spotfire

Is it possible to force the user to select only one value from a filter ?
For a radio button filter as below, is it possible to remove the buttons all & none and make sure that only one Choice is selected ?
you cannot change the existing filter features or functionality without developing a custom extension for a new filter control.
that said, you can certainly emulate a filter using what's called a Property Control and a Data Limiting Expression. for single selection, you're stuck with either a Dropdown control or a Listbox (single select) control.
you would need to...
create a Text Area Visualization on the page somewhere
insert a Listbox or Dropdown Property Control into the Text Area Visualization
create a Document Property with the same data type as your filter column and associate it to the Property Control. you can set this to Unique Values in Column or write in your own Fixed values.
open the Properties dialog on the visualization you'd like to filter and navigate to the Data page
scroll down to Limit Data Using Expression and use an expression like [MyFilterColumn] = "${MyDocumentProperty}" (quotes are required for string values; if numeric then omit quotes)
Please add this CSS in the HTML page of the spotifre to remove all and none
.ColumnFilter .sf-element-filter-item:last-of-type { display:none; }
.ColumnFilter .sf-element-filter-item:first-of-type { display:none; }
Another way to force the users to select one option is to add a Show/Hide in the visualization like this: Hide if UniqueCount([Field]) is greater than 1

Dynamic Fields in xPages

I have a repeat control that is gathering its data from a view. Displaying in a table is one column from the view. These entries can be variable. For each entry in the repeat control I would like to have a couple of user editable fields (comments and checkboxes). Since the amount and names of entries are dynamic I think dynamic field binding is the way to go. The problem is I have been struggling with it for a few days and have gotten no where.
So in the repeat I have a computedfield displying the value of the column. I was thinking of making the field name for the comments field the value of the computedfield. The datasource would be the same, just the fieldnames would change and be based on the entries in the row.
The previous entries stackoverflow entries about dynamic field binding all list passing custom properties, I still haven't gotten my head around those.
If the value of the computedfield1 = "One" then the datasource/field name for the inputText1 = "document1.One", and if the computedField1 = "Two" then the datasource inputText1 = "document1.Two"
Is this even possible?
I'm a little confused by if you want these to be things you're setting to render at page load or if you want them to dynamically change based on user entered data, but I'll assume it's the former and give you an example.
If I'm iterating through a view in a repeat control, I probably have something like:
<xp:repeat rows="50" var="currRow" value="#{ViewName}" IndexVar="rowNum">
</xp:repeat>
Inside my repeat, I will put a reference to a custom class
<xp:repeat rows="50" var="currRow" value="#{ViewName}" IndexVar="rowNum">
<xc:dynamicRowBinding dataSource="#{currentDocument}">
<xc:this.binding1>
<![CDATA[#{javascript: currRow.getColumnValue("binding1");}]]>
</xc:this.binding1>
</xc:dynamicRowBinding>
</xp:repeat>
What this is assuming is that the document you're binding things to on the XPage is declared as currentDocument, and that there is a column in your underlying view that is calculating the desired field binding for the current row based on the properties and values of that document.
In the custom control, the following exists:
By defining dataSource and binding1 as properties within the custom control, they will be available as compositeData.
Thus, to bind a field using these components, we simply put the following definition in our custom control:
<xp:inputText value="#{compositeData.dataSource[compositeData.binding1]}">
</xp:inputText>
I hope this helps!

XPages - Repeat Control - Get item Value

I would like to create a custom control which shows 3 columns,
column 1, value selected from checkbox (this is ok)
column 2, editable box , this is showing but not working 100%
column 3, a button to remove the row (still to be done)
So far:
After selecting the options, click "Create Rows" button and 1 row appears for each selected option.
Problem:
Only last value in editable box, is used, how can I get the value from each box ?
getComponent("inputText1").getValue() only shows the last value.
Example code is on this URL:
http://snipt.org/AAgd3
You bind the column values to array variables. Exercise 23 has a complete working example: http://www-10.lotus.com/ldd/ddwiki.nsf/dx/Tutorial-Introduction-to-XPages-Exercise-23
You just need to adjust it to the source/destination of your data. Let us know how it goes
If you want to bind them dynamically, you can also do this with expression language. It takes a bit of getting around in order to get the fields editable, but the way I've resolved it is to pass a calculated ID into a custom control, then using that for the binding.
For example: If I'm Working with a list of Unique Part Names, I may pass into my custom control a variable for a Comment. If I pass this in as fieldNameComment to my custom control, I can dynamically bind it to an inputText element through the following code.
I'm using a DominoDocument passed in as the dataSource.
Calling the Custom Control:
<xp:repeat var="CurrVal" value="#{DataSource}">
<xc:DynamicTableRow dataSource="#{EmissionsDocument}">
<xc:this.fieldNameComment><![CDATA[#{javascript:CurrVal+"Comment"}]]></xc:this.fieldNameComment>
</xc:DynamicTableRow>
</xp:repeat>
Inside the Custom Control:
<xp:inputText id="inputText5"
value="#{compositeData.dataSource[compositeData.fieldNameComment]}">
</xp:inputText>
As long as (for some reason) none of the string calculations are performed within the expression language syntax, this will yield an editable field. In my testing, if I tried to calculate a value by concatenating any strings, the field would be bound, but not appear as editable under any circumstances. If you want to bind directly to fields, this may be a good approach, but if you want to save your array and parse it through java, then Stephan's solution also works great Hope this helps!
Appended: Added repeat control to show iteration through the data source. Each iteration of the Data Source yeilds a value, CurrVal, to which the string "Comment" is appended. This creates a series of FieldNames based on the Values in the DataSource that are bound to inputs within the custom control called DynamicTableRow

Adding / removing fields in a repeat control dynamically and saving them to document

I found this discussion which describes how you can put an input text inside a repeat control and repeat it unlimited number of times and bind it to a field in a document dynamically.
Here's what I did. I created a repeat like this:
<xp:repeat indexVar="fieldSuffix" value="#{viewScope.rowCount}">
<xp:div>
<xc:dynamicInputText dataSource="#{contact}" fieldName="fullName_#{fieldSuffix}" />
</xp:div>
</xp:repeat>
In the custom control dynamicInputText I have written the input text control like this:
<inputText value="#{compositeData.dataSource[compositeData.fieldName]}" />
Then I created an Add button on which I increment viewScope.rowCount by 1 and partial refresh the repeat control. This adds a new row of input text. Similarly I created a Delete button on click of which decrement viewScope.rowCount by 1 and partial refresh the repeat control. This removes the last added input text.
Now if click on Add three times I get three input text fields on web page. I enter information in each of them. Then I click on Delete to remove the third (last) input text. Now when I save the data source all three fields (including the last one I removed) gets saved in the document.
Why does this happen? How can I stop the third field I removed to be saved in the document?
You just hid rendering of that field. Once you binded it, your Delete button must clear its value or remove that item from DDS. For example DDS.replaceItemValue( field, "" ) or (preferably) DDS.removeItem( field ).

How do I create a pager for a view that shows the alphabet instead of numbers?

I have a need to have an alphabetical pager for a view. I didn't see any of the samples or the custom pager that addresses this. I would think that this would be a pretty common thing.
MJ
I'm not quite sure what you really mean by an "alphabetical pager", but I assume you might be looking for some kind of alphabetical navigator like we have it in the personal NAB inside the Notes client, right?
If so you're not really looking for a pager but for an alphabetical view filter. Here's one way to get there:
create a panel, give it a distinctive ID like "viewContainer" or
something. Put your view panel into the panel; of course the view's main sorting order must be alphabetical
create a 2nd panel above "viewContainer", no ID necessary here
put a repeat inside this new panel and bind it to a new JavaScript array, like that:
new Array("a", "b", "c", ... , "x", "y", "z");
enter a collection name for the repeat, like "letter"
put a link control inside the repeat. The link's label will be
computed to the repeat's collection name, i.e. "letter".
assign an onclick event to the link setting a sessionScope variable to the current collection name's value, like that:
sessionScope.filter = letter;
set the event's refresh mode to partial so that it refreshes your viewContainer panel
highlight your view control inside the viewContainer. In its data properties look for the property field labelled "Filter by column value" and make it computed. Enter this code:
sessionScope.filter;
That's it.
Edit:
of course you can build the repeat's datasource array dynamically from the view itself. So, instead of building that static a-to-z array you could also use something like this:
#Unique(#Left(#DbColumn(#DbName(), "yourLookupView", viewColNumber), 1));
That should return an array only containing those letters that really are in your view.
Also you could another static link control outside the repeat resetting the filter to show all entries. It would be built like the repeated link with the onclick event calling this code:
sessionScope.filter=null;
Enjoy!
I would go for this: make a view categorized by formula #Left( value; 1). Then render result of #DbColumn as pager by repeat or some ExtLib component (links list, navigator, menu). Each link will either limit shown view to "single category" or jumps to "starts with" character.

Resources