36

誰かが 4 月にまったく同じ質問をしましたが、答えはありませんでした。しかし、彼が提供した情報が少なすぎたので。質問は放棄されました。

私も同じ問題を抱えてる。内にmain_page.html次の行があります。

<a href="/contact/edit/{{ item.id }}" title="Edit">edit</a>

そこをクリックすると、編集テンプレートが Twitter ブートストラップ モーダル内に表示されます。

url.py

(r'^contact/edit/(?P<contact_id>\d+)/$', contact_view),

view.py

def contact_view(request, contact_id=None):
    profile = request.user.get_profile()
    if contact_id is None:
        contact = Contact(company=profile.company)
        template_title = _(u'Add Contact')
    else:
        contact = get_object_or_404(profile.company.contact_set.all(), pk=contact_id)
        template_title = _(u'Edit Contact')
    if request.POST:
        if request.POST.get('cancel', None):
            return HttpResponseRedirect('/')
        form = ContactsForm(profile.company, request.POST, instance=contact)
        if form.is_valid():
            contact = form.save()
            return HttpResponseRedirect('/')
    else:
        form = ContactsForm(instance=contact, company=profile.company)
    variables = RequestContext(request, {'form':form, 'template_title': template_title})
    return render_to_response("contact.html", variables)

通常、contact.htmlは次のようになります。

        <form class="well" method="post" action=".">
            {% csrf_token %}
            {{form.as_p}}
            <input class="btn btn-primary" type="submit" value="Save" />
            <input name="cancel" class="btn" type="submit" value="Cancel"/>
        </form>

私はそれを中に入れることができました<div class="modal-body">。しかし、ビューからモーダルを開くにはどうすればよいですか?

4

2 に答える 2

51

モーダルの外で連絡フォームを使用する必要がない限り、これでうまくいくはずです。他の場所で使用する必要がある場合は、2 つのバージョン (1 つはモーダル、もう 1 つは非モーダル) を維持します。また、ヒント - django-crispy-formsにルックオーバーを与える - twitter-bootstrap クラスでフォームをレンダリングするのに役立ちます。

contact.html:

<div class="modal hide" id="contactModal">
<form class="well" method="post" action="/contact/edit/{{ item.id }}">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal">×</button>
    <h3>Editing Contact</h3>
  </div>
  <div class="modal-body">
       {% csrf_token %}
       {{form.as_p}}
  </div>
  <div class="modal-footer">
       <input class="btn btn-primary" type="submit" value="Save" />
       <input name="cancel" class="btn" type="submit" value="Cancel"/>
  </div>
</form>
</div>

main_page.html

<html>
...

<a data-toggle="modal" href="#contactModal">Edit Contact</a>

{% include "contact.html" %}

...
</html>

編集:

複数のフォームが存在する可能性があることがわかったので、各フォームを html 内に非表示にレンダリングするのはおそらく悪い考えです。おそらく、ajax-y バージョンに移動して、各フォームをオンデマンドでロードすることをお勧めします。ここでは、フォームの送信時にページ全体がリロードされると想定しています。フォームを非同期で送信する場合は、別の場所に回答があります

contact.htmlフラグメントを再定義することから始めます。モーダル内でレンダリングし、モーダルをうまく操作するために必要なすべてのマークアップを含める必要があります。元々持っているビューは問題ありませんが、フォームが無効なcontact場合を除いて、をレンダリングすることになり、他には何もありません。contact.html

<form class="well contact-form" method="post" action="/contact/edit/{{ item.id }}">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal">×</button>
    <h3>Editing Contact</h3>
  </div>
  <div class="modal-body">
       {% csrf_token %}
       {{form.as_p}} <!-- {{form|crispy}} if you use django-crispy-forms -->
  </div>
  <div class="modal-footer">
       <input class="btn btn-primary" type="submit" value="Save" />
       <input name="cancel" class="btn" type="submit" value="Cancel"/>
  </div>
</form>

そして今、あなたのmain_page.html

<html>
.. snip ..

<a class="contact" href="#" data-form="/contact/edit/{{ item.id }}" title="Edit">edit</a>
<a class="contact" href="#" data-form="/contact/edit/{{ item.id }}" title="Edit">edit</a>
<a class="contact" href="#" data-form="/contact/edit/{{ item.id }}" title="Edit">edit</a>

<div class="modal hide" id="contactModal">
</div>

<script>
    $(".contact").click(function(ev) { // for each edit contact url
        ev.preventDefault(); // prevent navigation
        var url = $(this).data("form"); // get the contact form url
        $("#contactModal").load(url, function() { // load the url into the modal
            $(this).modal('show'); // display the modal on url load
        });
        return false; // prevent the click propagation
    });

    $('.contact-form').live('submit', function() {
        $.ajax({ 
            type: $(this).attr('method'), 
            url: this.action, 
            data: $(this).serialize(),
            context: this,
            success: function(data, status) {
                $('#contactModal').html(data);
            }
        });
        return false;
    });
</script>

.. snip ..
</html>

これはすべてテストされていませんが、開始/反復するのに適した場所になるはずです。

于 2012-06-30T17:48:00.060 に答える
1

この投稿に遭遇したとき、私は同じ問題を抱えていました。私はこの解決策を試しましたが、実際にはうまくいきませんでした(しかしそれは私に方向性を与えました)。私は自分に合った解決策を思いついたのですが、それはハッキーな感じがするので、それをより良くする方法についていくつかの指針を受け取りたいと思います。

問題は同じです:Twitter Boostrapモーダルとdjangoフォーム内にフォームを表示します(django汎用フォームビューを使用してモデルを編集/追加します)

だから私がしたこと:

main.html

<script type="text/javascript">
    function genericLoadDialog(form_selector, dialog_selector, matchString){
        $.ajax({
            url: $(form_selector).attr('action'),
            type: 'POST',
            data:  $(form_selector).serialize(),
            success: function(data, textStatus, jqXHR){
                if(data.match(matchString)){
                // We got errors in form
                    $(dialog_selector).html(data).modal('show');
                            return false;
                }
                        $(dialog_selector).modal('hide');
            },
        })
    }
</script>

<body>
<div class="modal hide" id="{{ editor_dialog_id }}"></div>
<a data-toggle="modal" href="#{{ editor_dialog_id }}" onclick="$('#{{ editor_dialog_id }}').load('/create/form');">Title</a>
<body>

editor.html

<form id="{{ editor_form_id }}" action="{{ submit_url }}" method="POST">
    <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal">×</button>
        <h3>Modal header</h3>
    </div>
    <div class="modal-body" id="editor-dialog-body">
        {% if not form.is_valid %}
            <div class='hide'>invalid_form</div>
        {% endif %}
        {% csrf_token %}
        {{ form.as_p }}
    </div>
    <div class="modal-footer">
       <a href="#" class="btn" data-dismiss="modal">Cancel</a>
       <a href="#" data-toggle="modal" class="btn btn-primary" onclick="genericLoadDialog('#{{ editor_form_id }}', '#{{ editor_dialog_id }}', null, 'invalid_form');">Save</a>
    </div>
</form>

したがって、フローは次のとおりです。

  • タグをクリックすると、フォームの作成URLからモーダルdivにフォームが読み込まれます。
  • genericLoadDialog関数をトリガーするモーダル(送信)の保存ボタンをクリックします。このロードにより、フォームから収集されたデータを使用してフォームURLを作成するPOSTリクエストが作成されます
  • フォームが無効な場合は、モーダルhtmlをリロードしてエラーフィールドを表示します。それ以外の場合は、モーダルを閉じてdjangoを保存/リダイレクトする必要があります(djangoフォームビューでget_success_urlメソッドを使用しますが、何らかの理由で機能しません。オブジェクトは保存されます)

フォームがgenericLoadDialogで有効かどうかを確認する方法に不安があります。誰かがより良いアイデアを持っていれば、それがいいでしょう。

于 2012-07-07T10:51:46.437 に答える