1
\$\begingroup\$

I have 3 checkbox's with 8 different combinations and outcomes.

  • Selecting no checkboxes shows no divs.
  • Selecting one checkbox shows the colored div.
    For example; clicking the red checkbox.
  • Selecting two checkboxes shows the color1+color2 div. But doesn't show either of the single colored divs.
    For example; clicking the red and green checkboxes shows the redgreen div. But ensures both the red and green div boxes are hidden so there's only ever one div box showing.
  • Selecting all the checkboxes shows the rgb div. And doesn't show any other divs.

It does work I was wondering if this can be wrote in a simpler fashion?

$('input[type="checkbox"]').click(function () {
    $('.box').hide();
if ($('#red').is(':checked')) $('.red.box').show();
if ($('#green').is(':checked')) $('.green.box').show();
if ($('#blue').is(':checked')) $('.blue.box').show();    
       
if ($('#red').is(':checked') && $('#green').is(':checked')) $('.redgreen.box').show() && $('.red.box, .green.box').hide();

if ($('#red').is(':checked') && $('#blue').is(':checked')) $('.redblue.box').show() && $('.red.box, .blue.box').hide();

if ($('#green').is(':checked') && $('#blue').is(':checked')) $('.greenblue.box').show() && $('.green.box, .blue.box').hide();    

if ($('#red').is(':checked') && $('#green').is(':checked') && $('#blue').is(':checked'))  $('.rgb.box').show() && $('.red.box, .green.box, .greenblue, .redblue, .redgreen.box, .blue.box').hide();    

});
.box {
    padding: 20px;
    display: none;
    margin-top: 20px;
    border: 1px solid #000;
}

.redblue .redgreen .greenblue {
    border: 1px solid black;
}
.rgb {
    border: 1px dashed black;
}
.red {
    background: #ff0000;
}
.green {
    background: #00ff00;
}
.blue {
    background: #0000ff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
    <label>
        <input type="checkbox" id="red" name="colorCheckbox" value="red">red</label>
    <label>
        <input type="checkbox" id="green" name="colorCheckbox" value="green">green</label>
    <label>
        <input type="checkbox" id="blue" name="colorCheckbox" value="blue">blue</label>
</div>
<div class="red box"><strong>red</strong></div>
<div class="green box"><strong>green</strong></div>
<div class="blue box"><strong>blue</strong></div>

<div class="redgreen box"><strong>red green</strong></div>
<div class="redblue box"><strong>red blue</strong></div>
<div class="greenblue box"><strong>green blue</strong></div>

<div class="rgb box"><strong>rgb</strong></div>

\$\endgroup\$
3
  • \$\begingroup\$ This question is lacking any explanation of what the code should do. "3 checkbox's with 8 different combinations and outcomes" doesn't explain what value this has to the user. \$\endgroup\$ Commented Mar 10, 2021 at 13:34
  • \$\begingroup\$ No value for the user. But I've now explained in the OP what the outcome should be. \$\endgroup\$
    – Lowis
    Commented Mar 10, 2021 at 13:38
  • 2
    \$\begingroup\$ @Lowis I think what Toby Speight meant by value was "what problem does your code solve for a user of your code" or "how does your code implement a feature a user of your code may want". As such I think Toby is asking why you wrote the code, less what is your code doing \$\endgroup\$
    – Peilonrayz
    Commented Mar 10, 2021 at 13:56

1 Answer 1

1
\$\begingroup\$

A few notes on your code:

  • If you don't need supporting of very old or non-standard browsers, and given that your project does not relies heavily on jQuery, vanilla JavaScript can do the same work, without jQuery's overhead.
  • On each checkbox click, all coloured divs are queried again and again (jQuery('.box')), which is unnecessary as there are no changes in the DOM.
  • All checkboxes are queried multiple times, instead of selecting them once.
  • The if-then structure is quite cumbersome: if #red is checked, show .red.box. Then, if #green is also checked, hide .red.box and show .redgreen.box. Then, if #blue is checked too, hide .redgreen.box and show .rbg.box. One way for improving this part would be to first determine exactly which box should be checked and show only that box.
  • Personally, I would have used combinations of the .red/.green/.blue classes, instead of putting a different class for each combination (e.g. .box.red.green.blue instead of .box.rgb). That way each checkbox corresponds with a particular div class.

Here is my take on the problem/homework/exercise, that addresses most of the above remarks (no CSS/HTML changes; still using jQuery):

        const RED = 1;
        const GREEN = 2;
        const BLUE = 4;

        const DIV_CLASSES_MAP = [null, '.red', '.green', '.redgreen', '.blue', '.redblue', '.greenblue', '.rgb'];
        const DIVS = $('.box');
        const RED_TICK = $('#red');
        const GREEN_TICK = $('#green');
        const BLUE_TICK = $('#blue');

        let activeDiv = DIVS.filter(':visible');
        $('input[name="colorCheckbox"]').on('click', onCheckboxChange);

        function onCheckboxChange() {
            const redBit = RED_TICK.is(':checked') ? RED : 0;
            const greenBit = GREEN_TICK.is(':checked') ? GREEN : 0;
            const blueBit = BLUE_TICK.is(':checked') ? BLUE : 0;
            const mask = redBit + greenBit + blueBit;
            const activeClass = DIV_CLASSES_MAP[mask];
            activeDiv.hide();
            activeDiv = DIVS.filter(activeClass).show();
        }
\$\endgroup\$
1
  • \$\begingroup\$ I don't need support for older or non-standard browsers so I'll look into a javascript alternative. Does your solution use less queries on the checkbox/s? Thank you. \$\endgroup\$
    – Lowis
    Commented Mar 11, 2021 at 22:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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