I'm trying to make a left side navigation bar where by-default categories are listed and while clicking on a category, the subcategories are shown under it (in sort expanding sub-menu). I'm working in Django and relevant portions of my code are below. When I include the JS code, none of the links on the page work and when I exclude it, all the subcategories for all categories are shown by-default. I need only categories to be shown by default and while clicking on any, the respective subcategories be shown. What I'm missing here?
JS CODE: at the bottom of the page, loaded after the footer:
{% block theme_script %}
<script src="{% static " pinax/js/theme.js " %}"></script>
<script>
$(function() {
$(".nav-collapse88").hide();
$(".nav-collapse89 a").click(function(e) {
e.preventDefault();
$(".nav-collapse88", $(this).parent()).slideToggle();
});
})
</script>
{% endblock %}
My HTML:
My CATEGORYINDEX.HTML TEMPLATE:
{% load staticfiles %}
{% load i18n pybb_tags forumindexlistbycat %}
{% catindexlist as catindexlisted %}
{% block body %}
<div class="col-md-12 col-xs-12 body-container leftsidenavigator" style="margin-top:15px;">
<div class="col-md-12 col-xs-12 leftsidenavigator-inner" style="padding:0px;">
<h2><center>Categories</center></h2>
<ul class="catindexlist catlistcat nav-collapse89">
{% for category in catindexlisted %}
<div class="catindexlistitem">
<li class="category-name" style="font-weight:600;padding-right:20px;">{{category.name}}</li></div>
<div class="nav-collapse88">
<ul style="padding:0px;">
{% for forum in category|forumindexlistbycat %}
<div class="catlistforum"><li style="padding-right:10px;">{{forum.name}}</li></div>
{% endfor %}
</ul>
</div>
{% endfor %}
</ul>
</div>
</div>
{% endblock %}
MY SITE_BASE.HTML:
<div class="col-md-2" style="border-right:solid;text-align:right;height:99%;padding:0 0 0 0px;" id="sidebar"> {% include "categoryindex.html" %} </div>
All who answer will win a magical Pony! Thanks,
Using the concept of parent siblings you can do that as:
Code Snippet
$(function() {
$(".category-name a").parent('li').parent('div').siblings('div').hide();
$(".category-name a").click(function(e) {
e.preventDefault();
$(".category-name a").parent('li').parent('div').siblings('div').slideUp();
if(!($(this).parent('li').parent('div').siblings('div').is(":visible"))){
$(this).parent('li').parent('div').siblings('div').slideToggle();
}
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="catindexlist catlistcat nav-collapse89">
{% for category in catindexlisted %}
<div class="catindexlistitem">
<li class="category-name" style="font-weight:600;padding-right:20px;">{{category.name}}01</li>
</div>
<div class="nav-collapse88">
<ul style="padding:0px;">
{% for forum in category|forumindexlistbycat %}
<div class="catlistforum">
<li style="padding-right:10px;">{{forum.name}}01</li>
</div>
{% endfor %}
</ul>
</div>
{% endfor %}
</ul>
<ul class="catindexlist catlistcat nav-collapse89">
{% for category in catindexlisted %}
<div class="catindexlistitem">
<li class="category-name" style="font-weight:600;padding-right:20px;">{{category.name}}02</li>
</div>
<div class="nav-collapse88">
<ul style="padding:0px;">
{% for forum in category|forumindexlistbycat %}
<div class="catlistforum">
<li style="padding-right:10px;">{{forum.name}}02</li>
</div>
{% endfor %}
</ul>
</div>
{% endfor %}
</ul>
<ul class="catindexlist catlistcat nav-collapse89">
{% for category in catindexlisted %}
<div class="catindexlistitem">
<li class="category-name" style="font-weight:600;padding-right:20px;">{{category.name}}03</li>
</div>
<div class="nav-collapse88">
<ul style="padding:0px;">
{% for forum in category|forumindexlistbycat %}
<div class="catlistforum">
<li style="padding-right:10px;">{{forum.name}}03</li>
</div>
{% endfor %}
</ul>
</div>
{% endfor %}
</ul>
Related
I have a form and a related formset in my view/template. For several fields I use widgets: Select2 and a calendar (date-picker) from django admin app.
I also use dynamic addition of formset forms.
When I render a template for the first time, all widgets work fine. But when I add new formset form, widgets of this new form don't work.
I've read existing questions on this kind of problem: 1, 2, 3, 4, but they either not applicable for me, or not helping (2 and 3), or may be I am just doing something wrong (most likely - I'm new to it).
Much appreciated for any tips.
HTML:
{% extends "docs/base.html" %}
{% load static %}
{% block extrahead %}
{{ block.super }}
{{ form_matter.media.css }}
<link href="/static/django_select2/select2.min.css" type="text/css" media="screen" rel="stylesheet">
{% endblock %}
{% block content %}
{% if mat_id == None %}
<form id="MatterForm" action="{% url 'matter_create_url' %}" enctype="multipart/form-data" method="post">
{% else %}
<form id="MatterForm" action="{% url 'matter_edit_url' mat_id=mat_id %}" enctype="multipart/form-data" method="post">
{% endif %}
{% csrf_token %}
<fieldset>
{% for field in form_matter %}
<div class="form-row">
{% if field.errors %}
<div>{{ field.errors }}</div>
{% endif %}
<label class="form-label">{{ field.label_tag }}</label>
<div class="form-input">{{ field }}</div>
</div>
{% endfor %}
<h3>RESOLUTIONS</h3>
<div id="form_set">
{{ formset_resolutions.management_form }}
{% for form in formset_resolutions %}
<div class="formset-form">
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
<div class="form-row">
{% if field.errors %}
<div>{{ field.errors }}</div>
{% endif %}
<label class="form-label">{{ field.label_tag }}</label>
<div class="form-input">{{ field }}</div>
</div>
{% endfor %}
</div>
{% endfor %}
</div>
</fieldset>
<br>
<button class="btn" type="button" id="add_form" style="margin: 0 0 0 25px">ADD</button>
<button class="btn" type="submit" style="margin: 0 0 0 25px">SAVE</button>
<br><br><br>
<div id="empty_form" style="display:none">
<div class="formset-form">
{% for field in formset_resolutions.empty_form.visible_fields %}
<div class="form-row">
{% if field.errors %}
<div>{{ field.errors }}</div>
{% endif %}
<label class="form-label">{{ field.label_tag }}</label>
<div class="form-input">{{ field }}</div>
</div>
{% endfor %}
</div>
</div>
</form>
<script type="text/javascript">window.__admin_media_prefix__ = "{% static 'admin/' %}";</script>
<script type="text/javascript" src="/jsi18n/"></script>
<script type="text/javascript" src="/static/js/jquery.js"></script>
<script type="text/javascript" src="/static/django_select2/select2.min.js"></script>
<script>
$('#add_form').on('click', function() {
var form_idx = $('#id_resolution_set-TOTAL_FORMS').val();
$('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
$('#id_resolution_set-TOTAL_FORMS').val(parseInt(form_idx) + 1);
});
</script>
<script>$('div.form-row:has(label.form-label:has(label[for$="-DELETE"]))').css('background-color', '#ffc7c7')</script>
{{ form_matter.media.js }}
{% endblock content %}
In my django project, I am trying to build a menu for navigation on one single site. The navigation should be done by href="#about us" The menu has three sizes, one for big screens (PC), one for medium screens (Tablets), and one for small screens (Phones). The navigation works on PC size menu, but does not work on the other ones. To be clear, all of the menus redirects the user to something like mywebsite.com/info#about us, but just the PC menu actually scrolls the site. There, I fill the menus with some content from a database:
{% block big-menu %}
{% for faq in question_list %}
{{faq.question}}
{% endfor %}
{% endblock %}
{% block small-menu %}
{% for faq in question_list %}
{{faq.question}}
{% endfor %}
{% endblock %}
And there is the template for the menus:
<div class="w3-sidebar w3-bar-block w3-collapse w3-card w3-animate-right w3-hide-small" style="width:300px;right:0;top:0;" id="mySidebar">
<button class="w3-bar-item w3-button w3-large w3-hide-large" onclick="w3_close()"><h3>Menu ×</h3></button>
<a class="w3-bar-item w3-large w3-hide-small w3-hide-medium"><h3>Menu</h3></a>
{% block big-menu %}
{% endblock %}
</div>
<div class="w3-bar-block w3-collapse w3-animate-right w3-hide-large w3-hide-medium w3-light-gray" style="display:none;" id="smallSidebar">
<a class="w3-bar-item w3-large"><h3>Menu</h3></a>
{% block small-menu %}
{% endblock %}
</div>
And there I assign ids to content I am linking to in the menu:
<div class="w3-hide-small w3-hide-medium"style="width: calc(100% - 300px);">
{% for faq in question_list %}
<div class="w3-card-4" id="{{faq.question}}">
<h3 class="w3-container w3-blue">{{faq.question}}</h3>
<div class="w3-container">
{{faq.answer}}
</div>
</div>
{% endfor %}
</div>
<div class="w3-hide-large">
{% for faq in question_list %}
<div class="w3-card-4" id="{{faq.question}}">
<h3 class="w3-container w3-blue">{{faq.question}}</h3>
<div class="w3-container">
{{faq.answer}}
</div>
</div>
{% endfor %}
</div>
There are screenshots of working & not working menu:
The problem was caused by two elements (the big content and the small one) having the same id ({{faq.question}}). So, the fix is as following:
{% block big-menu %}
{% for faq in question_list %}
{{faq.question}}
{% endfor %}
{% endblock %}
{% block small-menu %}
{% for faq in question_list %}
{{faq.question}}
{% endfor %}
{% endblock %}
{% block body %}
<h1>Vitosoft - FAQ</h1>
<div class="w3-hide-small w3-hide-medium"style="width: calc(100% - 300px);">
{% for faq in question_list %}
<div class="w3-card-4" id="{{faq.question}}big">
<h3 class="w3-container w3-blue">{{faq.question}}</h3>
<div class="w3-container">
{{faq.answer}}
</div>
</div>
{% endfor %}
</div>
<div class="w3-hide-large">
{% for faq in question_list %}
<div class="w3-card-4" id="{{faq.question}}">
<h3 class="w3-container w3-blue">{{faq.question}}</h3>
<div class="w3-container">
{{faq.answer}}
</div>
</div>
{% endfor %}
</div>
A jquery script will do it, try the following:
$("a").on('click', function(event) {
# Distinguish the a tags with others by adding a class, like $('a.anchor').click
if (this.hash !== "") {
event.preventDefault(); // prevent the default behavior of the link
var hash = this.hash;
$('html, body').animate({ # With just a smooth animation within 800 miliseconds, we scroll towards the target anchor
scrollTop: $(hash).offset().top // we scroll
}, 800, function(){
// window.location.hash = hash; // Optional here
// this will return the part of the URL that follows the # symbol, including the # symbol.
});
} // End if
});
I have this jQuery script that I do not fully understand. I was wondering why I cannot replace the siblings('div') with a class or id? I think my code doesn't work properly. What I was trying to do is replace some content with a button click, and then the second content, replace it again with the second function.
<script>
$(document).ready(function () {
$('.btnClick').on('click', function () {
var faculty_id = $(this).attr('id');
$('#' + faculty_id + '_tab').show().siblings('div').hide();
});
$('.btnClick2').on('click', function () {
var department_id = $(this).attr('id');
$('#' + department_id + '_tab').show().siblings('div').hide();
});
});
</script>
<div class="row">
<div class="col-md-3">
<div class="jumbotron">
<h4>Search courses</h4>
<hr>
<br>
<ul>
{% for faculty in faculties %}
<li class="btnClick" id="fac_{{ faculty.pk }}">{{ faculty.name }}</li>
<ul>
{% for department in faculty.department_set.all %}
<li class="btnClick2" id="dep_{{ department.pk }}">{{ department.name }}</li>
<ul>
{% for study in studies %}
{% if study.department == department %}
<li>{{ study.name }}</li>
{% endif %}
{% endfor %}
</ul>
{% endfor %}
</ul>
{% endfor %}
</ul>
</div>
</div>
<div class="col-md-9">
<div class="jumbotron">
<div>
<h3>All courses</h3>
<ul>
{% for course in courses %}
<li>
<a class="first" href={{ course.slug }}>{{ course.name }}</a>
</li>
{% endfor %}
</ul>
</div>
{% for faculty in faculties %}
<div id="fac_{{ faculty.pk }}_tab" style="display:none;">
<h3> {{ faculty.name }} courses</h3>
<ul>
{% for department in faculty.department_set.all %}
{% for study in studies %}
{% if study.department == department %}
{% for course in courses %}
{% if course.study_programme == study %}
<li>
<a class="first"
href={{ course.slug }}>{{ course.name }}</a>
</li>
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endfor %}
</ul>
</div>
{% endfor %}
{% for faculty in faculties %}
<ul>
{% for department in faculty.department_set.all %}
<div id="dep_{{ department.pk }}_tab" style="display:none;">
<h3>Department of {{ department.name }} courses</h3>
<ul>
{% for study in studies %}
{% if study.department == department %}
{% for course in courses %}
{% if course.study_programme == study %}
<li>
<a class="first"
href={{ course.slug }}>{{ course.name }}</a>
</li>
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
</ul>
</div>
{% endfor %}
</ul>
{% endfor %}
</div>
</div>
</div>
</div>
Inside my well i have a list that splits to left and right. I want to place users in that list. I want to order them like: Firs one in the left list, second one in the right, third one in the left list, forth in the right... So every second user would be placed in the right list. Here is the html of the well:
<div class="well">
<h4>Users</h4>
<div class="row">
<div class="col-xs-6">
<ul class="list-unstyled">
<li>User1
</li>
<li>User3
</li>
</ul>
</div>
<div class="col-xs-6">
<ul class="list-unstyled">
<li>User2
</li>
<li>User4
</li>
</ul>
</div>
</div>
</div>
Now i cant do it just with classic for loop, because if i do as the below code shows, it would load the whole second list many times:
<div class="col-xs-6">
<ul class="list-unstyled">
{% for user in users %}
<li> {{ user }}
</li>
</ul>
</div>
{% if forloop.counter|divisibleby:2 %}
<div class="col-xs-6">
<ul class="list-unstyled">
<li>{{ user }}
</li>
</ul>
</div>
{% endfor %}
</div>
I would probably have to use forloop.counter|divisibleby:3 but i dont know how to load just users in the second unordered list , without the whole list being copied for every user. Maybe soulution would use javascript too?
I hope you understand my problem :D
Other thing you can do to avoid sending 2 additional arrays is to use divisibleby in this manner.
<div class="col-xs-6">
<ul class="list-unstyled">
{% for user in users %}
{% if not forloop.counter|divisibleby:2 %}
<li>{{ user }}
</li>
{% endif %}
{% endfor %}
</ul>
</div>
<div class="col-xs-6">
<ul class="list-unstyled">
{% for user in users %}
{% if forloop.counter|divisibleby:2 %}
<li>{{ user }}
</li>
{% endif %}
{% endfor %}
</ul>
</div>
EDIT: I figured it out, after two days of trying it just came to me. If anybody is dealing with the same problem; I handled it in views:
def index(request):
users = User.objects.all()
odd_users = users[::2]
even_users = users[1::2]
return render(request, 'index.html', {'users': users, 'odd_users': odd_users, 'even_users': even_users})
And then i just loaded it in template:
<div class="col-xs-6">
<ul class="list-unstyled">
{% for user in odd_users %}
<li>{{ user }}
</li>
{% endfor %}
</ul>
</div>
<div class="col-xs-6">
<ul class="list-unstyled">
{% for user in even_users %}
<li>{{ user }}
</li>
{% endfor %}
</ul>
</div>
Cheers!
On this site http://nashedom.ru there are JS scripts. Most are fast.
The modalka fancybox pages (for login users, in user cabinet, page объявления -> добавление объявления) are very slow. In Chrome loading is 25-28 seconds. In Firefox - 2,5 seconds.
The data is taken out of context.
HTML:
{% load hosts %}
<div class="b-header">
<div class="b-header__menu">
<div class="container">
<div class="row">
<div class="col-xs-12">
<div class="b-menu">
<a>...</a>
<a>...</a>
<a>...</a>
<a>...</a>
<span class="b-menu__item btn_change-location">
<a href="#change-location" class="fancybox dashed">
{% if user.is_authenticated %}
View ads on site:
{% if user.districts.all.count > 1 %}
{% for district in user.districts.all %}
{% if forloop.last %}
<span>{{ district }}</span>
{% else %}
<span>{{ district }},</span>
{% endif %}
{% endfor %}
{% else %}
{% for district in user.districts.all %}
<span>{{ district }}</span>
{% endfor %}
{% endif %}
{% if user.regions.all.count > 1 %}
{% for region in user.regions.all %}
{% if forloop.last %}
<span>{{ region }}</span>
{% else %}
<span>{{ region }},</span>
{% endif %}
{% endfor %}
{% else %}
{% for region in user.regions.all %}
<span>{{ region }}</span>
{% endfor %}
{% endif %}
{% if user.cities.all.count > 1 %}
{% for city in user.cities.all %}
{% if forloop.last %}
<span>{{ city }}</span>
{% else %}
<span>{{ city }},</span>
{% endif %}
{% endfor %}
{% else %}
{% for city in user.cities.all %}
<span>{{ city }}</span>
{% endfor %}
{% endif %}
{% else %}
View ads on site:
{% endif %}
</a>
</span>
</div>
</div>
</div>
</div>
</div>
Templates modal window
{% load hosts %}
{% load widget_tweaks static %}
<div id="change-location">
<form action="{% host_url "setlocation" host "www" %}" method="post">
{% csrf_token %}
<div id="chose-city-wrap">
<div class="b-modal__title">Select your city</div>
<p>
<div class="b-modal__item">
<span>{{ location_form.country.label }}</span>
{{ location_form.country }}
</div>
</p>
<p>
<div class="b-modal__item">
<span>{{ location_form.districts.label }}</span>
{{ location_form.districts }}
</div>
</p>
<p>
<div class="b-modal__item">
<span>{{ location_form.regions.label }}</span>
{{ location_form.regions }}
</div>
</p>
<p>
<div class="b-modal__item">
<span>{{ location_form.cities.label }}</span>
{{ location_form.cities }}
</div>
</p>
<br />
<div class="b-modal__item b-modal__item_btn">
<input class="b-btn b-btn_red" type="submit" value="Сохранить">
</div>
</div>
</form>
</div>
<!-- end snippet -->
cities download form on the page where the brakes modal window!
<fieldset>
<legend>The territory of distribution of the ads</legend>
{{ form.country|add_class:"b-input__input js-select" }}
{{ form.districts|add_class:"b-input__input js-select chosen-select" }}
{{ form.regions|add_class:"b-input__input js-select chosen-select" }}
{{ form.cities|add_class:"b-input__input js-select chosen-select" }}
{# form.geo|add_class:"b-input__input" #}
</fieldset>
As you explain it, you have a lot of data to get (countries, cities), if you do it in php, you will lock the page until you retrive all those datas.
To have a shorter loading time, you just have to make everything in js (ajax).
You load your page with the cities, countries, ... without data.
Once the page is loaded (document.ready), you call your ajax to fill your cities, countries and so on.