0

I am reading an XML file using JavaScript, and this part works as I am getting the data. Here is the XML file:

<bookstore>   
    <book category="romance">
        <title lang="en">Everyday Italian</title>
        <author>Giada</author>
        <year>2005</year>
        <price>30,00</price>
    </book>
    <book category="cooking">
        <title lang="en">Cook Book</title>
        <author>Manado</author>
        <year>2012</year>
        <price>44,00</price>
    </book>
    <book category="drama">
        <title lang="en">Intrigue</title>
        <author>L'amion</author>
        <year>2002</year>
        <price>29,99</price>
    </book>    
</bookstore>

Now I use JavaScript to display that data in a table. Also, I added two <input> buttons that each have an onclick attribute to call a specific function. One button calls the change() and the other calls remove().

Here is the code for the HTML page and JavaScript:

<html>

<head>
    <title>Index</title>
    <script type="text/javascript">

    function loadXMLDoc(dname) {
        if(window.XMLHttpRequest) {
            xhttp = new XMLHttpRequest();
        } else { // for IE 5/6
            xhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }

        xhttp.open("GET", dname, false);
        xhttp.send();
        return xhttp.responseXML;
    }

    // function to print all book titles
    function printTitles() {
        var xmlDoc = loadXMLDoc('bookstore.xml');
        var elements = xmlDoc.getElementsByTagName('title')
        document.write('<table border="1"><tr><th>Title</th></tr>');
        for(i = 0; i < elements.length; i++) {
            document.write("<tr>");
            document.write(
                "<td>" + elements[i].childNodes[0].nodeValue + "</td>");
            document.write("</tr>")
        }
        document.write("</table>");
    }

    // function to change the first book title
    function change(text) {
        var xmlDoc = loadXMLDoc('bookstore.xml');
        var elements = xmlDoc.getElementsByTagName('title');
        var title = elements[0].childNodes[0];
        title.nodeValue = text;
        printTitles(elements);
    }

    // function to remove the first book
    function remove(node) {
        var xmlDoc = loadXMLDoc('bookstore.xml');
        var rem = xmlDoc.getElementsByTagName(node)[0];
        xmlDoc.documentElement.removeChild(rem);
        printTitles(elements);
    }

    printTitles();

    </script>
</head>

<body>
    <input type="button" value="change" onclick="change('WORKS')"/>
    <input type="button" value="remove" onclick="remove('book')"/>
</body>

</html>

When I click the change button, both buttons disappear. When I click the remove button, only remove button disappears.

Here are all 3 states of my page (I cannot upload a photo because I don't have the rep):

http://postimg.org/image/5lrwf7rcz/

Now, I already searched for an answer and this question or this question answers didn't help me. I couldn't find a missing closing tag and returning false doesn't change anything.

UPDATE: I ran the debugger on Chrome and when I click the remove button, the remove() function never gets called but when I click the change button, the change() function does get called.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Bug Feature
  • 21
  • 1
  • 7
  • 3
    That's what `document.write` does, it overwrites the `document` ! – adeneo Sep 25 '14 at 17:38
  • so I am suppose to recreate the buttons each time they are pressed if I want things to work this way? – Bug Feature Sep 25 '14 at 17:40
  • 1
    Better not use `document.write` – Claudiu Creanga Sep 25 '14 at 17:40
  • 2
    No, you're supposed to ***not*** use `document.write` !!! – adeneo Sep 25 '14 at 17:41
  • And you're doing ajax, and trying to return the responseText without waiting for the readyState event ? – adeneo Sep 25 '14 at 17:44
  • I am following a tutorial, like I said, i'm still a newbie – Bug Feature Sep 25 '14 at 17:45
  • I found one error, i was missing a semicolon inside the `printTitles()` at `document.write("")` – Bug Feature Sep 25 '14 at 17:47
  • 1
    After reading about [`document.write`](https://developer.mozilla.org/en-US/docs/Web/API/document.write) you should get familiar with DOM manipulation methods [`createElement`](https://developer.mozilla.org/en-US/docs/Web/API/document.createElement), [`createTextNode`](https://developer.mozilla.org/en-US/docs/Web/API/document.createTextNode) and [`appendChild`](https://developer.mozilla.org/en-US/docs/Web/API/Node.appendChild). – Teemu Sep 25 '14 at 17:54
  • Don't call the function "remove". See this thread for more details: http://stackoverflow.com/questions/17178016/javascript-onclick-event-not-working-in-chrome-for-text-within-div-container. Also, you're not defining `elements` in there so the table can't be created. – marneborn Sep 25 '14 at 18:39

1 Answers1

0

I found a solution so I though I might post it here in case somebody needs it.

First of all, I was missing a semicolon inside the printTitles() at document.write("</tr>") but that wasn't the main reason behind the program not working.

After taking @Teemu's advice on functions createElement, createTextNode, appendChild and reviewing other helpful comments, I changed the code a lot. I used the mentioned functions and added the window.onload check to make sure I can edit the body after the page loads.

XML file stays the same and here is my HTML file with JavaScript:

<html>
<head>
    <title>Index</title>
    <script type="text/javascript">

    window.onload = function() {

        // function that loads an XML file through an HTTP request
        function loadXMLDoc(dname) {
            if(window.XMLHttpRequest) {
                xhttp = new XMLHttpRequest();
            } else { // for IE 5/6
                xhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }

            xhttp.open("GET", dname, false);
            xhttp.send();
            return xhttp.responseXML;
        }

        var xmlDoc = loadXMLDoc('bookstore.xml'); // holds the loaded XML file

        // builds a string from xml elements containing the HTML code for the body
        function buildBody(elements) {
            var body = '<table border="1"><tr><th>Title</th></tr>';
            for(i = 0; i < elements.length; i++) {
                body += "<tr>";
                body += 
                    "<td id='" + i +"'>" + elements[i].childNodes[0].nodeValue + "</td>";
                body += "</tr>";
            }
            body += "</table>";
            return body;
        }

        // prints the input buttons
        function printInputs(elements) {
            document.body.innerHTML = buildBody(elements);

            // button change
            var inputChange = document.createElement('input');
            inputChange.setAttribute('type', 'button');
            inputChange.setAttribute('value', 'Change first title');
            inputChange.onclick = function change() {  // on click function for the button
                    document.getElementById(0).innerHTML = 'WORKS';
            }
            document.body.appendChild(inputChange); // add button to the body

            // button remove
            var inputRemove = document.createElement('input');
            inputRemove.setAttribute('type', 'button');
            inputRemove.setAttribute('value', 'Remove first title');
            inputRemove.onclick = function remove() { // on click function for the button
                    document.getElementById(0).innerHTML = '';
            }
            document.body.appendChild(inputRemove); // add button to the body
        }

        function printTitles() {
                var xmlDoc = loadXMLDoc('bookstore.xml');
                var elements = xmlDoc.getElementsByTagName('title');
                printInputs(elements);  
        }

        printTitles();
    }


    </script>
</head>

<body>

</body>

</html>
Bug Feature
  • 21
  • 1
  • 7