2014-10-28 2 views
3
  • 여러 파일을 업로드하는 데 사용되는 페이지가 있습니다. 각 파일에 대해 사용자는 형식과 설명을 지정해야합니다. 따라서 MultiFileUploadField을 사용할 수 없습니다 ... RepeatingViewFileUploadField을 각 요소에 필요한 다른 두 필드와 함께 사용합니다.Wicket : ListView가있는 FileUploadField

  • 문제는 그 "파일 추가"버튼을 클릭 할 때마다 (AjaxLink), 이미 파일을했다 FileUploadFields ... 널 (null)으로 재설정됩니다

내가 무엇을 할 수

?

IModel<List<EtdDokument>> listModel = getListModel(); 
ListView<EtdDokument> dokumenteList = new ListView<EtdDokument>("dokumenteList", listModel) { 

    private static final long serialVersionUID = 1L; 

    @Override 
    protected void populateItem(ListItem<EtdDokument> item) { 
     final boolean showHeaders = ((getList() == null) || getList().size() == 0); 

     final WebMarkupContainer headRow = new WebMarkupContainer("headRow"); 
     headRow.setVisible(showHeaders); 
     item.add(headRow); 

     EtdDokumentRowPanel etdDokumentRow = new EtdDokumentRowPanel("bodyRow", item.getModel()); 
     item.add(etdDokumentRow); 

    } 
}; 
dokumenteList.setReuseItems(true); 
add(dokumenteList); 

AjaxLink<Void> addLink = new AjaxLink<Void>("addDokument") { 

    private static final long serialVersionUID = 1L; 

    @Override 
    public void onClick(AjaxRequestTarget target) { 
     EtdConfiguration etdConfig = EtdConfigForm.this.getModelObject(); 
     final EtdDokument newValue = new EtdDokument(etdConfig); 
     tempEtdDokumente.add(newValue); 
     target.addComponent(EtdConfigForm.this); 
    } 
}; 
add(addLink); 
  • EtdDokumentRowPanel, 나는 단지 FileUploadField 파일에 대한 TextField 보여 흥미 무관 : 여기

    는 (죄송합니다, 그것은 RepeatingView하지만 ListView 아니었다)이 ListView입니다 설명과 DropDownChoice을 사용하여 문서 유형을 선택하십시오 (우리 고유의 분류). 그것은 어떤 갱신 후 선택, 그리고 post 이벤트가 발생할 때 FileUploadField에 대한 실제 모델 객체 (선택이 끝난 파일)에만 설정되어 HTML의 <input type="file"> losts 때문에
+1

코드를 입력하십시오. 적어도 당신의'RepeatingView'과'Add File' 링크 구현. –

+0

자, 코드 조각을 추가했습니다. – diminuta

답변

2

좋아, 그것은 조금 까다로운. 따라서 을 onchange 이벤트와 함께 파일에 추가하더라도 사용자가 파일을 선택하면 모델이 null이됩니다.

실제로 우리는 post 요청이 js에서만 가능하며 '저장'스크립트를 구현하고, 아약스 업데이트가 진행되는 동안 이미 선택된 파일을 보관하고 다시 설정할 수 있지만 그것은 지루하다.

따라서이 문제를 해결하는 또 다른 방법은 새로 추가 된 구성 요소에서만 업데이트를 적용하고 다른 구성 요소에는 손대지 않는 것입니다.

모델 번호에 따라 addLink을 클릭 할 때만 새로운 wicket ID를 생성해야하기 때문에 RepeatingView을 사용할 것입니다. 여기에 코드입니다 (조심스럽게 의견을 읽고) :

/* Method, which init your form */ 
private void init() 
{ 
    /* Container, which will hold all FileUploadFields, 
     as RepeatingView adds children to it's parent object. */ 
    WebMarkupContainer container = new WebMarkupContainer("container"); 

    /* We need DOM id for container component. */ 
    container.setOutputMarkupId(true); 
    add(container); 

    final RepeatingView rv = new RepeatingView("dokumenteList"); 
    container.add (rv); 

    /* We need to add all default model values by ourselfs for RepeatingView: */ 
    for(EtdDokument doc : getListModel().getObject()) 
    { 
     createDocumentRow(rv, doc); 
    } 

    final AjaxLink<String> addLink = new AjaxLink<String>("addDokument") { 
     @Override 
     public void onClick(AjaxRequestTarget target) { 
      final EtdDokument newValue...; 
      final EtdDokumentRowPanel r = createDocumentRow(rv, newValue); 

      ... 

      /* This is it. We dynamicly adding created earlier component to markup. 
       This allows us to update this component via ajax. */ 
      target.prependJavaScript(
        "var item=document.createElement('div');" + //creating empty 'div' tag 
        "item.id='" + r.getMarkupId() + "'; " + // set markup id for this 'div'. 
        "Wicket.$('" + container.getMarkupId() + "').appendChild(item);" // add this 'div' as container child. 
      ); 

      /* Added 'div' is still empty, but this update will replace 
       it, by real component's markup.*/ 
      target.add(r); 
     } 
    }; 
    add(addLink); 
} 

/* This method creates new instance of EDRowP (with random id) and adds 
    it to RepeatingView. 
    I have dropped the implementation of your headRow, but you can include it 
    into the EDRowPanel or implement something similar. 
*/ 
private EtdDokumentRowPanel createDocumentRow(RepeatingView rv, EtdDokument doc) 
{ 
    EtdDokumentRowPanel row = new EtdDokumentRowPanel(rv.newChildId(), doc); 
    rv.add(row); 
    return row; 
} 

그리고 마크 업을 :

<form...> 
    ... 
    <div wicket:id="container"> 
     <div wicket:id="dokumenteList"></div> 
    </div> 
    <a href wicket:id="addDokument">Add</a> 
    .... 
</form> 

그것은 작은 문제가 너무 복잡 솔루션처럼 보인다,하지만 난 더 이상 우아한 하나가 있다고 생각 (또는 나는 그것을보기 위해 지금 너무 졸려 있을지도 모른다). 그리고 이것이 효과가 있습니다.

+0

정말 고마워, 내가 이것을 시도하고 그것이 작동하는지 보자 :) – diminuta

+1

@diminuta, 그것은 나의 기쁨이야 :). 나는 그것을 테스트했고 효과가있다. 뭔가 잘못되었을 때 알려주세요. –

+1

위대한 !! 그것은 작동합니다 :) 대단히 감사합니다! – diminuta

관련 문제