2
\$\begingroup\$

I'm a bit of a newb with jQuery but can get it working to perform the functionality that I'm after.

The below function checks the value of the radio input and then adds a class, depending on the selection. But it feels like there is a more efficient way of writing this.

$('input[name=choice]').change(function(){
	var inputVal = $('input[name=choice]:checked').val();
					
	if(inputVal == 'Option A') {
		$(".img-wrapper").addClass('option-a');
	} else {
		$(".img-wrapper").removeClass('option-a');
	}
	
	if(inputVal == 'Option B') {
		$(".img-wrapper").addClass('option-b');
		$(".img-wrapper").removeClass('option-a');
	} else {
		$(".img-wrapper").removeClass('option-b');
	}

	if(inputVal == 'Option C') {
		$(".img-wrapper").addClass('option-c');
		$(".img-wrapper").removeClass('option-a');
	} else {
		$(".img-wrapper").removeClass('option-c');
	}

	if(inputVal == 'Option D') {
		$(".img-wrapper").addClass('option-d');
		$(".img-wrapper").removeClass('option-a');
	} else {
		$(".img-wrapper").removeClass('option-d');
	}
});
<div class="view-choice">
   <input type="radio" name="choice" value="Option A">
   <input type="radio" name="choice" value="Option B">
   <input type="radio" name="choice" value="Option C">
   <input type="radio" name="choice" value="Option D">    
</div>

<div class="img-wrapper option-a"></div>
 

https://jsfiddle.net/fhaLztL6/

\$\endgroup\$
  • \$\begingroup\$ why only removing one class ? If I get it right, you need to remove all other 3 classes. Am I right? \$\endgroup\$ – J M Feb 6 '18 at 11:31
  • \$\begingroup\$ Sorry, I should have been clearer - the .img-wrapper has the class of option-a added when the page is loaded. I'll edit my question to show my HTML \$\endgroup\$ – AFK Feb 6 '18 at 11:39
  • \$\begingroup\$ Welcome to Code Review! I suggest including the relevant CSS in the question itself. The more realistic, the better. \$\endgroup\$ – 200_success Feb 6 '18 at 13:23
0
\$\begingroup\$

How about a 2 liner solution where you can convert the value using regex and toLowerCase() to transform the value into class name and instead of creating separate checks for every option where you would have to update the code every time your options increase in case they are coming from the databases.

$('input[name=choice]:checked').val().toLowerCase().replace(/\s+/, "-");

You should override all the classes and just provide the default class with the selected so rather than using

$(".img-wrapper").addClass('option-d');
$(".img-wrapper").removeClass('option-a');

using the following approach will override the previously applied any class and adds the new class.

.attr('class','img-wrapper '+className);

So all your code sum up to 3 lines.

$('input[name=choice]').change(function() {
  var className = $('input[name=choice]:checked').val().toLowerCase().replace(/\s+/, "-");
  $(".img-wrapper").attr('class', 'img-wrapper ' + className);
});

$('input[name=choice]').on('change',function() {
  var className = $('input[name=choice]:checked').val().toLowerCase().replace(/\s+/, "-");
  $(".img-wrapper").attr('class', 'img-wrapper ' + className);
});
.img-wrapper {
  background-color: #000 !important;
  width: 50px;
  height: 50px;
}

.option-a {
  background-color: #E91E63 !important;
}

.option-b {
  background-color: #607D8B !important;
}

.option-c {
  background-color: #FF9800 !important;
}

.option-d {
  background-color: #4CAF50 !important
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="view-choice">
  <input type="radio" name="choice" value="Option A">
  <input type="radio" name="choice" value="Option B">
  <input type="radio" name="choice" value="Option C">
  <input type="radio" name="choice" value="Option D">
</div>

<div class="img-wrapper"></div>

\$\endgroup\$
  • \$\begingroup\$ This is exactly the kind of thing I was after, thank you! \$\endgroup\$ – AFK Feb 9 '18 at 9:05
  • \$\begingroup\$ @AFK glad I could interpret what you wanted, a vote up would get me excited (⌐■_■) \$\endgroup\$ – Muhammad Omer Aslam Feb 9 '18 at 10:07
1
\$\begingroup\$

You could use labels for your radio inputs and use the actual class names for the values. Then on change, you'd just remove all the option classes and pass in your inputVal for the class to add. See the snippet below (colors added to the classes via CSS and text added in .img-wrapper to show it working).

$('input[name=choice]').change(function(){
	var inputVal = $('input[name=choice]:checked').val();
			
	$(".img-wrapper")
		.removeClass('option-a option-b option-c option-d')
		.addClass(inputVal);
});
.option-a
{
  color: red;
}

.option-b
{
  color: green;
}

.option-c
{
  color: blue;
}

.option-d
{
  color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="view-choice">
   <label for="option-a">Option A</label>
   <input type="radio" name="choice" value="option-a" checked>
   <label for="option-b">Option B</label>
   <input type="radio" name="choice" value="option-b">
   <label for="option-c">Option C</label>
   <input type="radio" name="choice" value="option-c">
   <label for="option-d">Option D</label>
   <input type="radio" name="choice" value="option-d">    
</div>

<div class="img-wrapper option-a">Blah</div>

\$\endgroup\$
1
\$\begingroup\$

There is a useful jQuery method named toggleClass. Instead of:

if(inputVal == 'Option A') {
    $(".img-wrapper").addClass('option-a');
} else {
    $(".img-wrapper").removeClass('option-a');
}

you can just write:

$(".img-wrapper").toggleClass('option-a', inputVal == 'Option A');
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.