Exporting input cells to HTML documents that have custom CSS definitions (e.g. default Bootsrap CSS), I find input tiles don’t always render out well. I would like to display the title text in another, separate cell and assign it different styling.
I remain a bit confused by what is happening both with your code and the given by @severo . Specifically, @severo’s appears to be selecting the first div element contained within the input element–hence that bit: ('div')[1] I noticed that can switch it out with the ('div')[0] and get the same result.
In yours, you appear to be ‘mapping’ div to div, right? Or is > in your code ‘greater than’? If it’s a mapping, does it mean “take all div (innerText) and return as div”?
For what it’s worth, when I extend out the entire element tree from viewof energy_transmission_type, I see a lot of ‘Forbidden’, but not an actual <div> element.
Any insights on how to better understand how this all fits together?
When in doubt, consult the documentation. Relying on false assumptions can send you down paths that are difficult to return from.
Let’s deconstruct both variants. Our element’s (simplified) HTML looks like this:
<form>
<div>
<div>Energy Transmission Type</div>
<textarea>Upgrading and automation.</textarea>
</div>
</form>
First, a recap: viewof is an ObservableHQ construct that, when used in a cell declaration, displays an HTML element, but passes its value property on to other cells. When we reference another cell via viewof (and that cell has been declared with viewof) we gain access to the DOM element and its API.
On to selections:
querySelectorAll() receives a CSS selector string and returns all matched elements as a NodeList (which, for the most part, behaves like an array). Because the div we’re looking for comes second, we access it via its index [1].
querySelector() acts similar to querySelectorAll(), but returns only the first matched element.
Next, the selector string div>div: ">" is the child combinator. It only matches direct children. In this case, any div that is the direct child of another div.
Finally, the innerText mystery: .innerText returns an element’s visible text content, but excludes text contained in input elements. It doesn’t matter how deeply nested the text is.
To observe the difference between selecting the parent div and its child, add a description to your textarea widget, and query the first div by using .querySelectorAll('div')[0] or .querySelector('div').
Wow @mootari! This is exceptionally helpful! I’ll continue to read through the documentation. It helps a lot to have this sort of guidance though, as in the absence of it I find it still very challenging to make sense of things…
Thank you so much!
Still one hold-up I have in following through your comments though:
… this is what I was referring to when I wrote:
… When I enter viewof energy_transmission_type and it returns an HTML form element, even extending out the entire tree I don’t see the <div> elements that make up the input. Instead, I get lots of elements like this (snippet):
How did you arrive at that ‘simplified’ HTML structure and know to look for the text in the <div> for the title? And how did we know it ‘comes second’? (And it appears that its also comes first, as I get the same value for ('div')[0] ?
… I will keep reading to see if I can’t figure out more of this myself. Probably I am missing something in all those dozens (or hundreds) of fields being reported for the inputs HTML element…
I copied the outerHTML as described above, then cleaned it up by hand.
By the way, have you ever wondered how Observable decides when to display an element, and when to inspect it?
As it turns out, the Inspector will check the element’s .parentNode property. If the element is already attached to another element the Inspector kicks in.