You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by Daniel Aschauer <da...@gmail.com> on 2010/04/20 16:16:22 UTC

Add new items to a list within a form by ajaxlink?

Hi!

I am new here, and I am creating my first Webapplication with Wicket
and already read through the whole book "Wicket in action".

But I still face some problem I could resolve:
In a form, where I use a compound model I want to add some new Object
to a list when a ajax link is clicked.
The problem is that the container that contains the list
(PropertyListView) will repaint and thus entries by the user are lost.
I know might submit the form first and so might be able to update the
model and reread it, but then I will have to skip the validation on
other fields in the form.

Can anyone help me out and give me some hint how this problem can be solved?
Thanks alot for any help!!!

Daniel
		this.participantlistview = new
PropertyListView<BasisExhibitionParticipant>("exhibition.participants")
{
			@Override
			protected void populateItem(ListItem<BasisExhibitionParticipant> item) {
				item.add(new TextField<String>("name"));
				item.add(new TextField<String>("surname"));
				item.add(new
DropDownChoice<String>("role",BasisExhibitionParticipant.roles));
			}
		};
		this.participantlistcontainer = new WebMarkupContainer("participants");
		this.participantlistcontainer.add(participantlistview);
		this.participantlistcontainer.setOutputMarkupId(true);
		form.add(this.participantlistcontainer);
		form.add(new AjaxSubmitLink("add_participant") {
			@Override
			protected void onSubmit(AjaxRequestTarget target, Form form) {
				System.out.println("Participant is: " +
participantlistview.getModelObject().get(0).getName());
				if (target != null) {
					target.addComponent(AddExhibition.this.participantlistcontainer);
				}
			}
		}.setDefaultFormProcessing(false));

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Add new items to a list within a form by ajaxlink?

Posted by Igor Vaynberg <ig...@gmail.com>.
participantlistview.setReuseItems(true)

-igor

On Tue, Apr 20, 2010 at 7:16 AM, Daniel Aschauer
<da...@gmail.com> wrote:
> Hi!
>
> I am new here, and I am creating my first Webapplication with Wicket
> and already read through the whole book "Wicket in action".
>
> But I still face some problem I could resolve:
> In a form, where I use a compound model I want to add some new Object
> to a list when a ajax link is clicked.
> The problem is that the container that contains the list
> (PropertyListView) will repaint and thus entries by the user are lost.
> I know might submit the form first and so might be able to update the
> model and reread it, but then I will have to skip the validation on
> other fields in the form.
>
> Can anyone help me out and give me some hint how this problem can be solved?
> Thanks alot for any help!!!
>
> Daniel
>                this.participantlistview = new
> PropertyListView<BasisExhibitionParticipant>("exhibition.participants")
> {
>                        @Override
>                        protected void populateItem(ListItem<BasisExhibitionParticipant> item) {
>                                item.add(new TextField<String>("name"));
>                                item.add(new TextField<String>("surname"));
>                                item.add(new
> DropDownChoice<String>("role",BasisExhibitionParticipant.roles));
>                        }
>                };
>                this.participantlistcontainer = new WebMarkupContainer("participants");
>                this.participantlistcontainer.add(participantlistview);
>                this.participantlistcontainer.setOutputMarkupId(true);
>                form.add(this.participantlistcontainer);
>                form.add(new AjaxSubmitLink("add_participant") {
>                        @Override
>                        protected void onSubmit(AjaxRequestTarget target, Form form) {
>                                System.out.println("Participant is: " +
> participantlistview.getModelObject().get(0).getName());
>                                if (target != null) {
>                                        target.addComponent(AddExhibition.this.participantlistcontainer);
>                                }
>                        }
>                }.setDefaultFormProcessing(false));
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: Add new items to a list within a form by ajaxlink?

Posted by ro...@func.nl.
Hi,

I think I solved that problem a while ago. The component below is backed
up by a List<String> and displays a single textfield for the first value
of the list. If you press the ajax-link an additional textfield is added
for the second item of the list, etcetera. As said, the values from the
textfields are backed by a List<String> Model. Making changes, then
clicking the ajax link does NOT destroy your previous changes. Submitting
this from within a form yields the List<String> Model with allt eh values
(and null if you added an empty TextField :S)

The code might not be working out of the box because I had to remove some
confusing overrides and I probably broke it :) But I think you'll get the
general idea.

cheers,
Rommert

===================== code + markup ====================

import java.util.List;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.OnChangeAjaxBehavior;
import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.ResourceModel;

public class MultipleTextFieldContainer extends WebMarkupContainer {
   private static final long serialVersionUID = 1L;

   public MultipleTextFieldContainer(final String id,
         final IModel<List<String>> listModel) {
      super(id);
      setOutputMarkupId(true);

      // set up a first value so the first textfield is displayed
      if (listModel.getObject().size() == 0) {
         // add the first value to empty list, in order to show at least 1
textfield
         listModel.getObject().add("");
      }

      final ListView<String> listView = getListView(listModel);
      add(listView);

      Link<Void> addLink = getAddLink(listModel);
      addLink.add(new Label("addLinkTitle", new Model("click to add an
item")));
      add(addLink);

   }

   private Link<Void> getAddLink(final IModel<List<String>> listModel) {
      Link<Void> addLink = new AjaxFallbackLink<Void>("addLink") {
         private static final long serialVersionUID = 1L;

         @Override
         public void onClick(final AjaxRequestTarget target) {
            // add a new value to the list
            listModel.getObject().add("");

            if (target != null) {
               target.addComponent(MultipleTextFieldContainer.this);
            }
         }

         @Override
         public boolean isVisible() {
            // show link until there are 10 items max
            return listModel.getObject().size() < 10;
         }
      };
      return addLink;
   }

   private ListView<String> getListView(final IModel<List<String>>
listModel) {
      final ListView<String> listView = new ListView<String>("textFields",
            listModel) {
         private static final long serialVersionUID = 1L;

         @Override
         protected void populateItem(final ListItem<String> item) {
            //for each item in the list, render a textfield.
            TextField<String> textField = getTextField(listModel, item);
            item.add(textField);
         }
      };
      listView.setReuseItems(true);
      setOutputMarkupId(true);
      return listView;
   }

   private TextField<String> getTextField(
         final IModel<List<String>> listModel, final ListItem<String> item) {
      TextField<String> textField = new TextField<String>("textField",
            new PropertyModel<String>(listModel, "" + item.getIndex()));
      if (item.getIndex() == 0) {
         textField.setRequired(true); // makes the first textfield required
      }

      textField.add(new OnChangeAjaxBehavior() {
         private static final long serialVersionUID = 1L;

         // this prevents you from losing state when ajax link is clicked
         @Override
         protected void onUpdate(final AjaxRequestTarget target) {
            modelChanged();
         }
      });
      return textField;
   }
}

with markup:

	<body>
               <div wicket:id="textFields">
                  <div wicket:id="formComponentContainer"
class="fieldsContainer">
                     <label wicket:id="label"></label>
                     <input class="inputText" type="text"
wicket:id="textField"/>
                     <span wicket:id="componentFeedback"
class="fieldErrorMessage">[error message]</span>
                  </div>
               </div>
               <a href="#" wicket:id="addLink"
class="extraLink"><wicket:panel
wicket:id="addLinkTitle">[add]</wicket:panel></a>
	</body>




> Hi!
>
> I am new here, and I am creating my first Webapplication with Wicket
> and already read through the whole book "Wicket in action".
>
> But I still face some problem I could resolve:
> In a form, where I use a compound model I want to add some new Object
> to a list when a ajax link is clicked.
> The problem is that the container that contains the list
> (PropertyListView) will repaint and thus entries by the user are lost.
> I know might submit the form first and so might be able to update the
> model and reread it, but then I will have to skip the validation on
> other fields in the form.
>
> Can anyone help me out and give me some hint how this problem can be
> solved?
> Thanks alot for any help!!!
>
> Daniel
> 		this.participantlistview = new
> PropertyListView<BasisExhibitionParticipant>("exhibition.participants")
> {
> 			@Override
> 			protected void populateItem(ListItem<BasisExhibitionParticipant> item)
> {
> 				item.add(new TextField<String>("name"));
> 				item.add(new TextField<String>("surname"));
> 				item.add(new
> DropDownChoice<String>("role",BasisExhibitionParticipant.roles));
> 			}
> 		};
> 		this.participantlistcontainer = new WebMarkupContainer("participants");
> 		this.participantlistcontainer.add(participantlistview);
> 		this.participantlistcontainer.setOutputMarkupId(true);
> 		form.add(this.participantlistcontainer);
> 		form.add(new AjaxSubmitLink("add_participant") {
> 			@Override
> 			protected void onSubmit(AjaxRequestTarget target, Form form) {
> 				System.out.println("Participant is: " +
> participantlistview.getModelObject().get(0).getName());
> 				if (target != null) {
> 					target.addComponent(AddExhibition.this.participantlistcontainer);
> 				}
> 			}
> 		}.setDefaultFormProcessing(false));
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org