Jquery multiple selector filter - javascript

I have a working example of code I need, but some improvement is required.
$("#filtroSolicitacoes").on("submit", function(){
$("#solicitacoes div").show();
var filter = "";
$(this).find("[data-form]").each(function(){
if( $(this).val() != "" ) filter += ("[" + $(this).attr("data-form") + "='" + $(this).val() + "']");
});
if(filter.length > 0) $("#solicitacoes div").not(filter).hide();
return false;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="filtros">
<form id="filtroSolicitacoes" type="post" name="filtroSolicitacoes">
Protocolo: <input data-form="id" type="text" name="filtroProtocolo" id="filtroProtocolo" size="5"/>
Solicitante: <input data-form="title" type="text" name="filtroSolicitante" id="filtroSolicitante" size="10"/>
Status:
<select data-form="status" name="filtroStatus" id="filtroStatus">
<option value="">-- Selecione Status--</option>
<option value="3">Aguardando Aprovação</option>
<option value="18">Encaminhado</option>
<option value="2">Iniciado</option>
<option value="1">Não Iniciado</option>
<option value="4">Pendente de Esclarecimento</option>
<option value="16">Reiniciado</option>
<option value="6">Reprovado</option>
</select>
Analista:
<select data-form="analista" name="filtroAnalista" id="filtroAnalista">
<option value="">-- Selecione Analista--</option>
<option value="23">Robert</option>
<option value="46">Allan</option>
<option value="49">Edward</option>
<option value="32">Jake</option>
<option value="14">Stella</option>
</select>
<button type="submit" id="filtrar" style="float:right; margin-right:10px">:: Filtrar ::</button>
</form>
</div>
<div id="solicitacoes">
<div id='1' title='Mike' status='18' analista='23'>Whatever content 1</div>
<div id='2' title='John' status='16' analista='46'>Whatever content 2</div>
<div id='3' title='Tom' status='2' analista='49'>Whatever content 3</div>
<div id='4' title='Mike' status='4' analista='23'>Whatever content 4</div>
<div id='5' title='Kate' status='3' analista='32'>Whatever content 5</div>
<div id='6' title='Steve' status='1' analista='14'>Whatever content 6</div>
</div>
Filterable items have single property:
<div id='6' title='Steve' status='1' analista='14'>Whatever content 6</div>
here status='1' attribute can have only one value (1 in this case). I need to be able add multiple values in one attribute, like so:
<div id='6' title='Steve' status='1 2' analista='14 15'>Whatever content 6</div>
And items with corresponding values must be shown up after filtration.
Unfortunately my knowledge doesn't admit me made that improvement, your help is highly appreciated.
Thank you!

Your main problem lies in how you are constructing your filter:
if( $(this).val() != "" )
filter += ("[" + $(this).attr("data-form") + "='" + $(this).val() + "']");
This means that you can only select a attribute that exacty matches the value, so if you have space separated values in your attributes, e.g. analista='14 15', the filter [analista='14'] or [analista='15'] will never match. Of course, one may find the easy way out of using the *= comparator, but that is very unreliable because that means [analista*='14'] will match any elements that contain analista="14 15" and also analista="140000" for example.
The fix I am proposing is going to slightly rewrite your filtering logic, so do stick with me step-by-step:
Remember to use data- attributes for non-standard attributes, i.e. you can keep id and title, but use data-status and data-analista instead of status and analista respectively.
In your JS, we can cache the $("#solicitacoes").find("div") collection for performance.
Instead of creating a concatenated string of filter, we simply create an empty object. It will serve as a dictionary with contains the attribute stored as the key, and the input field values as the values.
When that dictionary is created, we use the for (var x in ...) syntax to iterate through all keys in your dictionary.
In each iteration, we will have access to the attribute that we want to filter and the value we are interested in. That is your entry of the dictionary.
With this in hand, you can iterate through the cached collection of $("#solicitacoes").find("div"). We want to access the value of the attribute of interest, and then split/explode the string by the space character, so data-analista="14 15" for example will be converted into an array of [14, 15].
Check if the array contains the value in the dictionary entry
See proof-of-concept below: I have added additional space-separated values to the first <div> to illustrate the example.
$("#filtroSolicitacoes").on("submit", function() {
// Cache collection
var $divsToFilter = $("#solicitacoes").find("div");
$divsToFilter.show();
var dictionary = {};
$(this).find("[data-form]").each(function() {
if (this.value)
dictionary[$(this).attr('data-form')] = this.value;
});
// Loop through the dictionary to access individual entries
for (var key in dictionary) {
// We have the key, use it to get the value
var value = dictionary[key];
// Filter the divs
$divsToFilter.filter(function() {
// Explode/split all space-separate values stored in attribute into an array
var dataValues = $(this).attr(key);
// Check if our dictioanry entry's value matches any in the array
// If it is missing, we want to keep it in the filter so that we can hide it
return dataValues.indexOf(value) === -1;
}).hide();
}
return false;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="filtros">
<form id="filtroSolicitacoes" type="post" name="filtroSolicitacoes">
Protocolo: <input data-form="id" type="text" name="filtroProtocolo" id="filtroProtocolo" size="5" /> Solicitante: <input data-form="title" type="text" name="filtroSolicitante" id="filtroSolicitante" size="10" /> Status:
<select data-form="data-status" name="filtroStatus" id="filtroStatus">
<option value="">-- Selecione Status--</option>
<option value="3">Aguardando Aprovação</option>
<option value="18">Encaminhado</option>
<option value="2">Iniciado</option>
<option value="1">Não Iniciado</option>
<option value="4">Pendente de Esclarecimento</option>
<option value="16">Reiniciado</option>
<option value="6">Reprovado</option>
</select>
Analista:
<select data-form="data-analista" name="filtroAnalista" id="filtroAnalista">
<option value="">-- Selecione Analista--</option>
<option value="23">Robert</option>
<option value="46">Allan</option>
<option value="49">Edward</option>
<option value="32">Jake</option>
<option value="14">Stella</option>
</select>
<button type="submit" id="filtrar" style="float:right; margin-right:10px">:: Filtrar ::</button>
</form>
</div>
<div id="solicitacoes">
<div id='1' title='Mike' data-status='18 16 2' data-analista='23 46 49'>Whatever content 1</div>
<div id='2' title='John' data-status='16' data-analista='46'>Whatever content 2</div>
<div id='3' title='Tom' data-status='2' data-analista='49'>Whatever content 3</div>
<div id='4' title='Mike' data-status='4' data-analista='23'>Whatever content 4</div>
<div id='5' title='Kate' data-status='3' data-analista='32'>Whatever content 5</div>
<div id='6' title='Steve' data-status='1' data-analista='14'>Whatever content 6</div>
</div>
Bonus if you're using ES6: everything can be made slightly simpler. This is when you realise you don't actually need jQuery all the time ;)
document.getElementById('filtroSolicitacoes').addEventListener('submit', e => {
e.preventDefault();
const divsToFilter = document.querySelectorAll('#solicitacoes div');
const userFilters = e.target.querySelectorAll('[data-form]');
Array.from(divsToFilter).forEach(element => element.style.display = 'block');
const dictionary = {};
Array.from(userFilters).forEach(input => {
if (input.value)
dictionary[input.dataset.form] = input.value;
});
for (let key in dictionary) {
const value = dictionary[key];
Array.from(divsToFilter).forEach(element => {
var dataValues = element.getAttribute(key);
if (!dataValues.includes(value))
element.style.display = 'none';
});
}
});
<div id="filtros">
<form id="filtroSolicitacoes" type="post" name="filtroSolicitacoes">
Protocolo: <input data-form="id" type="text" name="filtroProtocolo" id="filtroProtocolo" size="5" /> Solicitante: <input data-form="title" type="text" name="filtroSolicitante" id="filtroSolicitante" size="10" /> Status:
<select data-form="data-status" name="filtroStatus" id="filtroStatus">
<option value="">-- Selecione Status--</option>
<option value="3">Aguardando Aprovação</option>
<option value="18">Encaminhado</option>
<option value="2">Iniciado</option>
<option value="1">Não Iniciado</option>
<option value="4">Pendente de Esclarecimento</option>
<option value="16">Reiniciado</option>
<option value="6">Reprovado</option>
</select>
Analista:
<select data-form="data-analista" name="filtroAnalista" id="filtroAnalista">
<option value="">-- Selecione Analista--</option>
<option value="23">Robert</option>
<option value="46">Allan</option>
<option value="49">Edward</option>
<option value="32">Jake</option>
<option value="14">Stella</option>
</select>
<button type="submit" id="filtrar" style="float:right; margin-right:10px">:: Filtrar ::</button>
</form>
</div>
<div id="solicitacoes">
<div id='1' title='Mike' data-status='18 16 2' data-analista='23 46 49'>Whatever content 1</div>
<div id='2' title='John' data-status='16' data-analista='46'>Whatever content 2</div>
<div id='3' title='Tom' data-status='2' data-analista='49'>Whatever content 3</div>
<div id='4' title='Mike' data-status='4' data-analista='23'>Whatever content 4</div>
<div id='5' title='Kate' data-status='3' data-analista='32'>Whatever content 5</div>
<div id='6' title='Steve' data-status='1' data-analista='14'>Whatever content 6</div>
</div>

Related

Show/hide divs based on values selected in multiple select2 dropdowns

I am building a search result filtering feature. I have a number of select2 dropdown boxes where the user can select multiple values from to either hide or show divs with matching class values. I have a number of divs with classes containing values matching values in the select2 dropdown boxes. How do I go about coding this functionality?
I can only get this to work for one selection, I'd like to be able to select multiple options from the dropdowns.
$('select.filterCandidates').bind('change', function() {
$('select.filterCandidates').attr('disabled', 'disabled');
$('#candidates').find('.row').hide();
var critriaAttribute = '';
$('select.filterCandidates').each(function() {
if ($(this).val() != '0') {
critriaAttribute += '[data-' + $(this).data('attribute') + '*="' + $(this).val() + '"]';
}
});
$('#candidates').find('.row' + critriaAttribute).show();
$('#filterCount').html('Showing ' + $('div#candidates div.row:visible').length + ' Matches');
$('select.filterCandidates').removeAttr('disabled');
});
$('#reset-filters').on("click", function() {
$('#candidates').find('.row').show();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div class="col-md-12">
<br>
<h4>Search Form</h4>
<br>
</div>
<div class="col-md-4">
<div class="form-group">
<select id="type" class="form-control filterCandidates" data-attribute="type">
<option value="0">Candidate Type</option>
<option value="CA">CA</option>
<option value="CFA">CFA</option>
<option value="CFO">CFO</option>
<option value="CIMA">CIMA</option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<select id="role" class="form-control filterCandidates" data-attribute="role">
<option value="0">Preferred Role</option>
<option value="Analyst">Analyst</option>
<option value="Associate">Associate</option>
<option value="CFO">CFO</option>
<option value="FD">FD</option>
<option value="FM">FM</option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<select id="roleType" class="form-control filterCandidates" data-attribute="roleType">
<option value="0">Preferred Role Type</option>
<option value="Permanent">Permanent</option>
<option value="Contract/Interim">Contract/Interim</option>
<option value="Internship">Internship</option>
</select>
</div>
</div>
</div>
just to give you a rough idea as you have not provided any code.
<script>
var SelectedValues = $('#ddlSelect option:selected');
var NotSelectedValues $('#ddlSelect option:not(:selected)');
$(SelectedValues ).each(function () {
$("."+$(this).val()+"").show(); //show all those divs containing
//this class
});
$(NotSelectedValues ).each(function () {
$("."+$(this).val()+"").hide();//hide all those divs containing
//this class
});
</script>
This is a rough idea , The above script will show all of the divs containing the classes you have selected in your select2 with id "ddlSelect" and hide those which you have not selected.
you can put this into a function and call it on onchange event of ddlSelect or whatever and however you want it to.

Add filters on objects using multiple <selects>

I have 2 select's and i'd like to filter elements based on the choices of these 2.
<div id="elements">
<div class='anElement' id="1" height="30" color="Red">elem1</div>
<div class='anElement' id="2" height="45" color="Blue">elem2</div>
<div class='anElement' id="2" height="30" color="Blue">elem3</div>
<div class='anElement' id="2" height="60" color="Blue">elem4</div>
</div>
<select id="select1">
<option value="all">All</option>
<option value="Blue">B</option>
<option value="Red">R</option>
</select>
<select id="select2">
<option value="all">All</option>
<option value="45">T</option>
<option value="50">NST</option>
</select>
Now i call the jQuery filter function to filter elements (for example on the attribute color 'Red'):
$('#select1').on('change',function(){
if ($('#select1').val() == 'Red') {
$('#elements .anElement').hide().filter('[color*="'Red' "]').show();
}
...
This becomes really messy though with 2 selectors since I need to apply, reapply and remove these filters dynamically in a right way so I get what I want from the options selected.
I have tried creating variables to check if something was changed in in the other selector but this got out of hand really fast with a lot of different variables and else if statements.
What's the best and most efficient way to do this? Kinda new to JS and jQuery.
This is how I would do it:
fix your html and change attributes to data-attributes
cache your selects and divs in variables
give a common class to your selects
bind the change to the class and filter:
var select1 = $('#select1'),
select2 = $('#select2'),
elements = $('.anElement');
$('.filter').on('change', function() {
// hide all divs
elements.hide();
// filter divs depending on elects
elements.filter(function() {
var element = $(this),
select1Val = select1.val(),
select2Val = select2.val();
if (select1Val === 'all' && select2Val === 'all') {
// return everything if both filters are all
return true;
} else if (select1Val === 'all') {
// only filter on height
return element.data('height') == select2.val();
} else if (select2Val === 'all') {
// only filter on color
return element.data('color') == select1.val();
} else {
//filter on both
return element.data('color') == select1.val() && element.data('height') == select2.val();
}
}).show(); // show the matching divs
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="elements">
<div class='anElement' id="1" data-height="30" data-color="Red">red 30</div>
<div class='anElement' id="2" data-height="45" data-color="Blue">blue 45</div>
<div class='anElement' id="2" data-height="30" data-color="Blue">blue 30</div>
<div class='anElement' id="2" data-height="60" data-color="Blue">blue 60</div>
</div>
<select id="select1" class="filter">
<option value="all">All</option>
<option value="Blue">B</option>
<option value="Red">R</option>
</select>
<select id="select2" class="filter">
<option value="all">All</option>
<option value="45">T</option>
<option value="50">NST</option>
</select>
You can use val of select to filter the divs based on color attribute
$('#select1').on('change', function () {
$("div.anElement").hide();
$("div.anElement[color=" + $(this).val() + "]").show();
});
Also your html is invalid.
You need to close qoutes around color attribute value. Also id elements is invalid it should be id="elements"
<div id="elements">
<div class='anElement' id="1" height="30" color="Red"></div>
<div class='anElement' id="2" height="45" color="Blue"> </div>
<div class='anElement' id="Div1" height="30" color="Blue"> </div>
<div class='anElement' id="Div2" height="60" color="Blue"> </div>
</div>
<select id="select1">
<option value="all">All</option>
<option value="Blue">B</option>
<option value="Red">R</option>
</select>
<select id="select2">
<option value="all">All</option>
<option value="45">T</option>
<option value="50">NST</option>
</select>

How to get option value of only the selected checkboxes?

I want to get option value of only selected checkbox, but I am getting value from all the checkboxes.
My HTML code:
<div class= "outer">
<div class="inner" id="inner">
<input type="checkbox" name="machine" value="plane">BBQ Sauce<br>
<select class="weight" name="m2" id="m2">
<option value="1">Light</option>
<option value="2">Normal</option>
<option value="3">Extra</option>
</select>
</div>
<div class="inner" id="inner">
<input type="checkbox" name="machine" value="plane"> Alfredo Sauce<br>
<select class="weight" name="m2" id="m2">
<option value="1">Light</option>
<option value="2">Normal</option>
<option value="3">Extra</option>
</select>
</div>
</div>
<input type="submit" value="Submit">
My JavaScript code:
function myAction(){
var vals = [];
var machine = document.getElementsByName('machine');
var m2 = document.getElementById('m2');
for(var i=0, n= machine.length; i<n; i++){
if(machine[i].checked){
vals.push(m2.value);
}
}
}
IDs must be unique.
Instead, you could use querySelectorAll() on the existing weight classes to grab only the select elements that follow a checked input (using the general sibling selector):
document.querySelectorAll('input:checked ~ .weight')
The select element values will be the same as their selected options' values.
Snippet
document.querySelector('input[type=submit]').addEventListener('click', myAction);
function myAction() {
var vals = [], //no need for new Array()
weights= document.querySelectorAll('input:checked ~ .weight');
for(var i = 0 ; i < weights.length ; i++) {
vals.push(weights[i].value);
}
console.log(vals);
}
<div class="outer">
<div class="inner" id="inner">
<input type="checkbox" name="machine" value="plane">I have a plane
<br>
<select class="weight" name="m2">
<option value="1">Light</option>
<option value="2">Normal</option>
<option value="3">Extra</option>
</select>
</div>
<div class="inner" id="inner">
<input type="checkbox" name="machine" value="plane">I have 2 planes
<br>
<select class="weight" name="m2">
<option value="1">Light</option>
<option value="2">Normal</option>
<option value="3">Extra</option>
</select>
</div>
</div>
<input type="submit" value="Submit">
You have m2 repeated twice in your code. HTML spec specifies undefined behavior when id is repeated (m2). Also your select box isn't a multi-select. You should just be able to get the value from the select box directly if that is the case.
You can use querySelector also on nested nodes,
so you could filter the div.inner blocks which have the input checked and then get the values from there:
function myAction() {
//var vals = new Array();
var inner = [].slice.call(document.querySelectorAll('.inner'));
var checked = inner.filter(function(x) {
var chk = x.querySelector('input');
if (chk.checked) return x;
})
var vals = checked.map(function(x){
var i = x.querySelector('select').value;
return i
});
}
BTW as Rick said your markup contain some errors so I would suggest to pass it through a validator_
for calling your function on click event of the input submit:
document.querySelector('input[type=submit').addEventListener('click', myAction)

How to show specific content based on 3 drop down selections?

I would like to display a div depending on a user's selection from two drop down lists.
While I'm going to display 3 dropdown options to the users, I'm only going to generate the output based on the selection of the first two:
This means that I will have a total of 9 possible outputs based on the user's selection:
Beaches --> Chill
Beaches --> Fast-Paced
Beaches --> Both
Museums --> Chill
Museums --> Fast-Paced
Museums --> Both
Mountains --> Chill
Mountains --> Fast-Paced
Mountains --> Both
Just for similar reference, a few months ago, I used the following script to generate a specific output based on 2 drop down selections:
http://jsfiddle.net/barmar/ys3GS/2/
<body>
<h2>Find your Animal Name</h2>
<p>Select your birth month and your favorite color and find your animal name.</p>
<form>
<select id="month">
<option value="">- birth month -</option>
<option value="January">January</option>
<option value="February">February</option>
<option value="March">March</option>
<option value="April">April</option>
<option value="May">May</option>
<option value="June">June</option>
<option value="July">July</option>
<option value="August">August</option>
<option value="September">September</option>
<option value="October">October</option>
<option value="November">November</option>
<option value="December">December</option>
</select>
<label class="January" for="January">January Name</label>
<label class="February" for="February">February Name</label>
<label class="March" for="March">March Name</label>
<label class="April" for="April">April Name</label>
<label class="May" for="May">May Name</label>
<label class="June" for="June">June Name</label>
<label class="July" for="July">July Name</label>
<label class="August" for="August">August Name</label>
<label class="September" for="September">September Name</label>
<label class="October" for="October">October Name</label>
<label class="November" for="November">November Name</label>
<label class="December" for="December">December Name</label>
<select id="color">
<option value="">- favorite color -</option>
<option value="Green">Green</option>
<option value="Blue">Blue</option>
<option value="Red">Red</option>
</select>
<label class="Green" for="Green">Green Name</label>
<label class="Blue" for="Blue">Blue Name</label>
<label class="Red" for="Red">Red Name</label>
</form>
<p id="output"></p>
</body>
But this need is a little different. Any thoughts on how I can achieve this? In other words – once the user selected the two options, I want the corresponding div (out of the 9 options) to show up below.
Thanks so much!
You can create 9 div elements and each div element will have two data attributes. One for travel preference and one for style. Like so:
<div class="result" data-preference="beaches" data-style="chill"></div>
<div class="result" data-preference="beaches" data-style="fast-paced"></div>
<div class="result" data-preference="beaches" data-style="both"></div>
<div class="result" data-preference="museums" data-style="chill"></div>
<div class="result" data-preference="museums" data-style="fast-paced"></div>
<div class="result" data-preference="museums" data-style="both"></div>
<div class="result" data-preference="mountains" data-style="chill"></div>
<div class="result" data-preference="mountains" data-style="fast-paced"></div>
<div class="result" data-preference="mountains" data-style="both"></div>
<style>
.result {display:none;}
.result.active {display:block;}
</style>
Also, let's go ahead and add some CSS to hide these div elements, and then setup an active class so that we can display the div once the user has made their selections.
The select elements where the user makes a choice will have options, and each value will have to be identical to the data-preference and data-style values. When a user has made a selection in both of the dropdowns we'll grab all the div's and filter out the one that has the matching data attributes.
$('#preference, #style').on('change', function(){
// set reference to select elements
var preference = $('#preference');
var style = $('#style');
// check if user has made a selection on both dropdowns
if ( preference.prop('selectedIndex') > 0 && style.prop('selectedIndex') > 0 ) {
// remove active class from current active div element
$('.result.active').removeClass('active');
// get all result divs, and filter for matching data attributes
$('.result').filter('[data-preference="' + preference.val() + '"][data-style="' + style.val() + '"]').addClass('active');
}
});
jsfiddle: http://jsfiddle.net/EFM9b/1/
The following is jQuery will work for any number of select fields. It uses the values of the options as CSS classes which are then used to match against the results boxes.
No hiding or showing of the results happens until all select boxes are chosen.
JSFiddle
http://jsfiddle.net/chnZP/
CSS
#results-container > div { display: none; }
HTML
<div id='select-container'>
<select>http://jsfiddle.net/9Qpjg/15/#update
<option value='none'>Select Option</option>
<option value='alpha'>Alpha</option>
</select>
<select>
<option value='none'>Select Option</option>
<option value='red'>Red</option>
<option value='blue'>Blue</option>
</select>
<select>
<option value='none'>Select Option</option>
<option value='dog'>Dog</option>
<option value='cat'>Cat</option>
</select>
</div>
<div id='results-container'>
<div class='dog red alpha'> Alpha Red Dog</div>
<div class='dog blue alpha'> Alpha Blue Dog</div>
<div class='cat red alpha'> Alpha Red Cat</div>
<div class='cat blue alpha'> Alpha Blue Cat</div>
<div>
JavaScript
jQuery(function($){
var
selects = $('#select-container select'),
results = $('#results-container > div');
selects.change(function(){
var values = '';
selects.each(function(){
values += '.' + $(this).val();
});
results.filter(values).show().siblings().hide();
});
});
Careful naming of your divs will get you most of the way there, e.g.
<div class='itinerary' id="beaches_chill">...</div>
<div class='itinerary' id="beaches_fast-paced">...</div>
...
<div class='itinerary' id="mountains_both">...</div>
Now show or hide these based on your dropdowns:
$('#preference, #style').change(function() {
$('.itinerary').hide();
$('#' + $('#preference option:selected').val() + '_' + $('#style option:selected').val()).show();
});
(Another answer here suggests using attributes--that's nicer than using the id, so do that.)

Dropdown to show or hide div content is not working

I can't figure out why this script wont work:
<select name="options" id="options">
<option value="divname1"> Loan Protection Insurance</option>
<option value="divname2"> GAP or Cash Assist Insurance</option>
<option value="divname3"> Home Insurance</option>
<option value="divname4"> Landlords Insurance</option>
<option value="divname5"> Car Insurance</option>
</select>
<div id="divname1" style="display: block">Test 1</div>
<div id="divname2">Test 2</div>
<div id="divname3">Test 3</div>
<div id="divname4">Test 4</div>
<div id="divname5">Test 5</div>
document.getElementById('id-of-select').onchange = function() {
var i = 1;
var myDiv = document.getElementById("divname" + i);
while(myDiv) {
myDiv.style.display = 'none';
myDiv = document.getElementById("divname" + ++i);
}
document.getElementById(this.value).style.display = 'block';
};
div {
display: none;
}
Here is the code
http://jsfiddle.net/2ukyA/7/
However i can get this code working
http://jsfiddle.net/2ukyA/
But i want to have more than one of these on a page so i need something that isn't based on just numbers.
Instead of hiding all divs manually, you could just hide the <div> related to the previously selected value. You could store an associative array (like a map) in which you had, for a given <select> id, the last selected value, or even <div> id. In the onchange event handler, just hide the <div> with the id in the map, and show the new one.
Notice you'll still need to have an association (implicit if they're the same, or explicit if you store it in an array) between the <option> and the <div> id.
See an example in this JSFiddle.
In this example, there is a multidimensional associative array (sort of a map of maps) that stores the <option>s for each <select>. Each <option> is also associated to the <div> id it shows when selected. This same array is used to store the previously selected value for the array (in the entry previousValue).
Notice the definition of the associative array is done statically in javacsript, but it could be dynamically retrieved off an external JSON file, or an AJAX request. The <select> elements could also be dynamically built, but you'd need a little bit more information (i.e. option descriptions).
Javascript:
var selectDivOptions=
{select1:
{
option11: 'div11',
option12: 'div12',
option13: 'div13'
},
select2: {
option21: 'div21',
option22: 'div22',
option23: 'div23'
}
};
for (var key in selectDivOptions){
var element = document.getElementById(key);
element.onchange = selectChange;
}
function selectChange(){
// Hide the div pointed by the previous value
var previousValue = selectDivOptions[this.id]['previousValue'];
if (previousValue){
document.getElementById(previousValue).style.display = 'none';
}
// Show the div
var divToShow = selectDivOptions[this.id][this.value];
if (divToShow){
document.getElementById(divToShow).style.display='block';
}
// Store the current value as the previous value
selectDivOptions[this.id]['previousValue'] = divToShow;
}
HTML
<select name="options" id="select1">
<option value="option11"> Option 11</option>
<option value="option12"> Option 12</option>
<option value="option13"> Option 13</option>
</select>
<div id="div11">Div 11</div>
<div id="div12">Div 12</div>
<div id="div13">Div 13</div>
<br />
<select name="options2" id="select2">
<option value="option21"> Option 21</option>
<option value="option22"> Option 22</option>
<option value="option23"> Option 23</option>
</select>
<div id="div21">Div 21</div>
<div id="div22">Div 22</div>
<div id="div23">Div 23</div>

Categories

Resources