SemperFi
SemperFi

Reputation: 190

NodeJs:- Take values from the first dropdown and populate the values in the second dropdown dynamically

I was working on a dropdown list and wanted the results shown in the second dropdown to be filtered according to the option selected in the first dropdown.

My EJS file is as follows:-

 <div class="form-group">
        <label for="">Category</label>
        <select id="list" name="mainCategory" id="maincategory-dropdown" onchange="getSelectValue()" class="form-control">
            <% mainCategories.forEach(function(cat){ %>
                <option value="<%= cat.slug %>"
                <% if (cat.slug == mainCategory) { %>
                selected="selected"
                <% } %>        
                ><%= cat.title %></option>
            <% }); %>
        </select>
    </div>

    <div class="form-group">
        <label for="">Subcategory</label>
        <select name="category" id="category-dropdown" class="form-control">
            <% categories.forEach(function(cat){ %>
                <option value="<%= cat.slug %>"
                <% if (cat.slug == category) { %>
                selected="selected"
                <% } %>        
                ><%= cat.title %></option>
            <% }); %>
        </select>
    </div>

I want the values in the subcategory dropdown to be shown as per the option selected in the category dropdown.

I am getting the values from the backend. The JS file is as follows:-

router.get('/edit-product/:id',ensureAuthenticated, function (req, res) {

    MainCategory.find(function(err,mainCategories){

        Category.find(function (err, categories) {

            Product.findById(req.params.id, function (err, p) {
                if (err) {
                    console.log(err);
                    res.redirect('/admin/products');
                } else {
                    var galleryDir = 'public/assets/img/products/' + p._id + '/gallery';
                //  var recommendationDir = 'public/assets/img/products/' + p._id + '/recommendation';
                    var galleryImages = null;
                //  var recommendationImages = null;

                    fs.readdir(galleryDir, function (err, files) {
                        if (err) {
                            console.log(err);
                        } else {
                            galleryImages = files;
                           // console.log("The gallery image is" + galleryImages)
                           //console.log(p);
                            res.render('admin/edit_product', {

                                product:p,
                                title: p.title,
                                description: p.description,
                                categories: categories,
                                category: p.category.replace(/\s+/g, '-').toLowerCase(),
                                mainCategories: mainCategories,
                                mainCategory: p.mainCategory.replace(/\s+/g, '-').toLowerCase(),
                                mainImage: p.mainImage,
                                thumbImage1 : p.thumbImage1,
                                thumbImage2 : p.thumbImage2,
                                thumbImage3: p.thumbImage3,
                                recommendationImage1: p.recommendationImage1,
                                recommendationImage2: p.recommendationImage2,
                                recommendationImage3: p.recommendationImage3,
                                recommendationUrl1: p.recommendationUrl1,
                                recommendationUrl2: p.recommendationUrl2,
                                recommendationUrl3: p.recommendationUrl3,
                                galleryImages: galleryImages,
                                id: p._id,
                                productID:p.productID                                
                            });
                        }
                    });
                }
            });

        });
    })
});

I am stuck in it a bit. Please help me out

Upvotes: 3

Views: 1620

Answers (2)

Yosef Tukachinsky
Yosef Tukachinsky

Reputation: 5895

const categories = ['a', 'b', 'c'];
const subCategories = {
  a: ['a-1', 'a-2', 'a-3'],
  b: ['b-1', 'b-2', 'b-3'],
  c: ['c-1', 'c-2', 'c-3'],
};
const catSelect = document.getElementById('cat');
const subCatSelect = document.getElementById('subcat');

catSelect.innerHTML = categories.map(cat => `<option val=${cat}>${cat}</option>`).join('');
catSelect.addEventListener('change', setSubcategories);
setSubcategories();


function setSubcategories() {
  subCatSelect.innerHTML = subCategories[catSelect.value].map(cat => `<option val=${cat}>${cat}</option>`).join('');
}
<select id="cat"></select>
<select id="subcat"></select>

Upvotes: 1

ROOT
ROOT

Reputation: 11622

If its Ok to use a pure javascript (jQuery) solution the following might help, its just filter the dropdown options based on data-dep attribute and return filtered options, or if you are looking for advanced dropdown options dependency check this jQuery plugin.

let $select1 = $( '#select1' ),
		$select2 = $( '#select2' ),
    $options = $select2.find( 'option' );
    
$select1.on( 'change', function() {
	$select2.html( $options.filter( '[data-dep="' + this.value + '"]' ) );
} ).trigger( 'change' );
option {
  margin: 0.5em;
}
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<div class="col-xs-6">
  <select class="form-control" name="select1" id="select1">
    <option value="1">option 1</option>
    <option value="2">option 2</option>
    <option value="3">option 3</option>
    <option value="4">option 4</option>
  </select>
</div>
<div class="col-xs-6">
  <select class="form-control" name="select2" id="select2">
    <option value="1" data-dep="1">option 1 - 1</option>
    <option value="2" data-dep="1">option 1 - 2</option>
    <option value="3" data-dep="1">option 1 - 3</option>
    <option value="4" data-dep="2">option 2 - 1</option>
    <option value="5" data-dep="2">option 2 - 2</option>
    <option value="6" data-dep="3">option 3 - 1</option>
    <option value="7" data-dep="3">option 3 - 2</option>
    <option value="8" data-dep="3">option 3 - 3</option>
    <option value="9" data-dep="4">option 4 - 1<option>
</select>
</div>

Upvotes: 3

Related Questions