Sanjoy Sen Sanjoy Sen - 5 months ago 9
jQuery Question

j-query function to update value onchange

I am very new to programming world. I have written the following code to calculate number of classes per faculty and total number of classes. But the code does not give the desired result. Any change in a particular row or column should effect only that row or column. Only the box in the South-East corner will be effected by change in any where. But in the present code one change effects all. How to fix it?

<html>
<head>
<script src="jquery-1.11.1.min.js"></script>
</head>
<body>
<table border="1" style="border-collapse:collapse" align="center">
<caption>
<h3>Assign Teacher</h3>
</caption>

<tr>
<th></th>
<th>MON</th>
<th>TUE</th>
<th>Total</th>
</tr>

<tr>
<td> <b>Sem I Honours</b>
</td>
<td align="center">
<select id="" onchange="" >
<option></option>
<option id="">SP</option>
<option id="">AP</option>
<option id="">Guest</option>
</select>
</td>

<td align="center">
<select id="" onchange="">
<option></option>
<option id="">SP</option>
<option id="">AP</option>
<option id="">Guest</option>
</select>
</td>

<td>
Total:
<span class="cnt-total">0</span>
<br/>
SP:
<span class="cnt-sp">0</span>
<br/>
AP:
<span class="cnt-ap">0</span>
<br/>
Guest:
<span class="cnt-guest">0</span>
</td>
</tr>

<tr>
<td> <b>Sem III Honours</b>
</td>
<td align="center">
<select id="" onchange="">
<option></option>
<option id="">SP</option>
<option id="">AP</option>
<option id="">Guest</option>
</select>
</td>

<td align="center">
<select id="" onchange="">
<option></option>
<option id="">SP</option>
<option id="">AP</option>
<option id="">Guest</option>
</select>
</td>

<td>
Total:
<span class="cnt-total">0</span>
<br/>
SP:
<span class="cnt-sp">0</span>
<br/>
AP:
<span class="cnt-ap">0</span>
<br/>
Guest:
<span class="cnt-guest">0</span>
</td>
</tr>

<tr>
<td>
<b>Total</b>
</td>

<td>
Total:
<span class="cnt-total">0</span>
<br/>
SP:
<span class="cnt-sp">0</span>
<br/>
AP:
<span class="cnt-ap">0</span>
<br/>
Guest:
<span class="cnt-guest">0</span>
</td>

<td>
Total:
<span class="cnt-total">0</span>
<br/>
SP:
<span class="cnt-sp">0</span>
<br/>
AP:
<span class="cnt-ap">0</span>
<br/>
Guest:
<span class="cnt-guest">0</span>
</td>

<td>
<b>Total:
<span class="cnt-total">0</span>
<br/>
SP:
<span class="cnt-sp">0</span>
<br/>
AP:
<span class="cnt-ap">0</span>
<br/>
Guest:
<span class="cnt-guest">0</span></b>
</td>
</tr>

</table>
<script>
$('select').change(function() {
// get all selects
var allSelects = $('select'),
total = 0,
sp = 0,
ap = 0,
guest = 0;

// for each select increase count
$.each(allSelects, function(i, s) {
// increase count
if($(s).val() == 'SP') { total++ }
if($(s).val() == 'AP') { total++ }
if($(s).val() == 'Guest') { total++ }
if($(s).val() == 'SP') { sp++; }
if($(s).val() == 'AP') { ap++; }
if($(s).val() == 'Guest') { guest++; }
});

// update count values summary
$('.cnt-total').text(total);
$('.cnt-sp').text(sp);
$('.cnt-ap').text(ap);
$('.cnt-guest').text(guest);
});
</script>
</body>
</html>

Answer

This traversal/matrix math operation (or a simple count by key) is not so simple. You said you're new into programming, so I made an implementation using some basic javascript techniques. Also, I updated your html to use some data- attributes, just to allow some further customization.

HTML

    <html>
    <head><script src="jquery-1.11.1.min.js"></script></head>
    <body>
    <table border="1" style="border-collapse:collapse" align="center"><caption><h3>Assign Teacher</h3></caption>

     <tr><th></th><th>MON</th><th>TUE</th><th>Total</th></tr>

     <tr><td><b>Sem I Honours</b></td><td align="center"><select  id=""  onchange="" data-class="Sem I Honours" data-day="MON"><option></option><option      id="">SP</option><option  id="">AP</option><option id="">Guest</option></select>  </td>

      <td align="center"><select  id=""  onchange="" data-class="Sem I Honours" data-day="TUE"><option></option>
     <option id="">SP</option><option id="">AP</option><option    id="">Guest</option>
      </select></td>

      <td>
      Total:<span class="cnt-total" data-class="Sem I Honours" data-key="any" data-day="any">0</span><br/>
      SP:<span class="cnt-total" data-class="Sem I Honours" data-key="SP" data-day="any">0</span><br/>
      AP: <span class="cnt-total" data-class="Sem I Honours" data-key="AP" data-day="any">0</span><br/>
      Guest: <span class="cnt-total" data-class="Sem I Honours" data-key="Guest" data-day="any">0</span></td></tr>


    <tr><td><b>Sem III Honours</b></td>
    <td align="center"><select   id="" onchange="" data-class="Sem III Honours" data-day="MON"><option></option><option     id="">SP</option><option id="">AP</option><option id="">Guest</option></select>   </td>

    <td align="center"><select   id="" onchange="" data-class="Sem III Honours" data-day="TUE"><option></option><option   id="">SP</option><option id="">AP</option><option id="">Guest</option></select>  </td>

     <td>
     Total:<span class="cnt-total" data-class="Sem III Honours" data-key="any" data-day="any">0</span><br/>
     SP:<span class="cnt-total" data-class="Sem III Honours" data-key="SP" data-day="any">0</span><br/>
     AP: <span class="cnt-total" data-class="Sem III Honours" data-key="AP" data-day="any">0</span><br/>
     Guest: <span class="cnt-total" data-class="Sem III Honours" data-key="Guest" data-day="any">0</span>
     </td>
     </tr>

     <tr><td><b>Total</b></td>


    <td>
    Total:<span class="cnt-total" data-class="any" data-key="any" data-day="MON">0</span><br/>
    SP:<span class="cnt-total" data-class="any" data-key="SP" data-day="MON">0</span><br/>
    AP: <span class="cnt-total" data-class="any" data-key="AP" data-day="MON">0</span><br/>
    Guest: <span class="cnt-total" data-class="any" data-key="Guest" data-day="MON">0</span>
    </td>

    <td>
    Total:<span class="cnt-total" data-class="any" data-key="any" data-day="TUE">0</span><br/>
    SP:<span class="cnt-total" data-class="any" data-key="SP" data-day="TUE">0</span><br/>
    AP: <span class="cnt-total" data-class="any" data-key="AP" data-day="TUE">0</span><br/>
    Guest: <span class="cnt-total" data-class="any" data-key="Guest" data-day="TUE">0</span>
    </td>

    <td>
    Total:<span class="cnt-total" data-class="any" data-key="any" data-day="any">0</span><br/>
    SP:<span class="cnt-total" data-class="any" data-key="SP" data-day="any">0</span><br/>
    AP: <span class="cnt-total" data-class="any" data-key="AP" data-day="any">0</span><br/>
    Guest: <span class="cnt-total" data-class="any" data-key="Guest" data-day="any">0</span>
    </td>

     </tr>

    </table>

<script><!-- script here --></script>
</body>
</html>

Javascript

<script>

(function() {


    var data = {};

    function resetData() {
        data = {};
    }

    function updateDataFromSelects() {
        resetData();
        $('select').each(function() {       
            var this_class = $(this).attr("data-class");
            var this_day = $(this).attr('data-day');
            if (typeof data[this_class] === "undefined") data[this_class] = {};
             data[this_class][this_day] = $(this).val();
        });
        updateTotals();
    }

    function updateTotals() {

        $('span.cnt-total').each(function() {
            var this_key = $(this).attr('data-key');
            var this_day = $(this).attr('data-day');
            var this_class = $(this).attr('data-class');

            $(this).text(totalByKey(this_class, this_day, this_key));

        });



    }

    function totalByKey(_class,_day, _key) {
        var count = 0;
        for (class_key in data) {
            if (class_key === _class || _class === "any") {
                for (day_key in data[class_key]) {
                    if (day_key === _day || _day === "any") {
                        var key = data[class_key][day_key];
                        if (key.length === 0) continue;
                        if (key === _key || _key === "any") count++;
                    }
                }
            }
        }
        return count;
    }


    function bind() {

        $('select').change(function() {
            updateDataFromSelects();
        });


    }

    $(document).ready(function() {
        bind();
        updateDataFromSelects();
    });


})();


</script>
Comments