Unable to locate ajax zone for dynamic update - ajax

I'm fairly new to Tapestry, and I'm trying to update a zone when selecting a value from a select component. This is where I'm trying to do that:
<t:Zone t:id="ispTypeZone" id="ispTypeZone">
<t:Select t:id="ispType"
t:blankLabel="[${message:select-label}]" t:zone="ispTypeZone"
t:value="ispType" event="valueChangedFromIspType"
disabled="${editable}" style="width:515px;"
t:blankOption="ALWAYS" t:validate="required"
/>
</t:Zone>
<t:Zone t:id="selectionZone" id="selectionZone">
<t:If t:test="${somethingSelected}">
<t:If test="${ispSelected}">
<t:Zone t:id="ovZone" id="ovZone">
<t:Select t:id="ovType" t:value="ovType"
t:blankLabel="[${message:select-label}]" t:zone="ovZone"
t:validate="required" event="valueChangedFromOvType"
style="width:515px;" />
</t:Zone>
<p:else>
<t:Zone t:id="vpZone" id="vpZone">
<t:Select t:id="vpType" t:value="vpType"
t:blankLabel="[${message:select-label}]" t:zone="vpZone"
t:validate="required" event="valueChangedFromVpType"
t:blankOption="ALWAYS" disabled="${editable}"
style="width:515px;" />
</t:Zone>
</p:else>
</t:If>
<p:else>
</p:else>
</t:If>
</t:Zone>
This is where I call the render:
void onValueChangedFromIspType(String ispType) {
//some code here
if (request.isXHR()) {
ajaxResponseRenderer.addRender(selectionZone);
}
}
Whatever the value selected from the select component, it triggers a render for selectionZone, but I keep getting an error message "Unable to locate Ajax Zone 'selectionZone' for dynamic update". Despite the error message, 'somethingSelected' is still being executed, but the following select components are not being displayed. I can't seem to find the problem, so if anyone could point me in the right direction, I would appreciate it.
Thanks.

If your ispType select change have to update something in selectionZone, then t:zone should selectionZone and not ispTypeZone.
In your class, declare your zone :
#InjectComponent
private Zone selectionZone;
In your onValueChange method a simple return should be enough :
void onValueChangedFromIspType(String ispType) {
//some code here
if (request.isXHR()) {
return this.selectionZone;
}
}

Related

ActionSupport not getting triggered

My action support is not getting triggered at all when I put it in my VF page. I looked at similar problems and changing the events but nothing seems to be doing the trick.
//suppose my object is called coffecup. This is a generic code, there may be small syntax error although probably not the problem.The rerender attribute rerenders coloumns on the pageblock table holding the coffecupSize and coffecupshape fields.The debug log shows that the setCoffeeCupSizeandShape method is not being entered at all
VF
<apex:column rendered="{!ifaccesible}">
<apex:facet name="header">Coffee Cup Colours</apex:facet>
<apex:outputField value="{!coffecup.colours}"> //A lookup field on the custom object
<apex:actionSupport event="onchange" action="{!setCoffeeCupSizeandShape}" rerender="coffecupSize, coffecupShape" />
<apex:inlineEditSupport />
</apex:outputField>
</apex:column>
Controller
public void setCoffeeCupSizeandShape
{
if (coffecup.colour == red)
CoffeeCupSize = large;
coffeeCupShape = round;
}
apex:outputField has no onchange event support. You need to use apex:inputField.
If you need apex:outputField here, look at this answer

ZK - EventQueue working, but data not refreshing

Ok, so I have spent way too much time on this already, but it is really bugging me! So, I have a page with a bunch of tabs on it. To keep things manageable, I want to turn each of those tabs into their own .zul page with their own ViewModel. I have implemented an EventQueue in order to pass the main object (the Tournament object) from the main page to all of the sup-pages.
The problem is, whenever the event is fired and it updates the Tournament object, the page will not refresh its data even though it has changed in the ViewModel. I have tried adding the #NotifyChange annotation with no success. While debugging, I have eliminated the extra .zul. See code below.
tournamentsTab.zul:
<tabpanel apply="org.zkoss.bind.BindComposer" viewModel="#id('bcvm') #init('com.cannon.tnt.trm.mvvm.BeltClassViewModel')">
<vlayout vflex="1">
<grid model="#load(bcvm.tournament.beltClasses)" emptyMessage="No belt ranks created yet." vflex="1">
<columns>
<column label="Name" align="center" width="200px"/>
<column label="Description" align="center"/>
<column label="Delete" align="center" width="120px"/>
</columns>
<template name="model">
<row>
<textbox value="#bind(each.name)" width="95%" onChanging="#command('setStateEditing')"/>
<textbox value="#bind(each.description)" width="95%"
onChanging="#command('setStateEditing')"/>
<button label="Delete" onClick=""/>
</row>
</template>
</grid>
</vlayout>
<!--<include src="beltClassPanel.zul"/>-->
</tabpanel>
BeltClassViewModel.java:
public class BeltClassViewModel {
private EventQueue eq;
private Tournament tournament;
#Init
public void init() {
eq = EventQueues.lookup("tournamentQueue");
eq.subscribe(new EventListener() {
public void onEvent(Event event) throws Exception {
setTournament((Tournament) event.getData());
}
});
}
public Tournament getTournament() {
return tournament;
}
#NotifyChange("{tournament}")
public void setTournament(Tournament selectedTournament) {
this.tournament = selectedTournament;
}
}
As I mentioned, the EventQueue part is working perfectly. The event is being fired and then received by the listener who makes the call to set the tournament object on the view model. The problem is, the referenced tournament object is not being updated in the UI. I have put a break point in the getTournament() call and verified that the ONLY time that gets called is when the page first loads.
PLEASE HELP!!! I know that usually these things are just something stupid I'm overlooking. Please prove my idiocy! :)
I suppose that you need to post notification manually, you can try something like this:
public void onEvent(Event event) throws Exception {
setTournament((Tournament) event.getData());
BindUtils.postNotifyChange(null, null, BeltClassViewModel.this, "tournament");
}
Eugene found the problem. A simple mistake. I had #NotifyChange("{tournament}") when it should have been #NotifyChange({"tournament"}). Thanks, Eugene and Stack Overflow!

play 2.0 form date validation fail

I'm using "Play 2.0"-Framework (v. 2.0.1) and running into some troubles with form validation of a date value.
Peace of my Model code:
#Entity
public class Appointment extends Model {
public Date start;
public Date end;
}
Peace of my template code:
<input type="text" id="start" name="start" placeholder="yyyy-mm-dd" />
<!-- ALSO tested with chrome beta v. 20 with html5 support-->
<input type="date" id="end" name="end" placeholder="yyyy-mm-dd" />
My Controller:
public class Appointment extends Controller {
static Form<Appointment> appointmentForm = form(Appointment.class);
//on calling form page
public static Result create() {
return ok(create.render("create", appointmentForm));
}
//called on saving form data
public static Result save() {
Form<Appointment> filledForm = appointmentForm.bindFromRequest();
if (filledForm.hasErrors()) {
return badRequest(
create.render("create", filledForm)
);
} else {
Appointment.create(filledForm.get());
return redirect(routes.Appointment.index());
}
}
}
If I select a date via jquery ui datepicker or type in myself in a format like "yyyy-mm-dd" or doesn't matter, but must be correct format I run into a validation error in my controller save()-method with the check "filledForm.hasErrors()" and the error message "wrong date format".
I thought it would be converted automatically from play, so that I don't have to add a convertion by my self. What can I do to solve this problem? Is it still an issue from play 2.0?
Thanky you.
Cheers,
Marco
I think you must define the format of the date. See Play Framework 2.0: Custom formatters for custom formatters. Perhaps a custom binder is necessary see https://groups.google.com/d/topic/play-framework/Xi2xAiCnINs/discussion
Just as some hints to give you a direction. Hopefully someone can give you a better answer.

How to save checkbox checked values in Database [duplicate]

I have a simple mvc project consisting of one table named Persons and that table has some attributes like name, age, surname and so on.
I Recently added an attribute to table which is type of bit in SQL and bool in C# and for me it represents some status. If it is ok I put that status to true or false.
In one controller I create an index view of my Persons in the database and I display the status as a checkbox. That is working ok. What I want to do is to change the status if I click on that checkbox instead of using an edit view for all of the atributes.
I just want to save checkbox value from my index view to database.
Some people advised me to create an action in my controller like so:
public ActionResult Save(int id, bool status){}
Where id is id of my person in db and status is a value of the checkbox I clicked.
So how do I call that function with jquery, ajax or javascript and send those params?
I am not so good with ajax and a little bit afraid of it :)
And one more thing I manage to show checkbox value corectly from my databse only in this way:
#Html.CheckBox("somename", item.Status)
<input name="somename" type="hidden" value="false"/>
Any help or advice or sending me to good direction is good!
You have several options. One way would be to place the checkboxes in a (normal) form and then use the jQuery Form plugin to Ajaxify the form:
#using(Html.BeginForm()) {
#Html.Checkbox(...)
}
<script type="text/javascript">
$(document).ready(function () {
$('form').ajaxForm({
success: Saved,
error: HandleError
});
});
function Error(response, status, err) {
// code to handle error here
}
function Saved(responseText, statusText, xhr, $form) {
// code to handle succes, if any
}
</script>
You could, of course, use an #Ajax.BeginForm as well, but this has the advantage of being easily downgradable. Just remove the jQuery form initialisation and you got yourself a regular form : )
Another possibility is to simply use an #Ajax.ActionLink. I wrote a blog post on how to deal with Ajax.ActionLink that I think will help you out.
The signature for your controller action on your question looks correct:
public ActionResult Save(int id, bool status){}
Another options is actually to create a Settings view model (call it what you will), and in there just have a bunch of bool properties to represent the checkboxes:
public class Settings
{
public bool Status { get; set; }
// more properties here
}
then you can bind your action to the Settings object:
public ActionResult Save(int id, Settings settings){}
This will come in handy in case you end up having multiple checkboxes to bind.

"Validation Error: Value is not valid" error from f:datetimeConverter

The following code creates a two radio buttons. Each option contains a date value that is successfully converted to a label of the format "yyyy-MM-dd". Once I make a selection and click the next button I get the following error "j_idt12:comDateChoice: Validation Error: Value is not valid". It seems simple enough but somethings wrong. Can any of you spot it?
I'm using JSF 2.0 in glassfish.
Backing bean
public List<SelectItem> getComDateList() {
List<SelectItem> items = new ArrayList<SelectItem>();
Calendar cal = GregorianCalendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.add(Calendar.MONTH, 1);
Date nextFirst = cal.getTime();
cal.add(Calendar.MONTH, 1);
Date followingFirst = cal.getTime();
items.add(new SelectItem(nextFirst, new SimpleDateFormat("yyyy-MM-dd").format(nextFirst)));
items.add(new SelectItem(followingFirst, new SimpleDateFormat("yyyy-MM-dd").format(followingFirst)));
return items;
}
JSF Code
<h:panelGrid columns="2">
<h:outputLabel value="#{msg.FinanceCommencementDate}" for="comDateChoice"/>
<h:selectOneRadio id="comDateChoice" value="#{signUpBean.current.commencementDate}" layout="pageDirection">
<f:convertDateTime type="date" dateStyle="short"/>
<f:selectItems value="#{signUpBean.comDateList}"/>
</h:selectOneRadio>
</h:panelGrid>
This error will occur if the selected item value didn't pass the Object#equals() check on any of the available select item values. This can happen if the getter returned a different list during the apply request values phase of the form submit request than it did during the initial request to display the form.
Because you're reconstructing the list in the getter instead of constructing once in the constructor of a view scoped bean, the Date objects will get a different timestamp on every call, it will be some minutes/seconds in the future as compared to the initial Date objects. Hence the equals() will fail.
Move this logic into the constructor of the bean and rewrite the getter so that it does what it is supposed to do: return only the data. Do not do loading logic in a getter. You should also put the bean in the view scope so that the constructor doesn't re-run when you submit the form.
#ManagedBean
#ViewScoped
public class SignUpBean {
private List<SelectItem> comDateList;
public SignUpBean() {
comDateList = new ArrayList<SelectItem>();
// Fill it here.
}
public List<SelectItem> getComDateList() {
return comDateList; // In getters, do nothing else than returning data!
}
}
Update: the converter is also a potential source of the problem. You've basically instructed it to strip off the time when rendering the HTML page. So it uses the default time when converting back to Date. Either use
<f:convertDateTime pattern="yyyy-MM-dd HH:mm:ss.SSS Z" />
or reset the time and timezone on the Calendar beforehand:
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.setTimeZone(TimeZone.getTimeZone("GMT"));
this way you can use just a <f:convertDateTime type="date" />

Resources