zk nested forEach - foreach

I have following structure to display in zul file and got List of clinic object from Java controller.
I tried several zk components in zul with no luck. What component should I use with a forEach?
ListBox
ListItem
Grid
Here is structure need to display :
For each clinic
{
For each clinic.location
{
For each (clinic.location.provider)
{
Output (provider display name)
}
Output (clinic name)
Output (clinic.location address)
Output (clinic.locatoin telephone number)
Output (clinic.web address)
}
}

As explained in the answer given by Darius, here is an example of how to use a <Grid> with a <rows> component
<?page title="Result"?>
<zk>
<window apply="org.zkoss.bind.BindComposer"
viewModel="#id('vm') #init('fully.qualified.viewmodel.classname')"
title="Result Window" border="normal" >
<div>
<grid>
<rows>
<row>
<listbox model="#bind(vm.listname)">
<listhead>
<listheader label="Item Name"
style="text-align:center;">
</listheader>
<listheader label="Attribute Value"
style="text-align:center;">
</listheader>
<listheader label="Qualifier Value"
style="text-align:center;">
</listheader>
</listhead>
<template name="model" var="item">
<listitem value="${item }">
<listcell label="#load(item.name)"
style="text-align:center;">
</listcell>
<listcell
style="text-align:center;">
<textbox
value="#bind(item.attributeValue)"
style="text-align:center;" />
</listcell>
<listcell
label="#load(item.qualifierValue)"
style="text-align:center;">
</listcell>
</listitem>
</template>
</listbox>
</row>
</rows>
</grid>
</div>
</window>
</zk>

You can use a Listbox or a Grid.
If you use a Listbox, it will contain Listitem objects
If you use a Grid, it will contain a Rows object, which will contain Row objects
To the Listitem or the Row, you will add other components: the simplest would be Label objects
I notice you have an inner table of providers. For these, you will probably need a nested Grid or Listbox. You could also use ZK's Detail component. it would allow you to expand in order to see the inner table.

There are multiple ways how to achieve this
including separate zul file to template row, whitch will contain a grid with separate view model - this style you can have shown all nested grid at once ,but it should and it will have performance issiues with larger ammout of data(because count of rows == count of viewmodels of nested grids)
include nested grid with own template ,and data model as parameter of view model,and show this grid on demand(button click,row click etc) - this is bether way in case of no performance issues,but you will be able to show only one nested grid at time
Final words - just don´t
Nesting a grid to grid is a very bad design,because it is incredibly hard to render this,and it is only usable for small data. The best way to do this,in my opinion is to create two separate grids,side by side,and show adition data on in second grid,after a click on row in first grid. This way you can achieve very fast gui with no performance issiues,ever with a lot of data. Another way is to create a popup on grid row,whitch will show additional data,a it is also a lot bether for your performance.

Related

How to display all Data form oData

With the oData i get about 100 Entries for equipments. The goal is that in my application all entries coming from the oData are displayed. Problem is only the first about 50 entries are shown. How can I solve this? is there somthing to do in my View?
<mvc:View controllerName="zppb.bde.equi.ZP_EquList.controller.Main" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m">
<Shell id="shell">
<App id="idAppMain">
<pages>
<Page id="page" title="{i18n>title}">
<content>
<Table id="idEquipmentTable" items="{MultiInfoSet>/}">
<headerToolbar>
<Toolbar>
<Button icon="sap-icon://filter" press="onFilterListPress"/>
</Toolbar>
</headerToolbar>
<items>
<ColumnListItem type="Navigation" visible="true">
<cells>
.
.
</cells>
</ColumnListItem>
</items>
</Table>
</content>
</Page>
</pages>
</App>
</Shell>
</mvc:View>
Generally, the preferred way would be to use the growing functionality, where the user scrolls down the table and it'll load more lines when they approach the end of the current list.
Not many changes required:
<Table
id="idEquipmentTable"
items="{MultiInfoSet>/}"
growing="true"
growingThreshold="100"
growingScrollToLoad="true">
There are a few other options if your list has a relatively low number of items and you do not want the user to scroll.
You'll find more information on this via the design guidelines: Responsive Table - Fiori Design Guidelines

XUL get the value of MENUITEM selected

I am creating a dropdown in XUL like this:
<button id="bid" oncommand="alert(event.target.nodeName)" >
<menupopup>
<menuitem label="one" value="one" />
<menuitem label="two" value="two" />
<menuitem label="three" value="three" />
</menupopup>
</button>
I want to alert the value of nodeitem which is being clicked. Using event.target.nodeName giving nodeName as menuitem but using nodeValue is retuning undefined as it starts to take value of button node. How can I get the value of the menuitem clicked. I also tried $(this).val() but even that gave undefined. Using $(this).attr('value')
also didn't help. I can put oncommand for menuitem but that doesn't seem to be actual solution. Is that the only way or some method exist to get the value?
The XUL code you have in the question is non-functional. Either you should be using a <menulist> instead of a <button>, or your <button> needs the property type="menu" or type="menu-button". If you are going to use a <button> without the type="menu" property, you would actually have to open a popup in the command event handler for the <button> and then select from there. That does not appear to be what you are wanting. It is, however, quite doable. I use a construction like that in one of my add-ons, except I have it open when one of several <label> items is clicked. This allows re-use of a single <menupopup> for multiple different items in the window. In that case, the <menupopup> is a rather large amount XUL code that I did not want to repeat and maintain multiple duplicates in the XUL for the window.
The value of the <menuitem> selected:
Your actual question is how to get the value of the <menuitem> selected by the user. All of the code below is tested and functional. As you can see from the code you can get the value of the <menuitem> you select (at the time of selection) from: event.target.value.
Using a <menulist> element:
The most common element to use would be a <menulist>. This would normally be used when you are having the user select from multiple options a choice that is going to be remembered and used later, or used to adjust what is presented in the user interface. It would generally not be used to select from multiple immediate actions (which are acted upon and the choice not remembered). A <menulist> is what is used in the examples for <menuitem> and <menupopup> on MDN.
<menulist id="bid2" oncommand="alert(event.target.value)" >
<menupopup>
<menuitem label="one" value="one" />
<menuitem label="two" value="two" />
<menuitem label="three" value="three" />
</menupopup>
</menulist>
The above code will give you what looks like a button with a selection of <menuitem> entries when you click on it. It will alert with the value of the <menuitem> you have selected.
This will produce an item that looks like:
Which you can click on to open a drop-down list:
If you select an item:
You will get an alert:
And the object will then show your selection:
Using a <button> element:
It is also possible to use a <button> element with the property type="menu" or type="menu-button" specified. However, this provides no visual feedback to the user as to which option is currently selected. [Note: Your JavaScript could manually change the <button> label property to provide this feedback.] You could use this type of element if it is button that produces an immediate action rather than a selection that is remembered.
The code:
<button type="menu" id="bid2" label="A Button" oncommand="alert(event.target.value)">
<menupopup>
<menuitem label="one" value="one" />
<menuitem label="two" value="two" />
<menuitem label="three" value="three" />
</menupopup>
</button>
This will produce an item that looks like:
Which you can click on to open a drop-down list:
If you select an item:
You will get an alert:
And the object will then NOT show your selection:
If you want to set the label of the <button> to reflect the selection made by the user, you could use:
<button type="menu" id="bid2" label="A Button" oncommand="event.target.parentElement.parentElement.label=event.target.value;alert(event.target.value)">
<menupopup>
<menuitem label="one" value="one" />
<menuitem label="two" value="two" />
<menuitem label="three" value="three" />
</menupopup>
</button>
When three is selected, that will result in a button that looks like:
Using a <toolbarbutton>:
You could, alternately, use a <toolbarbutton>.
When not hovered, doing so would look like:
When hovered:
When open for selection:
Choices in UI design:
There are many choices that you have to make when designing your user interface. There are many different ways to get to the same effective result, with somewhat different look and feel. You really should be trying these types of options on your own. You may find the XULRunner program XUL Explorer to be of use when prototyping XUL.
Selecting UI elements and a look and feel is, in my opinion, beyond the scope of questions on stackoverflow. While you probably won't get specific XUL help, you can ask UI design questions at: the User Experience stack exchange.

Getting correct parent ID in composite components

For partial updating my composite components, I have some problems finding the correct parent IDs. e.g. if my component is inside of a tabView
<p:tabView id="foo">
<p:tab>
<stg:mycomponent id="bar" />
</p:tab>
</p:tabView>
Now I need the String :foo:bar to find the correct parts, that I want to update. Via #{cc.id} I just get bar, so this does not work for me.
However, I tried to achieve this by some kind of dirty hack by adding a attribute to my component like this
<composite:attribute
name="parentId"
default=":#{component.namingContainer.parent.namingContainer.clientId}"
/>
If I hand over the String :foo:bar to parentId everything works fine, but of course that's not what I really want to do. I do not want to force the user of my component to hand over this ID.
But now the problem: If I do not hand over a parentId, I only can use my attribute in the "first level" of my component. If there are some kind of "nested IDs" then #{cc.attrs.parentId} is evaluated e.g. to foo:bar (which is nice) but also foo:bar:fooBar or somethin like that, depending on where #{cc.attrs.parentId} is located in my code.
I hope it's comprehensible what my problem is and what I am exactly asking for. If not, please leave a comment.
I am using primefaces 3.5 and JSF 2.1 (Mojarra)
If I understand, you need to update parts of a composite component within the composite component itself. Normally you don't need to know the parents IDs to achieve this.
As you are setting id on a primefaces component, you can update it with primefaces using the same id (without any :container:etc prefix) as long as your update is in the same scope.
Here is an example (see source below).
Observe the generated id's in the HTML page produced by JSF in the first tab:
First span : id="static" (raw html id, not PF, not unique in the document)
Second span : id="myform:tv1:comp1:static2" (PF-generated to ensure id is unique in the document)
Third span : id="myform:tv1:comp1:dynamic" (PF-generated, unique)
poll component use the id "myform:tv1:comp1:dynamic", even if we only provide "dynamic" in the source.
The parents does not need to know the ID of the component part to be updated
The component does not need to know the IDs of its parents/containers
Please note generated IDs on the second tab. PrimeFaces does its job by naming them unique.
Sample composite component:
<composite:interface>
<composite:attribute name="label" />
</composite:interface>
<composite:implementation>
<h1><h:outputText value="#{cc.attrs.label}"/></h1>
<span id="static1">
Static : #{testBean.increment}
</span>
<p:outputPanel id="static2">
Static : #{testBean.increment}
</p:outputPanel>
<p:outputPanel id="dynamic">
Dynamic : #{testBean.increment}
</p:outputPanel>
<p:poll interval="3" update="dynamic" />
</composite:implementation>
Use the component in a XHTML page:
<h:form id="myform">
<p:tabView id="tv1" >
<p:tab id="tab1" title="First Tab">
<comps:myComponent id="comp1" label="Abc" />
</p:tab>
<p:tab id="tab2" title="Second Tab">
<comps:myComponent id="comp2" label="Def" />
</p:tab>
</p:tabView>
</h:form>
And this is the code for the test bean:
#ManagedBean(name="testBean")
public class TestBean implements Serializable
{
static int _counter = 0;
public String getIncrement()
{
_counter++;
return Integer.toString(_counter);
}
}
I hope this example will be clear enough and close to what you want to get.
Please let me know.

How to make items (columns) in <apex:pageBlockTable> hyperlink?

I successfully created tables with style that salesforce provided. (like the one that highlighted on mouseover etc)
But I want the value of column to be a link to display detail info of the object.
When I don't create my own visualforce page, the table looks nice and the column
values (records) are all hyperlinked but can't figure out how to do it from visualforce apex code.
pageBlockTable and column definition does not seem to have attributes or anything that
make it hyperlink.
http://www.salesforce.com/us/developer/docs/pages/Content/pages_compref_pageBlockTable.htm
http://www.salesforce.com/us/developer/docs/pages/Content/pages_compref_column.htm
<apex:pageBlock title="test">
<apex:pageBlockTable value="{!workObj}" var="item">
<!-- below needs to be hyperlink -->
<apex:column value="{!item.name}" />
</apex:pageBlockTable>
</apex:pageBlock>
I could achieve my goal by throwing the good design away like below but I would like to keep the code above.
This works but no salesforce style is applied.
<apex:pageBlock title="my test title" >
<apex:dataTable value="{!workObj}" var="wn" cellpadding="2" cellspacing="2">
<apex:column>
<apex:facet name="header">仕事名一覧</apex:facet>
<apex:form >
<apex:commandLink value="{!wn.name}" />
</apex:form>
</apex:column>
</apex:dataTable>
</apex:pageBlock>
Instead of <apex:column value="{!item.name}" />, try doing it like this in the column body:
<apex:pageBlock title="test">
<apex:pageBlockTable value="{!workObj}" var="item">
<apex:column>
<apex:outputLink value="{!item.name}">{!item.name}</apex:outputLink>
</apex:column>
<apex:pageBlock title="test">
<apex:pageBlockTable value="{!workObj}" var="item">

Placing common contols in two tab pages

I have a tab item with 2 tab pages. I want to place 4 check boxes in each of the tab pages with all check boxes having the same property. How it can be done easily?
Bind all your checkboxes to the same property (from your ViewModel, you do have one, right?). Then they will all display the same information.
There's not much to the binding code.. You could try something like...
<TabControl>
<TabItem Header="Tab1">
<StackPanel>
<CheckBox Content="One" Checked="{Binding Path=MyProperty}"/>
<CheckBox Content="Two" Checked="{Binding Path=MyProperty}"/>
</StackPanel>
</TabItem>
<TabItem Header="Tab2">
<StackPanel>
<CheckBox Content="Three" Checked="{Binding Path=MyProperty}"/>
<CheckBox Content="Four" Checked="{Binding Path=MyProperty}"/>
</StackPanel>
</TabItem>
</TabControl>
..where MyProperty is a local property representing the state you want to show.

Resources