How to convert jquery ajax if else statement for switch statement

I am writing a jquery ajax script to load pages dynamically using ajax without reloading the page. below is my navigation menu which has 5 links.

 <nav>
 <ul id='menu' class="menu-items">
 <li><a href="#Browse_Page1" class="albums active" id="page1-link"><i class="arcd-archive"></i></br>Browse</a></li>
 <li><a href="#Top_albums_Page1" class="pages" id="page2-link"><i class="arcd-music97"></i></br>Top albums</a></li>
 <li><a href="#Top_artists_Page1" class="albums" id="page3-link"><i class="arcd-microphone52"></i></br>Top artists</a></li>
 <li><a href="#Top_lists_Page1" class="pages" id="page4-link"><i class="arcd-numbered8"></i></br>Top lists</a></li>
 <li><a href="#Charts_Page1" class="pages" id="page4-link"><i class="arcd-rising9"></i></br>Charts</a></li>
 </ul>
 </nav>

      

and this is jquery ajax that loads the first two pages of the navigation menu "# Browse_Page1" "# Top_albums_Page1" respectively.

 <script>
 $(function() {
 $('header nav a').on('click', function() {
 var linkClicked = $(this).attr('href');
 if(linkClicked.indexOf('Browse_Page') == true)
 {
     var $Browse_PageRoot = linkClicked.replace('#Browse_Page', '');
     if (!$(this).hasClass("active")) {
 $("header nav a").removeClass("active");
 $(this).addClass("active");}
 $('#loading').css('visibility','visible');
     $.ajax({
        type: "POST",
        url: "load.php",
        data: 'Browse_Page='+$Browse_PageRoot,

        dataType: "html",
        success: function(msg){

            if(parseInt(msg)!=0)
            {
                $('#main-content').html(msg);
                $('#loading').css('visibility','hidden');
                $('#main-content section').hide().fadeIn();
            }
        }

      });
     }
    else
    {
   var $Top_albums_PageRoot = linkClicked.replace('#Top_albums_Page',  ''); 
     if (!$(this).hasClass("active")) {
    $("header nav a").removeClass("active");
    $(this).addClass("active");} 
    $('#loading').css('visibility','visible');      
     $.ajax({
            type: "POST",
            url: "load2.php",
            data: 'Top_albums_Page='+$Top_albums_PageRoot,

            dataType: "html",
            success: function(msg){

                if(parseInt(msg)!=0)
                {
                    $('#main-content').html(msg);
                    $('#loading').css('visibility','hidden');
                    $('#main-content section').hide().fadeIn();
                }
            }            
          });
       }

     });

   });
  </script>

      

finally, these are the two php files used above by the jQuery ajax function "load.php" and "load2.php"

  <!--load.php-->
  <?php
  if(!$_POST['Browse_Page']) ;
  $page = (int)$_POST['Browse_Page'];
  if(file_exists('Browse/Browse_Page'.$page.'.html'))
  echo file_get_contents('Browse/Browse_Page'.$page.'.html');
  else echo 'There is no such page!';
  ?>

  <!--load2.php-->
  <?php
  if(!$_POST['Top_albums_Page']) die("0");
  $page = (int)$_POST['Top_albums_Page'];
  if(file_exists('Top-albums/Top_albums_Page'.$page.'.html'))
  echo file_get_contents('Top-albums/Top_albums_Page'.$page.'.html');
  else echo 'There is no such page!';
  ?>

      

and my site folder structure as follows.

  • Overview
  • Top Albums
  • Top performers
  • Top Lists
  • Diagrams

so my problem is, as I said above, the jquery ajax function is loading two different pages from two different directories and it works fine, but I have 5 page links in the nav menu and all the pages are in different catalogs, 5 different catalogs! but this function only supports two directories. I tried this to add more if other statements completely filled my wish, but it didn't work. since i am new to jquery, maybe i am doing it wrong! or is there a way to convert it to a switch statement? any help would be greatly appreciated. thank

+3


source to share


3 answers


This is really awful, you should aim to send data that can be easily read and understood on the server without having to repeat code for each dataset.

In other words, rewrite javascript to something like this

$(function () {
    $('header nav a').on('click', function () {
        var linkClicked = $(this).attr('href');
        var data = {
            page      : linkClicked.replace(/\D/g, ''),
            directory : linkClicked.replace(/(_Page(.*)|#)/g,'')
        }

        $("header nav a").removeClass("active");
        $(this).addClass("active");
        $('#loading').css('visibility', 'visible');

        $.post('load.php', data, function(msg) {
            $('#main-content').html(msg);
            $('#loading').css('visibility', 'hidden');
            $('#main-content section').hide().fadeIn();
        }, 'html');
    });
});

      

You are now sending data that looks something like this:



{
    page      : "1",
    directory : "Browse"
}

      

And on the server, you would make a jump to get the content in a single PHP file

<?php

    $page = filter_var( $_POST['page'], FILTER_VALIDATE_INT);
    $dir  = filter_var( $_POST['directory'], FILTER_SANITIZE_STRING);

    if ( $page !== false && $dir !== false ) {

        $link = $dir . '/' . $dir . '_Page' . $page . '.html';

        if ( file_exists( $link ) ) {
            echo file_get_contents( $link );
        } else {
            echo 'There is no such page!';
        }
    }
?>

      

+2


source


So, like that, I made some changes with explanations in the code comments.

Add an attribute data

for the page and another for the catalog, eg. 'data-page' and 'data-dir' for each item a

like

<nav>
<ul id='menu' class="menu-items">
<li><a href="#Browse_Page1" data-page="1" data-dir="Browse" class="albums active" id="page1-link"><i class="arcd-archive"></i></br>Browse</a></li>
<li><a href="#Top_albums_Page1" data-page="2" data-dir="Top-albums" class="pages" id="page2-link"><i class="arcd-music97"></i></br>Top albums</a></li>
<li><a href="#Top_artists_Page1" data-page="3" data-dir="Top-artists" class="albums" id="page3-link"><i class="arcd-microphone52"></i></br>Top artists</a></li>
<li><a href="#Top_lists_Page1" data-page="4" data-dir="Top-lists" class="pages" id="page4-link"><i class="arcd-numbered8"></i></br>Top lists</a></li>
<li><a href="#Charts_Page1" data-page="5" data-dir="Charts" class="pages" id="page4-link"><i class="arcd-rising9"></i></br>Charts</a></li>
</ul>
</nav>

      

Modify the function onclick

so that it picks up the page from the attribute data

and ajax

only sends the request to one php

script. I've also moved the "make active" logic into a function.



<script>
$(function() {
    $('nav ul#menu a').on('click', function(event) {
        event.preventDefault();
        // var linkClicked = $(this).data('page'); not using this anymore
        var pagevar = $(this).data('page');
        var dirvar = $(this).data('dir');
        // make the clicked link active, the rest of them inactive, show the loading element
        makeActive($(this));

        $.ajax({
            type: "POST",
            url: "load.php",
            data: {page:pagevar,dir:dirvar},
            success: function(msg){
                if(parseInt(msg)!=0) {
                    $('#main-content').html(msg);
                    $('#loading').css('visibility','hidden');
                    $('#main-content section').hide().fadeIn();
                }
            }
        });
    });

function makeActive(link){
    var ul = $(link).parent().parent();
    $('a',ul).removeClass("active");
    $(link).addClass("active");
    $('#loading').css('visibility','visible');
}

});
</script>

      

Finally, make your php

script handle any page request and I would like to stress the importance of defining a whitelist of valid values, otherwise you open yourself a large local file including vulnerabilities.

load.php   

// define your acceptable values for pages to avoid pains
$pages = array(1,2,3,4,5);
$directories = array("Browse","Top-albums","Top-artists","Top-lists","Charts");

if ((isset($_POST['page']) and in_array($_POST['page'],$pages)) and (isset($_POST['dir']) and in_array($_POST['dir'],$directories))  ){
    if(file_exists($_POST['dir'] . '/Browse_Page'.$_POST['page'].'.html'))
        echo file_get_contents('Browse/Browse_Page'.$_POST['page'].'.html');
}
else echo 'There is no such page!';

      

+1


source


After looking at your PHP code, it looks like it does nothing but read content from static HTML files. jQuery has a useful "load" function if you just want to load HTML content.

Alternatively, you can use HTML5 data attributes to store the paths to the HTML content files that you want to insert into your page. I see that one of the answers to your question uses this approach too. However, I recommend a simpler approach to the problem by simply including the entire relative path to the HTML content. This way, you have more flexibility as to how your content file structure is configured and maintained.

I am assuming that you have no special security requirements. There is no mention in your question, and your code does not imply such a need.

Here's an example:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <script type="text/javascript" src="//code.jquery.com/jquery-1.11.3.min.js"></script>
    <script type="text/javascript">

    (function($) {

      $(function() {
        $("header nav a").click(function() {
          var $this = $(this),
              loadFrom = $this.data("navigate-to"),
              fadeSpeed = 1000;

          $("header nav a").removeClass("active");
          $this.addClass("active");

          $("#loading").fadeIn(fadeSpeed, function() {
            $("#main-content").load(loadFrom, function(res, status, xhr) {
                if(status=="error") {
                  $("#main-content").html("Content couldn't be loaded.");
                }
            });
            $(this).fadeOut(fadeSpeed);
          });

        });
      });

    })(jQuery);

    </script>

  </head>
  <body>
    <header>
      <nav>
        <li><a href="#browse-page-1" data-navigate-to="/browse/page1.html" class="albums active">Browse</a></li>
        <li><a href="#top-albums-page-1" data-navigate-to="/top_albums/page1.html"  class="albums">Top Albums</a></li>
        <li><a href="#top-artists-page-1" data-navigate-to="/top_artists/page1.html" class="albums">Top Artists</a></li>
        <li><a href="#charts-page-1" data-navigate-to="/charts/page1.html" class="albums">Charts</a></li>
      </nav>
    </header>
    <div id="loading" style="display:none;">
      <p>
        Loading...
      </p>
    </div>
    <div id="main-content">

    </div>

  </body>
</html>

      

+1


source







All Articles