www.webdeveloper.com
Results 1 to 4 of 4

Thread: Javascript 2D arrays.

  1. #1
    Join Date
    Dec 2011
    Posts
    2

    Question Javascript 2D arrays.

    I have this very weird problem.
    I have this (sample of) javascript code in my head tag:
    Code:
    function bodyload() {
    var table = new Array();
    alert("works"); // TEMP
    }
    
    function setValues(linkID, type, datefrom) {
    	table[linkID] = new Array();
            //some temporarily commented code
    	alert("WORKS!"); // TEMP
    }
    and this in my body tag:
    HTML Code:
    <a id='bodybox' href="javascript:bodyload();" > BODYLOAD SCRIPTS </a>
    <a id='A_BOX' href="javascript:setValues(1,'m',744);"	> SET </a>
    The first link alerts "works".
    The second link ONLY works, if "table[linkID] = new Array();" is commented!

    What is the error?? I've of course tried with "[]" instead of "new Array()" and setting arguments for both....

    Can you discover the mistake??

  2. #2
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,774
    The bodyLoad function executes every time the link is clicked and resets the variable. Secondly, the variable is local in scope, so it ceases to exist outside of the function. Instead, you want to maintain state. I recommend writing a JavaScript "class" to encapsulate this functionality.

    Code:
    <!DOCTYPE HTML>
    <html>
      <head>
        <script type="text/javascript">
          function MyWidget(table) {
            var that = this; // "this" is a goofy variable, so we stash it as "that" so we can use it inside the onclick handler
            this.items = [];
            this.table = (typeof table === "string") ? document.getElementById(table) : table;
    
            // Put one click handler on the table, and use the data-action HTML
            // attribute of the element that was clicked to inspect what action
            // should be performed. This is called "Event Delegation"
            this.table.onclick = function(event) {
              event = event || window.event;
              var target = event.srcElement || event.target; // The element that got clicked
    
              // target.dataset is something the browser gives us for free (HTML5 custom attributes).
              // Most browsers support this. Old versions of Internet Explorer might not.
              if (target.dataset.action === "addItem") {
                // the data-action HTML attribute is "addItem", so lets add the item
                that.addItem(Number(target.dataset.id), target.dataset.title);
              }
              else if (target.dataset.action === "removeItem") {
                that.removeItem(Number(target.dataset.id));
              }
              else if (target.dataset.action === "getItem") {
                var item = that.getItem(Number(target.dataset.id));
    
                if (item) {
                  alert("Item: " + item.title + " <id: " + item.id + ">");
                }
              }
    
              return false; // if a link was clicked, prevent the page from unloading and moving to the next page
            };
          }
          MyWidget.prototype = {
            items: null,
            table: null,
            
            addItem: function(id, title) {
              this.items.push({id: id, title: title});
            },
    
            getItem: function(id) {
              for (var i = 0, length = this.items.length; i < length; i++) {
                if (this.items[i].id === id) {
                  return this.items[i];
                }
              }
    
              return null;
            },
    
            removeItem: function(id) {
              for (var i = 0, length = this.items.length; i < length; i++) {
                if (this.items[i].id === id) {
                  this.items.splice(i, 1);
                  return true;
                }
              }
    
              return false;
            }
          }
        </script>
      </head>
      <body>
        <table border="1" cellpadding="3" id="my_table">
          <tbody>
            <tr>
              <td>
                <a href="#" data-action="addItem" data-id="123" data-title="Cherry Ice Cream">+</a> /
                <a href="#" data-action="removeItem" data-id="123">-</a> /
                <a href="#" data-action="getItem" data-id="123">Show</a>
              </td>
              <td>Cherry Ice Cream</td>
              <td>3.95</td>
            </tr>
          </tbody>
        </table>
        <script type="text/javascript">
          var widget = new MyWidget("my_table");
        </script>
      </body>
    </html>
    Last edited by toicontien; 12-11-2011 at 07:37 PM.

  3. #3
    Join Date
    Dec 2011
    Posts
    2
    I am relatively new to javascript (Not programming, just JS). So I don't quite understand what you did there. I do know what a class is, I've worked with it in Java...
    Just 5 big questions will solve this for me:
    1: What does "? :" mean??
    (referring to line 8: "this.table = (typeof table === "string") ? document.getElementById(table) : table;")
    2: The "event" var in "function(event)", is that the table being clicked?
    (line 13: this.table.onclick = function(event))
    3: In line 37 ("MyWidget.prototype = {") What IS MyWidget.prototype??
    4: What is the "data-XXX" attributes in the <a> tag?? Never heard of such before.
    5: How do the program KNOW that MyWidget is a class and not a <i>function</i> as told?
    (referring to line 5: " function MyWidget(table) {" and line 83: "var widget = new MyWidget("my_table");")

    Also, when initializing var widget to MyWidget("my_table"), the MyWidget function does not return any value for the var widget??

    I sincerely hope that you'll take time to answer my questions. It'd help me a lot.
    Thanks in advance - Jackount.

    EDIT: btw, I do know, that the var widget is an object of the MyWidget class.
    Last edited by Jackount; 12-12-2011 at 10:17 AM.

  4. #4
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,774
    Quote Originally Posted by Jackount View Post
    1: What does "? :" mean??
    (referring to line 8: "this.table = (typeof table === "string") ? document.getElementById(table) : table;")
    That is the Ternary Operator:
    Code:
    var foo = (condition) ? value_when_true : value_when_false;
    If you've worked with Java, I believe Java also has a Ternary Operator. It's basically shorthand for an if-else statement.

    Quote Originally Posted by Jackount View Post
    2: The "event" var in "function(event)", is that the table being clicked?
    (line 13: this.table.onclick = function(event))
    The "event" variable is generated by the browser. When you click on something, the browser creates a click event object, which gets passed to any event handlers. There are differences with how Internet Explorer and the rest of the browsers handle events, which is why JavaScript libraries like jQuery are so popular, because they resolve those browser differences.

    Quote Originally Posted by Jackount View Post
    3: In line 37 ("MyWidget.prototype = {") What IS MyWidget.prototype??
    A "class" in JavaScript is really just a definition of a "prototypical" object of a certain type. If classes are to objects like blueprints are to a building, then prototypes are to objects like a car on display at car dealership is to the cars available for purchase. The Mozilla Developer Network wrote a fantastic article on Prototype vs Class Based Languages. Coming from Java, this will shed a lot of light on JavaScript.


    Quote Originally Posted by Jackount View Post
    4: What is the "data-XXX" attributes in the <a> tag?? Never heard of such before.
    This is something that the W3C is developing for HTML5.

    Essentially you can embed data in HTML elements using attributes that begin with "data-". This data will exist as string data on the DOM node in a property called "dataset". The data-* attributes map to keys in the dataset property where:

    (assuming "node" is a reference to an HTML tag)

    data-foo is available as node.dataset.foo

    data-foo-bar is available as node.dataset.fooBar

    If a browser doesn't support this feature, you can always use the getAttribute method of a DOM node:

    node.getAttribute("data-foo")
    node.getAttribute("data-foo-bar")

    Using data-* attributes can be a great way to transfer data from a server side application and make it available to JavaScript.

    Code:
    <button type="button" data-order-id="<%= order.getId() %>">Remove from cart</button>
    Let's say order.getId() returns 12345. After the JSP renders, and the HTML is sent to the browser, the BUTTON tag looks like:

    Code:
    <button type="button" data-order-id="12345">Remove from cart</button>
    You can grab a reference to that tag in JavaScript and use the dataset property or getAttribute method to get the shopping cart order order Id, which you can then pass back to your Java app in an Ajax request to remove that order from your shopping cart. Custom data attributes can be used as a bridge between server side data and JavaScript, among many other uses.

    In the example I gave, the data-action attribute is used by JavaScript to perform more than one action with a single click handler. This is called JavaScript Event Delegation.

    Quote Originally Posted by Jackount View Post
    5: How do the program KNOW that MyWidget is a class and not a <i>function</i> as told?
    (referring to line 5: " function MyWidget(table) {" and line 83: "var widget = new MyWidget("my_table");")
    The browser's JavaScript interpreter doesn't know until it goes to run a piece of code. It's less about telling the browser how it should use a piece of code, and more about how you use it. This relates to your next question:

    Quote Originally Posted by Jackount View Post
    Also, when initializing var widget to MyWidget("my_table"), the MyWidget function does not return any value for the var widget??
    In this case, this code is incorrect:
    Code:
    var widget = MyWidget("my_table");
    In order to the MyWidget function to act like a class, you need to use it in conjunction with the "new" operator:

    Code:
    var widget = new MyWidget("my_table");
    When you use the "new" operator, you aren't instantiating a class like you would in Java. Instead, the browser clones the MyWidget.prototype object and returns that as the value! The cornerstone of understanding object oriented programming in JavaScript is to know that new objects are created by cloning other objects. More specifically, new objects are created by cloning the prototype property of function objects (yes, functions are objects in JavaScript). The MyWidget function is called a Constructor Function. The "this" variable inside MyWidget points to the newly cloned MyWidget.prototype object.

    Read these articles for more information, probably in the order below:

    JavaScript: A Survey of the Language

    JavaScript: The World's Most Misunderstood Programming Language

    Prototypal Inheritance

    Private Members in JavaScripts

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles