4

Doubtful this needs much explaining but I think I need a second set of eyes to check this out because I just cannot fathom why it won't! Try using the "Energy Calculator" and no value will be returned when submitted despite me approaching it in the same way as the "Battery Charge Calculator" which does work.

Link: http://jsfiddle.net/Deva/426Jj/

1
  • If you are using jQuery in other parts of the page couldn't you use jQuery in this part also? Commented May 12, 2011 at 3:03

5 Answers 5

6

To elaborate on @alex's answer, you have selected the onLoad option of jsFiddle, which places your JavaScript code inside of an anonymous function:

window.onload = function() {
    function energyCalc() {
        var mass = document.forms['0'].mass.value;
        var finalMass = mass * 1000;
        var velocity = document.forms['0'].velocity.value;
        var finalVelocity = velocity * 0.3048;
        var energy = (0.5 * (finalMass * (finalVelocity * finalVelocity)));
        if ((mass && velocity) != '') {
            document.getElementById("energy").innerHTML = 'Energy of weapon: ' + energy + ' Joules';
        } else {
            document.getElementById("energy").innerHTML = 'You must enter values in both fields!';
        }
    }
}

Try this on for size: http://jsfiddle.net/mattball/Cbsa8/. All I did was select no wrap (head) and No library.

Keep in mind that it's better coding practice to write unobtrusive JavaScript. In this case you'd bind the event handler with JavaScript, using attachEvent (for IE <9) or addEventListener (for real browsers).


Edit re: OP edits

Open a console and the problem is immediately obvious after trying to use the Energy Calculator:

> Uncaught TypeError: Cannot read property 'value' of undefined (fiddle.jshell.net:100)

which is this line:

var mass = document.forms['0'].mass.value;

You're accessing the wrong form. You need to change all cases of forms['0'] to forms[1] in the energy calculator's code. Note the omitted quotes, by the way - document.forms is an array, not an object!

Also, you're clearly using jQuery, but you're not using it everywhere you could. Why not? There's a lot of room for improvement in your code. It's cleanup time!

HTML

<div id="main">
    <a href="#"><h3>Battery Charge Calculator</h3></a>
    <div class="slide">
        <form id="batteryForm" action="">
            <p>
                Battery Capacity (mah):
            </p>
            <p>
                <input name="capacity"/>
            </p>
            <p>
                Charge Rate (mA):
            </p>
            <p>
                <input name="rate"/>
            </p>
            <p>
                <input type="submit" value="Submit"/>
            </p>
            <br/>
            <p id="time"/>
        </form>
    </div>
    <a href="#"><h3>Energy Calculator</h3></a>
    <div class="slide">
        <form id="energyForm" action="">
            <p>
                Mass of BB (grammes):
            </p>
            <p>
                <input name="mass"/>
            </p>
            <p>
                Power of weapon (FPS):
            </p>
            <p>
                <input name="velocity"/>
            </p>
            <p>
                <input type="submit" value="Submit"/>
            </p>
            <br/>
            <p id="energy"/>
        </form>
    </div>
</div>

JavaScript

$(function() {
    $('#main > a > h3').click(function() {
        $(this).closest('a').next('div.slide').animate({
            height: 'toggle'
        }, 750);
    });

    function batteryCalc() {
        var capacity = this.capacity.value,
            rate = this.rate.value,
            time = capacity / (rate / 1.2),
            chargeTime = (Math.round(10 * time) / 10).toFixed(1),
            message = 'You must enter values in both fields!';

        if (capacity && rate) {
            message = 'Required time on charge: ' + chargeTime + ' hours';
        }

        $('#time').html(message);
        return false;
    }

    function energyCalc() {
        var mass = this.mass.value,
            finalMass = mass * 1000,
            velocity = this.velocity.value,
            finalVelocity = velocity * 0.3048,
            energy = (0.5 * (finalMass * (finalVelocity * finalVelocity))).toFixed(1),
            message = 'You must enter values in both fields!';

        if (mass && velocity) {
            message = 'Energy of weapon: ' + energy + ' Joules';
        }

        $('#energy').html(message);
        return false;
    }


    $('#batteryForm').submit(batteryCalc);
    $('#energyForm').submit(energyCalc);
});

Demo: http://jsfiddle.net/mattball/JSpaU/

Sign up to request clarification or add additional context in comments.

2 Comments

that's great! thanks for taking the time to do that. first time attempting anything jQuery so that would explain the mish mash of code. will try to review it all and understand. thank you.
No problem, you're welcome. In the future, if you have correct (working) code that you think could be otherwise improved, you can post it on codereview.se.
5

See the drop-down list on the left that says "onLoad"? Change it to "no wrap (head)" and it'll work.

4 Comments

this is very true - not that this was really my issue. the problem exists outside of jsFiddle too.
What is the problem, then, exactly? Does it not calculate correctly?
@matt then you should really be more specific when asking questions.
apologies, i just wanted to try and take everything else out of the equation. see: jsfiddle.net/Deva/426Jj for the full code. if modifying something in jsFiddle is the fix this won't help me as i'm trying to run it as its own HTML page. many thanks.
3

It's because of the way jsfiddle works. You need to declare the energyCalc function like so:

window.energyCalc = function() { ... }

Comments

2

energyCalc() is wrapped in a function (load event's function), and is not visible to the global scope.

Example

It works when it is made global.

jsFiddle.

Comments

0

Remove the action = "javascript:energyCalc()"

and add:

jQuery(document).ready(function()
{
    jQuery(document.forms[0]).submit(energyCalc);
});

No jquery

<form method="post" onsubmit="energyCalc();" >

EDIT

Also need return values (true or false)

Check out: http://jsfiddle.net/SabAH/7/ http://jsfiddle.net/SabAH/11/

UPDATE an explanation:

The action attribute tells the browser where to post to. The function needs to be run onsubmit.

UPDATE2 After looking at the new jsfiddle

http://jsfiddle.net/426Jj/2/

There were a few errors. Firstly your action="javascript:..." needs to be onsubmit="javascript: return ..." and remove the onclick of the submit buttons the energy method needed to reference forms[1] not forms[0] becasue it was the second form. Thats mainly it.

look at: http://jsfiddle.net/426Jj/2/

3 Comments

What does jQuery have to do with this?
thats a good point. Sort of a habit.! But it can easily be achieved without.
@wesley No jQuery now. Is that Better?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.