2014-03-07 66 views
11

我完全改变这个问题,因为它的一部分在Avnish的大力帮助下回答了here! 汤姆把我送到了正确的方向,所以谢谢汤姆!百里香多次选编辑

我的问题是,我不知道如何告诉Thymeleaf在编辑时预先选择对象元素。

让我告诉你:

looks like this

此解决方案:

 <select class="form-control" id="parts" name="parts" multiple="multiple" > 
      <option th:each="part : ${partsAtribute}" 
        th:selected="${servisAttribute.parts.contains(part)}" 
        th:value="${part.id}" 
        th:text="${part.name}">Part name</option> 
     </select> 

我已经试过这样:

  <select class="form-control" th:field="*{parts}" multiple="multiple" > 
      <option th:each="part : ${partsAtribute}" 
        th:field="*{parts}" 
        th:value="${part.id}" 
        th:text="${part.name}">Part name</option> 
      </select> 

没有工作。我也试过这个:

  <select class="form-control" th:field="*{{parts}}" multiple="multiple" > 
      <option th:each="part : ${partsAtribute}" 
        th:field="*{parts}" 
        th:value="${part.id}" 
        th:text="${part.name}">Part name</option> 
      </select> 

也没有工作。我已经尝试从选项标记中删除th:field =“* {parts}”,结果相同。

如果我将th:value更改为$ {part},但它不会返回字符串像[2,4,5,6,...],但部分实例像[部分@ 43b45j,部分@ we43y7,...] ...

更新:我只是注意到,这只适用于一部分选择:

<select class="form-control" th:field="*{parts}" multiple="multiple" > 
      <option th:each="part : ${partsAtribute}" 
        th:field="*{parts}" 
        th:value="${part.id}" 
        th:text="${part.name}">Part name</option> 
      </select> 

如果选择多个部件,这是行不通的......

回答

11

在Thymeleaf论坛讨论之后,我在 https://github.com/jmiguelsamper/thymeleafexamples-selectmultiple

实现一个完整的工作的例子,我想,以你的最终代码的唯一问题是,你必须使用双括号的语法来调用conversionService:

th:value="${{part}}" 

在Part类中实现正确的equals()和hashcode()方法以确保正确比较也很重要。

我希望我的例子能够帮助其他未来有类似问题的用户。

+4

这是必须的:“在Part类中实现正确的equals()和hashcode()方法以确保正确比较也很重要。” – Blejzer

7

使用01时,您不需要正常。 Thymeleaf会自动检查每个<option>值在<select>,哪怕是multiple

问题在于价值。您正在迭代parts,但每个选项的值为part.id。因此,您正在比较零件的实例与零件的ID(据我所知)。

但是,百里香也考虑到PropertyEditor(它重用org.springframework.web.servlet.tags.form.SelectedValueComparator)的情况。

这将用于比较对象与选项的值。它会将对象转换为它们的文本值(它们的id)并将其与该值进行比较。

<select class="form-control" th:field="*{parts}" multiple="multiple" > 
     <option th:each="part : ${partsAttribute}" 
       <!-- 
        Enable the SpringOptionFieldAttrProcessor . 
        th:field value of option must be equal to that of the select tag 
       --> 
       th:field="*{parts}" 
       th:value="${part.id}" 
       th:text="${part.name} + ${part.serial}">Part name and serial No.      
     </option> 
</select> 

属性编辑器

定义零件一个PropertyEditor。在比较这些值时以及将这些部分绑定到表单时,将调用PropertyEditor。

@Controller 
public class PartsController { 
    @Autowired 
    private VehicleService vehicleService; 

    @InitBinder(value="parts") 
    protected void initBinder(final WebDataBinder binder) { 
     binder.registerCustomEditor(Part.class, new PartPropertyEditor()); 
    } 

    private static class PartPropertyEditor extends PropertyEditorSupport { 
     @Override 
     public void setAsText(String partId) { 
      final Part part = ...; // Get part based on the id 
      setValue(part); 
     } 

     /** 
     * This is called when checking if an option is selected 
     */ 
     @Override 
     public String getAsText() { 
      return ((Part)getValue()).getId(); // don't forget null checking 
     } 
    } 
} 

另请参阅ConvertingPropertyEditorAdapterConverter现在在Spring中更优选在conversionService中注册的实例。

+0

谢谢你为这个伟大的答案。我已经做出调整并实施了您的建议,当然它仍然不起作用。我没有得到任何错误或任何东西,只是...你能告诉我在哪里寻找转换器的例子或文档,我发现所有的是Spring API ...只是这样我才能理解这个定制自定义编辑器如何做它是什么应该这样做... – Blejzer

+0

我最终实现了转换器。它花了一些时间,但它的工作。这次真是万分感谢。我尝试使用自定义属性编辑器,它也可以正常工作。我不能让百里香去工作。我将编辑我的问题,以便您和其他人可以看到...... – Blejzer

0
<select th:field="*{groupId}" > 
    <option th:each="group :${grouptype}" 
      th:value="${{group.groupId}}" 
      th:text="${group.Desc}"> 

    </option> 
</select> 

简单的选择例如

0

这个工作对我来说:

兽医有很多特色菜。

控制器:

@RequestMapping(value = "/vets/{vetId}/edit", method = RequestMethod.GET) 
public ModelAndView editVet(@PathVariable("vetId") int ownerId/*, Model model*/) { 

    ModelAndView mav = new ModelAndView("vets/vetEdit"); 

    mav.addObject("vet", this.vets.findById(ownerId)); 

    mav.addObject("allSpecialties", this.specialities.findAll());   

    return mav;  
} 

视图(使用日:选择):

<select id="specialities" class="form-control" multiple> 
      <option th:each="s : ${allSpecialties}"           
        th:value="${s.id}" 
        th:text="${s.name}" 
        th:selected="${vet.specialties.contains(s)}"> 
      </option> 
     </select> 

视图(使用日:字段):

<form th:object="${vet}" class="form-horizontal" id="add-vet-form" method="post"> 
    <div class="form-group has-feedback"> 
     <select th:field="*{specialties}" class="form-control" multiple> 
      <option th:each="s : ${allSpecialties}"           
        th:value="${s.id}" 
        th:text="${s.name}" 
        >    
      </option> 
     </select>   
    </div> 

我必须定义Specialty findOne(@Param("id") Integer id) throws DataAccessException;在SpecialtyRepository,否则会引发以下异常:“java.lang.IllegalStateException:Repository doe没有发现一种方法!“

package org.springframework.samples.petclinic.vet; 

import java.util.Collection; 

import org.springframework.dao.DataAccessException; 
import org.springframework.data.repository.Repository; 
import org.springframework.data.repository.query.Param; 
import org.springframework.transaction.annotation.Transactional; 

public interface SpecialtyRepository extends Repository<Specialty, Integer> { 

    @Transactional(readOnly = true) 
    Collection<Specialty> findAll() throws DataAccessException; 

    Specialty findOne(@Param("id") Integer id) throws DataAccessException; 
} 
0

我是这样做的:

<select th:field="*{influenceIds}" ID="txtCategoryName" class="m-wrap large" multiple="multiple"> 
    <option th:each="influence : ${influences}" th:value="${influence.get('id')}" th:text="${influence.get('influence')}" ></option> 
</select> 

我的DTO包含:

private List<String> influenceIds;