Interactive front end design for decision trees

On the front end, I aim to enable users to influence the outcome of a Decision Tree based on their selections.

For my Django-React App, I have adopted the style and tree example from the codeplayer. You can find it here:

I am tasked with creating an unordered list that will serve as a visual representation of a decision tree.

The user will have 4 options to choose from - labeled Option 1, 2, 3, and 4. These choices should trigger stylistic changes in the decision tree elements to aid the user's understanding. For instance, selecting Option 1 from a dropdown menu should display the corresponding box in a different color. Additionally, it would be beneficial to highlight all the nodes along the path from the parent node to the selected leaf node.

* {
  margin: 0;
  padding: 0;
}

.tree ul {
  padding-top: 20px;
  position: relative;
  transition: all 0.5s;
  -webkit-transition: all 0.5s;
  -moz-transition: all 0.5s;
}

.tree li {
  /* white-space: nowrap; */
  float: left;
  text-align: center;
  list-style-type: none;
  position: relative;
  padding: 20px 1px 0 1px;
  transition: all 0.5s;
  -webkit-transition: all 0.5s;
  -moz-transition: all 0.5s;
}


/*We will use ::before and ::after to draw the connectors*/

.tree li::before,
.tree li::after {
  content: '';
  position: absolute;
  top: 0;
  right: 50%;
  border-top: 1px solid #ccc;
  width: 50%;
  height: 20px;
}

.tree li::after {
  right: auto;
  left: 50%;
  border-left: 1px solid #ccc;
}


/*We need to remove left-right connectors from elements without
     any siblings*/

.tree li:only-child::after,
.tree li:only-child::before {
  display: none;
}


/*Remove space from the top of single children*/

.tree li:only-child {
  padding-top: 0;
}


/*Remove left connector from first child and
     right connector from last child*/

.tree li:first-child::before,
.tree li:last-child::after {
  border: 0 none;
}


/*Adding back the vertical connector to the last nodes*/

.tree li:last-child::before {
  border-right: 1px solid #ccc;
  border-radius: 0 5px 0 0;
  -webkit-border-radius: 0 5px 0 0;
  -moz-border-radius: 0 5px 0 0;
}

.tree li:first-child::after {
  border-radius: 5px 0 0 0;
  -webkit-border-radius: 5px 0 0 0;
  -moz-border-radius: 5px 0 0 0;
}


/*Time to add downward connectors from parents*/

.tree ul ul::before {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  border-left: 1px solid #ccc;
  width: 0;
  height: 20px;
}

.tree li a {
  border: 1px solid #ccc;
  padding: 5px 3px;
  text-decoration: none;
  color: #666;
  /* font-family: arial, verdana, tahoma; */
  display: inline-block;
  /* word-wrap: break-word;    */
  word-break: break-all;
  border-radius: 5px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  transition: all 0.5s;
  -webkit-transition: all 0.5s;
  -moz-transition: all 0.5s;
}
<div class="tree">
  <ul>
    <li>
      <a href="#">Parent</a>
      <ul>
        <li>
          <a href="#">Child</a>
          <ul>
            <li>
              <a href="#">Option 1</a>
            </li>
            <li>
              <a href="#">Option 2</a>
            </li>
          </ul>
        </li>
        <li>
          <a href="#">Child</a>
          <ul>
            <li>
              <a href="#">Option 3</a>
            </li>
            <li>
              <a href="#">Option 4</a>
            </li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
</div>

Answer №1

function chooseOption() {
  $(".modified").removeClass("changed");
  var e = document.getElementById("selection");
  var value = e.options[e.selectedIndex].value;
  $("a[dataValue='" + value + "']").parents("li").addClass("modified");
  $("a[dataValue='" + value + "']").parents("ul").addClass("modified");

}


/*$("a").on("click", function() {
  $(".modified").removeClass("changed");
  $(this).parents("li").addClass("changed");
  $(this).parents("ul").addClass("changed");
})*/
* {
  margin: 0;
  padding: 0;
}

.tree ul {
  padding-top: 20px;
  position: relative;
  transition: all 0.5s;
  -webkit-transition: all 0.5s;
  -moz-transition: all 0.5s;
}

.tree li {
  /* white-space: nowrap; */
  float: left;
  text-align: center;
  list-style-type: none;
  position: relative;
  padding: 20px 1px 0 1px;
  transition: all 0.5s;
  -webkit-transition: all 0.5s;
  -moz-transition: all 0.5s;
}


/*We will use ::before and ::after to draw the connectors*/

.tree li::before,
.tree li::after {
  content: '';
  position: absolute;
  top: 0;
  right: 50%;
  border-top: 1px solid #ccc;
  width: 50%;
  height: 20px;
}

.tree li::after {
  right: auto;
  left: 50%;
  border-left: 1px solid #ccc;
}


/*We need to remove left-right connectors from elements without
     any siblings*/

.tree li:only-child::after,
.tree li:only-child::before {
  display: none;
}


/*Remove space from the top of single children*/

.tree li:only-child {
  padding-top: 0;
}


/*Adding back the vertical connector to the last nodes*/

.tree li:last-child::before {
  border-right: 1px solid #ccc;
  border-radius: 0 5px 0 0;
  -webkit-border-radius: 0 5px 0 0;
  -moz-border-radius: 0 5px 0 0;
}

.tree li:first-child::after {
  border-radius: 5px 0 0 0;
  -webkit-border-radius: 5px 0 0 0;
  -moz-border-radius: 5px 0 0 0;
}


/*Time to add downward connectors from parents*/

.tree ul ul::before {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  border-left: 1px solid #ccc;
  width: 0;
  height: 20px;
}

.tree li a {
  border: 1px solid #ccc;
  padding: 5px 3px;
  text-decoration: none;
  color: #666;
  /* font-family: arial, verdana, tahoma; */
  display: inline-block;
  /* word-wrap: break-word;    */
  word-break: break-all;
  border-radius: 5px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
  transition: all 0.5s;
  -webkit-transition: all 0.5s;
  -moz-transition: all 0.5s;
}

.tree li.changed::before,
.tree li.changed::after {
  border-top: 1px solid red;
}

.tree li.changed::after {
  border-left: 1px solid red;
}

.tree li.changed:last-child::before {
  border-right: 1px solid red;
}

.tree ul ul.changed::before {
  border-left: 1px solid red;
}


/*Remove left connector from first child and
     right connector from last child*/

.tree li:first-child::before,
.tree li:last-child::after {
  border: 0 none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="selection" onchange="chooseOption()">
  <option value="Parent">Parent</option>
  <option value="Child 1">Child 1</option>
  <option value="Child 2">Child 2</option>
  <option value="Option 1">Option 1</option>
  <option value="Option 2">Option 2</option>
  <option value="Option 3">Option 3</option>
  <option value="Option 4">Option 4</option>
</select>
<div class="tree">
  <ul>
    <li>
      <a href="#" dataValue="Parent">Parent</a>
      <ul>
        <li>
          <a href="#" dataValue="Child 1">Child 1</a>
          <ul>
            <li>
              <a href="#" dataValue="Option 1">Option 1</a>
            </li>
            <li>
              <a href="#" dataValue="Option 2">Option 2</a>
            </li>
          </ul>
        </li>
        <li>
          <a href="#" dataValue="Child 2">Child 2</a>
          <ul>
            <li>
              <a href="#" dataValue="Option 3">Option 3</a>
            </li>
            <li>
              <a href="#" dataValue="Option 4">Option 4</a>
            </li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Looking for a way to view the files uploaded in a form using ajax?

Currently, I am encountering an issue while attempting to upload a file submitted in a form using PHP. To avoid page reloading, I have incorporated JS, jQuery, and AJAX between HTML and PHP. Unfortunately, I am facing difficulties with the $_FILES variable ...

An issue arises when attempting to execute npm with React JS

I encountered an error after following the setup steps for a react configuration. Can anyone provide assistance? This is the content of the webpack.config.js file: var config = { entry: './main.js', output: { path:'/', ...

How to prevent v-menu from overlapping a navbar in Vue.js

Exploring the examples on the main page of Vuetify, we come across the v-menu component showcased in detail. Check it out here: https://vuetifyjs.com/en/components/menus/#accessibility If you activate any of the buttons to open the v-menu and then scroll ...

Centering text both vertically and horizontally over an image using CSS

I've been attempting to center the div banner_title both vertically and horizontally within another div in this way... .box { text-align: center; } .banner_title { font-size: 32px; position: absolute; top: 50%; width: 100%; } .banner_titl ...

What is the best way to dynamically change the content of a div based on user selection?

When a user selects an option in the HTML, I want to display another div set to Block. I tried putting the OpenAskuser() function in a button, but it didn't work either. It would be ideal if we could achieve this without a button. Just have the displ ...

Is it feasible to dynamically insert and delete elements in React?

I'm currently in the process of rebuilding a project, specifically a drag and drop website builder, using React after it was originally built with a heavy reliance on jQuery. My main challenge lies in being able to dynamically add and remove elements ...

Catching the Selenium NoSuchElementError in JavaScript is impossible

Update: It's puzzling why this was marked as answered since the linked questions don't address the issue at hand and do not involve Javascript. My objective is to detect this error, rather than prevent it, given that methods like invisibilityOfEl ...

Seeking assistance in optimizing my Javascript code for more efficient canvas rendering

I've created a script for generating random moving lines as a background element for my portfolio. While it runs smoothly on its own, I encounter frame drops when combining it with other CSS animations and effects, especially at the beginning (althoug ...

I find that the Next.js useEffect function hinders my ability to smoothly navigate to a

I have a page displaying all the cards. When I click on a specific card, it redirects me to that card's details. The id is included in the URL. http://localhost:3000/cards/card?id=6539ccd487fa315543646ce5 I extract this id and retrieve the correspond ...

Pattern to filter out numeric values from a collection

I want to apply a regex pattern to the <input> form element. The pattern should specify a range of numbers that are not permitted as input. For example, let's say I have a list of numbers like {1,4,10}, and any number other than these should be a ...

What is the process for generating an oauthSignature?

I'm interested in using the Twitter API and I need to utilize some GET and POST methods. Fortunately, I have all the necessary keys such as consumer Key, Consumer Secret, Access Token, and Token Secret. However, I am facing an issue with generating oa ...

A simple guide on logging into Discord with token using the Selenium library in Python

I created a Python code using the selenium module to log in to Discord using a token number. The token number needs to be added to localStorage, so I used JavaScript code to add it successfully. However, upon checking Application -> localStorage -> https:/ ...

Ways to direct to a specific div upon clicking an anchor tag following a page reload?

<a href="#goto">Link 1</a> <div id="goto">DIV</div> Whenever I click on the anchor tag, my webpage reloads and displays a new div with the ID of goto. This div was previously hidden but is now visible at the bottom of the page. I ...

Can you explain the process of accessing data from [[PromiseValue]] while utilizing React hooks?

My current challenge involves fetching data from an API and utilizing it in various components through the Context API. The issue arises when I receive a response, but it's wrapped under a Promise.[[PromiseValue]]. How can I properly fetch this data ...

What is the best way to hide a custom contextmenu in AngularJs?

I created a custom contextmenu directive using AngularJs. However, I am facing an issue where the menu is supposed to close when I click anywhere on the page except for the custom menu itself. Although I have added a click function to the document to achie ...

Steps for incorporating a personalized theme in Material UI

For my react project, I decided to use Material UI as the component library. To customize the default theme provided by Material UI, I created my own color palette. However, even after adding a custom theme and wrapping my app.js with the ThemeProvider, ...

Converting HTML to plain text using the DOMDocument class

Is there a way to extract the text content from an HTML page source code, excluding the HTML tags? For example: <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <meta http-equiv="content-language" content="hu"/> <titl ...

Vue.js is experiencing issues with updating attributes within nested v-for loops

Exploring the realm of vue.js and react, I am currently in the process of adapting a basic editable HTML table example found in a React book to further my understanding of Vue. Here is a breakdown of what occurs within the code: User clicks on a td elem ...

import an external JavaScript file in an HTML document

Looking to load a .js file from a simple HTML file? If you have these files in the same folder: start.js var http = require('http'); var fs = require('fs'); http.createServer(function (req, response) { fs.readFile('index.htm ...

What is the method to incorporate spread into inner shadow within an SVG file?

Seeking assistance with creating an inset-shadow effect with spread for an SVG rectangle in Figma. Check out this example of a rectangle with inner-shadow and spread. I have successfully added blur and positioned the shadow using x and y coordinates, but ...