Using AJAX to implement CSS class effects

Currently, I am facing an issue with applying a highlighting effect to list items in a menu using a snippet of code. The menu items are just POST and I have created a second step to the menu where I want to apply the same effect to any element with a class of .highlight. However, my current code is not working as expected:

[deleted old code]

I could create a new id (let's say, '#highlighter2) and duplicate the code. But I am wondering if there is a more efficient way to apply the effect to a class instead of ID?

UPDATE (here is my updated code):

The script above DOES work on the first ul. The issue arises with the second ul, which appears via jquery (possibly due to being initially set to hidden). Here is the relevant HTML structure (it might be a bit complex, but note the hidden second div. This could be causing the problem. While the first list works perfectly fine with all the highlights, the second list doesn't respond.)?

//When the DOM is ready:

<script type="text/javascript">
$(document).ready(function() {

$('#foo li, #foo2 li').click(function() {
    // perform ajax actions
    $(this).siblings('li').removeClass('highlight');
    $(this).addClass('highlight');
});

//On click of a link in div:
$('#selectCompany a').click(function() {
    //Fade in second box:

    //Fetch id from clicked link:
    var id = $(this).attr('id');


    $.ajax({
        type: 'POST',
        url: 'getFileInfo.php',
        data: {'id': id},
        success: function(msg){
            //all echoed content from PHP file will be in the 'msg' variable:
            $('#selectCompanyUser').html(msg)
            $('#selectCompanyUser').fadeIn(400);
        }
});
    });
});
</script>
<div id="selectCompany" class="panelNormal">
<ul id="foo">
<?
// check if any rows were returned 
if (mysql_num_rows($membersresult) > 0) { 
    // yes 
    // display them one after another 
    while($row  = mysql_fetch_object($membersresult)) { 
        echo "<li>"."<a href=\"#\""." id=\"".$row->company."\">".$row->company."</a>"."</li>";
    }  
} 
else { 
    // no 
    // show status message 
    echo "No rows found!"; 
} 

// free up result set memory 
mysql_free_result($membersresult); 

// close connection 
mysql_close($link); 
 ?>

  </ul>
</div>


<!-- Second Box: initially hidden with CSS "display: none;" -->

<div id="selectCompanyUser" class="panelNormal" style="display: none;">
<div class="splitter"></div>

</div>

Answer №1

If you want to simplify your code block, you can create #highlighter2 and turn your existing code into a function that takes the ID value. Then, you can call this function twice like so:

function setHighlight(id) {
    var context = document.getElementById(id);
    var items = context.getElementsByTagName('li');
    for (var i = 0; i < items.length; i++) {
        items[i].addEventListener('click', function() {
            // perform AJAX operations

            // remove "highlight" class from all list items
            for (var j = 0; j < items.length; j++) {
                var classname = items[j].className;
                items[j].className = classname.replace(/\bhighlight\b/i, '');
            }

            // add "highlight" class to the clicked item
            this.className += ' highlight';
        }, false);
    }
}

setHighlight("highliter1");
setHighlight("highliter2");

With jQuery, you can achieve the same functionality more succinctly with the following code:

$("#highlighter1 li, #highlighter2 li").click(function() {
    // do AJAX stuff
    $(this).siblings('li').removeClass('highlight');
    $(this).addClass('highlight');
});

If any of the elements you want to click on are not present initially when using jQuery, you should consider using the live method instead:

$("#highlighter1 li, #highlighter2 li").live("click", function() {
    // do AJAX stuff
    $(this).siblings('li').removeClass('highlight');
    $(this).addClass('highlight');
});

Answer №2

Modify the replacement in /highlight/ig, it functions properly on http://jsfiddle.net/8RArn/

var container = document.getElementById('highlighter');
var elements = container.getElementsByTagName('li');

for (var index = 0; index < elements.length; index++) {
    elements[index].addEventListener('click', function() {
        // perform AJAX operations

        // eliminate the "highlight" class from all list items
        for (var j = 0; j < elements.length; j++) {
            var className = elements[j].className;
            elements[j].className = className.replace(/highlight/ig, '');
        }

        // apply the "highlight" class to the clicked item
        this.className += ' highlight';
    }, false);
}

Answer №3

Those advising to only use jQuery are misguiding you. While it may offer a quick fix, it can never replace the essential skill of learning Javascript.

Javascript has a powerful feature called closures that can easily solve this issue:

var addTheListeners = function (its) {
    var itemPtr;

    var listener = function () {
        // do AJAX stuff

        // visit only one item
        if (itemPtr) {
            var classname = itemPtr.className;
            itemPtr.className = classname.replace(/\bhighlight\b/i, '');
        }

        // set the "highlight" class on the clicked item
        this.className += ' highlight';
        itemPtr = this;
    }

    for (var i = 0; i < its.length; i++) {
        its[i].addEventListener ('click', listener, false);
    }
}

and then:

var context = document.getElementById ('highlighter');
var items = context.getElementsByTagName ('li');
addTheListeners (items);

You can call add the listeners for distinct sets of doc elements multiple times.

addTheListeners works by using a closure to store the list's currently selected item, allowing the listener functions below it to access this variable even after addTheListeners has finished executing.

This code is more efficient than yours due to two reasons:

  1. Avoids iterating through all items just to remove a class from one of them
  2. Avoids defining functions inside a for loop, preventing potential problems with closures

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using maxCDN to deliver static files within a Node application

Our current project is built using keystone and nunjucks, with all paths to static files following the format /stc/img/someimage.jpg. I am looking for a way to serve these files through middleware in our node server from maxCDN. Is there a solution that ...

The issue arises when applying Tailwind styling to template variables that have widget attributes in Django

Currently, I am attempting to implement daisyUI styling in my django web application project, however, I am facing some confusion regarding the styling. The specific issue arises when I try to apply daisyUI styling to a dynamically generated input text fie ...

Selectors within 'not' in document.querySelectorAll are failing to function as expected

I've been attempting to find a way to replace the jQuery .not() function with native JavaScript, but so far my attempts using document.querySelectorAll have not been successful. Here is what I am trying to achieve - converting this jQuery selector in ...

In Angular 4 applications, all vendor CSS files are converted into style tags at the beginning of the HTML document

In my Angular 4 project, I have integrated Bootstrap, Fontawesome, and some custom CSS. However, all these styles are rendering as separate tags at the top of my index.html file. I would like them to be combined into a single bundled CSS file for better ...

Link a YAML file with interfaces in JavaScript

I'm currently learning JavaScript and need to convert a YAML file to an Interface in JavaScript. Here is an example of the YAML file: - provider_name: SEA-AD consortiumn_name: SEA-AD defaults: thumbnail Donors: - id: "https://portal.brain ...

Executing AJAX requests to trigger a function in a separate MVC controller using Jquery

Below is the structure of my folders. Both of these folders are located within the Area folder. https://i.sstatic.net/KLGzl.png I'm currently attempting to invoke a function from the EmailController inside ITRequests/Scripts/Edit.js, but it's u ...

Adjusting canvas size to match content dimensions

I posed a similar inquiry and it was categorized as a duplicate even though the suggested duplicate did not provide an answer to my question. Edit: The purported duplicate was [stackoverflow.com/questions/17211920/make-canvas-height-auto][1] I am utilizi ...

Empower your presentations with slick cloning technology

I am facing an issue with my slider that I cannot seem to resolve. Currently, I am using slick to display 3 slides, but only the center one shows all the content. To achieve a continuous infinite slider effect where all slides appear in the center, I need ...

When utilizing scoped slots in BootstrapVue, you may encounter an error stating "Property or method 'data' is not defined."

Greetings! I am currently in the process of learning how to utilize BootstrapVue, and I decided to reference an example from the official BootstrapVue documentation. <template> <div> <b-table :fields="fields" :items="items" foot-clone ...

Update content without reloading the page

I've implemented a function to delete an image in my action.js file: export const removeImage = (id, image_id) => async () => { try { const response = await axios.delete( `localhost:3000//api/v1/posts/${id}/delete/${image_id}`, ...

Analyzing Compatibility and Ensuring Security

I recently started using Parse and have been exploring the documentation and answered questions. However, I still have a couple of inquiries on my mind. Firstly, I discovered that the Javascript SDK does not function on IE9 and IE8 without an SSL certific ...

What is the most efficient way to display a dynamic alphabetical order list?

sample code: <table width="100%" cellspacing="0" cellpadding="0" border="0" style="line-height: 1.7;"> <tbody> <?php $this->db->select('*'); $this->db->from('cm_options'); ...

Display data in Bootstrap table using JQuery and JSON

Can anyone help me figure out how to populate my bootstrap table (in Database.Master) with data (in DatabaseUI.aspx.cs)? I need to dynamically add rows to the table using JQuery. Do I need to convert my string to JSON first? I believe I may have to add an ...

convert a list of options into a dropdown selection menu

Is there a way to turn a regular menu into a dropdown menu for small devices without modifying the HTML code? I have a responsive design, but I'm not sure how to add that 'hamburger menu' style. Note: I am unable to make changes to the HTML ...

Designing a patterned rectangle filled with stylish text

I am relatively new to the world of HTML and CSS, and I am encountering a specific challenge with CSS. My goal is to design a section that looks like this: ---Image--- --Text-- ---Image--- --Text-- ---Image--- --Text-- ---Image--- --Text-- The ma ...

Error message: Icons failing to display in conjunction with template output | 404 error code

I'm trying to display icons based on a search, but I keep getting a 404 error for http://localhost:3000/static when I input a value. My current folder structure looks like this: Root directory > Public > Icons and Root directory > index.js. ...

Is it possible to generate a 3D building structure using an existing image with Jquery and Css?

Have you checked out this website made in flash? Do you think we could achieve the same using jquery and css? Visit here If you click on any building labeled "Release" You will see a hover animation effect on one of the buildings. I would like to replica ...

Detecting collisions between a ThreeJS camera and a 3D object model using raycasting

I'm trying to navigate a camera through a scene where I've loaded an object as a mesh, and I'm attempting to detect collisions between the camera and the walls of the object. I've been inspired by this threejs example: , and I've ...

Storing data locally and replacing the current URL with window.location.href

My course mate and I are working on writing a code that saves an order to local storage and redirects to an order page when the order button is clicked. However, we are facing issues where clicking on the order button doesn't register in the applicat ...

How can I create an HTML form input slider/range that accepts non-numeric values?

<input type="range" min="2" max="52" value="4" step="1"/> Is it possible to have an input range with non-numeric intervals, such as "Yes," "maybe," and "no"? Appreciate any guidance on this. Thank you. ...