Zk included .zul page does not wotk with main controller - include

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

Related

How can I create a template / class that will allow me to simplify some my Xaml where there are multiple elements into just one?

Here's an example of what I need to do now. Sometimes I have one span, sometimes more.
Note that this post is similar to that of another question. For the other question I had only one comment to use a custom control with no more advice offered and one answer to use JavaScript. I tried to add a second bounty to that question but it gave me the option of only adding a bounty of 500 points. The question is now so old that I doubt anyone will see it any more and as I cannot add a bounty (unless it's 500 points) I cannot give it more visibility.
Here's what I would like to simplify:
<Label>
<Label.FormattedText>
<FormattedString>
<Span Text="Hello " />
<Span Text="Hello " />
<Span Text=" Some more text." />
</FormattedString>
</Label.FormattedText>
</Label>
Here's what I would like to do instead of typing in <Label><Label.FormattedText><FormattedString> I would like to get some way to do this with only entering in <template:FormattedLabel>
<template:FormattedLabel>
<Span Text="Hello " />
<Span Text="Hello " />
<Span Text=" Some more text." />
</template:FormattedLabel>
or
<template:FormattedLabel>
<Span Text="Hello " />
</template:FormattedLabel>
Note that I have looked into custom controls but as far as I see I cannot find a way to make these accept some inside content which in this case would be one or more spans.
I have an example of something similar which could perhaps be used but I am not sure how to apply it. What I was hoping for was a template like this in the XAML below which is does something similar to what I need but for content pages:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Japanese;assembly=J"
xmlns:t="clr-namespace:J.Templates"
x:Class="Japanese.Templates.ContentScrollable"
x:Name="ContentPage" >
<ContentPage.Content>
<t:Stack Orientation="Vertical">
<ScrollView x:Name="scroll">
<ContentView Content="{Binding Source={x:Reference ContentPage}, Path=InnerContent}"
Margin="{DynamicResource PageMargin}" />
</ScrollView>
</t:Stack>
</ContentPage.Content>
</ContentPage>
With its C# back end:
public partial class ContentScrollable : ContentPage
{
public static readonly BindableProperty InnerContentProperty = BindableProperty.Create(nameof(InnerContent), typeof(View), typeof(ContentScrollable));
public View InnerContent
{
get => (View)this.GetValue(InnerContentProperty);
set => this.SetValue(InnerContentProperty, value);
}
public ContentScrollable()
{
InitializeComponent();
}
}
How can I accomplish what I am looking for?
You can do the following:
<!-- FormattedLabel.xaml -->
<?xml version="1.0" encoding="UTF-8"?>
<Label
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="YourNamespaceForTemplates.FormattedLabel" />
// FormattedLabel.xaml.cs
[ContentProperty(nameof(Spans))]
public partial class FormattedLabel : Label
{
private readonly ObservableCollection<Span> _spans;
public IList<Span> Spans => _spans;
public FormattedLabel()
{
_spans = new ObservableCollection<Span>();
_spans.CollectionChanged += OnSpansChanged;
InitializeComponent();
}
private void OnSpansChanged(object sender, NotifyCollectionChangedEventArgs e)
{
FormattedText?.Spans?.Clear();
FormattedText = FormattedText ?? new FormattedString();
Spans.ForEach(FormattedText.Spans.Add);
}
}
Basically, in this extension of Label we define the content to be a list of Span items, which will allow you to define them in XAML inside <FormattedLabel></FormattedLabel>. To make it work, we pass these items down to this.FormattedText.Spans.
To use it:
<template:FormattedLabel>
<Span Text="Hello " />
<Span Text="Hello " />
<Span Text=" Some more text." />
</template:FormattedLabel>
I have just checked it and it works perfectly. I hope this helps!

JSP kendo grid EDIT /ADD Handle ERROR response from spring rest Kendo UI v2015.3.1111

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();
}
}

how to load model data from database to listbox in java zk project with mvc design pattern?

I am unable to load data from database to listbox in my zk project
I have this index.zul file with a listbox which cycles through a list of bank accounts
<listbox id="cashBankListBox" mold="paging"
emptyMessage="No voucher Found in the list" height="auto"
width="auto">
<listhead>
<listheader>Voucher Number</listheader>
<listheader>Voucher Date</listheader>
<listheader>Type</listheader>
<listheader>Currency</listheader>
<listheader>Rate</listheader>
<listheader>Cheque Number</listheader>
<listheader>Cheque Date</listheader>
<template name="model">
<listitem>
<listcell>
<label
value="${each.cashBankVoucherNumber}" />
</listcell>
<listcell>
<label value="${each.cashBankVoucherDate}" />
</listcell>
<listcell>
<label value="${each.cashBankType}" />
</listcell>
<listcell>
<label value="${each.cashBankCurrency}" />
</listcell>
<listcell>
<label value="${each.cashBankRate}" />
</listcell>
<listcell>
<label value="${each.cashBankChequeNo}" />
</listcell>
<listcell>
<label value="${each.cashBankChequeDate}" />
</listcell>
</listitem>
</template>
</listhead>
</listbox>
And I attached this Controller :
public class CashBankController extends SelectorComposer<Component> {
#Wire
private Listbox cashBankListBox;
CashBank cashBankObject = new CashBank(); //model class CashBank
//there is no problem with service layers..
private ICashBankService iCashBankService = CashBankServiceImpl.getInstance();
private ListModelList<CashBank> lst = (ListModelList<CashBank>) iCashBankService.getAllCashBank();
#SuppressWarnings({"rawtypes"})
#Override
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
cashBankListBox.setItemRenderer(new ListitemRenderer() {
#Override
public void render(Listitem item, Object arg1, int arg2) throws Exception {
CashBank value = (CashBank) arg1;
item.appendChild(new Listcell(value.getCashBankVoucherNumber()));
item.appendChild(new Listcell(value.getCashBankVoucherDate().toString()));
item.appendChild(new Listcell(value.getCashBankType()));
item.appendChild(new Listcell(value.getCashBankCurrency()));
// item.appendChild(new
// Listcell(value.getCashBankRate().toString()));
item.appendChild(new Listcell(value.getCashBankChequeDate().toString()));
item.appendChild(new Listcell(value.getCashBankChequeNo()));
item.setValue(value);
}
});
cashBankListBox.setModel(new ListModelList<CashBank>(lst));
}
}
The service layers seems to work fine
but I'm getting this error :
javax.servlet.ServletException: Filtered request failed.
org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:384)
org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
root cause
java.lang.ClassCastException: java.util.ArrayList cannot be cast to org.zkoss.zul.ListModelList
com.hmt.controller.CashBankController.<init>(CashBankController.java:76)
you cannot cast an ArrayList to ListModelList
to solve your problem change
private ListModelList<CashBank> lst = (ListModelList<CashBank>) iCashBankService.getAllCashBank();
with
private ListModelList<CashBank> lst = new ListModelList<CashBank>(iCashBankService.getAllCashBank());

External javascript call from Brightcove BEML

Is there any way to reference a custom javascript function from BEML? I'd like to keep away from Flash since what ever I do needs to work in the HTML5 player as well.
<Runtime>
<Layout width="800" height="600" id="backgroundTemplate">
<Canvas>
<VideoDisplay id="videoPlayer" width="788" height="487" x="9" y="13"/>
<MediaControls x="5" y="509" width="791" height="87" id="mediaControls">
<VBox>
<Canvas height="25" padding="20">
<Playhead mediaController="{videoPlayer}" autohideSlider="false" useTimeToolTip="true"/>
</Canvas>
<HBox padding="10">
<HBox id="leftBtn_container" hAlign="left">
<ToggleButton id="playButton" width="60" height="60" x="0" y="0" showBack="true" click="{videoPlayer.play()}" toggledClick="{videoPlayer.pause()}" toggled="{videoPlayer.playing}"/>
</HBox>
<HBox id="rightBtn_container" hAlign="right">
<Button width="60" height="60" id="cite_btn" click="{someFunction.doSomething()}"/>
</HBox>
</HBox>
</VBox>
</MediaControls>
</Canvas>
</Layout>
</Runtime>
You would need to create a custom component.Creating Custom Player Components
Call custom component in BEML.
<Modules>
<Module file="http://urltocustomcomponent.com/my_component.swf" />
</Modules>
Button in BEML
<ToggleButton id="my_button" width="40" height="40" />
Actionscript for custom component.
package
{
import com.brightcove.api.APIModules;
import com.brightcove.api.BrightcoveModuleWrapper
import com.brightcove.api.CustomModule;
import com.brightcove.api.modules.ExperienceModule;
import com.brightcove.api.events.BEMLMouseEvent;
import flash.events.Event;
import flash.external.ExternalInterface;
import com.brightcove.api.components.Button;
public class yogaComponent extends CustomModule
{
override protected function initialize():void
{
// Get the experience module
var experienceModule:ExperienceModule = player.getModule(APIModules.EXPERIENCE) as ExperienceModule;
// Define Info Button
var button:Button = experienceModule.getElementByID("my_button") as Button;
// Our listener that calls the function
button.addEventListener(BEMLMouseEvent.CLICK, myCustomFunc);
}
// Custom Function
private function myCustomFunc(event:Event):void
{
if(ExternalInterface.available)
{
// this calls a javascript function in your html
ExternalInterface.call('myJavascriptAlertFunction');
}
}
}
}
Javascript function that is called on event click.
function myJavascriptAlertFunction()
{
alert('it works!');
}

Zk how to reach included .zul page component by id?

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).

Resources