Search code examples
javascriptangularangular16cookieconsent

klaro "Accept" and "Manage Preferences" order change


I have configured klaro cookie package in my Angular project with all the required configurations, but I want to change the order of "Accept" and "Modify choices" button:

button-order

"Accept" should be first, I don't want to use CSS property like order:0/1 or don't want to use flex-direction: column-reverse; Is there any configuration? I found that in this reference website the order is correct: reference-link

The purpose of ordering is to fulfill the accessibility criteria.

stackblitz

HTML structure: html


Solution

  • UPDATE

    I am providing this alternative answer, where we use an IIFE to run a setInterval every 500ms, then once the accept button becomes visible and the swap is done, the interval is cleared, this will eliminate the timing issue you are getting.

    We then need to add the js file to angular.json

            ...
            "scripts": [
              "node_modules/klaro/dist/klaro.js",
              "klaro-customize.js"
            ],
            ...
    

    klaro-customize.js

    (() => { // IIFE run on initialize
      // swap the elements
      const intervalRef = setInterval(() => {// run the function every 500 ms
        const accept = document?.querySelector('.cn-buttons');
        const managePreferences = document?.querySelector('.cm-link.cn-learn-more');
        if (accept?.parentNode && managePreferences?.parentNode?.firstChild) {
          accept.parentNode.insertBefore(
            accept,
            managePreferences.parentNode.firstChild
          );
          // once action done clear the interval
          clearInterval(intervalRef);
        }
      }, 500);
    })();
    

    Stackblitz Demo


    There is no configuration to do this, but we can use plain javascript to swap the elements when the component loads. I get the two elements, then use insertBefore of javascript to swap the two elements!

      ...
      constructor(private renderer: Renderer2, private elementRef: ElementRef) {
        ...
        // swap the elements
        const accept: any = document?.querySelector('.cn-buttons');
        const managePreferences: any = document?.querySelector(
          '.cm-link.cn-learn-more'
        );
        if (accept?.parentNode && managePreferences?.parentNode?.firstChild) {
          accept.parentNode.insertBefore(
            accept,
            managePreferences.parentNode.firstChild
          );
        }
      }
      ...
    

    FULL CODE:

    import { Component, ElementRef, Renderer2 } from '@angular/core';
    import { bootstrapApplication } from '@angular/platform-browser';
    import 'zone.js';
    import { klaroConfig } from './klaro-config';
    // we can either import Klaro without styles...
    import * as Klaro from 'klaro';
    // and the manually load the styles (e.g. to bundle them manually)
    
    // we set up Klaro with the config
    @Component({
      selector: 'app-root',
      standalone: true,
      template: `
        <h1>Hello from {{ name }}!</h1>
        <a target="_blank" href="https://angular.dev/overview">
          Learn more about Angular
        </a>
        <br/>
        <a class="button is-success" (click)="show()"
          >Change consent settings</a
        >
      `,
    })
    export class App {
      name = 'Angular';
      klaro!: any;
    
      constructor(private renderer: Renderer2, private elementRef: ElementRef) {
        (<any>window).klaro = Klaro;
        (<any>window).klaroConfig = klaroConfig;
        Klaro.setup(klaroConfig);
        // swap the elements
        const accept: any = document?.querySelector('.cn-buttons');
        const managePreferences: any = document?.querySelector(
          '.cm-link.cn-learn-more'
        );
        if (accept?.parentNode && managePreferences?.parentNode?.firstChild) {
          accept.parentNode.insertBefore(
            accept,
            managePreferences.parentNode.firstChild
          );
        }
      }
    
      ngOnInit() {}
    
      show() {
        Klaro.show();
      }
    }
    
    bootstrapApplication(App);
    

    Stackblitz Demo