Django Project - начальная навигация с не работающим JavaScript-скриптом - Куда должен идти JavaScript? - PullRequest
1 голос
/ 28 мая 2019

У меня есть проект Django, в котором у меня есть простая горизонтальная навигационная панель начальной загрузки (взято отсюда: https://www.w3schools.com/bootstrap4/tryit.asp?filename=trybs_ref_js_tab_js&stacked=h).

В нем пользователь нажимает на вкладку, и она отображает информацию об этой вкладке при нажатии.

В этом случае я использовал язык шаблонов django и хрустящие формы для создания формы внутри вкладки 1. Это хорошо отрисовывается и выглядит правильно с точки зрения форматирования и компоновки, но вкладки не работают. Я рассмотрел другие вопросы, связанные со стековым потоком, но ни один из них не относится конкретно к тому, что я спрашиваю.

Функциональность вкладок, как я полагаю, контролируется фрагментом кода Javascript:

<script>
$(document).ready(function(){
  $(".nav-tabs a").click(function(){
    $(this).tab('show');
  });
});
</script>

Будучи новичком в Django и дизайне внешнего интерфейса, я изо всех сил пытаюсь увидеть, а) где я допустил ошибку и что нужно исправить, чтобы закладки работали правильно при нажатии. б) как javascript реализован внутри всей структуры HTML-шаблона Django.

Под этим я подразумеваю, что Javascript обычно помещается внутри тегов 'head', но в этом случае шаблоны расширяют базовый шаблон, в котором есть заголовок, поэтому я не уверен, куда должен идти Javascript. Должен ли я, например, использовать внешние файлы Javascript в каждом случае? Что такое лучшая практика? Куда он должен идти по отношению к тому, куда идут "{% блоки" (начало и конец)?

Полезный ответ будет

а) указать на ошибку в коде, чтобы мои вкладки работали б) объяснить немного о макете / структуре, куда идут фрагменты JavaScript, которые расширяют функциональность html / boostrap, внутри шаблона на основе Django и в рамках использования языка шаблонов Django.

Весь код моего profile.html показан ниже

{% extends "socialmedia/base.html" %}
{% load crispy_forms_tags %}
{% block content %}

    <div class="content-section">
      <div class="media">
        <img class="rounded-circle account-img" src="{{ user.profile.image.url }}">
        <div class="media-body">
          <h2 class="account-heading">{{ user.username }}</h2>
          <p class="text-secondary">{{ user.email }}</p>
        </div>
      </div>

      <div class="container mt-3">

  <br>
  <!-- Nav tabs -->
  <ul class="nav nav-tabs">
    <li class="nav-item">
      <a class="nav-link active" href="#home">Tab 1</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="#menu1">Tab 2</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="#menu2">Tab 3</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="#menu3">Tab 4</a>
    </li>
  </ul>

  <!-- Tab panes -->
  <div class="tab-content">
    <div id="home" class="container tab-pane active"><br>
      <h3>Tab 1</h3>
      <p>Please fill in your account/profile information here.</p>


     <form method="POST" enctype="multipart/form-data">
        {% csrf_token %}
        <fieldset class="form-group">
            <legend class="border-bottom mb-4">Profile Information</legend>
            {{u_form|crispy}}
            {{p_form|crispy}}
        </fieldset>
        <div class="form-group">
            <button class="btn btn-outline-info" type="submit">Update....</button>
        </div>
    </form>
   </div>
    </div>

    <div id="menu1" class="container tab-pane fade"><br>
      <h3>Tab 2</h3>
      <p>Tab 2 information here</p>
    </div>
    <div id="menu2" class="container tab-pane fade"><br>
      <h3>Tab 3</h3>
      <p>Tab 3 information will go here</p>
    </div>
    <div id="menu3" class="container tab-pane fade"><br>
      <h3>Calendar</h3>
      <p>Manage your Calendar</p>
    </div>
  </div>
</div>
{% endblock content %}   
<script>
$(document).ready(function(){
  $(".nav-tabs a").click(function(){
    $(this).tab('show');
  });
});
</script>

То, что я пробовал: я пытался разместить код javascript в разных местах - например, перед {% endblock content%} и в верхней части страницы, но ни один из них не работал.

Обновление:

Я заметил, что выше cdn / css не был добавлен. При добавлении этого, это портит форматирование и щелчок, вроде как работает, но не правильно.

Обновленный код указан ниже. Опять же, мне нужны предложения относительно того, где правильно разместить этот блок кода для правильного форматирования и функциональности, а также код JavaScript.

  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>

Обновлено profile.html

Следующее теперь отображает страницу неправильно, перемещая изображение вверху и переменные имени пользователя и электронной почты нежелательным образом. Кроме того, вкладки работают, но не полностью. Хрустящая форма создается на каждой вкладке, а не только на первой, а содержимое других вкладок показано под ней.

{% extends "socialmedia/base.html" %}
{% load crispy_forms_tags %}
{% block content %}

<!--- this code has been added as per the update above -->

  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>



    <div class="content-section">
      <div class="media">
        <img class="rounded-circle account-img" src="{{ user.profile.image.url }}">
        <div class="media-body">
          <h2 class="account-heading">{{ user.username }}</h2>
          <p class="text-secondary">{{ user.email }}</p>
        </div>
      </div>

      <div class="container mt-3">

  <br>
  <!-- Nav tabs -->
  <ul class="nav nav-tabs">
    <li class="nav-item">
      <a class="nav-link active" href="#home">Tab 1</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="#menu1">Tab 2</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="#menu2">Tab 3</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="#menu3">Tab 4</a>
    </li>
  </ul>

  <!-- Tab panes -->
  <div class="tab-content">
    <div id="home" class="container tab-pane active"><br>
      <h3>Tab 1</h3>
      <p>Please fill in your account/profile information here.</p>


     <form method="POST" enctype="multipart/form-data">
        {% csrf_token %}
        <fieldset class="form-group">
            <legend class="border-bottom mb-4">Profile Information</legend>
            {{u_form|crispy}}
            {{p_form|crispy}}
        </fieldset>
        <div class="form-group">
            <button class="btn btn-outline-info" type="submit">Update....</button>
        </div>
    </form>
   </div>
    </div>

    <div id="menu1" class="container tab-pane fade"><br>
      <h3>Tab 2</h3>
      <p>Tab 2 information here</p>
    </div>
    <div id="menu2" class="container tab-pane fade"><br>
      <h3>Tab 3</h3>
      <p>Tab 3 information will go here</p>
    </div>
    <div id="menu3" class="container tab-pane fade"><br>
      <h3>Calendar</h3>
      <p>Manage your Calendar</p>
    </div>
  </div>
</div>
{% endblock content %}   
<script>
$(document).ready(function(){
  $(".nav-tabs a").click(function(){
    $(this).tab('show');
  });
});
</script>

Я также включаю свой базовый шаблон, base.html (который включает в себя голову и тело) ниже.

{% load static %}
<html>
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

{% if title %}
    <title>Fakebook Blog Posts - {{title}}</title>
{% else %}
    <title>Fakebook Blog</title>
{% endif %}

<!--this is django templating language-->
<link rel="stylesheet" href="{% static 'worldguestbook\main2.css' %}"/>

</head>
<body>

<header class="site-header">
  <nav class="navbar navbar-expand-md navbar-dark bg-steel fixed-top">
    <div class="container">
      <a class="navbar-brand mr-4" href="/">FakeBook Newsfeed</a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarToggle" aria-controls="navbarToggle" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarToggle">
        <div class="navbar-nav mr-auto">
          <a class="nav-item nav-link" href="{% url 'socialmedia-home' %}">Home</a>
          <a class="nav-item nav-link" href="{% url 'socialmedia-about' %}">About</a>
        </div>
        <!-- Navbar Right Side -->
        <div class="navbar-nav">
            {% if user.is_authenticated %}
                <a class="nav-item nav-link" href="{% url 'post-create' %}">New Post</a>
                <a class="nav-item nav-link" href="{% url 'profile' %}">Profile</a>
                <a class="nav-item nav-link" href="{% url 'logout' %}">Logout</a>

            {% else %}
              <a class="nav-item nav-link" href="{% url 'login' %}">Login</a>
              <a class="nav-item nav-link" href="{% url 'register' %}">Register</a>
            {% endif %}
        </div>
      </div>
    </div>
  </nav>
</header>

<main role="main" class="container">
  <div class="row">
    <div class="col-md-8">
        {% if messages %}
            {% for message in messages %}
                <div class="alert alert-{{message.tags}}">
                    {{ message }}
                </div>
            {% endfor %}
        {% endif %}

      {% block content %}{% endblock %}
    </div>
    <div class="col-md-4">
      <div class="content-section">
        <h3>Our Sidebar</h3>
        <p class='text-muted'>You can put any information here you'd like.
          <ul class="list-group">
            <li class="list-group-item list-group-item-light">Latest Posts</li>
            <li class="list-group-item list-group-item-light">Announcements</li>
            <li class="list-group-item list-group-item-light">Calendars</li>
            <li class="list-group-item list-group-item-light">etc</li>
          </ul>
        </p>
      </div>
    </div>
  </div>
</main>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>

Я наткнулся на возможный ответ (не на stackoverflow), который предполагал, что добавление блока DTL в базовый шаблон выглядит так:

{% block extra_js %}{% endblock extra_js %}

и затем добавление скрипта внутри этих тегов на странице profile.html будет работать, но это не так. (см. ниже дополнение, которое я пробовал)

добавлено в base.html ...

<body>
{% block extra_js %}{% endblock extra_js %}

<header class="site-header">
  <nav class="navbar navbar-expand-md navbar-dark bg-steel fixed-top">
    <div class="container">

в profile.html ....

      <h3>Calendar</h3>
      <p>Manage your Calendar</p>
    </div>
  </div>
</div>
{% block extra_js %}
<script>
$(document).ready(function(){
  $(".nav-tabs a").click(function(){
    $(this).tab('show');
  });
});
</script>
{% endblock extra_js %}
{% endblock content %}   

Выше не работает вообще.

Но при добавлении еще большего количества блоков в базу и последующем добавлении CSS в эти блоки в файле profile.html возникает та же проблема, что и описанная выше. (вкладки можно нажимать, но содержимое формы отображается во всех из них, а также содержимое вкладок создается внизу, как переполнение).

Чтобы уточнить, ниже добавлено в profile.html

{% block extra_css %}
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
{% endblock extra_css %}

с этим добавленным к base.html (в голове)

<head>
{% block extra_css %}{% endblock extra_css %}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...