mariya
mariya

Reputation: 295

Change page contents with jQuery and AJAX on click

I have a simple web page with the following HTML:

    <!doctype html>
    <html>
        <head>
            <title>Homework 8 - Home</title>
            <meta charset="utf-8">
            <link rel="stylesheet" type="text/css" href="style.css" />
            <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
            <script src="script.js"></script>
        </head>
        <body>
        <nav>
            <ul>
                <li><a href="home.html">Home</a></li>
                <li><a href="about.html">About</a></li>
                <li><a href="help.html">Help</a></li>
            </ul>
        </nav>
        <div id="content">
            <div id="page">
                Suspendisse vel ante ornare, vulputate lacus et, condimentum lorem.
            </div>
            <aside>
                <h3>Helpful Links</h3>
                <ul>
                    <li><a href="http://google.com/">Google</a></li>
                    <li><a href="http://facebook.com/">Facebook</a></li>
                </ul>
            </aside>
        </div>
        </body>
    </html>

and an array of data in the following php file:

    <?php


    function random_lipsum($amount = 1, $what = 'paras', $start = 0) {
        return simplexml_load_file("http://www.lipsum.com/feed/xml?amount=$amount&what=$what&start=$start")->lipsum;
    }



    $data = [
        'home' => ['title' => 'Home page', 
                   'content' =>     random_lipsum(3),
                   'links' => [
                        'http://google.com/' => 'Google',
                        'http://facebook.com/' => 'Facebook',
                    ]
        ],
        'about' => ['title' => 'About page', 
                   'content' =>     random_lipsum(3),
                   'links' => [
                        'http://abv.bg/' => 'ABV.BG',
                        'http://dir.bg/' => 'DIR.BG',
                    ]
        ],
        'help' => ['title' => 'Help page', 
                   'content' =>     random_lipsum(3),
                   'links' => [
                        'http://wikipedia.com/' => 'Wikipedia',
                        'http://stackoverflow.com/' => 'StackOverflow',
                    ]
        ],
    ];

    $page = (isset($_GET['page']) && isset($data[$_GET['page']]))?$_GET['page']:'home';

    echo json_encode($data[$page]);
    ?>

My task is to change the contents of the <div id="content"> the <title> of the page and the links in <aside> with jQuery and AJAX by clicking on the links in the <nav> and without reloading the page. For example when you click on the link About, the contents, title and aside links of the page should get changed to the ones in the data array in the php file with key about. I tried to write some code but nothing happens. Here is it(it is stored in a file called script.js that is referenced in the <head> of the HTML file):

    $(document).ready(function(){   //executed after the page has loaded
        $('nav ul li:nth-child(2) a').on('click',
            $.ajax({    //create an ajax request data.php
                type: "POST",
                url: "data.php",
                data: 'page=about',
                dataType: "html",   //expect html to be returned
                success: function(data){
                    $('#page').html(data.about.content);
                    $('title').html(data.about.title);
                    $('aside ul li:first-child a').html(data.about.links[0]);
                    $('aside ul li:nth-child(2) a').html(data.about.links[1]);
                }
            })
        );
    });

Can you please help me and tell me what I'm doing wrong?

Upvotes: 0

Views: 4366

Answers (2)

Barmar
Barmar

Reputation: 780818

Your PHP returns JSON, not HTML. Use:

dataType: "json"

The only HTML you're returning is in the values of the title and content properties. Also, the PHP associative array in the links element will become a Javascript object, not an array. I suggest you change it to an indexed array:

'links' => [
    [ 'url' => 'http://abv.bg/', 'name' => 'ABV.BG'],
    [ 'url' => 'http://dir.bg/', 'name' => 'DIR.BG']
]

Then the success function would be:

success: function(data) {
    $('#page').html(data.about.content);
    $('title').html(data.about.title);
    $.each(data.about.links(function(i, link) {
        $('aside ul li').eq(i).children('a').attr('href', link.url).html(link.name);
    });
}

And as pointed out in GolezTrol's answer, the handler argument to .on() must be a function:

$('nav ul li:nth-child(2) a').on('click', function(e) {
    e.preventDefault();
    $.ajax(...);
});

Since you're loading your page from localhost, you need to change the jQuery URL to go to the web:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

When you leave out the protocol prefix of a URL, it uses the same protocol as the page that contains it, and for local files that's file:. But you need to use http: or https: to get something from the web.

Upvotes: 3

GolezTrol
GolezTrol

Reputation: 116100

You need to wrap the code that needs to be executed on click inside a function, otherwise the Ajax request is executed immediately when the page is loaded, and the result of that call (which is a jqXHR object) is passed to .on() instead of a propert callback.

  $(document).ready(function(){   //executed after the page has loaded
        $('nav ul li:nth-child(2) a').on('click',
          function() {
            $.ajax({    //create an ajax request data.php
                type: "POST",
                url: "data.php",
                data: 'page=about',
                dataType: "html",   //expect html to be returned
                success: function(data){
                    $('#page').html(data.about.content);
                    $('title').html(data.about.title);
                    $('aside ul li:first-child a').html(data.about.links[0]);
                    $('aside ul li:nth-child(2) a').html(data.about.links[1]);
                }
            })
          }
        );
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: 0

Related Questions