简体   繁体   中英

Wicket AjaxButton does not update FeedbackPanel

I am trying to send a success message to a FeedbackPanel in Wicket, if an AjaxButton was clicked. Yet I recieve the following error message:

Wicket.Ajax.Call.processComponent: Component with id [[065DFC0DD1DC51103CC5FFEE61F2AE12]] was not found while trying to perform markup update.

I am already aware, that I have to output the markupID in the Java Code before I use the AjaxButton and set the target in the onSubmit . I also set setOutputMarkupPlaceholderTag once, yet it changed nothing.
I have also created a small test page, where I succeeded in sending the success message to the FeedbackPanel.

I thus started to debug the project and found out that the markupID returned from DefaultMarkupIdGenerator.generateMarkupId was indeed different that the one displayed in the HTML. Additionally all FeedbackPanels recieve this markupID during the ajax call.

feedbackPanelWartung12 vs. 065DFC0DD1DC51103CC5FFEE61F2AE12

To further complicate things, my FeedbackPanel is within a RepeatingView contained in a Panel within a page already containing a FeedbackPanel (inherited from its superclasses). The structure goes as follows:

Java Code

MyPage

public MyPage extends MySuperPage{

    //Constructors were left out

    //this method is called in the onInitialize of some
    //super class.
    @Override
    protected Component newContent() {
        setFeedbackPanelFilter();
        return new MyContainerPanel();
    }

    //this FeedbackPanel shall not recieve messages from child containers
    private void setFeedbackPanelFilter() {
        ((FeedbackPanel) this.get("feedback"))
            .setFilter( new ContainerFeedbackMessageFilter(this) {
                @Override
                public boolean accept(FeedbackMessage message) {
                    return !super.accept(message);
                }
        });
    }
}

MyContainerPanel

public MyContainerPanel extends Panel {

    //Constructors were left out

    @Override
    protected void onInitialize() {
        super.onInitialize();
        RepeatingView repeater = new RepeatingView("repeater");
        add(repeater);
        for (Object o : objects) {
            String id = repeater.newChildId();
            repeater.add(new MyPanel(id,o));
        }
    }
}

MyPanel

public MyPanel extends Panel {    
    private Object o;
    private CheckBox chkBox;
    private DateTimeField startDate, endDate;
    private TextField<String> message;
    private Form<Object> form;
    private AjaxButton button;
    private Label name;
    private FeedbackPanel feedbackPanel;

    //Constructors were left out

    @Override
    protected void onInitialize() {
        super.onInitialize();

        initFields();
        addFields();
        addAjaxButton();
        addAjaxFormComponentUpdatingBehavior();

        if (!o.isMaintenance())
            disableFields();
        }

    private void addAjaxButton() {
        button = new AjaxButton("submit") {
            @Override
            public void onSubmit(final AjaxRequestTarget target, final Form<?> form) {
                //do something
                feedbackPanel.success("Speichern erfolgreich");
                target.addChildren(AppWartungPanel.this.getPage(), FeedbackPanel.class);
            }
        };
        form.add(button);
    }

    private void addAjaxFormComponentUpdatingBehavior() {
        chkBox.add(new AjaxFormComponentUpdatingBehavior("onchange") {
            @Override
            protected void onUpdate(AjaxRequestTarget target) {
                switchVisibility();
                target.add(startDate);
                target.add(endDate);
                target.add(message);
                target.add(feedbackPanel);
            }
        });
    }

    private void switchVisibility() {
        if (o.isMaintenance())
            enableFields();
        else
            disableFields();
        }

    private void addFields() {
        add(form);
        form.add(feedbackPanel);
        form.add(chkBox);
        form.add(startDate);
        form.add(endDate);
        form.add(message);
        form.add(name);
    }

    private void initFields() {
        form = new Form<WartungDAO>("form", AppWartungPanel.this.getModel());
        chkBox = new CheckBox("wartung", new PropertyModel<Boolean>(o, "wartung"));
        chkBox.setOutputMarkupId(true);
        startDate = new DateTimeField("startDate", new PropertyModel<Date>(o, "startDate"));
        startDate.setOutputMarkupId(true);
        startDate.setRequired(true);
        endDate = new DateTimeField("endDate", new PropertyModel<Date>(o, "endDate"));
        endDate.setOutputMarkupId(true);
        endDate.setRequired(true);
        message = new TextField<String>("message", new PropertyModel<String>(o, "message"));
        message.setOutputMarkupId(true);
        message.setRequired(true);
        name = new Label("name", new PropertyModel<String>(o, "portal"));
        feedbackPanel = new FeedbackPanel("feedbackPanelWartung");
        feedbackPanel.setOutputMarkupId(true);
        feedbackPanel.setFilter(new ContainerFeedbackMessageFilter(this));
    }

    private void disableFields() {
        startDate.setEnabled(false);
        endDate.setEnabled(false);
        message.setEnabled(false);
    }

    private void enableFields() {
        startDate.setEnabled(true);
        endDate.setEnabled(true);
        message.setEnabled(true);
    }
}

HTML markup

MyPage

<!DOCTYPE html
 PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
    <body class="BG_MAIN">
           <div class="grid_16 BG1_GLOBAL">
               <div style="margin:10px;">
                   <div class="grid_3 alpha">
                    <wicket:container wicket:id="menu"></wicket:container>
                </div>
            <div class="grid_12 omega">
        <div class="INHALT">
                <h1 wicket:id="appHeader" style="margin-top: 0;"></h1>
                <div wicket:id="wartung" />
                <div wicket:id="feedback"></div>
                <wicket:container wicket:id="content"></wicket:container>
            </div>
        </div>
    </body>
</html>

MyContainerPanel

<html xmlns:wicket="http://wicket.apache.org">
    <wicket:panel>
        <div wicket:id="repeater">
        </div>
    </wicket:panel>
</html>

MyPanel

<html xmlns:wicket="http://wicket.apache.org">
    <wicket:panel>
        <div style="margin-left: 25px; margin-top: 25px;">
            <form wicket:id="form">
                <h2 wicket:id="name"></h2>
                <div wicket:id="feedbackPanelWartung"></div>
                <table style="border: none;">
                    <tbody>
                        <tr>
                            <td style="border: none;">Wartung aktiv?</td>
                            <td style="border: none;">
                                <input wicket:id="wartung" type="checkbox" />
                            </td>
                        </tr>
                        <tr>
                            <td style="border: none;">Nachricht zum Anzeigen:</td>
                            <td style="border: none;">
                                <input wicket:id="message" type="text" size="50" />
                            </td>
                        </tr>
                        <tr>
                            <td style="border: none;">Startdatum</td>
                            <td style="border: none;">
                                <div wicket:id="startDate"></div>
                            </td>
                        </tr>
                        <tr>
                            <td style="border: none;">Enddatum</td>
                            <td style="border: none;">
                                <div wicket:id="endDate"></div>
                            </td>
                        </tr>
                        <tr>
                            <td style="border: none;"></td>
                            <td style="border: none;">
                                <input wicket:id="submit" type="submit" value="Speichern" style="float: right;" />
                            </td>
                        </tr>
                    </tbody> 
                </table>
            </form>
        </div>
    </wicket:panel>
</html>

I can only guess that the error is due to the complexity of the page.

I also disabled the AjaxFormComponentUpdatingBehavior to check if it messes with the AjaxButton - It did not.
I also implemented everything with a normal Button, to check if the ContainerFeedbackMessageFilter and the FeedbackPanels worked - they did.

The AjaxButton is not crucial to the Page. Yet I would really like to understand, so if anybody has another nice idea to try out...

FeedbackPanel feedbackPanel = new FeedbackPanel("feedbackPanelWartung") {
    @Override
    public String getMarkupId() {
        return "feedbackPanelWartung." + someUniqueValuePassedToThePanel;
    }
};
feedbackPanel.setOutputMarkupId(true);

As luck had it, I had a unique value in one modelObject of the panel. I then overwrote the Component.getMarkupId() method and simply set my Id.
Worked like a charm.

I also found out, that the method feedbackPanel.setOutputMarkupId(true); Was irrelevant to my error message.
In other words: even if I tried to set the markup id for my component, it was never set in the first place and thus the ajax component was, rightfully so, never able to find a target.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM