I can't reach component by id in the included .zul page. I have one main.zul with a controller and I need to get a component in included zul page through the java controller class, but it returns null.
I know the included method creates new id space but is there any way to get this component?
UPDATE
Here is my code:
the main zul page
<?page title="DealerVizard.zul"?>
<?page id="main" ?>
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" arg0="./Dealer" ?>
<zk>
<style src="/resources/css/default.css" />
<window id="Dealer" class="index"
apply="com.i2i.prm.controller.IndexController">
<div class="content" width="100%">
<tabbox id="tb" forward="onSelect=onSelect">
<tabs id="tabs">
<tab id="info" label="INFO" />
<tab id="create" label="CREATE" />
<tab id="edit" label="EDIT" />
<tab id="test" label="TEST PANEL(LIST BOX)" />
</tabs>
<tabpanels>
<tabpanel id="DealerInfo">
<include id="DealerInfoContent"
src="View/Dealer/DealerInfo.zul" />
</tabpanel>
<tabpanel id="DealerCreate">
<include id="DealerCreateContent"
src="View/Dealer/DealerCreate.zul" />
</tabpanel>
<tabpanel id="DealerEdit">
<include id="DealerEditContent"
src="View/Dealer/DealerEdit.zul" />
</tabpanel>
<tabpanel id="PagingListBox">
<include id="PagingListBoxContent" // Included here
src="View/TEST/PagingListBox.zul" />
</tabpanel>
</tabpanels>
</tabbox>
</div>
</window>
</zk>
PagingListBox.zul (Included page)
<?page id="list" ?>
<zk>
<grid width="100%">
<columns>
<column label="" />
</columns>
<rows>
<row>
<listbox id="listModel" width="100%" height="100%"
visible="true" span="true" pagingPosition="top" rows="20"
selectedItem="#{DealerController.selected}"
model="#{DealerController.userList}"
forward="onSelect=//main/Dealer.onSelect">
<auxhead>
<auxheader colspan="1">
<textbox
value="#{DealerController.searchUser.name}" maxlength="9"
id="searchCO_ID" forward="onChanging=//main/Dealer.onSearch"
width="100%">
</textbox>
</auxheader>
<auxheader colspan="1">
<textbox
value="#{DealerController.searchUser.surname}" maxlength="21"
id="searchMSISDN" forward="onChanging=//main/Dealer.onSearch"
width="100%">
</textbox>
</auxheader>
<auxheader colspan="1">
</auxheader>
</auxhead>
<listhead>
<listheader label="Name"
sort="auto(UPPER(name))" />
<listheader label="Surname"
sort="auto(UPPER(surname))" />
<listheader label="Delete ?" />
</listhead>
<listitem self="#{each=USERLIST}">
<listcell>
<label value="#{USERLIST.user.name}" />
<textbox
value="#{DealerController.tmpUser.name}" visible="false" />
</listcell>
<listcell>
<label value="#{USERLIST.user.surname}" />
<textbox
value="#{DealerController.tmpUser.surname}" visible="false" />
</listcell>
<listcell>
<button label="Update"
forward="onClick=//main/Dealer.onUpdate" visible="false" />
<button image="icons/edit-delete.png"
label="Delete" forward="onClick=//main/Dealer.onDelete"
width="100%" disabled="true" />
<button label="Save"
forward="onClick=//main/Dealer.onSave" visible="false" />
<button label="Cancel"
forward="onClick=//main/Dealer.onCancel" visible="false" />
</listcell>
</listitem>
</listbox>
<paging id="pagingData" pageSize="20" />
</row>
</rows>
</grid>
</zk>
IndexCOntroller.java
public class IndexController extends GenericForwardComposer {
private List<User> userList = new ArrayList<User>() ;
AnnotateDataBinder binder;
Tabbox tb;
Window Dealer;
private int pageCount=0;
#Override
public void doAfterCompose(Component comp) throws Exception {
// TODO Auto-generated method stub
super.doAfterCompose(comp);
comp.setVariable(comp.getId() + "Controller", this, true);
binder = (AnnotateDataBinder) Dealer.getVariable("binder", true);
System.out.println(Path.getComponent("//list/listModel"));
}
public IndexController() {
// TODO Auto-generated constructor stub
}
}
Normally I wouldn't recommend using Path.getComponent() way to access other components as your application code becomes tightly coupled with your component structure in your view page.
In your case you simplest way is to use AbstractComponent#getFellow(String compId) method so for eg.
Include inc = (Include) Dealer.getFellow("PagingListBoxContent");
Listbox listModel = (Listbox) inc.getFellow("listModel");
System.out.println(listModel);
So in future even if you insert any other component in your ZUML page before your listbox your code will still work.
UPDATE: BTW there was an interesting blogpost on this very topic on ZK blog recently
if your include have id, you can use dollar sign to get the inner components
<zk>
<include id="inc" src="test.zul />
</zk>
test.zul
<zk>
<label id="lab1" value="test1" />
</zk>
you can use "inc$lab1" get the label in test.zul
You can access any component in any other id space using zscript or java. if it is on the same page, but different window then (component B in window A):
Path.getComponent("/A/B");
if it is on a different page then (component B in window A on page P):
Path.getComponent("//P/A/B");
You can find documentation here: http://books.zkoss.org/wiki/ZK%20Developer%27s%20Reference/UI%20Composing/ID%20Space
You can add in your IndexController.java:
...
private Include DealerInfoContent;
...
this way you can access the included component within the parent composer.
(I would suggest to use camelCase ids for it, though).
Related
I have written this test class for javafx application.
class HelloApplicationTest extends GuiTest {
#Override
protected Parent getRootNode() {
Parent parent = null;
try {
parent = FXMLLoader.load((getResource("hello-view.fxml")));
return parent;
}
catch (IOException ex) {
}
return parent;
}
#Test
void add_button() {
Button add_btn_1=find("#add_btn");
assertFalse(add_btn_1.disableProperty().get());
FxAssert.verifyThat("#add_btn", LabeledMatchers.hasText("Add"));
}
}
I am getting error like this -> java.lang.NoSuchMethodError: 'java.util.Iterator javafx.stage.Window.impl_getWindows()'
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="350.0" prefWidth="666.0" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.fxml_db.HelloController">
<children>
<Label layoutX="14.0" layoutY="14.0" prefHeight="39.0" prefWidth="295.0" text="Add and View Employee:">
<font>
<Font name="System Bold" size="24.0" />
</font>
</Label>
<Label layoutX="22.0" layoutY="93.0" prefHeight="27.0" prefWidth="124.0" text="Name:" />
<Label layoutX="22.0" layoutY="136.0" prefHeight="27.0" prefWidth="124.0" text="Address:" />
<Label layoutX="22.0" layoutY="181.0" prefHeight="27.0" prefWidth="124.0" text="Age:" />
<TextField fx:id="name" layoutX="106.0" layoutY="94.0" />
<TextField fx:id="address" layoutX="106.0" layoutY="137.0" />
<TextField fx:id="age" layoutX="106.0" layoutY="182.0" />
<Button fx:id="add_btn" layoutX="127.0" layoutY="223.0" mnemonicParsing="false" onAction="#add_details" text="Add" />
<TableView fx:id="table" layoutX="342.0" layoutY="51.0" prefHeight="260.0" prefWidth="305.0">
<columns>
<TableColumn fx:id="idcol" prefWidth="39.33331298828125" text="ID" />
<TableColumn fx:id="namecol" prefWidth="111.3333740234375" text="Name" />
<TableColumn fx:id="addresscol" prefWidth="110.00003051757812" text="Address" />
<TableColumn fx:id="agecol" prefWidth="40.6666259765625" text="Age" />
</columns>
</TableView>
<Button fx:id="connect_db" layoutX="14.0" layoutY="310.0" mnemonicParsing="false" onAction="#connect" text="Connect DB" />
<Button layoutX="200.0" layoutY="223.0" mnemonicParsing="false" onAction="#clear_data" text="Clear" />
</children>
</AnchorPane>
I am not able to fetch the components form the .fxml file. this is my .fxml code
Trying Kendo UI JSP editable grid. Grid is working with few problems.
(Version : Kendo UI v2015.3.1111 )
Export: Even with allPages="allPages", its exporting only current
page.
After CREATE, GRID is not updated with server response which has user createDate. Same with Update, grid not updated with update date
even though the updated user object is passed.
Grid shows user added even if it failed in the backend. How to handle error response for create /update and show the failed message ?
Any help greatly appreciated.
Controller create part:
#RequestMapping(value = "/user/create", method = RequestMethod.POST)
public #ResponseBody User create(#RequestBody Map<String, Object> model) {
log.debug("create");
User target = new User();
target.setUserName((String)model.get("UserName"));
target.setFirstName((String)model.get("firstName"));
target.setLastName((String)model.get("lastName"));
target.setOpenDate(getDateFromStr((String)model.get("openDate")));
target.setEditDate(getDateFromStr((String)model.get("editDate")));
User user = userDao.createUser(target);
log.info("user"+user.getUserId()+user.getOpenDate());
return user;
}
JSP PART:
<c:url value="/user/create" var="createUrl" />
<c:url value="/user/read" var="readUrl" />
<c:url value="/user/update" var="updateUrl" />
<c:url value="/user/destroy" var="destroyUrl" />
<c:url value="/user/saveexcel" var="saveExcelUrl" />
<c:url value="/user/savepdf" var="savePdfUrl" />
<kendo:grid name="grid" pageable="true" sortable="true" height="750px" filterable="true">
<kendo:grid-scrollable/>
<kendo:grid-pdf fileName="KendoUIGridExport.pdf" allPages="allPages" proxyURL="${savePdfUrl}"/>
<kendo:grid-excel fileName="KendoUIGridExport.xlsx" allPages="allPages" proxyURL="${saveExcelUrl}" />
<kendo:grid-editable mode="popup" confirmation="Are you sure you want to remove this item?"/>
<kendo:grid-toolbar>
<kendo:grid-toolbarItem name="create"/>
<kendo:grid-toolbarItem name="excel"/>
<kendo:grid-toolbarItem name="pdf"/>
</kendo:grid-toolbar>
<kendo:grid-columns>
<kendo:grid-column title="User Name" field="userName" width="120px"/>
<kendo:grid-column title="First Name" field="firstName" width="120px" />
<kendo:grid-column title="Last Name" field="lastName" width="120px" />
<kendo:grid-column title="Open Date" field="openDate" width="120px" format="{0:MM/dd/yyyy}" />
<kendo:grid-column title="Edit Date" field="editDate" width="120px" format="{0:MM/dd/yyyy}" />
<kendo:grid-column title=" " width="150px">
<kendo:grid-column-command>
<kendo:grid-column-commandItem name="edit" />
<kendo:grid-column-commandItem name="destroy" />
</kendo:grid-column-command>
</kendo:grid-column>
</kendo:grid-columns>
<kendo:dataSource pageSize="10" serverPaging="false" serverSorting="false" serverFiltering="false" serverGrouping="false" >
<kendo:dataSource-transport>
<kendo:dataSource-transport-create url="${createUrl}" type="POST" dataType="json" contentType="application/json"/>
<kendo:dataSource-transport-read url="${readUrl}" type="POST" dataType="json" contentType="application/json"/>
<kendo:dataSource-transport-update url="${updateUrl}" type="POST" dataType="json" contentType="application/json" />
<kendo:dataSource-transport-destroy url="${destroyUrl}" type="POST" dataType="json" contentType="application/json" />
<kendo:dataSource-transport-parameterMap>
<script>
function parameterMap(options,type) {
return JSON.stringify(options);
}
</script>
</kendo:dataSource-transport-parameterMap>
</kendo:dataSource-transport>
<kendo:dataSource-schema>
<kendo:dataSource-schema-model id="userId">
<kendo:dataSource-schema-model-fields>
<kendo:dataSource-schema-model-field name="userName" type="string" >
<kendo:dataSource-schema-model-field-validation required="true" />
</kendo:dataSource-schema-model-field>
<kendo:dataSource-schema-model-field name="firstName" type="string">
<kendo:dataSource-schema-model-field-validation required="true" />
</kendo:dataSource-schema-model-field>
<kendo:dataSource-schema-model-field name="lastName" type="string">
<kendo:dataSource-schema-model-field-validation required="true" />
</kendo:dataSource-schema-model-field>
<kendo:dataSource-schema-model-field name="openDate" type="date" editable="false" />
<kendo:dataSource-schema-model-field name="editDate" type="date" editable="false"/>
</kendo:dataSource-schema-model-fields>
</kendo:dataSource-schema-model>
</kendo:dataSource-schema>
</kendo:dataSource>
</kendo:grid>
Resolved myself: For pdf, allPages="true" works.
Grid refresh: FOR requestEnd event
function onRequestEnd(e) {
if (e.type == "create") {
e.sender.read();
}
else if (e.type == "update") {
e.sender.read();
}
}
I am trying to add inside custom grid within template but I cannot see these links in output along with other grid data ....
<cc0:Grid ID="StaffItemList" runat="server" FolderStyle="~/Styles/Grid" AutoGenerateColumns="false"
Width="100%" PageSizeOptions="5,10,20,50,100,-1" AllowFiltering="true" FilterType="ProgrammaticOnly"
AllowAddingRecords="false">
<Columns>
<cc0:CheckBoxSelectColumn ShowHeaderCheckBox="true" Width="50" ControlStyle-CssClass="UserInRoleGrid"></cc0:CheckBoxSelectColumn>
<cc0:Column DataField="id" HeaderText="ID" Visible="true" />
<cc0:Column DataField="loginid" HeaderText="loginid" Width="150" />
<cc0:Column DataField="forenames" HeaderText="forenames" />
<cc0:Column DataField="surnames" HeaderText="surnames" />
<cc0:Column DataField="gender" HeaderText="gender" />
<cc0:Column DataField="email" HeaderText="email" />
<cc0:Column DataField="deleted" HeaderText="deleted" />
</Columns>
<Templates>
<cc0:GridTemplate runat="server" ID="AddUserToRoleLink">
<Template>
addRole
</Template>
</cc0:GridTemplate>
</Templates>
</cc0:Grid>
I have found asnswer; code as following....
<cc0:Grid ID="StaffItemList" runat="server" FolderStyle="~/Styles/Grid" AutoGenerateColumns="false"
Width="100%" PageSizeOptions="5,10,20,50,100,-1" AllowFiltering="true" FilterType="ProgrammaticOnly"
AllowAddingRecords="false">
<Columns>
<cc0:Column DataField="id" HeaderText="ID" Visible="true"/>
<cc0:Column DataField="loginid" HeaderText="loginid" Width="150" />
<cc0:Column DataField="forenames" HeaderText="forenames" />
<cc0:Column DataField="surnames" HeaderText="surnames" />
<cc0:Column DataField="gender" HeaderText="gender" />
<cc0:Column DataField="email" HeaderText="email" />
<cc0:Column DataField="deleted" HeaderText="deleted" />
<cc0:Column DataField="Functions" HeaderText="deleted" >
<TemplateSettings TemplateId="AddUserToRoleControl"/>
</cc0:Column>
</Columns>
<Templates>
<cc0:GridTemplate runat="server" ID="AddUserToRoleControl">
<Template>
Add Role
</Template>
</cc0:GridTemplate>
</Templates>
</cc0:Grid>
jQuery
<script type="text/javascript">
$(document).ready(function () {
$(".AddStaffToRoleLink").on("click", function () {
var selectedStaffID = $(this).attr("id");
alert("this is " + selectedStaffID);
});
});
</script>
Title sounds like a real mouthful, so let me try to explain this. I'm very strong with grinding out Web Forms and this is my second crack at using a framework and MVC (don't ask about the first one). Start with a table like this:
Title: Milestones
Id int - Auto, PK
Project_Id int - FK, Many Milestones to One Project, Provided static for now
Number int
Name varchar(50)
Status_Id int - FK One Status to One Milestone
PlannedDate date
LatestEstimate date
MilestoneType_ID int - FK One Type to One Milestone
These all sit on an SQL server, are pulled in by an Entity and then are pulled in by an ObjectDataSource, like this:
<asp:ObjectDataSource runat="server" ID="MilestonesObjectSource" SelectMethod="GetByProject"
DeleteMethod="DeleteMilestone" TypeName="TCProjectManagement.Models.MilestonesAddition">
<SelectParameters>
<asp:Parameter DefaultValue="6" Name="ProjectID" Type="Int32" />
</SelectParameters>
<DeleteParameters>
<asp:Parameter Type="Int32" Name="Id" />
</DeleteParameters>
<UpdateParameters>
<asp:Parameter Type="Int32" Name="Id" />
<asp:Parameter Type="Int32" Name="Number" />
<asp:Parameter Type="String" Name="Name" />
<asp:Parameter Type="Int32" Name="Status_Id" />
<asp:Parameter Type="DateTime" Name="PlannedDate" />
<asp:Parameter Type="DateTime" Name="LatestEstimate" />
<asp:Parameter Type="Int32" Name="MilestoneType_ID" />
</UpdateParameters>
</asp:ObjectDataSource>
Sofar so good. Data pull seems to work out okay. I've got a couple more Object Sources that deal exclusively with the Foriegn Keys, so I'll skip those since they seem to be working.
The problems I have are attempting to stitch together many examples that don't seem to go together well. My objectives, in no paticular order:
1) Pin Editing: Click a button to edit, click it again to confirm. Rather do this than have somebody infer to double click for a change. Sofar, this sorta works.
2) Drop Downs for Foriegn Keys: While not in edit mode, should display the "Name" field of the FK. While in edit it should be a Drop Down for options (there's only three). This stays blank dispite what I do.
3) Deletion: Press a button to blow away a row. I put the button there but it's a copy of the JS for editing. What do I need to use to have it be deletion?
4) Dates: This doesn't work at all. One of the weird parts is that from the SQL server's type of Date, it gets changed to DateTime in the Entity and stays that way throughout. However, I cannot get the desired control of ext:DateField to cooperate with the provided data since it displays a time and completely blanks out when editing.. I know I'm doing something wrong here.
5) Saving Changes: Not quite sure I set it up right (or at all).
Provisions of Javascript:
<script type="text/javascript">
var pinEditors = function (btn, pressed) {
var columnConfig = btn.column,
column = columnConfig.column;
if (pressed) {
column.pinOverComponent();
column.showComponent(columnConfig.record, true);
} else {
column.unpinOverComponent();
column.hideComponent(true);
}
};
var pinDeleters = function (btn, pressed) { };
</script>
And ASP Code:
<ext:GridPanel ID="MilestonesGridPanel" runat="server" Title="Milestones" Width="1000px"
Height="300px">
<Store>
<ext:Store ID="MilestonesGridStore" runat="server" DataSourceID="MilestonesObjectSource">
<Model>
<ext:Model runat="server" IDProperty="Id">
<Fields>
<ext:ModelField Name="Id" Type="Int" />
<ext:ModelField Name="Number" Type="Int" />
<ext:ModelField Name="Name" Type="String" />
<ext:ModelField Name="Status_Id" Type="Int" />
<ext:ModelField Name="PlannedDate" />
<ext:ModelField Name="LatestEstimate" />
<ext:ModelField Name="MilestoneType_ID" Type="Int" />
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<ColumnModel>
<Columns>
<ext:Column ID="IdColumn" runat="server" DataIndex="Id" Text="DBID" Visible="false" />
<ext:ComponentColumn ID="NumberColumn" runat="server" DataIndex="Number" OverOnly="true"
Pin="true" Flex="1" Text="Number" Editor="true">
<Component>
<ext:NumberField ID="NumberColumnNumberField" runat="server" />
</Component>
</ext:ComponentColumn>
<ext:ComponentColumn ID="NameColumn" runat="server" DataIndex="Name" OverOnly="true"
Pin="true" Flex="1" Text="Name" Editor="true">
<Component>
<ext:TextField ID="NameColumnTextField" runat="server" />
</Component>
</ext:ComponentColumn>
<ext:ComponentColumn ID="StatusColumn" runat="server" DataIndex="Status_Id" OverOnly="true"
Pin="true" Flex="1" Text="Status" Editor="true">
<Component>
<ext:ComboBox ID="StatusColumnDropDownBox" runat="server" QueryMode="Local" Editable="false"
StoreID="MilestoneStatusStore" DisplayField="Name" ValueField="ID" EmptyText="Empty" />
</Component>
</ext:ComponentColumn>
<ext:ComponentColumn ID="PlannedDateColumn" runat="server" DataIndex="PlannedDate"
OverOnly="true" Pin="true" Flex="1" Text="Planned Date" Editor="true">
<Renderer Format="Date" FormatArgs="'m/d/y'" />
<Component>
<ext:DateField ID="PlannedDateColumnTextField" runat="server" Format="MM/dd/yyyy"
EmptyText="Empty" />
</Component>
</ext:ComponentColumn>
<ext:ComponentColumn ID="LatestEstimateColumn" runat="server" DataIndex="LatestEstimate"
OverOnly="true" Pin="true" Flex="1" Text="Latest ETA" Editor="true">
<Renderer Format="Date" FormatArgs="'m/d/y'" />
<Component>
<ext:DateField ID="LatestEstimateColumnTextField" runat="server" Format="MM/dd/yyyy"
EmptyText="Empty" />
</Component>
</ext:ComponentColumn>
<ext:ComponentColumn ID="MilestoneTypeColumn" runat="server" DataIndex="MilestoneType_ID"
OverOnly="true" Pin="true" Flex="1" Text="Milestone Type" Editor="true">
<Component>
<ext:ComboBox ID="MilestoneTypeColumnComboBox" runat="server" QueryMode="Local" Editable="false"
StoreID="MilestoneTypesStore" DisplayField="Name" ValueField="ID" EmptyText="Empty" />
</Component>
</ext:ComponentColumn>
<ext:ComponentColumn ID="EditColumn" runat="server" Width="30" PinAllColumns="false"
AutoWidthComponent="false" OverOnly="true" Text="Edit" Sortable="False">
<Component>
<ext:Button ID="EditButton" runat="server" ToolTip="Pin Editors" Icon="Pencil" AllowDepress="true"
EnableToggle="true" Width="25">
<Listeners>
<Toggle Fn="pinEditors" />
</Listeners>
</ext:Button>
</Component>
</ext:ComponentColumn>
<ext:ComponentColumn ID="DeleteColumn" runat="server" Width="30" PinAllColumns="false"
AutoWidthComponent="false" OverOnly="true" Text="Delete" Sortable="False">
<Component>
<ext:Button ID="DeleteButton" runat="server" ToolTip="Delete Milestone" Icon="Delete"
AllowDepress="true" EnableToggle="false" Width="25">
<Listeners>
<Click Handler="#{MilestonesGridStore}.remove(this.parentMenu.dataRecord)" />
</Listeners>
</ext:Button>
</Component>
</ext:ComponentColumn>
</Columns>
</ColumnModel>
<SelectionModel>
<ext:RowSelectionModel runat="server" Mode="Single">
<Listeners>
<Select Handler="#{DeleteMilestoneGridButton}.enable();" />
<Deselect Handler="if (!#{MilestonesGridPanel}.selModel.hasSelection()) {
#{DeleteMilestoneGridButton}.disable();
}" />
</Listeners>
</ext:RowSelectionModel>
</SelectionModel>
<Buttons>
<ext:Button ID="AddtoMilestoneGridButton" runat="server" Text="Insert" Icon="Add">
<Listeners>
<Click Handler="#{MilestonesGridStore}.insert(0, {}); #{MilestonesGridPanel}.editingPlugin.startEditByPosition({row:0, column:0});" />
</Listeners>
</ext:Button>
<ext:Button ID="DeleteMilestoneGridButton" runat="server" Text="Delete" Icon="Delete"
Disabled="true">
<Listeners>
<Click Handler="#{MilestonesGridPanel}.deleteSelected();
if (!#{MilestonesGridPanel}.hasSelection()) {
#{DeleteMilestoneGridButton}.disable();
}" />
</Listeners>
</ext:Button>
<ext:Button ID="RefreshMilestonesGridButton" runat="server" Text="RefresH" Icon="Reload">
<Listeners>
<Click Handler="#{MilestonesGridStore}.load();" />
</Listeners>
</ext:Button>
<ext:Button ID="SaveMilestoneGridButton" runat="server" Text="Save" Icon="Disk">
<Listeners>
<Click Handler="#{MilestonesGridStore}.sync();" />
</Listeners>
</ext:Button>
</Buttons>
</ext:GridPanel>
I used tabbox to create tabbed page. And each tab includes another zul page. I have 1 controller applied to main page.
If I add some action to component on included zul page, on controller class I cant catch it. If I apply controller to my zul then it creates new instance of controller class.
Here is my code.
<zk>
<style src="/resources/css/default.css" />
<window id="Dealer" class="index"
apply="com.i2i.prm.controller.IndexController" width="100%"
height="100%">
<div class="content" >
<tabbox id="tb" width="100%" forward="onSelect=onSelect">
<tabs id="tabs">
<tab id="info" label="INFO" />
<tab id="create" label="CREATE" />
<tab id="edit" label="EDIT" />
</tabs>
<tabpanels>
<tabpanel id="DealerInfo">
<include id="DealerInfoContent" src="View/Dealer/DealerInfo.zul" />
</tabpanel>
<tabpanel id="DealerCreate">
<include id="DealerCreateContent" src="View/Dealer/DealerCreate.zul" />
</tabpanel>
<tabpanel id="DealerEdit">
<include id="DealerEditContent" src="View/Dealer/DealerEdit.zul" />
</tabpanel>
</tabpanels>
</tabbox>
</div>
</window>
</zk>
And dealerEdit.zul
<zk>
<window title="Dealer Edit" >
<grid width="100%" sizedByContent="true">
<columns>
<column label="" />
</columns>
<rows>
<row >
<label value="Name"></label>
<textbox
value="#{DealerController.user.name }">
</textbox>
</row>
<row>
<label value="Surname"></label>
<textbox
value="#{DealerController.user.surname }" forward="onChange=onASD">
</textbox>
</row>
<row>
<label value="Address"></label>
<textbox
value="#{DealerController.user.address }">
</textbox>
</row>
</rows>
</grid>
</window>
</zk>
This is my controller (IndexController.java) class:
public class IndexController extends GenericForwardComposer {
private User user = new User();;
AnnotateDataBinder binder;
Tabbox tb;
#Override
public void doAfterCompose(Component comp) throws Exception {
// TODO Auto-generated method stub
super.doAfterCompose(comp);
comp.setAttribute(comp.getId() + "Controller", this);
binder = new AnnotateDataBinder(comp);
user.setName("Abdul");
user.setSurname("Rezzak");
user.setAddress("Giderken sağda");
binder.loadAll();
}
public IndexController() {
// TODO Auto-generated constructor stub
}
public void onDFG(ForwardEvent event){
System.out.println(this.hashCode());
}
public void onASD(ForwardEvent event){
System.out.println(this.hashCode());
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
remove <window title="Dealer Edit" > from your included page (DealerEdit.zul) as it forms its own IdSpace. Don't forget to remove the closing </window> tag.
change your onASD method name to include your Include component id i.e. onASD$DealerEditContent. It seems Include also form its own IdSpace and forward event does not work across IdSpace
This should work.
UPDATE 1: I just confirmed that Include is an IdSpace owner component as it implements IdSpace interface so this is the only workaround in your case.
UPDATE 2: I found one more easier way to deal with forwarding events across different IdSpace which is to use component Path within ZUML file for specifying target component. For example in your case you can specify page id in main.zul page
<?page id="main" ?>
and while forwarding event in your included page such as DealerEdit.zul page
<textbox forward="onChange=//main/Dealer.onASD" />
Rest of the code will remain the same.
Reference: http://books.zkoss.org/wiki/ZK_Developer%27s_Reference/Event_Handling/Event_Forwarding#Using_component_Path