Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what could cause html and script to behave different across iterations of a for loop?

I'm trying to build a side navigation bar where categories are listed and upon clicking a category a respective sub list of subcategories is shown right below the category. And if the category is clicked again, the sub list contracts.

So I'm running a loop across category objects. Inside this outer loop, I'm including a an inner loop to list subcategories and a script that hides the submenu and slidetoggles it only when a category is clicked. I'm using django template tags to dynamically assign class names for my html elements and also to refer to them in the script. So after all for loop iterations, there is a list of subcategory and a dedicated script for each category and they have unique class names so no chance of an overlap. So the weird part is, this works perfectly for most categories, but some of the categories and their submenu remain open and when clicked on the category the page reloads.

I don't get it, what could cause the exact same code (run in a for loop) to behave so differently?

This is my code:

{% load staticfiles %}
{% load i18n pybb_tags forumindexlistbycat %}
{% catindexlist as catindexlisted %}

{% block body %}<div class="col-sm-12 col-md-12 col-xs-12 col-lg-12 body-container leftsidenavigator" style="margin-top:15px;">
    <div class="col-sm-12 col-md-12 col-xs-12 col-lg-12 leftsidenavigator-inner" style="padding:0px;">
         <h2><center>Categories</center></h2>
             <ul class="catindexlist catlistcat nav-collapse89">
                   {% for category in catindexlisted %}
                         <li class="catindexlistitem category-name{{category.name}}{{category.name}}" style="font-weight:600;padding-right:20px;"><a href="">{{category.name}}</a></li>
                         <ul style="padding:0px;" class="nav-collapse88">
                         {% for forum in category|forumindexlistbycat %}
                               <li class="catlistforum{{category.name}}{{category.name}} forum-name" style="padding-right:10px;"><a href="{{ forum.get_absolute_url }}">{{forum.name}}</a></li>
                         {% endfor %}</ul><script>

                         $(function() {
                              $(".catlistforum{{category.name}}{{category.name}}").hide();
                                    $(".category-name{{category.name}}{{category.name}} a").click(function(e) {
                                     e.preventDefault();
                                     $(".catlistforum{{category.name}}{{category.name}}").slideToggle();
                                          if(!($(this).parent('li').siblings('div').children('ul').children('div').is(":visible"))){
                                              $(this).parent('li').siblings('div').children('ul').children('div').is(":visible").slideToggle();
                                          }});
                                      })
                                </script>
                           {% endfor %}
                           </ul>
                      </div>
                      </div>
                  {% endblock %}
     {% block theme_script %}<script src="{% static "pinax/js/theme.js" %}"></script>{% endblock %}
like image 611
Dr Confuse Avatar asked Sep 24 '16 04:09

Dr Confuse


2 Answers

The most probable cause is the use of {{category.name}} for class names.

The code snippet doesn't show what values is accepted for category.name and my guess is it can be user input? See naming rules in section Attribute Values what is valid for class names.

It can be solved using template tag slugify ({{category.name|slugify}}) but my recommendation is to try re-design the solution a bit.

like image 169
Daniel Backman Avatar answered Nov 04 '22 07:11

Daniel Backman


Is there any chance that the category name contains spaces?

Just a tip: You are not using good practice in your code. IMO you should get your javascript code outside of the forloop and remove {{ category_name }} classes. catindexlistitem on click should toggle hidden class (i noticed you use bootstrap) to it's child ul.

By adding a more generic event listener you simplify your code and by using css you improve performance. In case you want to add effects you still can with css3.

like image 1
Kroustou Avatar answered Nov 04 '22 07:11

Kroustou