1

I've to create a modal dialog which contains a AjaxBootstrapTabbedPanel with two or more tabs. All tabs belong to the same form. Each tab contains required input fields, select boxes or drop down choices. Until now, I don't use own validators, but this is a future task.

I was able to trigger the validation when switching between the tabs.

When I use the dialog like variant A and B, I get proper feedback from validation.

Variant A

  1. open the dialog
  2. closing the dialog via submit button immediately results in feedback message "please enter a value in field..."

Variant B

  1. open the dialog
  2. switch to another tab without filling required fields on initial tab gives also "please enter a value in ..."

Variant C - validation problem

But using the dialog in this way doesn't result in feedback messages:

  1. open the dialog
  2. enter all required values on the initial tab
  3. don't enter values in required fields on another tab
  4. use the submit button to close the diaolg: no feedback message!!, but there has to be one or more

In Variant C, no logging output from the method BootstrapAjaxButton#onError() is printed.

I'm using Wicket 7.6.0 and Wicket-Bootstrap 0.10.11

Class for modal dialog

public abstract class OwsDetailsDialog extends Modal<Ows>
{
    private static final long serialVersionUID = -8110788978602397064L;

    private BootstrapAjaxButton createOwsBtn;
    private BootstrapForm<Ows> owsForm;

    public OwsDetailsDialog(String id,
            IModel<Ows> owsModel)
    {
        super(id, owsModel);
        setOutputMarkupPlaceholderTag(true);
        setDefaultModel(owsModel);

        owsForm = new BootstrapForm<>("owsForm");
        owsForm.setOutputMarkupId(true);
        add(owsForm);

        List<ITab> tabs = createTabs(owsModel);
        MyAjaxTabbedPanel tabbedPanel = new MyAjaxTabbedPanel("tabbedPanel", tabs);
        owsForm.add(tabbedPanel);

        createOwsBtn = new BootstrapAjaxButton("submitOws",
                Model.of("Create"), Buttons.Type.Default)
        {
            @Override
            protected void onError(AjaxRequestTarget target, Form<?> form)
            {
                super.onError(target, form);
                target.add(form, tabbedPanel);
                System.out.println("onError() at form ID " + form.getId() + " target.getPage() "
                        + target.getPage());
            }

            @Override
            protected void onSubmit(AjaxRequestTarget target, Form<?> form)
            {
                super.onSubmit(target, form);
                System.out.println("click on create");
                createOws(target, owsModel);
            }
        };
        owsForm.add(createOwsBtn);

        BootstrapAjaxButton cancelBtn = new BootstrapAjaxButton("cancelOws",
                Model.of("Cancel"), Buttons.Type.Default)
        {
            @Override
            protected void onSubmit(AjaxRequestTarget target, Form<?> form)
            {
                super.onSubmit(target, form);
                cancel(target);
            }
        };
        cancelBtn.setDefaultFormProcessing(false);
        owsForm.add(cancelBtn);

        //FeedbackPanel feedbackOwsDialog = new FeedbackPanel("feedbackOwsDialog");
        //add(feedbackOwsDialog);
    }

    private List<ITab> createTabs(IModel<Ows> owsModel)
    {
        List<ITab> tabs = new ArrayList<>();

        tabs.add(new AbstractTab(Model.of("Data 1"))
        {
            private static final long serialVersionUID = -9107223557866453561L;

            @Override
            public WebMarkupContainer getPanel(String panelId)
            {
                return new OwsMainInfoContainer(panelId, owsModel);
            }
        });
        tabs.add(new AbstractTab(Model.of("Data 2"))
        {
            private static final long serialVersionUID = -7323530522820254738L;

            @Override
            public WebMarkupContainer getPanel(String panelId)
            {
                return new OwsSecondaryInfoContainer(panelId, owsModel);
            }
        });

        return tabs;
    }

    protected class OwsMainInfoContainer extends Panel
    {
        private static final long serialVersionUID = -2965824809083715016L;

        public OwsMainInfoContainer(
                String panelId, IModel<Ows> owsModel)
        {
            super(panelId, owsModel);
            add(new RequiredTextField<>("title"));
            add(new RequiredTextField<>("url"));

            List<OwsType> types = Arrays.asList(OwsType.values());

            DropDownChoice<OwsType> dropDownChoice = new DropDownChoice<>("category", types,
                    new ChoiceRenderer<OwsType>()
                    {
                        private static final long serialVersionUID = 8139757791037487164L;

                        @Override
                        public Object getDisplayValue(OwsType owsType)
                        {
                            return owsType.getName();
                        }
                    });

            add(dropDownChoice.setRequired(true));

            add(new FeedbackPanel("feedbackMain"));
        }
    }

    protected class OwsSecondaryInfoContainer extends Panel
    {
        private static final long serialVersionUID = -7396160769731997541L;

        public OwsSecondaryInfoContainer(
                String panelId, IModel<Ows> owsModel)
        {
            super(panelId, owsModel);
            add(new DateTextField("firstPublished"));
            add(new TextField<>("provider").setRequired(true));
            add(new TextField("price").setRequired(true));
            add(new FeedbackPanel("feedbackSecondary"));
        }
    }

    protected abstract void createOws(AjaxRequestTarget target
            , IModel<Ows> owsWithUtilDateIModel);

    protected abstract void cancel(AjaxRequestTarget target);

    // http://www.volkomenjuist.nl/blog/2009/12/01/ajaxtabbedpanel-store-state-when-switching-tabs/
    class MyAjaxTabbedPanel extends AjaxBootstrapTabbedPanel<ITab>
    {
        private static final long serialVersionUID = 1513951445901529991L;

        public MyAjaxTabbedPanel(String id, List<ITab> tabs)
        {
            super(id, tabs);
        }

        @Override
        protected WebMarkupContainer newLink(String linkId, final int index)
        {
            return new AjaxSubmitLink(linkId, owsForm)
            {
                private static final long serialVersionUID = 7049548660275591812L;

                @Override
                protected void onSubmit(AjaxRequestTarget target, Form<?> form)
                {
                    setSelectedTab(index);
                    if (target != null)
                    {
                        target.add(form);
                    }
                    onAjaxUpdate(target);
                    System.out.println("onSubmit() on target.getPage(): " + target.getPage());
                }

                @Override
                protected void onError(AjaxRequestTarget target, Form<?> form)
                {
                    MyAjaxTabbedPanel component = MyAjaxTabbedPanel.this;
                    target.add(component);
                    System.out.println("in onError() , target.add() on " + component.getId());
                }
            };
        }
    }
}

Class extending WebPage

public class MyPage extends WebPage
{
    private static final long serialVersionUID = 6826446949682313116L;

    public MyPage()
    {
        Form<Void> form = new Form<Void>("buttonForm");
        add(form);
        form.setOutputMarkupId(true);


        OwsDetailsDialog owsDialog = new OwsDetailsDialog("owsDialog"
                , new CompoundPropertyModel<Ows>(new Ows()))
        {
            @Override
            protected void createOws(AjaxRequestTarget target,
                    IModel<Ows> model)
            {
                Ows ows = model.getObject();
                System.out.println("object: "+ ows);
                close(target);
            }

            @Override
            protected void cancel(AjaxRequestTarget target)
            {
                System.out.println("click auf abbrechen");
                close(target);
            }
        };
        add(owsDialog);

        BootstrapAjaxButton createOwsButton = new BootstrapAjaxButton("createOwsButton",
                Model.of("OWS neu"), Buttons.Type.Default)
        {
            @Override
            protected void onSubmit(AjaxRequestTarget target, Form<?> form)
            {
                super.onSubmit(target, form);
                owsDialog.setDefaultModelObject(new Ows());
                target.add(owsDialog);
                TabbedPanel tabbedPanel = (TabbedPanel) owsDialog.get("owsForm:tabbedPanel");
                tabbedPanel.setSelectedTab(0);
                owsDialog.show(target);
            }
        };

        form.add(createOwsButton);
    }
}

PoJo

package example.tryOut.ows;

import java.util.Date;

public class Ows
{
    private Integer index=0;
    private String title = "";
    private String provider = "";
    private String url = "";
    private OwsType category;
    private Date firstPublished =null;
    private Double price=0.0;

    public Integer getIndex()
    {
        return index;
    }

    public void setIndex(Integer index)
    {
        this.index = index;
    }

    public String getTitle()
    {
        return title;
    }

    public void setTitle(String title)
    {
        this.title = title;
    }

    public String getProvider()
    {
        return provider;
    }

    public void setProvider(String provider)
    {
        this.provider = provider;
    }

    public String getUrl()
    {
        return url;
    }

    public void setUrl(String url)
    {
        this.url = url;
    }

    public OwsType getCategory()
    {
        return category;
    }

    public void setCategory(OwsType category)
    {
        this.category = category;
    }

    public Date getFirstPublished()
    {
        return firstPublished;
    }

    public void setFirstPublished(Date firstPublished)
    {
        this.firstPublished = firstPublished;
    }

    public Double getPrice()
    {
        return price;
    }

    public void setPrice(Double price)
    {
        this.price = price;
    }

    @Override
    public String toString()
    {
        return "Ows{" +
                "index=" + index +
                ", title='" + title + '\'' +
                ", provider='" + provider + '\'' +
                ", url='" + url + '\'' +
                ", category=" + category +
                ", firstPublished=" + firstPublished +
                ", price=" + price +
                '}';
    }
}

Markup

Page

<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org">
<head>
    <meta charset="UTF-8">
</head>
<body>
<form wicket:id="buttonForm">
    <button wicket:id="createOwsButton"></button>
</form>
<div wicket:id="owsDialog"></div>
</body>
</html>

Dialog

<!DOCTYPE html>
<html xmlns:wicket="http://wicket.apache.org">
<head>
    <meta charset="UTF-8">
</head>
<body>
<wicket:extend>
    <form wicket:id="owsForm">
        <div wicket:id="tabbedPanel" class="container" style="width: inherit"></div>
        <button type="submit" wicket:id="submitOws" class="btn btn-main">Anlegen</button>
        <button type="reset" wicket:id="cancelOws" class="btn btn-main">Abbrechen</button>
    </form>
</wicket:extend>
</body>
</html>

<!DOCTYPE html>
<html lang="en" xmlns:wicket="http://wicket.apache.org">
<head>
    <meta charset="UTF-8">
</head>
<body>

<wicket:panel>
    <div class="form-group">
        <label wicket:for="url">URL</label>
        <div class="controls">
            <input type="text" wicket:id="url" class="form-control"/>
        </div>
    </div>
    <div class="form-group">
        <label wicket:for="title">Title</label>
        <div class="controls">
            <input type="text" wicket:id="title" class="form-control"/>
        </div>
    </div>
    <div class="form-group">
        <label wicket:for="category">OWS Category</label>
        <div class="controls">
            <select wicket:id="category">
                <option value="">dummy1</option>
                <option value="">dummy2</option>
            </select>
        </div>
    </div>

    <div wicket:id="feedbackMain"></div>
</wicket:panel>

</body>
</html>

<!DOCTYPE html>
<html lang="en" xmlns:wicket="http://wicket.apache.org">
<head>
    <meta charset="UTF-8">
</head>
<body>
<wicket:panel>
    <div class="form-group">
        <label wicket:for="price">Price</label>
        <div class="controls">
            <input type="text" wicket:id="price" class="form-control"/>
        </div>
    </div>

    <div class="form-group">
        <label wicket:for="provider">Provider</label>
        <div class="controls">
            <input type="text" wicket:id="provider" class="form-control"/>
        </div>
    </div>

    <div class="form-group">
        <label wicket:for="firstPublished">First published</label>
        <div class="controls">
            <input type="date" wicket:id="firstPublished" class="form-control"/>
        </div>
    </div>

    <div wicket:id="feedbackSecondary"></div>
</wicket:panel>
</body>
</html>
JimHawkins
  • 4,843
  • 8
  • 35
  • 55

0 Answers0