skip to Main Content

My dependencies are EJS, Express, and Mongoose.

I am trying to figure out how I can make a Form/Select/Option that is dynamically driven by another Select/Option. In my app.js I have two different arrays, optionOneList and optionTwoList, that are created when I query the database. Then in my first EJS section I have an Select list with both of the query parameters as options. I would like the optionOneList or optionTwoList variables to be used in creating the options for the second EJS template section, and the results will differ depending on what is selected in the first EJS section.

I tried troubleshooting this the following ways:

  1. Creating a standalone js file with the arrays after they are queried and passing that into the EJS template. From looking at other stackoverflow posts it didn’t seem like this would work because you can’t pass a js variable value to an ejs variable.
  2. I can’t save the array/variable in a section of the EJS template because once the page loads I essentially lose access to it (this is client/server related, but I am not well versed enough in this topic to explain this better – hopefully someday).

I also assumed I would have some luck if I just saved optionOneList/optionTwoList as local variables, but that wasn’t working for me either.

Express Template Section One

app.get('/general', async (req, res) => {
    const optionOneList = await collectionOne.find({ "Person": "queryOne" });
    const optionTwoList = await collectionOne.find({ "Person": "queryTwo" });
    res.render('general/index', {optionOneList: optionOneList, optionTwoList: optionTwoList} )
});

EJS Template Section One

Note: This first select is what I want to drive what options that are available for the second select

<select id="firstSelection">
        <option selected>Default</option>
        <option value="queryOne">queryOne</option>
        <option value="queryTwo">queryTwo</option>
</select>

EJS Template Section One

<select id="secondSelection">    
        <% for (let available of optionOneList) {%>
        <option>
        <%= available.Name %>
        </option>
        <% } %>
</select>

I am happy to take links to specific parts of the documentation that could point me in the right direction, or critiques on my understanding of why certain things didn’t work. Thanks in advance for any feedback or resources.

2

Answers


  1. If you are a novice developer, look towards SPA (Single Page) applications that are created using React. Look at the example of this library from github. Data should be transferred using the http protocol.

    Login or Signup to reply.
  2. I’m a bit late to the party but arrived here and found out, kinda, how to do it.

    In the following code, im passing an array like you do with res.render(). Im writing all my options in my select, with EJS templating for sure ;). Don’t forget the value attribute in your options !

    <select class="selectpicker" id="firstSelection">
        <% for( let idx in myArray) { %>
          <option value='<%= myArray[idx]%>'>
            <%= myArray[idx]%>
          </option>
        <% }; %>
    </select>
    

    I use the selectpicker from Bootstrap 4 (not 5 because it’s an old project) to make it look better, I dont like CSS.

    Now I need to switch between them. I tried to stick the most to your issue, but I may be missing some things, at least you need to get the logic right . But let’s get into it.

    First you’ve got to use some jQuery, import it via CDN or your server, if you use CDN, prioritize the minified version which is lighter :

    CDN :
    <script src="https://code.jquery.com/jquery-3.6.4.min.js" integrity="sha256-oP6HI9z1XaZNBrJURtCoUT5SUnxFr8s3BzRl+cbzUq8=" crossorigin="anonymous"></script>

    Server side :
    <script src="js/jquery-3.6.0.min.js"></script>

    You need to know that the variables you pass through the res.render() function are only available on that page you rendered. If you are using include(yourEjsFile) for more in-depth templating, pass those same variables again like so : include(yourEjsFile, {var1, var2})

    To make things easier, create one dropdown per option you want, and set them invisible (display: none in CSS) we will make them show right after.

    Alright, now here’s the switcheroo function :
    I assume the possible values output for your first dropdown are your other dropdowns IDs

    $('#firstSelection').click(() => {
        let value = $(this).val(); //'this' is the current element : #firstSelection
        $("#queryOne").css("display", "none"); // hide all dropdowns
        $("#queryTwo").css("display", "none");
        $('#' + value).css("display", "block"); // show the correct one
    });
    

    jQuery is a powerful tool, if you use it correctly, your sites will be dynamic pretty easily. And NOT as Amwey said, dont go React. It is wayyy to complicated for beginners (and experienced devs) and took me a few weeks to get it running properly even tho I had a bit of web experience at that time. I tried to be as explicit as possible because I have no resource to give to you :/

    Hope it helped someone on this planet!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search