Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Struggling with Functions

Hey, I have been trying to practise my JS and decided to do a series of calculations from form input then eventually graph it with charts.js

However I have it working as it should but its a mess and everytime I try to create functions to run on submit It just won't work. Here is what I have, some pointers in the right direction would be great.

    $(document).ready(function(){
        $('#submit').click(function(){
                // Input Variables
                var weight = $('.weight').val();
                var height = $('.height').val();
                var age = $('.age').val();
                var activityLevel = $('#activityLevel option:selected').val();
                var weightLifting = $('.weightLift').val();
                var aerobicTrain = $('.aerobicTrain').val();
                var goal = $('#goal option:selected').val();
                var activityLevelName = $('#activityLevel option:selected').html();



                // Convertions
                var heightCm = height * 100;
                var weightLb = weight * 2.2;

                // Output variables
                var bmi = weight / ( height * height );
                var bmr = weightLb * 11;


                // Daily Expenditure Formula
                var strengthTraining = weightLifting * 5;
                var aerobicTraining = aerobicTrain * 8;
                var calcTraining = strengthTraining + aerobicTraining / 7;
                var rmr = weightLb * 11;
                var dailyExpenditure = rmr * activityLevel;

                var dailyNeeds = dailyExpenditure + calcTraining;
                var loseWeight = dailyNeeds - 1000;
                var gainWeight = dailyNeeds + 1000;

                if($('#goal option:selected').val()  == "Gain") {
                    var dailyNeeds = dailyNeeds + 1000;
                } else if ($('#goal option:selected').val()  == "Lose") {
                    var dailyNeeds = dailyNeeds - 1000;
                } else {
                    var dailyNeeds = dailyNeeds + 0;
                }


                // Protein
                var proteinGrams = weightLb * 1;
                var proteinCal = proteinGrams * 4;
                var proteinPc = proteinCal / dailyNeeds * 100;

                // Fat
                var fatCal = dailyNeeds * 0.3;
                var fatGrams = fatCal / 9;
                var fatPc = fatCal / dailyNeeds * 100;

                // Carbs
                var carb = proteinCal + fatCal;
                var carbCal = dailyNeeds - carb;
                var carbGrams = carbCal / 4;
                var carbPc = carbCal / dailyNeeds * 100;

                $('.result span').html(Math.round(bmi));
                $('.bmr span').append(Math.round(bmr));
                $('.calorieNeeds span').append(Math.round(dailyNeeds));

                $('#weightOut span').html(weight);
                $('#heightOut span').html(height);
                $('#ageOut span').html(age);
                $('#activityLevelOut span').html(activityLevelName);
                $('#weightLiftingOut span').html(weightLifting);
                $('#aerobicTrainOut span').html(aerobicTrain);
                $('#goalOut span').html(goal);

                });

        });

Cheers

3 Answers

In that case, you'll have to move the BMI and other calculating functions in separate functions. And when you do that, you'll need to feed these new functions inputs/parameters.

eg. for the BMI calculation, you current code has var bmi = weight / ( height * height );

When you refactor that out to a separate function, you'll need to do something like this.

// declare the calculateBMI method
function calculateBMI(weight, height) {
   var bmi = weight / ( height * height );
   return bmi;  // this returns the result.
}

and elsewhere in your code where you declared the bmi variable, you'll need to do this:

// pass in the weight variable and the height variable into the calculateBMI method as parameters.
var bmi = calculateBMI(weight, height); 

Hope that makes sense.

That's exactly what I mean and great example. I will be able to work my way through from here.

Thanks for you guidance.

When you are taking input from a form and manipulating the DOM you need to prevent the form from submitting and causing the page to refresh ( unless you are using AJAX ). You want to target the form element and call .submit() rather than a click event on the submit button. You will then want to prevent the form from actually submitting.

e.g

$(function(){
    $('#form').submit(function(event){
        event.preventDefault();
        // rest of code
    });
});

Cheers I will change that over now, how do I go about moving these calculations into functions so its cleaner? I have tried to create functions and then call it at the end of the click and they will output to console but not the page. Is that due to not preventing the default refresh?

Actually adding the above code stops me returning data based on input?

All you have to do is move the code in the function() {} into a separate function declaration, like so:

function submitForm(event) {
               event.preventDefault(); 
                // Input Variables
                var weight = $('.weight').val();
                var height = $('.height').val();
                var age = $('.age').val();
                var activityLevel = $('#activityLevel option:selected').val();
                var weightLifting = $('.weightLift').val();
                var aerobicTrain = $('.aerobicTrain').val();
                var goal = $('#goal option:selected').val();
                var activityLevelName = $('#activityLevel option:selected').html();



                // Convertions
                var heightCm = height * 100;
                var weightLb = weight * 2.2;

                // Output variables
                var bmi = weight / ( height * height );
                var bmr = weightLb * 11;


                // Daily Expenditure Formula
                var strengthTraining = weightLifting * 5;
                var aerobicTraining = aerobicTrain * 8;
                var calcTraining = strengthTraining + aerobicTraining / 7;
                var rmr = weightLb * 11;
                var dailyExpenditure = rmr * activityLevel;

                var dailyNeeds = dailyExpenditure + calcTraining;
                var loseWeight = dailyNeeds - 1000;
                var gainWeight = dailyNeeds + 1000;

                if($('#goal option:selected').val()  == "Gain") {
                    var dailyNeeds = dailyNeeds + 1000;
                } else if ($('#goal option:selected').val()  == "Lose") {
                    var dailyNeeds = dailyNeeds - 1000;
                } else {
                    var dailyNeeds = dailyNeeds + 0;
                }


                // Protein
                var proteinGrams = weightLb * 1;
                var proteinCal = proteinGrams * 4;
                var proteinPc = proteinCal / dailyNeeds * 100;

                // Fat
                var fatCal = dailyNeeds * 0.3;
                var fatGrams = fatCal / 9;
                var fatPc = fatCal / dailyNeeds * 100;

                // Carbs
                var carb = proteinCal + fatCal;
                var carbCal = dailyNeeds - carb;
                var carbGrams = carbCal / 4;
                var carbPc = carbCal / dailyNeeds * 100;

                $('.result span').html(Math.round(bmi));
                $('.bmr span').append(Math.round(bmr));
                $('.calorieNeeds span').append(Math.round(dailyNeeds));

                $('#weightOut span').html(weight);
                $('#heightOut span').html(height);
                $('#ageOut span').html(age);
                $('#activityLevelOut span').html(activityLevelName);
                $('#weightLiftingOut span').html(weightLifting);
                $('#aerobicTrainOut span').html(aerobicTrain);
                $('#goalOut span').html(goal);
}

$(function() {
    $('#form').submit(submitForm(event));
});

But my aim was to have a function for each calculation eg function calcBMI(){}; and so on so it's cleaner looking. Just to be clear I'm not asking for someone to do it for me just to advise. When I moved the bmi stuff into a calcBMI function and set that to output it to HTML it didn't,