2012-07-04 30 views
0

我正在制作一个表单,让教师创建问题。一类问题是多选题。该表单有一个textArea,您可以在其中编写问题表达式,以及一个带替代方案textField的listView。Wicket:重新绘制文本框并保留用户输入

有一个按钮来添加一个新的选择(添加一个新的textField),当按下它重新绘制所有的替代品,并添加一个新的。现在问题是这样的:我想让列表视图中已有的文本字段带有文本,以便在重绘后保留教师写的文本,但我不知道如何使这成为可能(除了在每次重绘之前将值保存到数据库,但这似乎是一个坏主意)。

这是我的MultipleChoiceQuestionPanel的代码,我希望它已经足够。

public class MultiChoiceQuestionPanel extends QuestionPanel { 

    private List<Alternative> alternatives; 

    @SpringBean 
    private AlternativeRepository alternativeRepository; 

    public List<Alternative> getAlternatives(){ 
     return alternatives; 
    } 

    public MultiChoiceQuestionPanel(String id, MultipleChoiceQuestion q){ 
     super(id, q); 

     final WebMarkupContainer parent = new WebMarkupContainer("alternativesContainer"); 
     parent.setOutputMarkupId(true); 
     add(parent); 
     parent.add(new Label("AnswerLabel", "Svar")); 

     q.setAlternatives(alternativeRepository.findByMultipleChoiceQuestion(q)); 
     alternatives = q.getAlternatives(); 
     Form form = new Form("addForm"); 
     form.add(new ListView<Alternative>("alternatives", alternatives) { 
      @Override 
      protected void populateItem(final ListItem<Alternative> alternativeListItem) { 
       alternativeListItem.add((TextField<String>) new TextField<String>("alternative", new AlternativeModel(alternativeListItem.getModelObject())).setRequired(true).setType(String.class)); 
       Form form = new Form("removeForm"); 
       form.add(new AjaxSubmitLink("remove") { 
        @Override 
        protected void onSubmit(AjaxRequestTarget target, Form<?> form) { 
         Alternative selected = alternativeListItem.getModelObject(); 
         alternativeRepository.delete(selected); 
         getAlternatives().remove(selected); 
         target.addComponent(parent); 
        } 
       }); 
       alternativeListItem.add(form); 
       add(alternativeListItem); 
      } 
     }); 

     AjaxSubmitLink a = new AjaxSubmitLink("add") { 
      @Override 
      protected void onSubmit(AjaxRequestTarget target, Form<?> form) { 
       Alternative alternative = new Alternative(); 
       MultipleChoiceQuestion mcq = (MultipleChoiceQuestion) getQuestion(); 
       alternative.setSequenceNumber(mcq.getAlternatives().size()); 
       alternative.setMultipleChoiceQuestion((MultipleChoiceQuestion) getQuestion()); 
       alternativeRepository.save(alternative); 
       getAlternatives().add(alternative); 
       target.addComponent(parent); 
      } 
     }; 
     a.setDefaultFormProcessing(false); 
     form.add(a); 
     parent.add(form); 
    } 
} 

任何帮助表示赞赏。

回答

3

Javadoc of ListView

警告:尽管你可以表格中嵌套列表视图,你必须设置 的setReuseItems属性为true,以便有验证工作 正常。默认情况下,setReuseItems为false,其效果为 ListView将用新实例替换所有子组件。在这个背后的想法 是,你总是呈现新的数据,并且人们通常使用ListViews显示只读列表(至少,这是我们认为的 ),这是很好的默认行为。

但是,由于 组件在渲染开始之前被替换,因此这些组件的特定消息的搜索将失败,因为它们将被其他实例替换为 。另一个问题是“错误的”用户输入保持为组件的实例数据(临时的) 。由于这些组件被 替换为新组件,当 setReuseItems为false时,您的用户将永远不会看到错误的数据。

这基本上就是这里发生的事情。你必须为你的ListView设置ReuseItems为true。

+0

谢谢你,这解决了问题! –

+0

@LeoSundholm不客气。 – Nicktar

+0

虽然这似乎创造了一个新问题。 添加新的textField完美地工作,但我的删除按钮现在行为很奇怪。无论我按下哪个删除按钮,它都是最后一个textField的文本消失,而不是我删除的textField中的文本。为什么会有任何解释/建议? –

相关问题