🏠 back to Observable

Embedding radio button viewof into HTML page

I am trying to build a simple webpage to display a map I built in an Observable notebook. I would like to use this website template. The problem I am running into is how to get the viewof components to render properly, specifically the radio buttons:

The dropdown menu is just fine, but the radio buttons do not look anything like the radio buttons on the website template (which you can also see by navigating to the ‘Elements’ page in the menu at the website template):

This is my html code for the chart and the viewofs which I am basing on the source html of the ‘Elements’ page:

<div id="main">
    <div class="inner">
        <h1>BMI Classification Prevalence</h1>

        <div id="chart"></div>

        <section>
            <div class="row gtr-uniform">
                <div class="col-4 col-12-small" id="zoomLevel">
                </div>
                <div class="col-4 col-12-small" id="ageGroup">
                </div>
                <div class="col-4 col-12-small" id="classification">
                </div>
                <div class="col-4 col-12-small" id="colorScheme">
                </div>
            </div>
        </section>
    </div>
</div> 

For what it is worth, the radio buttons still ‘work’: i.e., clicking Adult or Child will switch the map being displayed.

Is what I am trying to do not possible with this template?

Can you share a link to your notebook / webpage? I don’t see any radio elements (<input type="radio">) in the snippet you posted…

This is a public versions of the notebook:

Right now the webpage is only running locally on my computer (I am building the website using flask. Do you want me to post all the html for the page?

There are no radio elements in the html I have written. The html for the radio buttons on the template website is:

<form method="post" action="#">
    <div class="row gtr-uniform">
        <div class="col-4 col-12-small">
            <input type="radio" id="demo-priority-low" name="demo-priority" checked>
            <label for="demo-priority-low">Low</label>
        </div>
        <div class="col-4 col-12-small">
            <input type="radio" id="demo-priority-normal" name="demo-priority">
            <label for="demo-priority-normal">Normal</label>
        </div>
        <div class="col-4 col-12-small">
            <input type="radio" id="demo-priority-high" name="demo-priority">
            <label for="demo-priority-high">High</label>
        </div>
    </div>
</form>

but I am lost as to how to convert that into something usable by the viewof.

EDIT: HTML of the page: https://pastebin.com/Ci1zj40i

Oh, OK. The radio elements get added to the page by Javascript from the imported “Inputs” notebook so indeed, you don’t have to write them separately.

One thing I noticed is that the radio and label elements get added to your notebook like this (you can see this if you open your browser’s “inspector”):

<label style="display: inline-block; margin: 5px 10px 3px 0; font-size: 0.85em;">
  <input type="radio" name="input" checked="" style="vertical-align: baseline;" value="Adult">
  Adult
</label>

In particular, note that the <input> element is nested inside the <label> element.

This differs from the HTML on the template website where the <input> and <label> elements are siblings.

Now let’s look at the CSS provided in the “Phantom” template files, namely the file assets/css/main.css (the only relevant CSS file used in elements.html). If you search for “radio”, you’ll find a bunch of rules that take this form:

input[type="radio"] + label {
  /* stuff */
}
/* and some more rules that look the same except with various additional selectors
like :checked, :before, etc. */

The + combinator means that all these rules only apply when the <input> and <label> show up in order as siblings as in elements.html.

To get these rules to apply to the nested elements generated by your notebook, you’ll need to edit all these rules so that they use the > combinator like this:

label > input[type="radio"] {
  /* stuff */
}

Warning: I haven’t tested this change out, so let me know if it works…

1 Like

I see what you are saying with regards to the way in which the radio and label elements get added.

I tried changing the css rules as you pointed out, but I think that there are some other rules in the scss files located in assets/sass/components/_form.scss that might also need editing to make things work right and I don’t really have the know how to do that.

However, I started to look at how the radio input was defined in

which is where I got the input from in the first place. It seems like I might be able to change the definition of the radio input to have the <input> element not be nested inside the <label> element.

Yes, editing the JS should work as well. The only slightly tricky thing will be figuring out the best way to automatically add id attributes to the input elements and corresponding for attributes to their label elements.