I need a nested list with subitem numbering, like this:
1. Item 1
1.1 - Subitem 1
1.2 - Subitem 2
1.3 - Subitem 3
1.4 - Subitem 4
1.5 - Subitem 5
2. Item 2
2.1 - Subitem 1
2.2 - Subitem 2
2.3 - Subitem 3
2.4 - Subitem 4
2.5 - Subitem 5
Well, I know I cannot achieve that with pure HTML. It would be great to use something like this and have the sublist automatically numbered:
<ol>
<li>
Item 1
<ol>
<li>Subitem 1</li>
<li>Subitem 2</li>
<li>Subitem 3</li>
<li>Subitem 4</li>
<li>Subitem 5</li>
</ol>
</li>
<li>
Item 2
<ol>
<li>Subitem 1</li>
<li>Subitem 2</li>
<li>Subitem 3</li>
<li>Subitem 4</li>
<li>Subitem 5</li>
</ol>
</li>
</ol>
Is there a solution for this using JavaScript or jQuery or something?
I need a nested list with subitem numbering, like this:
1. Item 1
1.1 - Subitem 1
1.2 - Subitem 2
1.3 - Subitem 3
1.4 - Subitem 4
1.5 - Subitem 5
2. Item 2
2.1 - Subitem 1
2.2 - Subitem 2
2.3 - Subitem 3
2.4 - Subitem 4
2.5 - Subitem 5
Well, I know I cannot achieve that with pure HTML. It would be great to use something like this and have the sublist automatically numbered:
<ol>
<li>
Item 1
<ol>
<li>Subitem 1</li>
<li>Subitem 2</li>
<li>Subitem 3</li>
<li>Subitem 4</li>
<li>Subitem 5</li>
</ol>
</li>
<li>
Item 2
<ol>
<li>Subitem 1</li>
<li>Subitem 2</li>
<li>Subitem 3</li>
<li>Subitem 4</li>
<li>Subitem 5</li>
</ol>
</li>
</ol>
Is there a solution for this using JavaScript or jQuery or something?
Share Improve this question edited Jun 1, 2012 at 17:06 Gilles 'SO- stop being evil' 108k38 gold badges215 silver badges260 bronze badges asked Dec 5, 2009 at 17:30 Marcos BuarqueMarcos Buarque 3,4188 gold badges46 silver badges47 bronze badges 2- While you can't get "dotted hierarchical numbering" like you describe with pure HTML, you can change the numbering style for each level (number, uppercase letter, lowercase letter, greek symbol, etc). And that might be good enough, depending on your need. – jpsimons Commented Dec 5, 2009 at 19:22
- Thanks, darkporter, I know that, but what I really need is a subnumbered list that carries its parent number and a dot separator. Abraços. – Marcos Buarque Commented Dec 6, 2009 at 3:29
3 Answers
Reset to default 8You can use CSS to do so:
OL { counter-reset: item }
LI { display: block }
LI:before { content: counter(item) ". - "; counter-increment: item }
LI LI:before { content: counters(item, ".") " - "; counter-increment: item }
But it requires support for counter
and counters
.
Edit Here’s a jQuery approach similar to dcneiner’s but with no limitation to depth:
function foo($ol, counters) {
counters = counters || [];
$ol.each(function(i) {
var $this = $(this);
$this.children("li").each(function(i) {
var $this = $(this);
$this.prepend(counters.concat([i+1]).join(".") + " ");
$this.children("ol").each(function(j) {
foo($(this), counters.concat([i+1]));
});
});
});
}
foo($("ol:not(li > ol)"));
If you want to do it cross-browser with jQuery:
$("ol#list ol").each(function(i, el){
$(this).children().each(function(ci,cel){
$(this).prepend('<span class="pseudo-num">' + [i + 1, ci + 1].join('.') + ' </span>');
});
}).addClass('pseudo-processed');
And in your CSS:
ol .pseudo-num { display: none }
ol.pseudo-processed { list-style: none; padding-left: 0 }
ol.pseudo-processed .pseudo-num { display: inline; font-weight: bold }
This is for one level only. You could alter the code to create a recursive function for multiple levels.
This is setup to progressively enhance your page. Without Javascript it would fallback to normal nested numbering.
UPDATE: Thanks to @Gumbo work, I reworked this code into a recursive plugin. It would use the same CSS as in my previous example, but now it is a "full fledged" jQuery plugin with support for any depth:
$.fn.outline = function(options, counters){
var options = $.extend({}, $.fn.outline.defaults, options),
counters = counters || [];
this.each(function(){
$(this).children('li').each(function(i){
var ct = counters.concat([i + 1]);
if(counters.length){
$('<span></span>')
.addClass(options.numberClass)
.text(ct.join('.') + ' ')
.prependTo(this);
}
$(this).children('ol').outline(options, ct);
})
});
if(!counters.length) this.addClass(options.processedClass)
}
$.fn.outline.defaults = {
numberClass: 'pseudo-num',
processedClass: 'pseudo-processed'
}
You could then call it on a specific #id
:
$("#list").outline();
Or use @Gumbo's nice selector to apply it to all ol
tags on one page:
$("ol:not(li > ol)").outline();
And you can either override the defaults globally, or on an individual basis:
$.fn.outline.defaults.processedClass = 'ol-ready';
// or
$("#list").outline({processedClass: 'ol-ready'});
Neither js nor jquery but CSS:
<STYLE type="text/css">
UL, OL { counter-reset: item }
LI { display: block }
LI:before { content: counters(item, "."); counter-increment: item }
</STYLE>
More here: http://www.w3/TR/WCAG10-CSS-TECHS/#lists