javascriptphpclassforeachmenu

how to add a class to one button inside a menu based on php foreach?


i have a video site like youtube . admin can add many categories with no limit . these categories display on top of the site as a horizontal menu . this is the code that display the categories :

<?php 
    foreach($pt->categories as $key => $category) {
        if (1) { 
?>
            <div class="swiper-slide">
            <a class="" 
                href="{{LINK videos/category/<?php echo $key?>}}" 
                data-load="?link1=videos&page=category&id=<?php echo $key?>">
<?php echo $category?></a>
            </div>
<?php 
        } 
    }
?>

by this code if i add "active" to class="" , all the buttons of the menu will has "active" .

what i need is :

each button has "active" class when it clicked .

example : categories : CARS , SPORT , NEWS , KIDS . buttons : CARS , SPORT , NEWS , KIDS .

clicking on SPORT button will open sport page, SPORT button must have "active" class after clicked and CARS , NEWS , KIDS buttons dont have "active" class .

clicking on KIDS button will open kids page , KIDS button get "active" class and remove "active" class from SPORT button .


Solution

  • If you want active class on the current URL's menu item, you need to identify it. I try to identify it by extracting the id from the query string, but maybe a better approach would be to extract the category. Is ajax used? how does a typical link to category SPORT look like, for example?

    I also added a function to escape the html before outputting it, for security.

    <?php
    
    function esc_attr($str)
    {
        return htmlspecialchars((string) $str, ENT_QUOTES);
    }
    
    // get id from request
    $id = $_GET['id'] ?? null;
    
    foreach ($pt->categories as $key => $category) {
        if (1) {
            $class = '';
            if ($key == $id) {
                $class = 'active';
            }
            ?>
            <div class="swiper-slide">
                <a class="<?php echo esc_attr($class); ?>" href="{{LINK videos/category/<?php echo esc_attr($key); ?>}}" data-load="?link1=videos&page=category&id=<?php echo esc_attr($key); ?>">
                    <?php echo $category ?></a>
            </div>
            <?php
        }
    }
    ?>
    

    To sort by "active" first, I will do it using 2 passes. Not efficient but simple.

    for ($mode = 0; $mode < 2; $mode++) {
    
        foreach ($pt->categories as $key => $category) {
            if (1) {
                $class = '';
                if ($key == $id) {
                    $class = 'active';
                }
    
                if ($class == "active" && $mode == 1 || $class != "active" && $mode == 0) {
                    continue;
    
                }
                ?>
                <div class="swiper-slide">
                    <a class="<?php echo esc_attr($class); ?>" href="{{LINK videos/category/<?php echo esc_attr($key); ?>}}" data-load="?link1=videos&page=category&id=<?php echo esc_attr($key); ?>">
                        <?php echo $category ?></a>
                </div>
                <?php
            }
        }
    
    }