I'm working in a ZK application and I need to add <row>'s components based on user input. The zul is like this:
<grid id="mygrid">
<rows id="rows">
<row>
<cell>
<label value="Rows to add 1:"/>
</cell>
<cell>
<textbox id="txt_addRows1"/>
</cell>
</row>
<!-- Here I need to add rows specified in txt_addRows1 -->
<row>
<cell>
<label value="Rows to add 2:"/>
</cell>
<cell>
<textbox id="txt_addRows2"/>
</cell>
</row>
<!-- Here I need to add rows specified in txt_addRows2 -->
<row align="right">
<cell colspan="2">
<button id="btn_generate" label="Generate"/>
</cell>
</row>
</rows>
</grid>
In the composer I can do something like:
Row someRow = new Row();
row.setParent(rows);
My question is: how do I specify that the new row (generated programmatically in the composer) to be rendered in the specified places and not others?
Any suggestion/guide is also welcomed. Thanks in advance for your answers.
There are 2 ways to insert something in the DOM.
First way is to set the parent, the second one is adding a child.
If you check the AbstractComponent api. you see they also speak of appendChild and insertBefore(Component newChild, Component refChild)
So the code would look like :
rows.insertBefore(newRow,rowWhatComesAfterYourRow);
Related
<ObjectListItem
title="{i18n>uBOMItem}: {Item} Component: {ComponentDesc}"
number="{ComponentNo}"
>
I am using sap.m.ObjectListItem. While binding, I need tab space between {Item} & {ComponentDesc}.
E.g. like \t
Currently, sap.m.ObjectListItem does not support rendering whitespace for title.
And I agree with alexP's answer that it's not clean to combine multiple labels ("{i18n>uBOMItem}:" and "Component:") into one.
That being said; if it's really necessary to do so, however, you'll need to extend ObjectListItem.
Example: https://embed.plnkr.co/WaMaP4wqMevsjMxX
Internally, ObjectListItem renders its title from sap.m.Text. The Text control has a public property called renderWhiteSpaceapi which we can use to allow tabs to be rendered.
ObjectListItem is only for one value. In your case it's better to use CustomListItem.
<CustomListItem>
<HBox width="100%">
<VBox>
<Label emphasized="true" text="{i18n>uBOMItem}: {Item}" />
</VBox>
<VBox class="sapUiSmallMarginBegin">
<Label emphasized="true" text="Component: {ComponentDesc}" />
</VBox>
<VBox width="50%" justifyContent="End">
<ObjectNumber number="{ComponentNo}" />
</VBox>
</HBox>
</CustomListItem>
It's not clean to output two data bindings from your model in one label, text or similar. You should split the output. In case of an i18n label and a data binding in one control i would make a exception.
I'm working in a web application using ZK. I'm struggling with a window where I need to render a grid with as much rows as the user specifies. It should be something like:
<grid>
<columns>
<column width="150px"/>
<column width="350px"/>
</columns>
<rows>
<row>
<cell>
<label value="Rows to add"/>
</cell>
<cell>
<textbox id="txt_rowamount"/>
</cell>
</row>
</rows>
</grid>
<grid id="grid">
<columns>
<column width="100px" label="Field 1" align="center"/>
<column width="100px" label="Field 2" align="center"/>
<column width="100px" label="Field 3" align="center"/>
</columns>
<rows id="rows" forEach="${rowModelList}">
<row>
<cell>
<textbox value="${each.field1}" />
</cell>
<cell>
<textbox value="${each.field2}" />
</cell>
<cell>
<textbox value="${each.field3}" />
</cell>
</row>
</rows>
</grid>
<button id="btn_generate" label="Generate Rows"/>
So, if you type 4 in txt_rowamount a grid with 4 row components and 3 textbox components in each row. The textboxes should be empty and when I complete every textbox the user input should be binded to fieldN of every rowModel item, do I make myself clear?
I'm trying with something like this in the composer:
private ListModel<RowModel> rowModelList;
#Autowired
private Grid grid;
#Override
public void doAfterCompose(final Window component) throws Exception {
super.doAfterCompose(component);
rowModelList = new ListModelList<>();
grid.setVisible(false);
}
public void onClick$btn_generate() {
// TODO Add four empty elements to rowModelList
grid.setVisible(true);
}
Being RowModel like
public class RowModel {
private String field1;
private String field2;
private String field3;
// ommited constructors, getters and setters
}
I believe that the approach should be MVVM instead of the current MVC but I don't know how to do this. Besides, I don't know if you can mix the approachs in the same application and what are the advantages and disadvantages of doing that.
I've seeing the ZK grid demos but all of them are using already populated objects to render the tables, so it's not useful to me.
If someone can give me a hand in this issue, it would be greatly appreciated. If you need more information on the code or the requirements for this problem, please comment it out.
Thanks in advance for your answers.
It seems there's a lot missing in your current attempt, so I'll try to fill the gaps.
If impatient here a runnable example on zkfiddle.
Since you were talking about binding component attributes to model values I'd suggest using ZK's DataBinding which integrates nicely into the MVVM development pattern (sorry for the link, but that's not a one-liner).
In any case the example illustrates how to combine ZK features such as (ListModelList with templates, Property-/Command-Binding) into a simple dynamic UI.
As you can see in code, adding, (re)moving a row inside the model requires rudimentary operations (the grid will update its child-rows automatically):
rows.add(new RowModel(...));
rows.remove(row);
Since the ListModelList is assigned to the <grid> component via #init(vm.rows), the grid will listen to changes to the ListModel and add remove grid-rows accordingly. It uses the <template name="model" var="rowModel"> to render new rows when added to the model. The template variable rowModel variable represents the rowModel object. (more on that in our documentation)
I hope this information is not overwhelming ... if so please let me know.
BTW: the forEach-attribute you were trying to use previously is used for static ui composition (at zul parse time) where no dynamic control is required. For dynamic cases use ListModel(List) in combination with templates.
Robert
I would like to read some values from my vm. Here's an example of what I've done so far
<div forEach="${vm.activityData.activityList}">
<label
value="#load(c:cat3('vm.activitiData.', each, '.organizer' ))" />
</div>
But it seems like it is unable to read the each inside the cat3. My objective is to get the organizer for each activity. Any idea how to achieve this ?
Update
For example, I want to simplify from this codes :
<div>
<label value="#load(vm.activityData.A.name)" />
<label value="#load(vm.activityData.ASponsor)" />
<label value="#load(vm.activityData.AOrganizer)" />
<separator/>
<label value="#load(vm.activityData.B.name)" />
<label value="#load(vm.activityData.BSponsor)" />
<label value="#load(vm.activityData.BOrganizer)" />
<separator/>
</div>
into
<div forEach="${vm.activityData.activityList}">
<label value="#load(c:cat3('vm.activityData.', each, '.name'))" />
<label value="#load(c:cat3('vm.activityData.', each, 'Sponsor'))" />
<label value="#load(c:cat3('vm.activityData.', each, 'Organizer'))" />
<separator/>
</div>
Basically what I want to do is to dynamically combine part of strings into one string. And then use #load(string).
Today I had the time to test it and I prepared a fiddle for you.
Your ZK version is good but I did forget to add one more thing.
You have to make use of the custom-attributes otherwise it wouldn't work.
Solution :
<div forEach="${vm.activityData.activityList}">
<custom-attributes field="${each}"/>
<label value="#load(vm.activityData[field].name)" />
<label value="#load(vm.activityData[c:cat(field, 'Sponsor')]" />
<label value="#load(vm.activityData[c:cat(field, 'Organizer')]" />
<separator/>
</div>
I created fast a working fiddle where you can test or look how it works.
It's my first time working on zk and i have this guideline.
There is an empty column on the far right that fills the empty space between the last column and the right edge of the Grid. When the content is loaded the scroll should appear inside that column.
Is it possible to do this? do you have any suggestion?
Something like this fiddle if your run it under zk 7.0.2 or 7.0.3?
If link dies this is the code :
<zk>
<window border="normal" title="hello" >
<grid height="300px">
<columns>
<column label="Chat Message" sort="auto" />
<column label="By" sort="auto" />
</columns>
<rows id="rows">
<zk forEach="1,2,3,4,5,6,7,8,9,10">
<row>
<label value="Message ${each}"/>
<label value="By User ${each}"/>
</row>
</zk>
</rows>
</grid>
</window>
</zk>
I have issue with making below layout. Please provide me some code example how to create below layout. As the screenshot depict I need two part equally sized. Left part containing the latin text and right side the radio buttons and rest. The "From" teksts should be left aligned and the amounts and icons should be right alligned. How do I construct this layout best way in ZK and in ZK way ?
Screenshot Example
You can see below code for demo purpose and adjust component according to your requirments
<zk>
<window border="normal" title="hello" apply="pkg$.TestComposer" width="100%" height="100%">
<hbox heights="40%,20%,40%" width="100%" height="100%">
<borderlayout width="100%" height="100%">
<center>
Here is My Content
</center>
</borderlayout>
<borderlayout width="100%" height="100%">
<center>
<vbox widths="30%,30%,30%" width="100%" height="100%">
<checkbox />
<checkbox />
<checkbox />
</vbox>
</center>
</borderlayout>
<splitter width="100%"/>
<borderlayout width="100%" height="100%">
<center>
<vbox widths="30%,30%,30%" width="100%" height="100%">
<label value = "hariom123"/>
<label value = "hariom123"/>
<label value = "hariom123"/>
</vbox>
</center>
</borderlayout>
</hbox>
</window>
</zk>
You can run above code in Zk Fiddle
It kills me to respond to this answer given the level of detail you provided. In the future please do post some code showing what you've tried and why it doesn't work. With that, we can quickly get you back on track. Your question here is just fishing for code =/
<hlayout hflex="1">
<!--
size/flex on labels doesn't work, wrap label in a div to control size
-->
<div hflex="1">
<label value="lorem ipsum.."/>
</div>
<grid hflex="1">
<columns>
<!--
Last column is small, first two share available space.
-->
<column>
<column>
<column width="30px">
</columns>
<rows>
<row>
<radio label="This is a radio button"/>
<label value="From: 100,00 $"/>
<image src="info.png"/>
<row>
<row>
<radio label="This is a radio button 2"/>
<label value="From: 200,00 $"/>
<image src="info.png"/>
<row>
<row>
<radio label="This is a radio button 3"/>
<label value="0,00 $"/>
<image src="info.png"/>
<row>
</rows>
</grid>
</hlayout>
There are many other ways to get this layout. I chose a grid next to a div so the radio buttons, labels, and icons on the right are guaranteed to line up. You have other options though.
PS: of course you will need to apply CSS to make the ZK grid less gaudy.