0

I'm working on a website and wanting to do advanced stuff (at least for me) that is way over my head. My javascript knowledge is extremely limited and need help with this.

I have an html form that accepts 5 text input fields labeled 1-5 representing a percentage distribution. I want to use javascript to do the following:

  1. Read all fields and make sure the total sum is equal to 100.
  2. Disable unnecessary fields when total sum equals 100.
  3. Disable Submit button if total sum is not 100%.
  4. Add the % at the end of the user entry.

I found two separate scripts to accomplish all this, one is javascript and the other one is JQuery. For some reason the JQuery is not working and it is yielding the following error:

Uncaught TypeError: $ is not a function

I've tried modifying the JQuery code, as suggested in multiple solutions online, like the following:

(function($){ "JQuery Code here" })(jQuery);

This get's rid of the error, however the JQuery code does not work.

Both the javascript.js and the JQuery.js files are being propperly enqueued in the WP theme's functions.php file.

Any help will be greately appreciated!!

HTML

<label for="entryFee">Entry Fee:</label>
<input id="entryFee" name="entry_fee" onblur="this.value = '$' + formatNumber(this.value, 1, 2, true)" type="text" value="" placeholder="$100.00" /> &nbsp;
<h4>Prize Distribution</h4>

<label for="1stPlace">1st Place:</label> <input id="1stPlace" name="1st_place" type="text" onblur="this.value = formatNumber(this.value, 1, 0, true) + '%'" placeholder="60%" maxlength="3" size="4" class="percentageField" required />

<label for="2ndPlace">2nd Place:</label> <input id="2ndPlace" name="2nd_place" type="text" onblur="this.value = formatNumber(this.value, 1, 0, true) + '%'" placeholder="30%" maxlength="3" size="4" class="percentageField" />

<label for="3rdPlace">3rd Place:</label> <input id="3rdPlace" name="3rd_place" type="text" onblur="this.value = formatNumber(this.value, 1, 0, true) + '%'" placeholder="10%" maxlength="3" size="4" class="percentageField" />

<label for="4thPlace">4th Place:</label> <input id="4thPlace" name="4th_place" type="text" onblur="this.value = formatNumber(this.value, 1, 0, true) + '%'" placeholder="0%" maxlength="3" size="4" class="percentageField" />

<label for="5thPlace">5th Place:</label> <input id="5thPlace" name="5th_place" type="text" onblur="this.value = formatNumber(this.value, 1, 0, true) + '%'" placeholder="0%" maxlength="3" size="4" class="percentageField" />

<span id="percent">0</span>%


<input id="submitButton" type="submit" value="Submit" disabled>

</form>

Javascript

// Reformats a number by inserting commas and padding out the number of digits
// and decimal places.
//
// Parameters:
//     number:        The number to format. All non-numeric characters are
//                    stripped out first.
//     digits:        The minimum number of digits to the left of the decimal
//                    point. The extra places are padded with zeros.
//     decimalPlaces: The number of places after the decimal point, or zero to
//                    omit the decimal point.
//     withCommas:    True to insert commas every 3 places, false to omit them.


function formatNumber(number, digits, decimalPlaces, withCommas)
{
        number       = number.toString();
    var simpleNumber = '';

    // Strips out the dollar sign and commas.
    for (var i = 0; i < number.length; ++i)
    {
        if ("0123456789.".indexOf(number.charAt(i)) >= 0)
            simpleNumber += number.charAt(i);
    }

    number = parseFloat(simpleNumber);

    if (isNaN(number))      number     = 0;
    if (withCommas == null) withCommas = false;
    if (digits     == 0)    digits     = 1;

    var integerPart = (decimalPlaces > 0 ? Math.floor(number) : Math.round(number));
    var string      = "";

    for (var i = 0; i < digits || integerPart > 0; ++i)
    {
        // Insert a comma every three digits.
        if (withCommas && string.match(/^\d\d\d/))
            string = "," + string;

        string      = (integerPart % 10) + string;
        integerPart = Math.floor(integerPart / 10);
    }

    if (decimalPlaces > 0)
    {
        number -= Math.floor(number);
        number *= Math.pow(10, decimalPlaces);

        string += "." + formatNumber(number, decimalPlaces, 0);
    }

    return string;
}

JQuery

(function($){
$('.percentageField').keyup( function () {
    //limit the value to between 0 and 100
    var thisVal = parseInt($(this).val(), 10);
    if (!isNaN(thisVal)) {
        thisVal = Math.max(0, Math.min(100, thisVal));
        $(this).val(thisVal);
    }
    
    //get total of values
    var total = 0; 
    $('.percentageField').each(function() {
        var thisVal = parseInt($(this).val(), 10);
        if (!isNaN(thisVal))
            total += thisVal;
    });
    
    //change the value of the current entry to limit sum to 100
    if (total > 100) {
        $(this).val(thisVal - (total - 100));
        total = 100;
    }
    
    
    if (total == 100) {
        //enable submit button
        $('#submit_button').removeAttr('disabled');
        
        //disable empty input fields
        $('.percentageField').each(function() {
            var thisVal = parseInt($(this).val(), 10);
            if (isNaN(parseInt($(this).val(), 10)) || thisVal == 0)
                $(this).attr('disabled','disabled'); 
        });
    }
    else {
        //disable submit button
        $('#submitButton').attr('disabled','disabled');
        
        //enable all input fields
        $('.percentageField').removeAttr('disabled');
    }
    
    //update percentage
    $('#percent').html(total);
});
})(jQuery);
  • 1
    Possible duplicate of [Self-invoking function jQuery](https://stackoverflow.com/questions/17319718/self-invoking-function-jquery) – tshimkus Mar 21 '19 at 00:02
  • See also: https://stackoverflow.com/questions/8305288/what-is-the-purpose-of-this-function-function-code-here-jquery – tshimkus Mar 21 '19 at 00:02
  • Have you loaded the jquery library first? – Talha Mar 21 '19 at 03:51
  • @Talha, the libraries are loaded in the following order: jquery.js, jquery-migrate.min.js, my-javascript-code.js, and my-jquery-code.js – Juan Carlos Lau Mar 21 '19 at 06:01
  • @tshimkus, I'm not sure how I'm duplicating the self-invoke. Without adding it to my JQuery file, I get the error "Uncaught TypeError: $ is not a function". If it was being duplicated, I wouldn't give me the error when I remove it from my file, right? – Juan Carlos Lau Mar 21 '19 at 06:06

1 Answers1

0

The JQuery script was running before the DOM was ready. Enclosing the entire code set within $('document').ready(function() did the trick:

(function($){
$('document').ready(function()
   { <<JQuery Code>> });
})(jQuery);