読者です 読者をやめる 読者になる 読者になる

修行@ホーチミン

ホーチミン長期出張の日記です

jinja2/Modal/JSの組み合わせで苦戦

やりたいこと

 

  • APIから受け取ったホテルのリストを現在はJinja2テンプレートのfor文を使って表示している。
  • その並んだホテルにそれぞれUpdateボタンを配置。
  • Updateボタンを押したら対象のホテルのModalダイアログが開く。
  • 開いた時点で、Inputの内容は既存のホテルの状態をValueで持っている。
  • 更新ボタンでValidate処理。
  • OKならAjaxで、APIへAjaxでPOSTリクエスト。
  • 更新した結果を表示。

 

苦戦ポイント

 

formをValidateしてAjaxで通信 - 修行@ホーチミン

上記では、新規作成のため既存ホテルを気にすることがなかったので、その調子でUpdateも簡単にできるかと思ったんですけど詰まりました。

 

失敗その① Modalダイアログもfor文で作っちゃおう

 

それぞれ専用のModalダイアログを作るところまではよかったのですが、そもそもidが重複してしまうのでModalダイアログを開くとほかのホテルの内容だったりと..。

そのあとあれこれと試したのですが、記憶から消えてしまいました。

記憶力のなさはほんとにヤバいんでどうにかならないですかね。

 

失敗その② IDの値にホテルIDを使ってみる

 

これでidは一意になるものの、JS側で全部のid専用の実装が必要とかいろいろ考えているうちに、エンジニア的考え方まるでないなと落ち込みつつこの方法はまあないので、すぐにほかの方法を考える。

 

苦肉の策の現在

 

UPDATE専用Modalダイアログを作成

 

これでIdは一意です。

 

<!-- Update Hotel Modal -->
<div class="modal fade bd-example-modal-lg" id="updateHotelModal" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">
                    <span aria-hidden="true">&times;</span>
                </button>
                <h4 class="modal-title" id="modal-label">Update Hotel</h4>
            </div>
            <div class="modal-body">

            <form id="updateHotel">
                    <input type="hidden" name="id" id="updId" value="">
                <div class="form-group">
                    <label for="updName" class="form-control-label">Hotel Name:</label>
                    <input type="text" class="form-control" name="updName" id="updName" value="">
                </div>
                <div class="form-group">
                    <label for="updAddress" class="form-control-label">Hotel Address:</label>
                    <input type="text" class="form-control" name="updAddress" id="updAddress" value="">
                </div>
                <div class="form-group">
                    <label for="updCountryCode" class="form-control-label">Country Code:</label>
                    <input type="text" class="form-control" maxlength="2" name="updCountryCode" id="updCountryCode" value="">
                </div>
                <div class="form-group">
                    <label for="updCityCode" class="form-control-label">City Code:</label>
                    <input type="text" class="form-control" maxlength="3" name="updCityCode" id="updCityCode" value="">
                </div>
                    <div class="form-group">
                        <label for="updGrade">Hotel Grade:</label><br>
                        <select class="span1" name="updGrade" id="updGrade">
                        <option>1</option>
                        <option>2</option>
                        <option>3</option>
                        <option>4</option>
                        <option>5</option>
                        </select>
                    </div>
                <div class="form-group">
                    <label for="updFacility" class="form-control-label">Hotel Facility:</label>
                    <input type="text" class="form-control" name="updFacility" id="updFacility" value="">
                </div>
                <div class="form-group">
                    <label for="updImagePath" class="form-control-label">Image URL:</label>
                    <input type="text" class="form-control" name="updImagePath" id="updImagePath" value="">
                </div>
                <img class="img-responsive" id="updImage" >
            </form>

            </div>
            <div class="modal-footer">
                <div id="response_parameter" ></div>
                <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
                <button type="button" id="updateBtn" class="btn btn-primary">Update</button>
            </div>
        </div>
    </div>
</div>
<!-- End Update Hotel Modal -->

 

Modalダイアログ動的に変更

 

それぞれのホテル更新用にModalダイアログを作成すべく、Jinja2のホテルリスト表示用for文の中に下記ボタン設置。

※ボタン以外省略  

{% for hotel in data.hotels %}

        <button class="btn btn-warning" type="button" onclick="createUpdateHotelmodal( {{ hotel | to_json }} )">Update</button>

{% endfor %}

 

Modalダイアログに対象ホテルのvalue埋め込み ⇒ Modalダイアログ開く

 

function createUpdateHotelmodal( data ){
    $('#updId').val(data.id);
    $('#updName').val(data.name);
    $('#updAddress').val(data.address);
    $('#updCountryCode').val(data.countryCode);
    $('#updCityCode').val(data.cityCode);
    $('#updGrade').val(data.grade);
    $('#updFacility').val(data.facility);
    $('#updImagePath').val(data.imagePath);
    $('#updateHotelModal').modal('show');
}

 

Updateボタン押下で、validate ⇒ Ajax通信 ⇒ 結果表示

 

    $("#updateBtn").click(function(){
        $("#updateHotel").validate(hotelUpdateValid);
        if (!$("#updateHotel").valid()) {
            return false;
        };
        $.ajax( {
            type: "POST",
            url: "/hotel/update",
            dataType: "json",
            data: {
                "id" : $('#updId').val(),
                "name" : $('#updName').val(),
                "address" : $('#updAddress').val(),
                "countryCode" : $('#updCountryCode').val(),
                "cityCode" : $('#updCityCode').val(),
                "grade" : $('#updGrade').val(),
                "facility" : $('#updFacility').val(),
                "imagePath" : $('#updImagePath').val()
            }
        }).done(function( response ){
            alert( "Hotel Id = " + response.data.hotel.id + " updated." );
        }).fail(function( data ){
            alert( "faild" );
        });

 

これで一応要件を満たした動きはしてくれていそうですが、あまりお勧めとしない方法だそうでして。

しかし...その後いろいろと調べてみたものの、やはりほかの方法でうまく処理する方法が思いつきませんでした。

せっかくアドバイスいただいたのに、すみません..。

 

でもまだ時間あるので、手を動かしながらかんがえます。