I've got 2 radio buttons on my Tapestry5 page and I want to update zone when value changes:
<t:radio t:id="allDay" t:mixins="zoneUpdater" t:event="allDayChanged" t:clientEvent="change" zone="timeRecZone"/>
<t:radio t:id="timeRestricted" t:mixins="zoneUpdater" t:event="timeRestrictedChanged" t:clientEvent="change" zone="timeRecZone"/>
<t:zone t:update="show" elementName="div" t:id="timeRecZone" id="timeRecZone">
<t:if test="timeRestrictedSelected">
.
.
.
I'm using known zoneUpdater mixin which works fine for me with textfield at other place of my page. But here, I don't really see timeRecZone get updated, because area under the IF condition is not being shown and I don't see following statement being logged when I'm clicking radios.
public boolean isTimeRestrictedSelected() {
log.info("***** isTimeRestrictedSelected...");
return selectedTimeRestriction == TimeRestriction.TIME_RESTRICTED;
}
This part (change event) works though:
public void onAllDayChanged() {
selectedTimeRestriction = TimeRestriction.ALL_DAY;
log.info("***** allDayChanged called: " + selectedTimeRestriction);
}
public void onTimeRestrictedChanged() {
selectedTimeRestriction = TimeRestriction.TIME_RESTRICTED;
log.info("***** timeRestrictedChanged called: " + selectedTimeRestriction);
}
Has anybody experienced this while working with radio/zone update? Many thanks.
Mea culpa, solution is here:
public void onAllDayChanged() {
selectedTimeRestriction = TimeRestriction.ALL_DAY;
ajaxResponseRenderer.addRender("timeRecZone", timeRecZone);
}
public void onTimeRestrictedChanged() {
selectedTimeRestriction = TimeRestriction.TIME_RESTRICTED;
ajaxResponseRenderer.addRender("timeRecZone", timeRecZone);
}
Related
I have wicket component with onClick event where I'd like to run javascript code which:
reloads the page
after page has been reloaded, scroll down to the markupId which was clicked
I have to pass as parameter the "markupId" value from wicket to javascript to find out to which position should I scroll down
WicketComponent.java
MyPanel div = new MyPanel("div");
div.add(new AjaxEventBehavior("click") {
#Override
protected void onEvent(AjaxRequestTarget target) {
// some requests...
String markupId = div.getMarkupId();
target.appendJavaScript("window.location.reload();");
target.appendJavaScript(jsReload(markupId));
}
div.add(AttributeModifier.replace("onclick", "clicked('" + div.getMarkupId() + "');"));
#Override
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
response.render(JavaScriptReferenceHeaderItem.forReference(new JavaScriptResourceReference(this.getClass(), "script.js")));
}
WicketComponent.html
<div wicket:id="div" onclick="clicked('markupId');">Text</div>
script.js
function clicked(markupId) {
window.location.reload();
}
document.addEventListener("DOMContentLoaded", function (event) {
let elementOffset = $("#{markupId}").offset().top; // how to pass here markupId parameter from wicket ?
let windowOffset = $(window).scrollTop();
window.scrollTo(0, elementOffset- windowOffset);
});
how to pass parameter "markupId" in javascript file which was attached in renderHead() or may be there is another solution for this ? I'll appreciate any help. Thanks!
you should solve your problem using location hash as described here:
Can we have code after location.reload(true)?
for the hash value use a fixed markup id for your component, something like:
div.setMarkupId("myMarkupId");
div.add(new AjaxEventBehavior("click") {
#Override
protected void onEvent(AjaxRequestTarget target) {
// some requests...
String markupId = div.getMarkupId();
target.appendJavaScript("window.location.hash = 'myMarkupId'");
target.appendJavaScript("window.location.reload();");
//that's it! no other js is needed
}
}
I haven't tried it but after page reloading it should scroll down to your component.
I am quite new to Wicket. I am adding a model to a sub-panel(ChartPanel) from a main panel (MainPanel) on a button click.
MainPanel.java
On button click, I am re-adding the chartPanel after I change its model. Following is the code I am using in the buttonClick of the MainPanel. Here the onRenderAnnotations event is generated on some click in the UI.
#OnEvent
public void onRenderAnnotations(RenderAnnotationsEvent aEvent)
{
LOG.trace("clicked on the annotation");
renderChart( aEvent.getRequestHandler());
}
private void renderChart(IPartialPageRequestHandler aRequestHandler)
{
MultiValuedMap<String, Double> recommenderScoreMap = getLatestScores(aRequestHandler);
Map<String,String> curveData = new HashMap<String,String>();
LearningCurve learningCurve = new LearningCurve();
for (String recommenderName : recommenderScoreMap.keySet()) {
String data = recommenderScoreMap.get(recommenderName).stream().map(Object::toString)
.collect(Collectors.joining(", "));
curveData.put(recommenderName,data);
learningCurve.setCurveData(curveData);
learningCurve.setMaximumPointsToPlot(MAX_POINTS_TO_PLOT);
}
chartPanel.setDefaultModel(Model.of(learningCurve));
// to avoid the error, A partial update of the page is being rendered
try {
aRequestHandler.add(chartPanel);
}
catch (IllegalStateException e) {
LOG.warn("Not updating the chart. " + e.toString());
setResponsePage(getPage());
}
}
ChartPanel.java
After this in the chartPanel, I want to use the updated model to add component inside the chartpanel. What would be the best way to do that?
I want to do something like this in the class ChartPanel:
#Override
protected void onRender()
{
super.onModelChanged();
LearningCurve newLearningCurve = getModel().getObject();
requestTarget = ???
String js = createJavascript(newLearningCurve);
requestTarget.prependJavascript(js);
}
My question is, in the above code how to get the request target since it is not an ajax request neither do I get it in the arguments. Should I use some other function where I also get a requestTarget. But I want it to be called every time the model of ChartPanel is updated from anywhere.
Pardon my ignorance. I have been trying for a few days but I am still stuck. I tried to explain it enough but if any information is missing, please comment and I will add it right away.
Thanks.
You should override renderHead() instead:
#Override
public void renderHead(IHeaderResponse response)
{
super.renderHead(response);
response.render(OnLoadHeaderItem.forScript(
createJavascript(newLearningCurve)));
}
This way your chart will be shown correctly regardless whether it was added due to an AjaxRequest or simply when the page is rerendered.
I'm trying to make a Chat, so that when I press enter or press the 'Send' Button, the input of the Textfield will go into a ListView. And it does it's job, although the code is really messy.
My controller code is as following:
public void initialize() {
sendButton.setDisable(true);
}
public void isChatEmpty() {
boolean isChatEmpty = textInput.getText().isEmpty();
sendButton.setDisable(isChatEmpty);
}
public void sendMessageOnClick(){
sendButton.setOnAction((e) -> {
String message = textInput.getText();
chatHistory.getItems().add("Sorin: " + message + "\n");
textInput.setText(null);
sendButton.setDisable(true);
});
}
public void sendMessageOnEnter(){
textInput.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
String message = textInput.getText();
chatHistory.getItems().add("Sorin: " + message + "\n");
textInput.setText(null);
sendButton.setDisable(true);
System.out.print("test");
}
});
}
I know it works because I can see it in the GUI, but I somehow, get a Nullpointer on my 'isChatEmpty', which to be fair, I do not know why.
Caused by: java.lang.NullPointerException
at sample.Controller.isChatEmpty(Controller.java:29)
Also, is there a way to combine the two Lambdas functions?
Thank you in advance!
In case of enter and click there is an easy way to deal with this: Use the onAction method for both. For TextField this is triggered when you press enter. Furthermore those handlers should be assigned from fxml. Also use binding to disable the button:
<TextField fx:id="textInput" onAction="#send"/>
<Button fx:id="sendButton" text="Send" onAction="#send"/>
#FXML
private void initialize() {
sendButton.disableProperty().bind(textInput.textProperty().isEmpty());
}
#FXML
private void send() {
String message = textInput.getText();
if (message != null && !message.isEmpty()) {
chatHistory.getItems().add("Sorin: " + message);
textInput.clear();
}
}
In isChatEmpty() method the result of textInput.getText() is null as you set it with textInput.setText(null);.
This null causes NPE (see docs for String.isEmpty()).
To resolve this you can remove isChatEmpty() method and setup unidirectional binding:
public void initialize() {
sendButton.disableProperty().bind(textInput.textProperty().isEmpty());
}
Note the .isEmpty() here is not a call to String.isEmpty() but to
StringExpression.isEmpty() what generates binding of type BooleanBinding.
I was successfully deleting selected items from listbox and after that all objects were deleted from db and listbox was refreshed.
then i added the confirmation box with yes and no option, then my list wasn't refreshed. i saw this thread with similar problem on zk forum with a solution, i implemented it but getting the class cast exception
I am using MVVM
http://forum.zkoss.org/question/73640/refreshing-listbox-after-deleting-an-itemrow/
code getting the exception:
AnnotateDataBinder binder = (AnnotateDataBinder) userWin.getAttribute("binder");
binder.loadAll();
exception:
Mar 21, 2013 5:22:23 PM org.zkoss.zk.ui.impl.UiEngineImpl handleError:1352
SEVERE: >>java.lang.ClassCastException: org.zkoss.bind.AnnotateBinder cannot be cast to org.zkoss.zkplus.databind.AnnotateDataBinder
looking forward to hear from you. I have searched the net, but couldn't find anything but updating the zk. i am already using the latest version of zk 6.5.1.1.
thanks in advance.
#after adding your suggested line of code, my list was not updated, here is my method
#Override
#Command("deleteAllSelected")
#NotifyChange({"selectedObject","objectList"})
public void deleteAllSelected() {
logger.info("in deleteAllSelected()>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
logger.info("direct selection: " + objectList.getSelection());
final Set<UserIntelliopsDTO> setMe = objectList.getSelection();
logger.info("selectedion size in dellete all" + setMe.size());
EventListener<ClickEvent> clickListener = new EventListener<Messagebox.ClickEvent>() {
public void onEvent(ClickEvent event) throws Exception {
if (Messagebox.Button.YES.equals(event.getButton())) {
int i =0;
for(UserIntelliopsDTO dto:setMe){
userService.deleteUserIntelliops(dto.getUserIntelliOps().getUserId());
logger.info("siapa:userIntelliops " + dto.getUserIntelliOps() + dto.getUserIntelliOps().getUserId());
selectedObject = null;
logger.info("iteration: " + i);
++i;
}
selectedObject = null;
deleteAllSelectedButton.setVisible(false);
enableEditMode(true);
}
}
};
Messagebox.show("Are you sure you want to delete all selected records?", "Delete All Selected",
new Messagebox.Button[] { Messagebox.Button.YES,
Messagebox.Button.NO }, Messagebox.QUESTION,
clickListener);
BindUtils.postNotifyChange(null, null, this, "*");
}
I am assuming you are using MVVM Model..So you can do this thing when you will click on delete button below method will code...
#Command
public void doDeleteItems(#ContextParam(ContextType.VIEW) Component view) {
logger.debug("Delete Icon selected");
if (myModel.getSelectedListItem() == null || myModel.getSelectedListItem().isEmpty()) {
showError("No rows are selected");
} else {
Messagebox.show("Are you sure you want to delete?", "Alert !!", Messagebox.YES | Messagebox.NO, Messagebox.QUESTION,new org.zkoss.zk.ui.event.EventListener() {
public void onEvent(Event evt) throws InterruptedException {
if (evt.getName().equals("onYes")) {
//Add code for Deletion
if (listModel.contains(deletedObj))
listModel.remove(deletedObj);
}
else{
//Do somthing else
}
BindUtils.postNotifyChange(null, null, this, "*");//this means current viewmodel object and refresh the variables
}
As i did BindUtils.postNotifyChange() it will do magic for you refreshing the list or you can use NotifyChange("*")
One more thing you have to do here remove object from list after deleting the record...
Is there a way to disable the Back button in a browser (basically clearing the History token stack) in GWT? Once I browse to a certain page in my application I want to make sure that the user can't use the back button to go back, but only be able to use links on the page to navigate the site.
You cannot disable a button just intercept it and change its return to something the browser does not understand.
This removes the history:
Window.addWindowClosingHandler(new ClosingHandler() {
#Override
public void onWindowClosing(ClosingEvent event) {
event.setMessage("My program");
}
});
To understand it see: http://groups.google.com/group/google-web-toolkit/browse_thread/thread/8b2a7ddad5a47af8/154ec7934eb6be42?lnk=gst&q=disable+back+button#154ec7934eb6be42
However, I would recommend not doing this because your it goes against good UI practices. Instead you should figure out a way that the back button does not cause a problem with your code.
Call the method below in the onModuleLoad().
private void setupHistory() {
final String initToken = History.getToken();
if (initToken.length() == 0) {
History.newItem("main");
}
// Add history listener
HandlerRegistration historyHandlerRegistration = History.addValueChangeHandler(new ValueChangeHandler() {
#Override
public void onValueChange(ValueChangeEvent event) {
String token = event.getValue();
if (initToken.equals(token)) {
History.newItem(initToken);
}
}
});
// Now that we've setup our listener, fire the initial history state.
History.fireCurrentHistoryState();
Window.addWindowClosingHandler(new ClosingHandler() {
boolean reloading = false;
#Override
public void onWindowClosing(ClosingEvent event) {
if (!reloading) {
String userAgent = Window.Navigator.getUserAgent();
if (userAgent.contains("MSIE")) {
if (!Window.confirm("Do you really want to exit?")) {
reloading = true;
Window.Location.reload(); // For IE
}
}
else {
event.setMessage("My App"); // For other browser
}
}
}
});
}
I found a way to make GWT ignore the back-button: Just add historyitem x if no historyitem was set and do nothing on x.
set a historyitem on startup
History.newItem("x")
in the ValueChangeHandler of History add the following:
String historyToken = event.getValue();
if (!historyToken.equals("x"))
History.newItem("x");
Window.addWindowClosingHandler(new ClosingHandler() {
#Override
public void onWindowClosing(ClosingEvent event) {
event.setMessage("My program");
}
});
That is not a fool proof solution. In fire fox I can press the back button and the onWindowClosing method is never invoked. The reason is that I have used History.newItem() and since history exists the back button or backspace buttons simply navigate through the browser history.
So....fix that :)
Put this in your index.html file:
window.open('html page(For example trial.html)', 'Name of the desired site', width='whatever you want',height='whatever you want', centerscreen=yes, menubar=no,toolbar=no,location=no,
personalbar=no, directories=no,status=no, resizable=yes, dependent=no, titlebar=no,dialog=no');