NibblyPig
NibblyPig

Reputation: 52942

How do I do an <ol> with decimals?

Looking to create a list like this:

1. Section Header
    1.1 Some Text Here That is Quite Long
    1.2 Some Text Here That is Quite Long
    1.3 Some Text Here That is Quite Long
2. Section Header
    2.1 Some Text Here That is Quite Long
    2.2 Some Text Here That is Quite Long
    2.3 Some Text Here That is Quite Long

but ideally as a proper or combination thereof (I like to have neat proper pages). Is this possible?

Upvotes: 3

Views: 5128

Answers (3)

brianpeiris
brianpeiris

Reputation: 10795

Here's a JavaScript solution for browsers that don't fully support CSS2. I've tested it in Firefox 3.5, IE6, IE7, IE8 and Chrome 4.0. I've written a pure JavaScript version and an equivalent jQuery (1.4!) version which, as you can imagine, is much shorter.

The benefit to using JavaScript is that it is much more customizable than CSS. For example, the JavaScript solution allows for interspersed content (i.e. You can have multiple <ol>s inside a single parent <li> and the numbering will be continuous regardless of what HTML you put in between the child <ol>s. (See the demo)).

One drawback is that selecting the text in the JavaScript list will select the numbers as well as the text (the CSS solution helpfully omits the numbers from the selection).

Working Demos

jQuery Version

http://jsbin.com/unujo (editable via http://jsbin.com/unujo/edit)

Pure JavaScript Version

http://jsbin.com/ekono (editable via http://jsbin.com/ekono/edit)

Full Source:

jQuery Version

(function ($) {
  $.fn.addNumbering = function (separator, parentNumbering) {
    var root = !parentNumbering;
    parentNumbering = parentNumbering || '';
    separator = separator || '.';

    $.each(this, function () {
      var items = root ? $(this).children() : this;

      items.each(function (ii, item) {
        var numberingText = parentNumbering + (ii + 1) + separator;

        // We don't add numbering to root list items since
        // the CSS already does that correctly.
        if (!root) {
          $('<span></span>', {
            text: numberingText,
            className: 'numbering'
          }).prependTo(this);
        }

        $.fn.addNumbering.call([$(this).find('>ol>li')], separator, numberingText);
      });
    });
  }
})(jQuery);

$('.numbered').addNumbering();

Pure JavaScript Version:

function addNumbering(list, separator, parentNumbering) {
  var root = !parentNumbering;
  parentNumbering = parentNumbering || '';
  separator = separator || '.';

  // If 'list' is an Array, assume we were given a
  // collection of ordered lists and call addNumbering on each
  if (Object.prototype.toString.call(list) === "[object Array]") {
    each(
      list, 
      function (list, ii) {
        addNumbering(list, separator, parentNumbering);
      }
    );
    return;
  }

  var
    listItem = function (childNode) {
      // Ignore text nodes. We assume that
      // the HTML follows standards so all the
      // remaining nodes should be list items.
      return childNode.nodeType === 1;
    },
    items = select(list.childNodes, listItem);

  each(
    items,
    function (item, ii) {
      var numberingText = parentNumbering + (ii + 1) + separator;

      // We don't add numbering to root list items since
      // the CSS already does that correctly.
      if (!root) {
        var numbering = document.createElement('span');
        numbering.innerHTML = numberingText;
        numbering.className = 'numbering';

        item.insertBefore(numbering, item.childNodes[0]);
      }

      var
        subLists = select(
          item.childNodes,
          function (childNode) {
            return childNode['tagName'] && childNode.tagName.toLowerCase() === 'ol';
          }
        ),
        subListItemWrapper = {childNodes: []};
      each(
        subLists,
        function (subList) {
          subListItemWrapper.childNodes =
            subListItemWrapper.childNodes.concat(select(
              subList.childNodes,
              listItem
            ));
        }
      );

      addNumbering(subListItemWrapper, separator, numberingText);
    }
  );
}

function select (things, selectFunction) {
  if (Array.filter) {
    return Array.prototype.slice.call(things, 0).filter(selectFunction);
  }
  var selected = selected || [];

  each (
    things,
    function (thing) {
      selectFunction(thing) && selected.push(thing);
    }
  );

  return selected;
}

function each (things, eachFunction) {
  if (Array.forEach) {
    things.forEach(eachFunction);
    return;
  }
  var numThings = things.length, ii;

  for (ii = 0; ii < numThings; ii++) {
    eachFunction(things[ii], ii, things);
  }
}

addNumbering(select(
  document.body.childNodes,
  function (childNode) {
    return childNode.nodeType === 1 && childNode.className.indexOf('numbered') !== -1;
  }
));

HTML and CSS

<!doctype html> 
<html lang="en"> 
<head> 
  <title></title> 
  <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> 
  <style type="text/css" media="screen"> 
    body { background-color: #000; font: 16px Helvetica, Arial; color: #fff; }

    .numbering { padding: 0 0.8em 0 1.2em; }
    .numbered ol { list-style-type: none; }
    .numbered > li > ol { padding-left: 0; }
  </style> 
</head> 
<body> 
  <ol> 
    <li>This</li> 
    <li>is a
      <ol> 
        <li>vanilla</li> 
        <li>list</li> 
      </ol> 
    </li> 
  </ol> 

  <ol class="numbered"> 
    <li>This is a numbered list</li> 
    <li>Vestibulum auctor dapibus neque.
      <ol> 
        <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li> 
        <li>Aliquam tincidunt mauris eu risus.</li> 
      </ol> 
      It even handles interspersed content! Note that he numbering continues where it left off:
      <ol> 
        <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li> 
        <li>Aliquam tincidunt mauris eu risus.</li> 
      </ol> 
    </li> 
  </ol> 

  <ol class="numbered"> 
    <li>This is another numbered list</li> 
    <li>Aliquam tincidunt mauris eu risus.</li> 
    <li>Vestibulum auctor dapibus neque.
      <ol> 
        <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li> 
        <li>Aliquam tincidunt mauris eu risus.</li> 
        <li>Vestibulum auctor dapibus neque.
          <ol> 
            <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li> 
            <li>Aliquam tincidunt mauris eu risus.</li> 
          </ol> 
        </li> 
        <li>Aliquam tincidunt mauris eu risus.</li> 
        <li>Vestibulum auctor dapibus neque.</li> 
      </ol> 
    </li> 
    <li>Aliquam tincidunt mauris eu risus.</li> 
    <li>Vestibulum auctor dapibus neque.</li> 
    <li>Aliquam tincidunt mauris eu risus.</li> 
    <li>Vestibulum auctor dapibus neque.</li> 
  </ol> 
</body> 
</html>

Upvotes: 3

hsz
hsz

Reputation: 152226

<ol type="1">
    <li>abc</li>
</ol>

Upvotes: 2

Related Questions