Creating a multi-select where you select each element and clicking a button displays the corresponding data for each option below to compare

jquery

#1

Hi!! I’m new to coding and am trying to create a simple multi-select option which will allow user to select multiple options. On selecting and clicking the button provided, the corresponding data should be displayed below for each option to allow them to compare. For this I have tried to create a JSON array within my Jquery code but am unable to get it to display the corresponding data. Please help.

<html>
    <head>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
        <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
        <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
    </head>
    <style>
        .hide{
            visibility: hidden
        }
    </style>
<body>

<body style="font-family: Arial">
Options:
<input type="checkbox" name="Station" value="Opt1">Option1
<input type="checkbox" name="Station" value="Opt2">Option2
<input type="checkbox" name="Station" value="Opt3">Option3
<input id="btnSubmit" type="submit" value="submit" />
<br /><br />
<div id="divResult"></div>

</body>

<script>
    $(document).ready(function(){
        var StatJSON = {
          "Opt1":  {
            "Name": "Mat",
            "Parameter1": "65",
            "Parameter2": "30"
        },
          "Opt2": {
            "Name": "Mik",
            "Parameter1": "62",
            "Parameter2": "40"
        }
    };

    $('#btnSubmit').click(function(){
        var getCheckedCheckBoxes = function () {
        var input = $('Input[type="checkbox"]:checked');
        if (input.lenght > 0) {
            input.each(Function() {
                resultString =+ StatJSON.this;
            });
        }        
        $('#divResult').html(resultString);
        }
        else {
        $('#divResult').html("No Radio Button Selected");
        }
    }
});
</script>
</html>

#2

Check your indentation. Things aren’t lined up the way you think they are, and it may become clear why it’s not triggering if you sort that out.


#3

Hi!! Thanks for the reply. I’ve relooked and gone through a million websites for the answer but not getting what I need. Find below the code with a few revisions, but Im still not able to get it to display the result I need. Could you please be able to point-out where exacty I’m going wrong here?? Thanks again!

<html>
    <head>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
        <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
        <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
    </head>
    <style>
        .hide{
            visibility: hidden
        }
    </style>
<body>

<body style="font-family: Arial">
Options:
<input type="checkbox" name="Station" value="Opt1">Option1
<input type="checkbox" name="Station" value="Opt2">Option2
<input type="checkbox" name="Station" value="Opt3">Option3
<input id="btnSubmit" type="submit" value="submit" />
<br /><br />
<div id="divResult"></div>

</body>

<script>
    $(document).ready(function(){
        var StatJSON = {
          "Opt1":  {
            "Name": "Mat",
            "Parameter1": "65",
            "Parameter2": "30"
        },
          "Opt2": {
            "Name": "Mik",
            "Parameter1": "62",
            "Parameter2": "40"
        }
    };

    $('#btnSubmit').click(function(){
        var getCheckedCheckBoxes = function () {
        var input = $('Input[type="checkbox"]:checked');
        if (input.length > 0) {
            input.each(function() {
                var resultString =+ StatJSON.$(this).val();
            });
        }        
        else {
        $('#divResult').html("No Radio Button Selected");
        }
    $('#divResult').html(resultString);
    }
    });
});
</script>
</html>

#4

On a cursory investigation of your code, it looks like you are creating a function called getCheckedCheckBoxes but aren’t executing it.

I suspect that what you need to do is to move the getCheckedCheckBoxes function definition out of the click event, and to pass getCheckedCheckBoxes to the click event instead.

function getCheckedCheckBoxes() {
    ...
}
$('#btnSubmit').click(getCheckedCheckBoxes);

That’s about as simple as it gets.


#5

Also, you have to use the square bracket notation if you want to access dynamic property names. And then you might want to JSON.stringify() the result (or otherwise extract the desried data) as otherwise you’ll just get a series of "[object Object]" strings.


#6

(or at the very least, stick some commas in there, cause MatMik isn’t probably going to be very readable once you add more options…)

Additionally, you cant define a var inside a looped function and have it retain data, and can’t append to a non-existent string. Initialize the variable (resultString) outside the loop.

EDIT: Additional additional: Your append structure is backwards. =+ has no meaning. (Well no, that’s a lie, it has a meaning which is “Equals to Undefined Plus…”, but that’s not what you’re trying to say.) += does.


#7

You have no !doctype, two <body> tags, a <style> section that is in neither the head nor the body section and some JS that is outside the <body>. That should be enough to confuse most browsers.


#8

Hi,

Thank you all for your valuable inputs and suggestions. :slight_smile:

I have incorporated and revised my code, have also cleaned it up but still not getting an output. The fault seems to be some stupid error in the coding which I’m unable to narrow down on.

Would be of great help if someone could point-out and correct it as I’ve been stuck on this for a longtime now and am unable to proceed.

Once again, thanks!! And please help me solve this.

Corrected code:

<!DOCTYPE html>
<html>
    <head>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
    </head>

<body>
Options:
<input type="checkbox" name="Station" value="Opt1">Option1
<input type="checkbox" name="Station" value="Opt2">Option2
<input type="checkbox" name="Station" value="Opt3">Option3
<input id="btnSubmit" type="submit" value="submit" />
<br /><br />
<div id="divResult"></div>
 </body>

<script>
    $(document).ready(function(){
        var StatJSON = {
          "Opt1":  {
            "Name": "Mat",
            "Parameter1": "65",
            "Parameter2": "30"
        },
          "Opt2": {
            "Name": "Mik",
            "Parameter1": "62",
            "Parameter2": "40"
        }
    };

    $('#btnSubmit').click(function(){
        $('input[type="checkbox"]:checked').each(function() {
            var this_input = $(this);
            if (this_input.is(':checked')){
            resultString += [StatJSON.$(this).val()];
            }
        $('#divResult').html(resultString);
        }
    });
});
</script>
</html>

#9

Okay.
Five major things.

#1: The If That Never Was

$('input[type="checkbox"]:checked').each(function() { 
  var this_input = $(this); 
  if (this_input.is(':checked')){

The if will always be true. You’ve already selected only the checkboxes that are checked.

#2: resultString is now not defined anywhere.

It should be defined just inside the start of the .click() function’s definition.

#3: That’s not the square bracket notation @m3g4p0p meant

StatJSON is the object you’re trying to pull from; the element you’re trying to pull out of it is the one identified by the value.
StatJSON[$(this).val()]

Also pulling this (if corrected) will give you the entire object back as he also pointed out, so you’re probably actually trying to access the .Name element of the object you pull back.
StatJSON[$(this).val()].Name

#4: Your output is being sent from inside the loop.

Not strictly a problem, because the browser will end with the correct value, but unnecessary workload on the browser to render the resulting div multiple times. The setting of the div’s html should occur after the loop completes.

#5: There’s no way this code actually compiles.

This code must be failing and throwing errors into your javascript console because you never close the ( on the .each. May I gently suggest having a look at some basic javascript debugging methods?

(And yes, I’m conscious of the fact that I’m typing this response at the same time as Paul, so there may be significant overlap in our responses. Not trying to snipe you, Paul! :slight_smile: )


#10

I’ve found that using JSLint to imform me of any obvious problems helps a lot, to the point where I have my code editor tell me about all linting problems as I write the code, so that I can fix it right there and then.

Here’s what it has to say about things, where I’ve used comments in the code sections to show the old previous line of code before it was updated.

Use double quotes, not single quotes.

The main reason for using double quotes is that when there’s both single and double quotes that can be used, it’s better to settle on one of them for the sale of consistency. Because we’re not supposed to use HTML code in our JavaScript, and double quotes let you more easily use words such as “you’re” and “it’s”, double quotes are the standard that has been set.

If you look at jQuery’s attribute equals selector documentation page, you’ll also see that double quotes are used, with single quotes inside.

    // $('#btnSubmit').click(function(){
    $("#btnSubmit").click(function(){
    ...
        // $('input[type="checkbox"]:checked').each(function() {
        $("input[type='checkbox']:checked").each(function() {
    ...
            // if (this_input.is(':checked')){
            if (this_input.is(":checked")){
    ...
        // $('#divResult').html(resultString);
        $("#divResult").html(resultString);

Unexpected ‘this’.

The this keyword ends up becoming confusing because it can frequently change meaning. As a result, using properly named variable helps to prevent that confusion.

        // $("input[type='checkbox']:checked").each(function() {
        $("input[type='checkbox']:checked").each(function(ignore, input) {
            // var this_input = $(this);
            // if (this_input.is(":checked")){
            if (input.is(":checked")){
            // resultString += [StatJSON.$(this).val()];
            resultString += [StatJSON.$(input).val()];

Bad property name ‘$’.

            resultString += [StatJSON.$(input).val()];

Here, StatJSON is the object and you are attempting to use a property accessor. When using dot notation the property must be a valid identifier contains alphanumerics. $(input).val() is not a valid identifier.

Instead of using dot notation, you need to use bracket notation instead.

            // resultString += [StatJSON.$(input).val()];
            resultString += StatJSON[$(input).val()];

Expected ‘)’ to match ‘(’ from line 15 and instead saw ‘}’.

Here’s line 15, and line 21 on which the error occurred.

        $("input[type='checkbox']:checked").each(function(ignore, input) {
            ...
    });

Nothing seems to be wrong there, so it helps to look at the line inside of them too.

        $("input[type='checkbox']:checked").each(function(ignore, input) {
            if (input.is(":checked")){
                resultString += StatJSON[$(input).val()];
            }
            $("#divResult").html(resultString);
        }
    });

The if statement has a starting and a closing brace, which can be ignored for the purpose of investigating the problem.

There is a single closing brace below the divResult line, that doesn’t seem to have a matching starting brace.

It seems that you haven’t properly closed the each statement, which needs to be }); instead of just }

That is confirmed by checking the other }); lines which appropriately close off the click event and the document ready lines respectively.

We can just correct the single closing brace line so that it properly closes the each statement.

        // }
        });
    });

Undeclared ‘$’.

JSLint must be told about global variable, so we declare them at the top of the code.

/*global $ */
...

/*global*/ requires the Assume a browser option.

Let’s do that.

/*jslint browser */
/*global $ */
...

Undeclared ‘resultString’.

    $("#btnSubmit").click(function(){
        ...
                resultString += StatJSON[$(input).val()];

As there is no var declaration, resultString is being defined as a global variable.
You can prevent that by declaring it in the each function.

    $("#btnSubmit").click(function(){
        var resultString = "";
        ...
                resultString += StatJSON[$(input).val()];

Expected ‘$’ at column 0, not column 4.

We now have a lot of code indentation issues, for which the best solution is to use the Online JavaScript Beautifier where after beautifying the code, we can copy and paste it back into JSLint.

Expected one space between ‘function’ and ‘(’.

$(document).ready(function() {

Beautifying the code also helps to find unnamed anonymous functions.
While it’s possible to “fix” this by adding a space, it’s better if we properly name our functions.

We don’t have to use the ready method either. Instead, we can use the recommended way instead of just passing a function to the jQuery object.

// $(document).ready(function() {
$(function ready() {

Expected one space between ‘function’ and ‘(’.

We should name this click function too.

    // $("#btnSubmit").click(function() {
    $("#btnSubmit").click(function showCheckedValues() {

Expected one space between ‘function’ and ‘(’.

We should name this each function too

        // $("input[type='checkbox']:checked").each(function addEachValue(ignore, input) {
        $("input[type='checkbox']:checked").each(function addValue(ignore, input) {

Line is longer than 80 characters.

The line is too long now though, so we should either break the line after the each parenthesis, or assign the checked fields to an appropriate value. I’ll choose the latter.

        // $("input[type='checkbox']:checked").each(function addValue(ignore, input) {
        var $checked = $("input[type='checkbox']:checked");
        $checked.each(function addValue(ignore, input) {

And JSLint now likes the code. You should find that it now works a lot better than it did before.


#11

Hi!! Thank you both @Paul_Wilkins and @m_hutley! :slight_smile: Sorry about the delayed revert, it wasnt allowing me to post a reply. I have managed to update the code with your inputs and some other help and it is working now.

However, it’s currently giving me separate tables for each selected input. But if you observe, the keys (row heading) are the same, I actually require each selection to appear to the right of the previous selection in a single table. Basically I need to build a simple comparison table to compare each option across parameters. How do I do this?

Thanks a million again!!! And many, many thanks, @Paul_Wilkins for that very detailed explanation!! :slightly_smiling_face::+1:

    <!DOCTYPE html>
    <html>
        <head>
            <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
        </head>
     <style>
         .opt{
             margin: 10px;
             padding: 10px;
             background: #eee;
             border: 1px solid #222;
         }
         .select{
             font-family: Sans-serif;
             font-size : 10px;
             font-size: #222;
             font-style: italic;    
             }
     </style>   
    <body>
    Options:
    <input type="checkbox" name="Station" value="Opt1" class="select">Option1
    <input type="checkbox" name="Station" value="Opt2" class="select">Option2
    <input type="checkbox" name="Station" value="Opt3" class="select">Option3
    <input id="btnSubmit" type="submit" value="submit" />
    <br /><br />
    <div id="divResult"></div>
    </body> 

    <script>
        jQuery(document).ready(function( $ ){
            var StatJSON = {
            "Opt1":  {
                "Name": "Mat",
                "Parameter1": "65",
                "Parameter2": "30"
            },
            "Opt2": {
                "Name": "Mik",
                "Parameter1": "62",
                "Parameter2": "40"
            },
            "Opt3": {
                "Name": "Mir",
                "Parameter1": "65",
                "Parameter2": "90"
            }
        };

        $('#btnSubmit').click(function(){ 
        var resultString = '';
        $('input[type="checkbox"]:checked').each(function() {
        var this_input = $(this);
        if (this_input.is(':checked')){
        resultString += PrintHtml(StatJSON[$(this).val()]);
        }
        });
        $('#divResult').html(resultString);
        });
    });

    function PrintHtml(obj){
        var html='<div class="opt">';
        if (obj){
            $.each(obj, function(k,v){
                html += '<div>'+k+' : '+v+'</div>'; 
            });
        }
        html += '</div>';
        return html;
    }
    </script>
    </html>

#12

For that I highly recommend the fine folk in our CSS forum for helping with issues of layout.