web-dev-qa-db-ja.com

編集で選択された胸腺の複数

この質問の一部が回答されたため、私はこの質問を完全に変更します ここ Avnishの多大な支援により!トムは私を正しい方向に導いてくれたので、ありがとうトム!

私の問題は、編集時にオブジェクト要素を事前選択するように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、...]などのIDの文字列は返されず、Partインスタンスが返されます[Part @ 43b45j、Part @ we43y7、...]のように...

[〜#〜] update [〜#〜]:1つのパーツのみが選択されている場合、これが機能することに気づきました:

<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>

複数のパーツが選択されている場合、機能しません...

15
Blejzer

Thymeleafフォーラムでの議論の後、私は https://github.com/jmiguelsamper/thymeleafexamples-selectmultiple で完全に機能する例を実装しました

最終コードの唯一の問題は、conversionServiceを呼び出すために二重ブラケット構文を使用する必要があることだと思います:

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

適切な比較を保証するために、Partクラスに適切なequals()およびhashcode()メソッドを実装することも重要です。

私の例が将来同様の問題を持つ他のユーザーを助けることを願っています。

13
user211430

th:selectedを通常使用する場合、th:fieldは必要ありません。 Thymeleafは、multipleであっても、<option>の各<select>の値を自動的にチェックします

問題は価値にあります。 partsを反復処理していますが、各オプションの値はpart.idです。したがって、あなたはpartのインスタンスをpartのidと比較しています(私が見る限り)。

ただし、Thymeleafは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
        }
    }
}

ConvertingPropertyEditorAdapterもご覧ください。 Converterに登録されているconversionServiceインスタンスは、最近のSpringでより好まれています。

7
Tom Verelst

これは私にとってはうまくいきます:

獣医には多くの専門があります。

コントローラ:

_@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;     
}
_

表示(th:selectedを使用):

_<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>
_

表示(th:fieldを使用):

_<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>
_

そして、SpecialtyRepositoryでSpecialty findOne(@Param("id") Integer id) throws DataAccessException;を定義する必要があります。そうしないと、次の例外がスローされます:「Java.lang.IllegalStateException:リポジトリでfind-one-methodが宣言されていません!」

_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;
}
_
1
Gabriel
<select id="produtos" name="selectedItens" style="width: 100%;" multiple="multiple" required="">
                <option th:value="${p.id}" th:text="${p}" th:each="p : ${slideShowForm.itens}" th:selected="${#lists.contains(slideShowForm.selectedItens,p)}"></option>
            </select>
0
viniciusalvess

ここに私がそれをした方法があります:

  <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;
0