Home > Back-end >  Options to make jQuery Ajax code more efficient / logical
Options to make jQuery Ajax code more efficient / logical

Time:11-16

I have the following HTML to display content pulled from an ajax script (ajax.php):

HTML

<ul class="list-unstyled" id="var_adjectives"><li><a href='#'>Loading...</a></li></ul>
<button id="37" onclick='update_adjectives();'>Refresh</button>

<hr />

<ul class="list-unstyled" id="var_brands"><li><a href='#'>Loading...</a></li></ul>
<button id="37" onclick='update_brands();'>Refresh</button>

<hr />

<ul class="list-unstyled" id="var_clothes"><li><a href='#'>Loading...</a></li></ul>
<button id="37" onclick='update_clothes();'>Refresh</button>

<hr />

When the page first loads, the following JS is used to populate the list items against the relevant <ul> tag (passing in two parameters each time):

Javascript Page Load

$(document).ready(function(){
    $.post('ajax.php',{u:37,n:1} ,function(data){ var this_record = data.output; $('#var_adjectives').html(this_record);},'json');
    $.post('ajax.php',{u:37,n:33},function(data){ var this_record = data.output; $('#var_brands').html(this_record);},'json');
    $.post('ajax.php',{u:37,n:67},function(data){ var this_record = data.output; $('#var_clothes').html(this_record);},'json');
});

The refresh button can be used to refresh the content in the relevant <ul> tag, calling the following relevant JS function, from the onclick event on each of the 3 buttons:

Javascript Refresh Functions

function update_adjectives() {
    $.post('ajax.php'
         , {u:37,n:1}
         , function(data){ var this_record = data.output; $('#var_adjectives').html(this_record); }
         , 'json')
};

function update_brands() { 
    $.post('ajax.php'
         , {u:37,n:33}
         , function(data){ var this_record = data.output; $('#var_brands').html(this_record); }
         , 'json')
};

function update_clothes() {
    $.post('ajax.php'
         , {u:37,n:67}
         , function(data){ var this_record = data.output; $('#var_clothes').html(this_record); }
         , 'json')
};

As you can see, there is a lot of overlap in the basic design of the JS.

I have these questions:

  1. I am stuck working out how I can end up with one single line in the block of JS used to populate content when the page first loads.

  2. I'd like to only have 1 function used to refresh content - because in my example above I have 3 blocks, but in my real page I have about 30 blocks.

While the JS is created by the PHP code when the page loads (rather than me writing it long-hand), it still would be nice to have much cleaner code which avoids having e.g. 30 refresh functions and 30 lines of code to populate each of the different <ul> IDs when first loading the page.

In each case, I can see I would need to pass an ID of relevant <ul> but I am tied up in knots working out if I can achieve what I'm trying to do.

Probably there are many things wrong with using the onclick event too!

Any advice would be much appreciated, thank you.

CodePudding user response:

The most likely blocker is your API endpoint design. According to what you posted, you must access one category at a time and that must be done by sending the {u:N,n:N} combo object as the body of the POST request.

It would simplify things greatly if your endpoint accepted a different object. Something like {category:'name'} would allow greater flexibility.

You could use {category: 'all'} for the initial view of all categories and use {category: 'clothes'} for individual categories for the update/refresh.

Extending that to the click of the refresh buttons. You can use a single event handler and event bubbling to deal with every button click.

First you would add the event handler to containing element for all the <ul> elements.

Given this layout:

<div id='container'>
  <ul><li><span>loading...</span></li></ul>
  <button data-category="adjectives">Refresh</button>
  <ul><li><span>loading...</span></li></ul>
  <button data-category="brands">Refresh</button>
  <ul><li><span>loading...</span></li></ul>
  <button data-category="clothes">Refresh</button>
</div>

You can react to all the button clicks like this:

document.getElementById('container').addEventListener('click', update);

The update() event handler can determine which button was clicked by checking out the data- attribute on the button. Then, make the AJAX request and place the data into the correct <ul> by finding the closest or the prev() sibling <ul> element.

function update() {
  const category = this.dataset.category;
  $.post('ajax.php', {category: category}
    , function(data) {
    $('button').data(category).prev('ul').html(data.output);
  }, 'json')
};
  • Related