У меня есть проект 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 %}