1

I have a checkboxlist control, in this control I wan't every checkbox to fire an event whenever the checkbox is clicked (manually or programmatically). Html code generated by checkboxlist lloks something like below:

<div id="divleft">
    <table id="MainContent_CheckBoxList1">
        <tbody>
            <tr>
                <td><input id="MainContent_CheckBoxList1_0" name="ctl00$MainContent$CheckBoxList1$0" onclick="router(this);" value="1" type="checkbox"><label for="MainContent_CheckBoxList1_0">Option1</label></td>
            </tr>
            <tr>
                <td><input id="MainContent_CheckBoxList1_1" name="ctl00$MainContent$CheckBoxList1$1" onclick="router(this);" value="2" type="checkbox"><label for="MainContent_CheckBoxList1_1">Option2</label></td>
            </tr>
            <tr>
                <td><input id="MainContent_CheckBoxList1_2" name="ctl00$MainContent$CheckBoxList1$2" onclick="router(this);" value="3" type="checkbox"><label for="MainContent_CheckBoxList1_2">Option3</label></td>
            </tr>
            <tr>
                <td><input id="MainContent_CheckBoxList1_3" name="ctl00$MainContent$CheckBoxList1$3" onclick="router(this);" value="4" type="checkbox"><label for="MainContent_CheckBoxList1_3">Option4</label></td>
            </tr>
        </tbody>
    </table>
</div>

On click of checkbox I am hiding or showing div(s). The div looks like:

 <div id="divright">
    <div id="divoption1" style="display: none;">
        I am in option1 div
    </div>
    <div id="divoption2" style="display: none;">
        I am in option2 div
    </div>
    <div id="divoption3" style="display: none;">
        I am in option3 div
        </div>
    </div>
</div>

I have a jquery code which does the heavy duty work for showing / hiding divs.

$(document).ready(function () {
    RunOnce();
});

function uncheckAllCheckboxes(previouscheckedCheckboxValue, currentcheckedCheckboxValue) {
    if (previouscheckedCheckboxValue != null && previouscheckedCheckboxValue != currentcheckedCheckboxValue) {
        window.isRunOnce = 'false';
        $('[id$=divleft]').find('input:checkbox[value="' + previouscheckedCheckboxValue + '"]').prop('checked', false).click();
        //variable used to avoid infinite loop
        window.isRunOnce = null;
    }
    return currentcheckedCheckboxValue;
}

function router(control) {
    if (control.value == '1') {
        Option1Controller(control.value);
    }
    if (control.value == '2') {
        Option2Controller(control.value);
    }
    if (control.value == '3') {
        Option3Controller(control.value);
    }
}

function Option1Controller(currentCheckBoxValue) {
    if ($('[id$=divleft]').find('input:checkbox[value="' + currentCheckBoxValue + '"]').is(':checked') == true) {
        $('[id$=divoption1]').show();

        if (window.isRunOnce == null) {
            window.previouscheckBoxValue = uncheckAllCheckboxes(window.previouscheckBoxValue, currentCheckBoxValue);
        }

    }
    else {
        $('[id$=divoption1]').hide();
    }
}

function Option2Controller(currentCheckBoxValue) {
    if ($('[id$=divleft]').find('input:checkbox[value="' + currentCheckBoxValue + '"]').is(':checked') == true) {
        $('[id$=divoption2]').show();
        if (window.isRunOnce == null) {
            window.previouscheckBoxValue = uncheckAllCheckboxes(window.previouscheckBoxValue, currentCheckBoxValue);
        }
    }
    else {
        $('[id$=divoption2]').hide();
    }
}

function Option3Controller(currentCheckBoxValue) {
    if ($('[id$=divleft]').find('input:checkbox[value="' + currentCheckBoxValue + '"]').is(':checked') == true) {
        $('[id$=divoption3]').show();

        if (window.isRunOnce == null) {
            window.previouscheckBoxValue = uncheckAllCheckboxes(window.previouscheckBoxValue, currentCheckBoxValue);
        }
    }
    else {
            $('[id$=divoption3]').hide();
    }
}
function RunOnce() {
    Option1Controller('1');
    Option2Controller('2');
    Option3Controller('3');
}

Problem lies with function uncheckAllCheckboxes, in this function, I am unchecking previously checked checkboxes: I have tried:

$('[id$=divleft]').find('input:checkbox[value="' + previouscheckedCheckboxValue + '"]').prop('checked', false); 

Above query unchecks the corresponding checkbox but does not fire the onclick event?

$('[id$=divleft]').find('input:checkbox[value="' + previouscheckedCheckboxValue + '"]').click(); just after the above query.

It fires the click event but also undoes 1, so it is useless.

$('[id$=divleft]').find('input:checkbox[value="' + previouscheckedCheckboxValue + '"]').prop('checked', false).click();

This query also seems to do nothing

My requirement is simple: I need to pro grammatically check/uncheck checkboxes which are identified by parent id and the value of checkbox control. After checking/unchecking, the control should fire click event also.

Any help shall be appriciated.

Note: I am new to this jquery stuff, so any improvements in my code are also welcomed.

Devesh
  • 396
  • 1
  • 4
  • 23
  • [this link](http://stackoverflow.com/questions/11205957/jquery-difference-between-change-and-click-event-of-checkbox) solves my problem – Devesh Sep 22 '13 at 13:34

2 Answers2

1

I think you are using too much code.

Check this:

$('input[type="checkbox"]').change(function () {
    var this_index = $(this).closest('tr').index(); //check the index of the tr of this input
    $("#divright > div").eq(this_index).show(); //show the div inside divright that has same index as this_index
});

And this demo. I removed all inline function calls. I think this is a easier way.

Sergio
  • 28,539
  • 11
  • 85
  • 132
  • thanks for the prompt response, I think by inline calls You mean the onclick event which I was having with every checkbox? I have to write that much code because: 1. the original code is more complicated and with more conditions, 2. I am trying to implement mvc in javascript with the help of jquery – Devesh Sep 22 '13 at 13:21
  • Hi Sergio, since I am not that conversant with jquery Can You please confirm that: 1) You have replaced all that infrastructure code with this code, which is a single event for all the checkboxes in the page. I don't understand the other two lines. Can You please elaborate it or some pointer to this will be helpful – Devesh Sep 22 '13 at 13:45
  • @shankbond, I was away, just updated with small comment. Did you understand the idea of those lines. I think that code could replace all of your code... but maybe you have more functions you didn't post here – Sergio Sep 22 '13 at 14:28
  • thanks for helping me out, now I understood the meaning of those lines:the code says that, which ever checkbox is clicked get its index, show the div in divright with the same index. Yes Sergio, the current code changes the behavior of check-boxes as if they are radio buttons, only one selected at a time. there is some more code which changes the behavior of checkboxes to multiple checkbox selection, I left this part for the sake of simplicity :) – Devesh Sep 22 '13 at 14:48
  • One final question though: why have You taken the index of tr? not any checkbox? – Devesh Sep 22 '13 at 14:50
  • @shankbond, i took the index of tr because the input has no other inputs in the same DOM tree level – Sergio Sep 23 '13 at 14:32
1

Have you considered using radio buttons instead of checkboxes? They have same behavior you trying to achieve with checkboxes. I've created a fiddle

HTML

<label for="checkbox1">Div 1</label>
    <input type="checkbox" name="div" id="checkbox1" data-div-id="1">
<label for="checkbox2">Div 2</label>
    <input type="checkbox" name="div" id="checkbox2" data-div-id="2">
<label for="checkbox3">Div 3</label>
    <input type="checkbox" name="div" id="checkbox3" data-div-id="3">

<hr/>

<div id="div1">DIV1</div>
<div id="div2">DIV2</div>
<div id="div3">DIV3</div>

<br/>

<label for="radio1">Div 4</label>
    <input type="radio" name="div" id="radio1" data-div-id="4">
<label for="radio2">Div 5</label>
    <input type="radio" name="div" id="radio2" data-div-id="5">
<label for="radio3">Div 6</label>
    <input type="radio" name="div" id="radio3" data-div-id="6">

<hr/>        

<div id="div4">DIV4</div>
<div id="div5">DIV5</div>
<div id="div6">DIV6</div>

JS

$(document).ready(function() {

    var checkboxes = $('input:checkbox'),
        radios     = $('input:radio'),
        divs       = $('div');

    // hide all divs
    divs.hide();

    checkboxes.change(function( e ) {
        var e = e || window.event,
            target = e.target || e.srcElement;

        $('#div' + $(target).data('div-id')).toggle();
    });

    radios.change(function( e ) {
        var e = e || window.event,
            target = e.target || e.srcElement;

        divs.hide();
        $('#div' + $(target).data('div-id')).toggle();
    });
});

you can see the comparison between both. And wouldn't use inline js anymore and css when possible. And try to avoid using tables if it not for tabular data, they are known for causing performance issues. Read this

Community
  • 1
  • 1
orustammanapov
  • 1,792
  • 5
  • 25
  • 44
  • 1) You are correct for radio buttons but due to client's restriction I have to forcefully use checkboxes here. 2) Thanks for the advice regarding table, but as You know that checkbox list control of asp.net automatically generates tables. – Devesh Sep 22 '13 at 13:47