Djangoroidの奮闘記

python,django,angularJS1~三十路過ぎたプログラマーの奮闘記

Django e-commerce part49 jQuery Flash Message

jQueryでフラッシュメッセージを表示させる。

product_detail.html に試しに入れてみる。

<div class="alert alert-success alert-dismissible" role="alert">
  <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
  <strong>Warning!</strong> Better check yourself, you're not looking too good.
</div>

さらに修正してみる。

<div class='container container-alert-flash'>
    <div class='col-sm-3 col-sm-offset-8'>
        <div class="alert alert-success alert-dismissible" role="alert">
          <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
          <strong>Warning!</strong> Better check yourself, you're not looking too good.
        </div>
    </div>
</div>

container-alert-flashのstyleを修正してみる。

.container-alert-flash{
    position: absolute;
    top: 10px;
    z-indes: 50000;
    width: 100%;
    right: 0%;
    margin: 0px;
    display:none;
}

alert messageだけを切り離して、messageのtemplateを作成する。

alert.html

<div class='container container-alert-flash'>
    <div class='col-sm-3 col-sm-offset-8'>
        <div class="alert alert-success alert-dismissible" role="alert">
          <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
          <strong>Warning!</strong> Better check yourself, you're not looking too good.
        </div>
    </div>
</div>

jQueryは、""ダブルクオートではなく、'シングルクオートを使うため、書き換えておく。

alert.html

<div class='container container-alert-flash'>
    <div class='col-sm-3 col-sm-offset-8'>
        <div class='alert alert-success alert-dismissible' role='alert'>
          <button type='button' class='close' data-dismiss='alert' aria-label='Close'><span aria-hidden='true'>&times;</span></button>
          <strong>Warning!</strong> Better check yourself, you're not looking too good.
        </div>
    </div>
</div>

jQueryにinclude で入力する。

$("#submit-btn").click(function(event){
    event.preventDefault();
    var formData = $("#add-form").serialize();
    console.log(formData);
    $.ajax({
        type: "GET", //"POST"
        url: "{% url 'cart' %}",
        data: formData,
        success: function(data){
            $("#jquery-message").text("Added " + data.item_added + " Deleted " + data.deleted)

            var template = "{% include 'alert.html' %}"
            console.log(template)

        },
  ...

ただ、このままだとerrorが出てしまうので、解消する必要あり。 errorの内容は、jQueryは、改行とかスペースがあると、うまく処理できないという感じのもの。 例えば、上記の例だと、var template = "<alert.htmlの内容>" という風に、丸ごとalert.htmlの内容がそのまま代入される。そのため、改行などなしで、1行の文として渡す必要あり。

さっき、シングルクオートにしたのはそのため。

alert.html のスペースなどをなくす。

<div class='container container-alert-flash'><div class='col-sm-3 col-sm-offset-8'><div class='alert alert-success alert-dismissible'role='alert'><button type='button' class='close' data-dismiss='alert' aria-label='Close'><span aria-hidden='true'>&times;</span></button><strong>Warning!</strong>Better check yourself, youre not looking too good.</div></div></div>

ここでAtom利用者は注意!

editorで、Atomを使っていると、saveの時に、最後の行に、自動で改行を追加する仕様になっている。 そのため、alert.htmlもそのまま保存すると、最後に改行が入ってしまい、うまくjQueryで読み込めない。

Atomで保存時の処理の設定を変更する - たけぞう瀕死ブログ

こちらの方のブログを参照にやってみました。

alertを表示させてみる。

        success: function(data){
            $("#jquery-message").text("Added " + data.item_added + " Deleted " + data.deleted)

            var template = "{% include 'alert.html' %}"
            console.log(template)
            $("body").append(template);
            $(".container-alert-flash").fadeIn();
            setTimeout(function(){
                $(".container-alert-flash").fadeOut();
            }, 1800);
  • $("body") の最後にtemplateを追加して、
  • .container-alert-flashをフェードインさせて
  • setTimeoutで、時間を指定してフェードアウトさせる。

alert messageの箇所を関数にしてみる。

function showFlashMessage(message){
    var template = "{% include 'alert.html' %}"
    $("body").append(template);
    $(".container-alert-flash").fadeIn();
    setTimeout(function(){
        $(".container-alert-flash").fadeOut();
    }, 1800);
}

$("#submit-btn").click(function(event){
    event.preventDefault();
    var formData = $("#add-form").serialize();
    console.log(formData);
    $.ajax({
        type: "GET", //"POST"
        url: "{% url 'cart' %}",
        data: formData,
        success: function(data){
            $("#jquery-message").text("Added " + data.item_added + " Deleted " + data.deleted)
            showFlashMessage("カートに商品が追加されました!")

        },
        error: function(response, error){
            // console.log(response)
            // console.log(error)
            $("#add-form").submit()
        },

    })

ただ、このままだと、指定したmessageは反映されないので、alert.htmlの内容を少し変更する必要あり。

alert.htmlの変更したい部分に変数を設定する。

いつものdjango template言語。

<div class='container container-alert-flash'><div class='col-sm-3 col-sm-offset-8'><div class='alert alert-success alert-dismissible'role='alert'><button type='button' class='close' data-dismiss='alert' aria-label='Close'><span aria-hidden='true'>&times;</span></button><strong>ありがとうございます!</strong>{{ message }}</div></div></div>

product_detail.htmlのshowFlashMessaaageに、引数を反映させるように設定する。

ここもdjango template言語。{% %} with 変数名=引数

function showFlashMessage(message){
    var template = "{% include 'alert.html' with message='" + message + "'%}"
    $("body").append(template);
    $(".container-alert-flash").fadeIn();
    setTimeout(function(){
        $(".container-alert-flash").fadeOut();
    }, 1800);
}

.container-alert-flash をcustom.cssに移す。

showFlashMessage を、custom.jsに移す。

javascript.html にcustom.jsを参照するように記述する。

base.html に, javascript.htmlがincludeされているため。

{% load staticfiles %}
<!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <script src="{% static 'js/bootstrap.min.js' %}"></script>
    <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
    <script src="{% static 'js/ie10-viewport-bug-workaround.js' %}"></script>
    <script src="{% static 'js/custom.js' %}"></script>

customs.js/showFlashMessage の内容を修正する。

var template = "{% include 'alert.html' with message='" + message + "'%}"

この部分がもはや機能しないので、書き換える必要がある。多分、jsファイルには、djangoテンプレート言語が適用できないためだと思われる。

ひとまず、alert.htmlをそのまま代入してみる。

var template = "<div class='container container-alert-flash'><div class='col-sm-3 col-sm-offset-8'><div class='alert alert-success alert-dismissible'role='alert'><button type='button' class='close' data-dismiss='alert' aria-label='Close'><span aria-hidden='true'>&times;</span></button><strong>ありがとうございます!</strong><br/>{{ message }}</div></div></div>"

{{message}}の箇所を、少し書き換える。

    var template = "<div class='container container-alert-flash'><div class='col-sm-3 col-sm-offset-8'><div class='alert alert-success alert-dismissible'role='alert'><button type='button' class='close' data-dismiss='alert' aria-label='Close'><span aria-hidden='true'>&times;</span></button><strong>ありがとうございます!</strong><br/>" + message + "</div></div></div>"

これで動作するはず。

carts/templates/carts/views.htmlも編集してみる。

$.ajax({
        type: "GET", //"POST"
        url: "{% url 'cart' %}",
        data: data,
        success: function(data){
            $("#jquery-message").text("Added " + data.item_added + " Deleted " + data.deleted);
            if (data.deleted){
                $("#item-"+item).fadeOut();
            } else {
                $("#item-line-total-"+item).text(data.line_total);
                $("#subtotal").text(data.subtotal);
            }
            showFlashMessage("カートの中身が更新されました!");
        },

これで更新した時に、メッセージが出るようになった。