Brad
Brad

Reputation: 65

Javascript Variable Printing

I have a background in C++ but have some questions with what I'm trying to do in Javascript. I needed to make a pseudo class since Javascript doesn't have them. I basically want to print something different based on what selection is chosen. I only defined two "fruits" in this example but what I would be doing would use a lot more. Any help would be greatly appreciated. I know there are some flaws in this like the select does not link in any way to the fruit function.

<!DOCTYPE html>
<html>
<script>
   function select_fruit(name)
   {
      var fruit_name = name;
   }

   function fruit(name, color, amt)
   {
      this.name = name;
      this.color = color;
      this.amt = amt;
   }

   apple = new fruit("apple", "red", 5);
   orange = new fruit("orange", "orange", 1);

   document.getElementById("name").innerHTML = name;
   document.getElementById("color").innerHTML = color;
   document.getElementById("amt").innerHTML = amt;
</script>

<body>
   <select name="pick_these" onchange="fruit(this.value)">
      <option value="apple">Apple</option>
      <option value="orange">Orange</option>
   </select><br />

   <p>I want *amt *color *fruit</p><!--This should say I want 5 red apple, if it's selected on the dropdown-->
</body>
</html>

Upvotes: 1

Views: 155

Answers (2)

LetterEh
LetterEh

Reputation: 26696

I'm going to go ahead and agree with cdhowie's comment about 125%.
Attempting to use JS like Java/C#/C++/ActionScript/etc is going to work.
You'll be able to eke something out, and it's going to do something functional, once you hack your way around it for a while.

But that's really, really not the way the language should be used.
If you've got a technical understanding of other languages, Crockford's "JavaScript: the Good Parts" is a great way to hit the ground running.
If you have limited/no understanding of how languages are parsed, or you're really feeling lost inside of JavaScript, compared to your comfort-zone, then Crockford's book is like a bootcamp for people who want a solid starting-point for grasping the language, at a low-level (using the language as-is, with no libraries and minimal use of design-patterns).

I would say that Stoyan Stefanov's "JavaScript Patterns" is a fantastic next-step, as it does exactly what it says on the label, and it does a great job of it.

Anyway, you've got quite a few problems, here.

The first is that your script is asking for elements and their values before they even exist.
JS/the DOM are not pre-compiled. For the most part, until you get into client/server communication, or you're defining functions and using them elsewhere, what you see is what you get, in the order you put them down.

In this case, you're asking for an element where el.id === "name".
If you look above this line in your code, you'll notice that no element above it has that id.

The soluution here would be to make sure that your script is below the intended target (or to wrap everything in functions, and call the functions below the <select> so you know that it exists).

This brings us to the second issue: your elements have no IDs.

If you have no IDs on them, grabbing those elements by ID isn't going to work.

<select id="my-select-box"></select>

<script>
    var select = document.getElementById("my-select-box");
</script>

If you put them the other way around, it won't work.
If you're missing an .id attribute, it won't work.

As for "classes", don't think of it as defining hard-classes and then creating instances.
Sometimes, that's useful/necessary.
Other times, all you need to care about is instances.

What I mean is: in C++, think of all of the times you might have been tempted to create a full-blown class, when really a simple struct might have done.
And what about a struct where all you really need is a single instance?

Now imagine giving that struct methods, without needing to do any other work (headers, etc).

<select id="fruit-list">
    <option value="apples">apple</option>
    <option value="oranges">orange</option>
    <option value="bananas">banana</options>
</select>
<p id="fruit-output"></p>

var Fruit = function (name, colour, starting_amount) {

    var public_interface = {
        name   : name,
        colour : colour,
        amount : starting_amount
    };

    return public_interface;
};


var apples  = Fruit("apple",   "red",   4),
    oranges = Fruit("orange", "orange", 2),
    bananas = Fruit("banana", "yellow", 1);



var fruit_basket = {

    selected  : "",
    output_el : null,
    apples    : apples,
    oranges   : oranges,
    bananas   : bananas,

    add : function (fruit, num) {
        this[fruit].amount += num;
    },

    remove : function (fruit, num) {
        this[fruit].amount -= num;
    },

    print : function () {
        var fruit   = fruit_basket.selected,
            el      = fruit_basket.output_el,
            message = "I want " + fruit.amount
                    + " " + fruit.colour
                    + " " + fruit.name;

        if (fruit.amount !== 1) { message += "s" }

        if (el.hasOwnProperty("textContent")) {
            el.textContent = message;
        } else {
            el.innerHTML = message;
        }
    },

    select : function (el) {
        var index = el.selectedIndex,
            fruit = el.options[index].value;

        fruit_basket.selected = fruit_basket[fruit];
    },

    set_output : function (el) {
        fruit_basket.output_el = el;
    }

};



var select_box = document.getElementById("fruit-list"),
    output_el  = document.getElementById("fruit-output");


fruit_basket.set_output(output_el);
select_box.addEventListener("change", function () {
    fruit_basket.select(this);
    fruit_basket.print();
});

This isn't the answer, but consider how much more straightforward this is than a C++ or Java solution, where you'd have to build classes for all of the above.

If this were more advanced, perhaps you'd consider separating your data from your view and your control in more obviously-separated ways.

But again, that doesn't mean that you need huge inheritance hierarchies, or lots of classes which do relatively little.
It's a very straightforward language, which supports construction/initialization, but you can also make a "singleton" just by inventing an object on the spot.

I'd suggest putting that research into it, if you intend to use the language seriously.

Upvotes: 0

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324620

First of all, you are missing the <head> tag. That aside, you need to move your document.getElementById..... lines to the select_fruit() function, and change the onchange event to call select_fruit instead. Here's how I'd do what you're attempting:

HTML:

<select id="fruitlist">
    <option value="apple">Apple</option>
    <option value="orange">Orange</option>
</select>
<p id="result"></p>

JS:

window.onload = function() { // or just `(function() {` if script is after above HTML
    var fruits = {
        "apple":{
            "color":"red",
            "amt":5
        },
        "orange":{
            "color":"orange",
            "amt":1
        }
    }, result = document.getElementById('result');
    document.getElementById('fruitlist').onchange = function() {
        var selection = this.options[this.selectedIndex].value;
        result.innerHTML = "I want "+fruits[selection].amt+" "
            +fruits[selection].color+" "+selection;
    };
}; // or `})();` if you used `(function() {` at the start

Upvotes: 2

Related Questions