I have a question about how to present some structured data using HTML.
I have some tree-like data, which you might normally present using sections and subsections (i.e. <h1>, <h2>, etc.) and/or using nested lists (i.e. lists whose items contain lists of sub-items).
An example of this data is a to-do list, which has tasks that include sub-tasks and sub-sub-tasks.
Each of these data also has associated properties, for example:
bool completed;
DateTime completionDate;
Priority priority;
My question is, what do you suggest as a good way to present this data on one page, using HTML?
My first idea is to present it as a table:
One of the table's columns shows the task or sub-task
Other columns in each row show the values of the properties (e.g. "completed", etc.) associated with that task
My problem with this is that showing all tasks and sub-tasks in one table column would lose the information about how the tasks are nested: for example it wouldn't show that the second row is actually a subtask of the first row. Can you suggest a way to work-around that problem? I thought of decorating items with a variable number of chevrons like '>' to show how deeply nested each item is, for example:
TASK COMPLETED
Some major task No
> A subtask Yes
> Another subtask Yes
> > A sub-subtask Yes
Next major task No
Some problems with that however are:
It might look ugly, and I'm not sure that it's as intuitively understandable and as readable as it can be. Might some other ornament, or simply variable-length whitespace indent, be better?
I don't see an elegant way to encode it using HTML+CSS; for example, would you insert the ornament using HTML, or insert it using CSS; and if using CSS, would that be by adding something like class="level1" through class="level6" to show the nesting level?
A second way would be to present it as text that flows vertically, for example ...
<h1>Some major task</h1>
<p>Completed: no.</p>
<h2>A subtask</h2>
...etc...
... which I will do as well, but I also want a view which lets the reader scan the column of property values, which is easier when the property values are aligned in a column instead of interspersed with other text.
This is more about UI design than coding, but ... I'm surely not the first person to want to display this kind of data, but I don't remember having seen any examples, so I'd like to ask you.
The UI component you want is called a TreeTable (or Tree Table). There are various implementations of it in Javascript/HTML. Here's one that uses Javascript. Here's another one that's pure HTML/CSS (but doesn't collapse/expand)
You're talking about nesting in the hierarchal structure of HTML. By its very nature you don't really have to do any special work at all.
A simple, recursive list is all you need, without any special considerations for depth or anything. You can even add expand-collapse functionality to any level if you want without much extra work.
<ul>
<li>
<div class="task-group">
<span class="task-title">Task 1</span>
<span class="task-status">Complete</span>
<ul>
<li>
<div class="task-group">
<span class="task-title">Task 1a</span>
<span class="task-status">Complete</span>
</div>
<li>
<div class="task-group">
<span class="task-title">Task 1b</span>
<span class="task-status">Incomplete</span>
</div>
</li>
</ul>
</div>
</li>
</ul>
Then you just style each task-group to have a relative margin to its parent so that the nesting becomes recursive. Set up fancy (or no) bullets for the tasks with li's style, and customize the positioning of the task-status class to make it lay out the way you want it.
You can also get lower subtasks to recursively inherit smaller text size by setting a relative text-size in the CSS. Something like .75em, so that each level is three quarters smaller than the previous level.
Something like this:
.task-group {
font-size: .75em;
margin-left: 1em;
}
.task-title {
text-decoration: underline;
float: left;
}
.task-status {
float: right;
}
UL, OL and LI are good for this purpose. Structuring it as JSON is even better. You can render the HTML from JSON in any way you wish.
The question has no right or wrong answer. But I'll answer this question within a question.
If using CSS, would that be by adding
something like class="level1" through
class="level6" to show the nesting
level?
No. You would use the appropriate selector in CSS.
li {
// level one style
}
li li
{
// level two style
}
etc.
Related
Trying to determine the correct syntax for using Microdata inside my breadcumbs implementation. Everything I have read seems to lean towards the fact that the breadcrumbs are structured inside an ordered or unorderd list. Mine is not.
<body itemscope="" itemtype="http://schema.org/WebPage">
...
<div class="breadcrumbs" itemprop="breadcrumb">
Home
<span class="delimiter"> > </span>
Parent Item
<span class="delimiter"> > </span>
<span>Child</span>
</div>
...
</body>
If I run it inside Google's tool it seems correct, but compared to their example it is missing a lot of elements and doesn't have the structure of their example BreadcrumbList.
I'm also a little confused about the correct properties for the links. Should they all have title and url properties?
I was looking at the examples at the bottom of the page here: http://schema.org/WebPage
The breadcrumb property expects one of two values:
Text
BreadcrumbList
If you provide a Text value (like you do in the example), you can’t provide data about each link. If you are fine with that, the Microdata in your example is correct (but it also contains RDFa, which doesn’t seem to make sense, at least not without further context; so if you didn’t add them intentionally, you might want to remove the property attributes).
If you want to provide data about each link, you have to provide a BreadcrumbList value.
For the Microdata, it doesn’t matter whether or not you use a list. If the example uses ol→li→a→span, you could as well use something like div→span→a→span. You just have to make sure to use the correct element type.
If you can’t add parent elements to the a elements, it’s still possible to use BreadcrumbList. But then you would have to duplicate the URL with a link element inside the a element.
Why would you use "div class" instead of "div id"
Usually when I name a div I use "id" to give a name to an element and with set parameters. I really only use "class" to give it special characteristics. For my example .
However, I have a professor who will "class" to identify all his divs. For example prof example .
Can someone explain the benefit of something like "div class" instead of "div id".
<div class="some_class">
<p>This can be used any number of times on one HTML page</p>
</div>
<div id="some_id">
<p>This CAN be used multiple times with the same ID,
but it is invalid code, as a specific ID should
only be used ONCE per html page</p>
</div>
Here's an older yet still good explanation.
ID are unique for the page, so it's better for identification.
Class aren't unique and are supposed to be to group similar style things together.
Said otherwise, if you need to apply something to THAT SPECIFIC div, you should call it by the id, because it will take priority over other CSS styles that may affect it.
Classes will allow you to set some common ground in your style so you can use similar fonts or sizes in different kind of elements.
If you are using Javascript there is a big advantage of using classnames to identify elements instead of id's.
Giving an id to an element also creates a global javascript variable with the same name. See Do DOM tree elements with ids become global variables? for more about that behaviour.
Having such implicitly created variables is at best confusing, and at worst leading to hard to find errors.
In the style of the example on this page I'm trying to get all of the senses in which a particular name could be applied to a specific person based on the wikipedia disambiguation page.
The trouble is that wikipedia pages are highly non-uniform.
One common feature though is that the list of names will appear in a ul element as part of a link a and in the title= component of the link there will be a reference to the name we're looking for. Since these are links to the associated wikipedia pages.
Using jsoup, or some other method, how could I recognize these components?
h2:contains(people) + ul a
^that works for when they're all in a section entitled People but as I mentioned, this is not always the case.
Perhaps in pseudocode we could do something like this:
ul a && title contains *String*
Maybe something like this:
a[href], [title]
but only matching part of the title, not the whole thing.
This is an example of a very non-structured page where such a method would be called for.
This is an example of one where it's not important.
But I'm trying to make something generalizable that will apply equally well to both types.
This kind of works:
Elements linx = docx.select("a:contains(Corzine)");
for (Element linq : linx)
{
System.out.println(linq.text());
}
but maybe one among you might hit upon a better solution.
Let's assume you have an overview like this:
To me, this is both a table and a couple of nested lists.
What is the semantically correct way of implementing this in HTML?
Unlike Mike, I don't think we're dealing with tabular data here. You have nested lists of publications. Following a few guidelines (Google, html5 Doctor, ...) about authorship and publications dates; the extra data about publication you're dealing with is more likely "labels" to your content that could be styled in many ways, thus rejecting the tabular data hypothesis. I've chosen the following approach per <li> :
<span class="title">What Should I use, li or table?</span>
<time datetime="2014-04-08T15:27Z">2d ago</time>
<address><a rel="author" href="#">John Jackson</a></address>
I reproduced your nested list in this JSFiddle, styled it as yours and styled it in a non-tabular way. You'll notice the HTML segment never changed in any of the three styling I've produced. Being able to style it like the previous Fiddles demonstrates how the HTML is semantically appropriate.
Semantics often induces different valid approaches, some of my usage might not be perfect, but the main idea should be appropriate. Let me know if this answers your question properly! :-)
I think some of the others are being thrown off by the bullets. This contains tabular data, so a table is fitting. The list-like styling can be easily created within table cells.
It seems to me, however, that the representation of data is entirely as a table, and the list-like structure is just to show the structure of messages (ie, by indenting replies).
It's a nested list. The first one is the outermost, with three items under it, some of which have lists of their own.
Essentially it could look something like this:
<ul>
<li>What Should I use
<ul>
<li>Re: What Should I use </li>
<li>I think the best option is . . .
<ul> . . . </ul>
</li>
</ul>
</li>
</ul>
To get the name and date info lined up you could probably use a float: right span element, and to prevent the li from wrapping you'd probably need to set overflow appropriately, but I think it's just a matter of formatting.
I have the following HTML:
<ul class='dropSelect'>
<li data-value="one">
<span>Menu1</span>
</li>
<li data-value="two">
<span>Menu2</span>
</li>
<li data-value="three">
<span>Menu3</span>
</li>
</ul>
My question is: is it better practice to place the data-value attribute on the span next to the actual menu item text or is it just as good to place on the parent li element as I have done? This attribute will receive data from a web service and I'm using some js to grab the value of this attribute and placing it inside of another element on the page.
SOF warned me upon posting this question that it might be too subjective ... and it might be ... but my concern is to understand what, if any, impact my placement of this attribute may have on UI engineering, javascript DOM manipulation, accessibility, etc.
Broadly speaking, I suggest storing data on the element that most closely maps to the data's 'parent' or 'owner'. It's all about what conveys the most meaning.
For example, if you are representing a list of 'people' in your html thus
<ul>
<li class="person">Tim Bresnan</li>
<li class="person">Joe Root</li>
</ul>
and you wish to associate a date of birth without displaying it, put it on the li items as they represent the person.
$('.person').data('dob');
If however your html representation of a person is more complex, say
<ul>
<li class="person">
<div class="name">Tim Bresnan</div>
<div class="dob">28th Feb 1985</div>
</li>
<li class="person">
<div class="name">Joe Root</div>
<div class="dob">30th Dec 1990</div>
</li>
</ul>
you might wish to include the ISO8601 datetime representation as data on the dob class elements.
$('.person .dob').data('dob');
Although html5 data attributes are subjective, and can be used anytime/anywhere, I'm assuming you are looking these elements up by them in your situation. In your situation I'd put them in the same place you did for a couple of reasons.
This is the top level (child), so it's very easy to grab them all by the data attribute.
$('li[data-value]')
At some point you might have much more inside each <li>, right now it might only be the <span> but by having the list-item hold the data-value you can easily get other DOM elements inside of it. If you had it inside of the span you'd have to go UP a level to the list-item, then .find() whatever element you want.
If your span held data-value:
$('[data-value="whatever"]').closest('li').find('.someOtherThing');
Instead now you don't have to do that pointless look-up for the parent <li>!
$('[data-value="whatever"]').find('.someOtherThing');
I would say to put the data-values in the span within the listing. I think it's best to put the data-attribute closest to the string it has an effect on, in this case the span.
On another note, this piece of jQuery works fine:
$(document).ready( function() {
$("li").click(function(){
var txt = $(this).text();
$("#mydiv").text(txt);
});
});
With this, I've tested in jsFiddle (http://jsfiddle.net/YqePE/) that clicking on a li, can return it's text value, and so it would also return any data-attribute you have in that li.
BUT, if by some sort of weird CSS makeup, it can be possible this would generate an unwelcome outcome, where as you think you don't click a certain LI, the browser thinks you do. To prevent this, you would want to make the span holding the data-attribute.
From what it seems like you're trying to do. You could use jQuery's .index(). (Yes, I know it wasn't tagged jQuery)
$('ul.dropSelect > li').each(function(){
var i = $(this).index();
});
It is not necessary to use the data attribute for this information.
Try to use pseudo class selectors of CSS or jQuery to bind the specif item:
CSS:
.dropSelect li:nth-child(1) {
// First <li>
}
Or jQuery:
// Second <li>
$('.dropSelect li').eq(1)
DEMO: http://jsfiddle.net/wYpK6/