Constraint the effect of JQuery Code


#68

Let’s start with what you have there currently.

var totsub = $('.htmljs').parent().find( "input:not(:empty)").length;

We can move parts of that into separate variables, to help make it easier to understand what’s happening.

    var semesters = $('.htmljs').parent();
    var totsub = semesters.find( "input:not(:empty)").length;

The :empty selector doesn’t tell you that the field is empty. Instead, it says that the element doesn’t have any children elements.

To achieve what you’re wanting, we need to get the semester inputs, and filter based on the field having content.

    var semesters = $('.htmljs').parent();
    var totsub = $(semesters).filter(function hasGrade(index, semester) {
        var inputs = $(semester).find("input");
        var filled = inputs.filter(function isFilled(index, input) {
            return input.value > "";
        });
        return filled.length > 0;
    }).length;

We can now look to simplify things. The first thing we can do is to extract the functions:

    function isFilled(index, input) {
        return input.value > "";
    }
    function hasGrade(index, semester) {
        var inputs = $(semester).find("input");
        var filled = inputs.filter(isFilled);
        return filled.length > 0;
    }
    var semesters = $('.htmljs').parent();
    var totsub = $(semesters).filter(hasGrade).length;

After which, we can then attempt to inline some of the code:

    function hasGrade(index, semester) {
        return $(semester).find("input").filter(isFilled).length;
    }

And that’s a working solution for the problem, that doesn’t result in a lot of nested confusion.


#69

I copy pasted your solution - Initially it shows 0, but as soon as we fill any Input DIV it shows “1”, but after that filling any addition input box doesn’t increase the value.

This is the final script that I am using here:

$(document).on("keyup", ".cgpatot", function() {
				// var totsub = $('.htmljs').parent().find( "input:not(:empty)").length;
				function isFilled(index, input) {
			        return input.value > "";
			    }
			    function hasGrade(index, semester) {
			        var inputs = $(semester).find("input");
			        var filled = inputs.filter(isFilled);
			        return filled.length > 0;
			    }
				function hasGrade(index, semester) {
			        return $(semester).find("input").filter(isFilled).length;
			    }
			    var semesters = $('.htmljs').parent();
			    var totsub = $(semesters).filter(hasGrade).length;
			    var sum = 0;
			    $(".cgpatot").each(function(){
			        sum += +$(this).val();
			    });
				var finalcgpa = sum/totsub;
			    $(".total").val(totsub);
			});

#70

My understanding is that the value shows the number of semesters that contain an entry. Is that mistaken?


#71

var totsub should finally be able to calculate the total number of subjects that have the entry. Even if we go by your understanding than also it is unable to count all the semesters that has entry.


#72

That’s easy then, you can remove the isFilled and hasGrade functions and just use the following instead:

var totsub = $("input").filter(function isFilled(index, input) {
  return input.value > "";
}).length;

#73

Hi there @Paul_Wilkins

It worked, but there are certain challenges:

  1. Even if we press the space bar on an input field than the counters runs,

For example only 5 inputs are filled and it is counting as 6:

  1. secondly when we fill the input box #2(Means we enter something in the 2nd input box) then the counter should be adding and making it number “2”, but this is an anomaly it adds and counts to 3 after that it works smoothly like 4, 5, 6, 7…

In the 2nd column also I have also converted each input box to number, but that doesn’t solves this issue.


#74

That can be improved by checking if the input field converts to a number.
Typically Number(input.value) would just be used by itself, but because 0 is expected as a valid value, we should check that it’s not NaN instead.

// return input.value > "";
var num = Number(input.value);
return !isNaN(num);

I don’t have my test code with me right now, so the above is tentative until testing can occur.

Edit: An improved solution is in the next post. Leave the code as being:

return input.value > "";

The field containing the total is being included in what gets searched.
You need to restrict things to only the fields where grades are entered. They are all inside of a class called “class2”, so use (".class2 input") instead of (“input”)


#75

Change the number fields from type=“text” to type=“number” and you won’t have the spacebar problems.