Press the button to dynamically update the CSS using PHP and AJAX

I have been facing challenges with Ajax, so I decided to switch to using plain JavaScript instead. My goal is to create a button on a banner that will allow me to toggle between two pre-existing CSS files to change the style of the page. I already have a form in another PHP file where I can select the desired style and submit it to update the style across the plugin. I am considering implementing this functionality using a POST request.

Below is the code for my form:

/**
 * This class handles the display of settings content
 */
class WoosterPartnerSettings
{
    public function __construct()
    {
        if (get_option('partner_license') && get_option('partner_license') != '') {
            add_action('tab_content_settings', array($this, 'wooster_partner_settings'));
            add_action('admin_init', array($this, 'display_style'));
            add_action('admin_enqueue_scripts', array($this, 'enqueue_style'));
        }
    }

    public function wooster_partner_settings()
    {
?>
        <div class="wrap">
            <h1><?php echo __('Wooster Settings', 'wooster-partner'); ?></h1>
            <hr class="line">

            <form method="post" action="options.php">
                <?php settings_fields('wooster-settings-group'); ?>
                <?php do_settings_sections('wooster-settings-group'); ?>

                <p class="parag"><?php echo __('The Wooster Companion plugin offers two display styles:', 'wooster-partner'); ?></p>

                <label for="style_wordpress">
                    <input type="radio" id="style_wordpress" name="wooster_style" value="companion-wp.css" <?php checked(get_option('wooster_style'), 'companion-wp.css'); ?>>
                    <?php echo __('WordPress Style', 'wooster-partner'); ?>
                </label>

                <label for="style_wooster">
                    <input type="radio" id="style_wooster" name="wooster_style" value="companion-wooster.css" <?php checked(get_option('wooster_style'), 'companion-wooster.css'); ?>>
                    <?php echo __('Wooster Style', 'wooster-partner'); ?>
                </label><br>

                <input type="submit" class="wooster-button" value="<?php echo __('Save Changes', 'wooster-partner') ?>">
            </form>
        </div>
<?php
    }


    public function display_style()
    {
        register_setting('wooster-settings-group', 'wooster_style');
    }

    public function enqueue_style()
    {
        if (is_admin()) {
            if (isset($_GET['page']) && strpos($_GET['page'], 'wooster') === 0) {
                $selected_style = get_option('wooster_style', 'companion-wp.css'); // default style
                wp_enqueue_style('wooster-custom-style', plugins_url('wooster-partner/assets/css/' . $selected_style));
            }
        }
    }
}
new WoosterPartnerSettings();

And here is the code for the banner that will be added to all the plugins:

if (!class_exists('WoosterBanner')) {
    class WoosterBanner
    {
        public function __construct()
        {
            if (isset($_GET['page']) && in_array($_GET['page'], ['wooster','wooster-followup','wooster-licenses','wooster-companion','wooster-customers','wooster-partner','wooster-settings','wooster-setup']) && is_admin()) {
                add_action('admin_enqueue_scripts', array($this, 'enqueue_styles'));
                add_action('in_admin_header', array($this, 'wooster_header_section'));
                 add_action('wp_ajax_switch_css', array($this, 'switch_css')); // request when the user is logged in
            }
        }

        public function wooster_header_section() {
            ?>
            <div id="top-bar-banner">
            <div class="wooster-banner">
            <div class="logo">
                <img src="<?php echo plugins_url('assets/img/logo.avif', __DIR__); ?>" alt="Logo">
            </div>
            <div class="actions">
                <form method="post" action="options.php" id="form">
            <?php settings_fields('wooster-settings-group'); ?>
            <button type="button" id="wooster-exchange-button" class="button">
                <i class="fas fa-exchange-alt"></i>
            </button>
        </form>
        <a href="#" class="button"><i class="fas fa-question-circle"></i></a>
    </div>
</div>
</div>
</div>
<?php
        }



        public function switch_css() {

            $style = isset($_POST['style']) ? $_POST['style'] : '';
            
            if ($style === 'wooster-custom-style-css') {
                setcookie('selected_style', $style, time() + 3600, COOKIEPATH, COOKIE_DOMAIN);
                echo plugins_url('assets/css/companion-wooster.css', __FILE__);
            } elseif ($style === 'csspartner-css') {
                setcookie('selected_style', $style, time() + 3600, COOKIEPATH, COOKIE_DOMAIN);
                echo plugins_url('assets/css/companion-wp.css', __FILE__);
            }

            exit;
        }

        public function enqueue_styles() {
            wp_enqueue_style('wooster-banner', plugins_url('assets/css/banner.css', __DIR__));
            wp_enqueue_style('font-awesome', 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css', array(), '5.15.4');

            wp_enqueue_script('jquery');
            wp_enqueue_script('wooster-banner', plugins_url('assets/js/banner.js', __DIR__), array('jquery'), null, true);


        }
    }
    new WoosterBanner();

}
    var currentStyle = 'style_wordpress';

    document.getElementById("wooster-exchange-button").addEventListener("click", function() {
        var style1 = document.getElementById('style_wordpress');
        var style2 = document.getElementById('style_wooster');

        if (currentStyle === 'style_wordpress') {
            style1.disabled = true;
            style2.disabled = false;
            currentStyle = 'style_wooster';
        } else {
            style1.disabled = false;
            style2.disabled = true;
            currentStyle = 'style_wordpress';
        }
    });
});
 ``

Answer №1

I attempted to make changes in the form above, but I encountered an issue where it only worked with the Wooster style selected. The method was not being called. To resolve this, I had to manually call the method on button click.

 <?php
/**
 * Implementation of the WoosterBanner class
 * This class generates a banner for the Wooster plugin
 *
 * @package Wooster
 */
class WoosterBanner
{
    public function __construct()
    {
        if (isset($_GET['page']) && in_array($_GET['page'], ['wooster','wooster-followup','wooster-licences','wooster-compagnon','wooster-customers','wooster-partner','wooster-settings','wooster-setup']) && is_admin()) {
        add_action('admin_enqueue_scripts', array($this, 'enqueue_styles'));
        add_action('in_admin_header', array($this, 'wooster_header_section'));
        add_action('admin_footer', array($this, 'add_switch_style_button'));
        }
    }

    /**
     * Displays the banner at the top of the Wooster plugin settings page
     *
     * @return void
     */
    public function wooster_header_section()
    {
        ?>
        <div id="top-bar-banner">
            <div class="wooster-banner">
                <div class="logo">
                    <img src="<?php echo plugins_url('assets/img/logo.avif', __DIR__); ?>" alt="Logo">
                </div>
                <div class="actions">
                <a class="button"><i class="fas fa-question-circle"></i></a>
                <a class="button" id="switch-style"><i class="fas fa-exchange-alt"></i></a>
                <a class="button"><i class="fas fa-user"></i></a>
            </div>
            </div>
        </div>
        <?php
    }

    /**
     * Adds functionality for switching styles in the Wooster plugin
     *
     * @return void
     */
    public function add_switch_style_button()
    {
        ?>
        <script>
        document.addEventListener('DOMContentLoaded', function() {
            var switchButton = document.getElementById('switch-style');
            var currentStylesheetId = 'csspartner-css';
            var otherStylesheetId = 'wooster-custom-style-css';
            
            switchButton.addEventListener('click', function() {
                var currentStylesheet = document.getElementById(currentStylesheetId);
                var otherStylesheet = document.getElementById(otherStylesheetId);

                if (currentStylesheet && otherStylesheet) {
                    currentStylesheet.disabled = !currentStylesheet.disabled;
                    otherStylesheet.disabled = !otherStylesheet.disabled;
                }
            });
        });
        </script>
        <?php
}

    /**
     * Loads the selected style for the Wooster plugin settings page
     *
     * @return void
     */

    public function enqueue_styles()
    {
        wp_enqueue_style('wooster-banner', plugins_url('assets/css/banner.css', __DIR__));
        wp_enqueue_style('font-awesome', 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css', array(), '5.15.4');
        wp_enqueue_script('jquery'); // Js library
        wp_localize_script('switch-style', 'switch_style_vars', array(
            'wooster_style_url' => plugins_url("wooster-partner/assets/css/compagnon-wooster.css"),
            'wp_style_url' => plugins_url("wooster-partner/assets/css/compagnon-wp.css"),
        ));
    }
}

new WoosterBanner();

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

How to retrieve JSON data from unidentified objects using JQuery

I have made an AJAX call and received a JSON file as the response: [ { "LINKNAME": "Annual Training", "HITS": 1 }, { "LINKNAME": "In Focus Newsletter", "HITS": 1 }, { "LINKNAME": "NITA (secured)" ...

JavaScript regex for the 'hh:mm tt' time format

I need to validate time in the format 'hh:mm tt'. Here is an example of what needs to be matched: 01:00 am 01:10 Pm 02:20 PM This is what I have tried so far: /^\d{2}:\d{2}:\s[a-z]$/.test('02:02 am') ...

jQuery import children into output

When inserting a div every nth-child and later calling the children of the parent, the jQuery inserted elements do not appear in this new list. How can I retrieve the inserted elements as well? Apologies if this is confusing. If it's easier to under ...

Shadows persist despite light intensity being reduced to 0 during runtime

Struggling to figure out how to get rid of these persistent shadows... During runtime, I attempt: light.intensity = 0.0; This makes the scene darker (which is good), but the shadows created by the light remain visible. I've experimented with both ...

I am encountering a problem while performing JavaScript validations

In jQuery or using the element's ID, I can validate a textbox. For example: var field = document.getElementById('tbxSearchField').value if (field == "") {alert("please enter text");} The HTML code is as follows: <input class="input" id ...

Display a custom AngularJS directive on content loaded through $http request

I'm facing a dilemma. I have created a directive app.directive('a', function() { return { restrict: 'E', link: function(scope, elem, attrs) { elem.on('click', function(e){ ...

React Component Div Containing a Hydration Error

Can someone help me resolve the Hydration error related to a nested div issue? I am working on a component that has two main functions - fetching data and mapping it. However, I keep encountering a hydration error and I'm not sure why it's happe ...

When scrolling, the selected text does not maintain its correct position

I'm looking to enable my users to search by selecting text. Once they select text, a new button will appear on the right side of the selected text giving them the option to search or not. However, when the user scrolls to the bottom of the page, the p ...

Struggling to configure an input field using ExtJS

I am trying to use an onChange event to update an input field with the selected option. Below is my code: HTML: <select id="builds" onchange="setBuild()"> <option value="select">Select</option> ... </select> <input ty ...

Range slider position not being updated after user interaction

I am working on a webpage with an embedded video and a range slider that serves as a progress bar. Using Javascript, I update the value of the range slider as the video plays, allowing users to navigate through the video content. However, I have encounter ...

When the enter key is pressed in a contenteditable div, line breaks are disregarded

Is there a way to ensure that when the return key is pressed to start a new line for a post, the output actually starts on a new line? I've been having trouble with this and would like to know the most common solution. Check out the demo below for te ...

Concealing alert messages automatically in CodeIgniter PHP after a certain amount of time

After attempting to use a script to hide the flash message once displayed, I found that it was not working as expected. The flash message remains visible until the page is refreshed. Controller: if ($this->email->send()) { $this- ...

Converting nested json objects to HTML format with the help of jQuery

I've been wracking my brain on this issue for quite some time and I just can't seem to crack it. After posting a question, I received some helpful answers and decided to implement the code provided in the second response (be sure to check out my ...

What is the process for getting non-event javascript instructions to function properly once a DOM element has been added

After inserting DOM elements (such as an AJAX response), event-delegation is necessary to ensure that events work properly. But what about basic JavaScript instructions? All instructions are organized by affected PHP page to simplify code updates and avoi ...

Ways to utilize the map() function with data retrieved from an axios response?

Utilizing axios for data retrieval from the server and then storing it in the state. However, when attempting state.map( post => {console.log(post)} ), no output is displayed. The technologies being used are Express, Mongoose, NextJS, and Axios. My ap ...

What is the simplest method for comparing transaction amounts?

I'm in the process of integrating PayPal into my website using their REST API. My goal is to allow users to input the amount they want to deposit. While I can obtain the total during payment creation, I'm unsure how to smoothly pass it to the exe ...

Transferring the AJAX response into a JavaScript variable

New to AJAX and JS here. I am implementing an AJAX code that fetches data from a php service. I am trying to figure out how to store the returned data in a JavaScript variable, which I can then display on the UI. Below is my AJAX code snippet: <script ...

What could be causing my LESS files not to compile properly in grunt?

I've successfully installed npm and ran npm init. Additionally, I've installed the following packages using npm: grunt grunt-contrib-less grunt-contrib-watch jit-grunt --save-dev My Gruntfile.js configuration looks like this: module.exports = f ...

Typescript error: the argument passed as type a cannot be assigned to the parameter of type b

In my programming interface, I have defined shapes as follows: type Shape = | Triangle | Rectangle; interface Triangle {...} interface Rectangle {...} function operateFunc(func: (shape: Shape) => void) {...} function testFunction() { const rectFun ...

Vue.js encountering an issue of receiving null for the JSON data upon the initial loading phase

Currently, I am expanding my knowledge on vue.js and experimenting with calling a json file to parse the data. Although everything seems to be functioning as intended, whenever I refresh the page, there is a momentary blank screen before the data loads. In ...