My zkoss code is not binding the value from java method.
<window border="normal" id="home"
apply="com.test.HomeController">
<caption label="#{home.name}"></caption>
<button label="text"></button>
</window>
public class HomeController extends GenericForwardComposer{
public String getName() {
return "MY ZKOSS";
}
}
The window caption is not showing MY ZKOSS . can any one tell me what is the issue?
ZK can use the MVVM pattern.
<window id="win" apply="org.zkoss.bind.BindComposer" viewModel="#id('vm') #init('myController')">
<caption label="#load(vm.myText)"></caption>
</window>
public class myController {
private String name = "MY ZKOSS";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
ZK Developer Reference - MVVM
value binding through getter for a controller extending from GenericForwardComposer will work with EL expression like label="${$composer.name}"
The kind of data binding you are trying to use will work if controller is extending from component base class for eg HomeController extends from Window instead of GenericForwardComposer. For this to work change apply to use like shown below
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>
<window border="normal" id="home" use="com.test.HomeController">
<caption label="#{home.name}"></caption>
<button label="text"></button>
</window>
This may help you.
Controller:
package foo;
import org.zkoss.zk.ui.select.SelectorComposer;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zk.ui.select.annotation.Listen;
import org.zkoss.zul.*;
public class MyComposer extends SelectorComposer<Window> {
#Wire
Textbox input;
#Wire
Label output;
#Listen("onClick=#ok")
public void submit() {
output.setValue(input.getValue());
}
#Listen("onClick=#cancel")
public void cancel() {
output.setValue("");
}
}
And in your zul:
<window apply="foo.MyComposer">
<div>
Input: <textbox id="input" />
</div>
<div>
Output: <label id="output" />
</div>
<button id="ok" label="Submit" />
<button id="cancel" label="Clear" />
</window>
the member fields input, output are automatically assigned with components with identifiers of "input" and "output", respectively. The methods submit() and cancel() will be called when user clicks on the corresponding buttons.
http://books.zkoss.org/wiki/ZK_Developer%27s_Reference/MVC/Controller/Composer#Custom_Controller
Related
I have a xamarin forms application. It has a tabbedpage within it multiple tabs. The tabbedpage and te tabs, each of them has their own viewmodel as a bindingcontext.
In the app.xaml I defined a controltemplate. I use this control template in each tab, because I want each of those tabs to have a button at the bottom of the page.
At this moment: the button in the controltemplate binds with a property defined in each tab. But I want the button to bind at one place. Isn't it possible to create a viewmodel special for the controltemplate and bind the button defined in the controltemplate with that viewmodel?
Current code:
<ControlTemplate x:Key="ActivityStatusButton">
<StackLayout>
<ContentPresenter>
</ContentPresenter>
<StackLayout VerticalOptions="EndAndExpand" HorizontalOptions="Fill" Padding="15">
<Button Style="{StaticResource RedBackGroundWithWhiteTextButtonStyle}" Command="{TemplateBinding BindingContext.ClickOnStatusButton, Mode=TwoWay}" Text="{TemplateBinding BindingContext.ok, Mode=TwoWay}"></Button>
</StackLayout>
</StackLayout>
</ControlTemplate>
A typical tab:
<ContentPage ...>
<ContentPage.Content>
<Label Text="hello"></Label>
</ContentPage.Content>
<!--The control template is placed here (the button) -->
You could create a Custom Control (a subclass of ContentView) like
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Name="template"
x:Class="App24.MyControlTemplate">
<ContentView.Content>
<StackLayout VerticalOptions="EndAndExpand" HorizontalOptions="Fill" Padding="15">
<Button Clicked="Button_Clicked" Command="{Binding Source={x:Reference template},Path=ButtonCommand}" Text="{Binding Source={x:Reference template},Path=ButtonText}" CommandParameter="{Binding Source={x:Reference template},Path=CommandParameter}" />
</StackLayout>
</ContentView.Content>
</ContentView>
using System;
using System.Windows.Input;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace App24
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MyControlTemplate : ContentView
{
public event EventHandler ButtonClick;
public static readonly BindableProperty ButtonTextProperty =
BindableProperty.Create("ButtonText", typeof(string), typeof(MyControlTemplate), default(string));
public string ButtonText
{
get => ((string)GetValue(ButtonTextProperty));
set => SetValue(ButtonTextProperty, value);
}
public static readonly BindableProperty ButtonCommandProperty =
BindableProperty.Create("ButtonCommand", typeof(ICommand), typeof(MyControlTemplate), null, BindingMode.Default, null);
public ICommand ButtonCommand
{
get => (ICommand)GetValue(ButtonCommandProperty);
set
{
SetValue(ButtonCommandProperty, value);
}
}
public static readonly BindableProperty CommandParameterProperty =
BindableProperty.Create("CommandParameter", typeof(object), typeof(MyControlTemplate), null);
public object CommandParameter
{
get => (object)GetValue(CommandParameterProperty);
set => SetValue(CommandParameterProperty, value);
}
public MyControlTemplate()
{
InitializeComponent();
}
private void Button_Clicked(object sender, EventArgs e)
{
ButtonClick?.Invoke(sender, e);
}
}
}
Now you could add it to any page and binding Text , Command or CommandParameter in code behind .
<StackLayout VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
<local:MyControlTemplate ButtonText="{Binding ButtonText}" ButtonCommand="{Binding ClickCommand}" CommandParameter="test" />
</StackLayout>
I'm trying to get to grips with kendo binding in MVVM.
I have a Razor page that looks like this...
Index.cshtml
#page
#model IndexModel
#{
ViewData["Title"] = "Index";
}
<div id="frm">
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
<div class="form-group">
<label><input type="text" class="form-control" data-bind="value: Username"/></label>
</div>
<button type="submit" class="btn btn-primary">Click</button>
}
<label>
<input type="text" class="form-control" data-bind="value: Username" />
</label>
</div>
<script>
var raw = #Html.Raw(Model.Me.ToJson());
var vm = new kendo.observable(raw);
kendo.bind($("#frm"), vm);
</script>
Index.cshtml.cs...
public class IndexModel : PageModelBase
{
[BindProperty]
public Person Me { get; set; }
public void OnGet()
{
Me = new Person { Username = "Bobby Brown" };
}
public void OnPost()
{
var p = Me;
p.Username += ".";
}
public class Person
{
public string Username { get; set; }
public string ToJson() => JsonConvert.SerializeObject(this);
}
}
When I render the page, the 2 inputs are, properly bound to the passed in value from the server-side model.
When I change the value in one of the inputs client-side and change focus, the other input changes.
I expect all of this.
When I click the button, the control returns to the server and executes the code in OnPost().
What doesn't happen is for Me to be set to something other than null.
I've tried it as is shown above,
I've tried refactoring the OnPost() method to OnPost(Person me) but me isn't set.
I've tried assessing the Request.Form object but there is nothing there.
I'm sure it must be simpler than I'm trying to make it.
Can anyone offer any advice about that I'm doing wrong, please?
Basically, I'm dim.
I worked it out. I was trying to fit a square peg into a round hole.
I added a hidden input in the form with the name Me to match the property name I was binding to.
I changed the button to a regular button (from a submit button) and added an onClick handler that did this...
function submitForm() {
$("#Me").val({ Username: vm.get("Username") });
$("#frm").submit();
}
And "lo, there was light".
Thanks for listening
This is the Parent HTML
<parent-component>
<child></child>
<button type="submit" [disabled]="!childForm.valid">
</parent-component>
This is Child HTML
<child>
<form #childform=ngform>
<input required type="text">
</form>
</child>
I need to access the childform status in the parent component
Child template:
<form #childform=ngForm>
<input required type="text">
</form>
Child component:
export class ChildComponent implements OnInit {
#Output() validityChange = new EventEmitter<boolean>();
#ViewChild('childform') form: NgForm;
private validStatus: boolean;
ngOnInit() {
if (!this.form) return;
this.form.valueChanges
.subscribe(_ => {
if(this.validStatus !== this.form.valid) {
this.validStatus = this.form.valid;
this.validityChange.emit(this.form.valid);
});
}
}
Parent template:
<child (validityChange)="childFormValid = $event"></child>
<button type="submit" [disabled]="!childFormValid">
Parent component:
export class ChildComponent implements OnInit {
private childFormValid: boolean;
...
}
Probably you could do it using #ViewChild:
Child component template file:
<form #form="ngForm">
<input type="text" ngModel required name="input">
</form>
and use #ViewChild in child component TS file like this:
#ViewChild('form') form: NgForm;
Parent component template file:
<button type="submit" *ngIf="childForm" [disabled]="!childForm.valid">Submit</button>
and in your parent component TS file reference to child component as well:
export class ParentComponent implements AfterViewInit {
#ViewChild('child') child: ChildComponent;
public childForm;
ngAfterViewInit(): void {
this.childForm = this.child.form.form;
}
}
Use an output
<child (myOutput)="myFunction($event)"></child>
In your parent component :
myFunction(event: Event) {
console.log(event); // hello world
}
In your child component
import { Output, EventEmitter } from '#angular/core';
// ...
#Output() myOutput: new EventEmitter();
doSomething() {
thisMyOutput.emit('hello world');
}
Child Component
export class ChildparentComponent implements OnInit {
#Output() toParent = new EventEmitter<string>();
constructor() { }
onChange(value:string){
this.toParent.emit(value);
}
In Child Html
<app-childparent (toParent)="childValue = $event"></app-childparent>
In Parent
Access this child value in parent template like {{childValue}}
A working example of the Same
https://rahulrsingh09.github.io/AngularConcepts/#/inout
Its Backend Code
https://github.com/rahulrsingh09/AngularConcepts/blob/master/src/app/parentchild/parentchild.component.html
I have three forms in one page, each calls a different backing bean, but when i use a form other than the first one the call goes three times to the first form, each form persists into a DB.Table and the persistence is being done three times when i click the commandButtons, is this bad practice or am I missing something in my code ?
<h:form id="ciclista-form" >
<div id="ciclista-link"><h1>Crear Ciclista</h1></div>
// inputTexts ... .. .
<h:commandButton action="#{ciclistaBean.guardarCiclista()}" value="Guardar Ciclista" class="ciclista-form-btn"/>
</h:form>
<h:form id="Etapa-form" > Etapa-form -->
<div id="Etapa-link"><h1>Crear Etapa</h1></div> -->
// input texts . ..
<h:commandButton action="#{etapaBean.guardarEtapa()}" value="Guardar Etapa" class="carrera-form-btn"/> -->
</h:form> Etapa-form -->
<h:form id="carrera-form" > <!-- carrera-form -->
<div id="carrera-link"><h1>Crear carrera</h1></div>
// input texts . . .
<h:commandButton action="#{carreraBean.guardarCarrera()}" value="Guardar Carrera" class="etapa-form-btn" />
</h:form> <!-- carrera-form -->
all calls go to first form, why is this ?
The snipped you show seems ok, what type are your beans? What scope do they have? Have they dependencies to another?
I tried to follow you idea with following code, it works in my setup...
<h:body>
<h:form id="ciclista-form">
<div id="ciclista-link">
<h1>Crear Ciclista</h1>
<h:inputText value="#{ciclistaBean.text}"/>
</div>
<h:commandButton action="#{ciclistaBean.guardarCiclista()}" value="Guardar Ciclista" class="ciclista-form-btn" />
</h:form>
<h:form id="Etapa-form">
<div id="Etapa-link">
<h1>Crear Etapa</h1>
<h:inputText value="#{etapaBean.text}"/>
</div>
<h:commandButton action="#{etapaBean.guardarEtapa()}" value="Guardar Etapa" class="carrera-form-btn" />
</h:form>
<h:form id="carrera-form">
<div id="carrera-link">
<h1>Crear carrera</h1>
<h:inputText value="#{carreraBean.text}"/>
</div>
<h:commandButton action="#{carreraBean.guardarCarrera()}" value="Guardar Carrera" class="etapa-form-btn" />
</h:form>
</h:body>
with three independend #RequestScoped beans
#ManagedBean(name = "ciclistaBean")
#RequestScoped
public class SO26836137_F1 {
private String text;
public void guardarCiclista() {
System.out.println("Form 1 submitted: " + text);
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
#ManagedBean(name = "etapaBean")
#RequestScoped
public class SO26836137_F2 {
private String text;
public void guardarEtapa() {
System.out.println("Form 2 submitted: " + text);
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
#ManagedBean(name = "carreraBean")
#RequestScoped
public class SO26836137_F3 {
private String text;
public void guardarCarrera() {
System.out.println("Form 3 submitted: " + text);
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
Today I am stuck with the spring-form with the POST method which doesn't give posted item to the Controller which I wanted. Here is my code.
Controller.java
#Controller
#RequestMapping("/cart")
public class CartController extends CommonController
{
#RequestMapping(value = "/add", method = RequestMethod.POST)
public ModelAndView addCart(#ModelAttribute("productList") Item item, BindingResult result,Model model){
System.out.println(item.getId()); /// <-- doesn't gives me the ID
return new ModelAndView("cart");
}
}
ProductList.jsp
/// Loop through the products of search itemlist and generates the forms with the correct items
<c:forEach var="item" items="${productList.items}" varStatus="status">
${item.name}
<div class="addCart">
<c:url value="/cart/add.html" var="addURL" />
<form:form method="POST" action="${addURL}" modelAttribute="productList">
<form:hidden path="items[${status.index}].id"/>
<input type="submit" class="addCartBtn" value="Add to cart" />
</form:form>
</div>
BackingBean.java
public class SearchForm implements Serializable
{
private Collection<Item> items;
private String term;
// getters and setters
}
The ${productList} is the backingbean which loops through all items.
I don't really know what the problem is why it isn't giving me the correct data it passed through the POST.
Many thanks.
Covert your spring:hidden tag to normal html hidden tag:
<form:hidden path="items[${status.index}].id"/>
to
<input type="hidden" name="id" value="${item.id}"/>