How to remove a box using Javascript? [closed]

In this library app I’ve added trash bins on each card at the bottom right of each box. I would like to add the functionality to actually delete each card (grid item) by clicking on its corresponding trash bin.

I’m new to javascript and I don’t know how to do this yet

It says it needs more details but I don’t know what to add besides this so I’ll just leave this note here and see if it accepts it this time.

const myLibrary = [
  { title: 'A storm of Swords', author: 'George R. R. Martin', numOfPages: '1008 pages', hasRead: true ? 'Read.' : "Hasn't been read yet" },
  { title: 'A Game of Thrones', author: 'George R. R. Martin', numOfPages: '720 pages', hasRead: false ? 'Read.' : "Hasn't been read yet" },
  { title: "The Hobbit", author: "J.R.R. Tolkien", numOfPages: "295 pages", hasRead: true ? "Read." : "Hasn't been read yet." }
];

function Book(title, author, numOfPages, hasRead) {
  this.title = title;
  this.author = author;
  this.numOfPages = numOfPages;
  this.hasRead = hasRead;
  this.info = function() {
    return `${title} by ${author}, ${numOfPages}, ${hasRead}`;
  }
}

const deleteCard = document.querySelector('.grid-item svg');
console.log(myLibrary[0]);

function addBook() {
  const fTitle = document.getElementById("bookTitle").value;
  const fAuthor = document.getElementById("author").value;
  const fNumOfPages = document.getElementById("numOfPages").value;
  const fHasRead = document.getElementById("hasRead").checked ? "Read." : "Hasn't been read yet.";

  if (fTitle && fAuthor && fNumOfPages) {
    const newBook = new Book(fTitle, fAuthor, fNumOfPages, fHasRead);
    
    addBookToLibrary(newBook);
  
    const gridItem = document.createElement("div");
    gridItem.className = "grid-item";

    // Add content to the grid item
    gridItem.innerHTML = `
      <svg xmlns="http://www.w3.org/2000/svg" width="4px" height="54px" viewBox="0 0 384 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><style>svg{fill:#ffffff}</style><path d="M342.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 210.7 86.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L146.7 256 41.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 301.3 297.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.3 256 342.6 150.6z"/></svg>
      <h3>${newBook.title}</h3>
      <p>${newBook.author}</p>
      <p>${newBook.numOfPages}</p>
      <p>${newBook.hasRead}</p>
    `;
    gridContainer.appendChild(gridItem);
  }
}

function addBookToLibrary(book) {
  myLibrary.push(book);
}

/////////////////////////

const modal = document.querySelector('.modal');
const openModal = document.querySelector('.open-button');
const closeModal = document.querySelector('.close-btn');

openModal.addEventListener('click', () => {
  modal.showModal();
});

closeModal.addEventListener('click', () => {
  modal.close();
})

/////////////////////////

const gridContainer = document.getElementById("gridContainer");

function updateGrid() {
  myLibrary.forEach(item => {
  // Create a div for each grid item
  const gridItem = document.createElement("div");
  gridItem.className = "grid-item";

  // Add content to the grid item
  gridItem.innerHTML = `
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M135.2 17.7L128 32 32 32C14.3 32 0 46.3 0 64S14.3 96 32 96l384 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-96 0-7.2-14.3C307.4 6.8 296.3 0 284.2 0L163.8 0c-12.1 0-23.2 6.8-28.6 17.7zM416 128L32 128 53.2 467c1.6 25.3 22.6 45 47.9 45l245.8 0c25.3 0 46.3-19.7 47.9-45L416 128z"/></svg>
    <h3>${item.title}</h3>
    <p>${item.author}</p>
    <p>${item.numOfPages}</p>
    <p>${item.hasRead}</p>
  `;

  // Append the grid item to the container
  gridContainer.appendChild(gridItem);
})};

updateGrid();
* {
  box-sizing: border-box;
}

dialog::backdrop {
  background: rgb(0 0 0 / .4);
}

.modal {
  padding: 1.5em;
  max-width: 50ch;
}

dialog {
  border: 2px solid black;
  border-radius: 12px;
}

.close-btn {
    position: absolute;
    top: 10px;
    right: 10px;
    background: none;
    border: none;
    font-size: 1.2rem;
    cursor: pointer;
}

body {
  background-color: rgb(215, 137, 28);
}

dialog label {
  font-size: 18px;
  display: block;
  padding: 8px 0 8px;
}

dialog input[type=checkbox] {
  display: block;
  margin: 0 0 16px;
}

dialog input[type=text],
dialog input[type=number] {
  width: 100%;
}

dialog h2 {
  margin: 0 0 10px;
}

dialog text {
  width: 100%;
}

.close-button {
  margin-bottom: 10px;
}

h2 { 
  padding-right: 22px;
}

/* input:invalid {
  outline: 2px solid red;
}

input:valid {
  border: 2px solid black;
} */

/* -------------------- */
/* --------GRID-------- */
/* -------------------- */

.grid-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
  padding: 16px;
}
.grid-item {
  border: 1px solid #ccc;
  border-radius: 8px;
  padding: 16px;
  text-align: center;
  background-color: #f9f9f9;
  position: relative;
}
.grid-item h3 {
  margin: 0 0 8px;
}
.grid-item p {
  margin: 0;
  color: #666;
}
.fa-trash {
  position: absolute;
  z-index: 101;
}
.grid-container .grid-item {
  position: relative;
}

.grid-item svg {
  height: 20px;
  width: 20px;
  position: absolute;
  right: 15px;
  bottom: 15px;
  cursor: pointer;
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="style.css">
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
  <script src="https://kit.fontawesome.com/e8fb2c6b62.js" crossorigin="anonymous"></script>
</head>
<body>
  <h2>An interesting title</h2>
    <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Amet maiores placeat dolorum corporis nihil sapiente cupiditate animi rem ab tenetur facilis ad hic corrupti eligendi, nulla labore, impedit eveniet repudiandae!</p>
    
  <button class="button open-button">open modal</button>
  
  <dialog class="modal" id="modal">
    <h2>Enter details</h2>

    <form class="form" method="dialog">
      
      <label>Book Title </label>
      <input type="text" id="bookTitle" required />

      <label>Author </label>
      <input id="author" type="text" id="author" required />

      <label>Number of pages </label>
      <input type="number" id="numOfPages" required />

      <label>Click if you've finished reading it</label>
      <input type="checkbox" id="hasRead" />

      <input id="addBookBtn" type="submit" onclick="addBook()" />
    </form>
    <button class="close-btn" id="closeDialog">&times;</button>
  </dialog>

  <div class="grid-container" id="gridContainer">
    
  </div>

  <script src="index.js"></script>
</body>
</html>

How to handle JavaScript reinitialization for dynamically loaded AJAX content with WordPress script dependencies?

I am dynamically loading content via AJAX and appending it to the frontend. While the content loads successfully, the issue arises with initializing JavaScript functionality for the newly loaded elements, especially in a WordPress environment where scripts have dependencies.

What I have tried:

Extracting and registering scripts from the AJAX response:
I attempted to extract all tags from the AJAX response and dynamically load them one by one using the following approach:

$.ajax({
    url: 'your-endpoint',
    success: function(data) {
        const content = $(data);
        $('#content-container').html(content);

        // Extract scripts and reinitialize
        content.find('script').each(function() {
            const script = document.createElement('script');
            script.src = $(this).attr('src') || '';
            script.text = $(this).html();
            document.head.appendChild(script);
        });
    }
});

This approach works in some cases, but in WordPress, many scripts rely on dependencies registered with wp_enqueue_script. Without those dependencies being properly enqueued, I encounter errors like:

ReferenceError: wp is not defined

My Question:
How can I properly handle JavaScript initialization for dynamically loaded AJAX content in WordPress, ensuring all dependencies are resolved?

Is there a way to automatically re-register or reinitialize WordPress scripts (and their dependencies) for dynamically loaded content without manually enqueueing them beforehand?

I’m looking for a scalable solution that aligns with WordPress best practices.

How can I properly handle JavaScript initialization for dynamically loaded AJAX content in WordPress, ensuring all dependencies are resolved?

Is there a way to automatically re-register or reinitialize WordPress scripts (and their dependencies) for dynamically loaded content without manually enqueueing them beforehand?

I’m looking for a scalable solution that aligns with WordPress best practices.

How to make OneTrust and Google Maps to work nicely

The company I work for uses OneTrust to handle GDPR. I have the task to make a google map show up. I have had issues making the https://maps.googleapis.com/maps/api script tag to work as I wanted to use a library. Anyway I got it working by adding the attribute data-ot-ignore to the script tag. But now the maps thing is not calling my back end to get the layers I need to put on top of the map. I have an API that I call and it works fine in a local, contrived sample but once it’s on the full blown test environment it just won’t call my API to get the layers

The way google maps retrieves the layers is by calling the function in the ImageMapTyle object we have to define:

  new google.maps.ImageMapType({
    getTileUrl(coord, zoom): string {
      return `${coverage_rest_root}/tiles/service/gmaps?layers=${layerProps[overlayRev].apiName}&zoom=${zoom}&x=${coord.x}&y=${coord.y}&format=image/png`;
    },
    tileSize: new google.maps.Size(TILE_SIZE, TILE_SIZE),
    opacity: layerProps[overlayRev].opacity,
    name: overlayRev,
  });

which makes me not be able to add neither a class nor an attribute, which are the two ways to tell OneTrust to ignore the script

Is there a way to call reusable rules in javascript block as the following: testRigor.execute(“my reusable rule with ‘param1′”)?

Trying to achieve the following but it ends up just blocking the server and never finishing the execution even when cancelling the test run:

    execute JavaScript text starting from next line and ending with [END]
        var tenantName = "Ford CSP";
        testRigor.execute('map tenant name "' + tenantName + '" to vinDecoder domain');
    [END]

To execute a resuable rule in a javaScript block

How to flatten a tree of table columns into a flat list of table columns with headers

I have a nested tree of table columns. Here are the typescript types.

export interface TableLeafColumn {
  label: string;
  key?: string;
}

export interface TableContainerColumn {
  label: string;
  columns: TableColumn[];
}

// Union type to represent either a leaf or container column
export type TableColumn = TableLeafColumn<T> | TableContainerColumn;

Here’s an example of such a type:

const columns: TableColumn[] = [
  {
    label: "Name",
    key: "name",
  },
  {
    label: "Details",
    columns: [
      {
        label: "Age",
        key: "age",
      },
      {
        label: "Address",
        columns: [
          { label: "City", key: "city" },
          { label: "Country", key: "country" },
        ],
      },
    ],
  },
];

I would like a function called flattenColumns that will return TableColumn[][]. For example, the input above would return:

const result = [
  [
    { label: "" }, // placeholder for Name
    { label: "Details", colSpan: 3 }
  ],
  [
    { label: "" }, // placeholder for Name
    { label: "" }, // placeholder for Age
    { label: "Address", colSpan: 2  }
  ],
  [
    { label: "Name", key: "name" },
    { label: "Age", key: "age" },
    { label: "City", key: "city" },
    { label: "Country", key: "country" },
  ]
]

I have tried to write the function, but nothing worked. The tricky party is adding the placeholders, so that every leaf column appears at the bottom.

Not sure if the result I gave above is the best representation for this, but I want to render such table headers inside an HTML table, and I figured that format would be the easiest to utilise.

JS fetch headers are not included before request (Flask)

I’m using JS to get the screen width of the page, posting it, and then calling it from within my Flask app HTML template to determine functionality of a graph (either interactive Plotly or an image). I am correctly getting the width, but I have errors either “415 Unsupported Media Type Did not attempt to load JSON data because the request Content-Type was not ‘application/json'” or “Unexpected token ‘<‘, “<!DOCTYPE “… is not valid JSON”

If I don’t call the data = request.get_json() line in app.py, I get the second error; it seems like the fetch body is not executing properly and it’s just getting the whole page. If I call this line, I get the Unsupported Media Type error, the headers don’t log, and the print statement regarding the DOM loading doesn’t load either.

I’m very new to JS and just want to get the screen width and pass it back to the Flask app. It seems like even though I have document.addEventListener('DOMContentLoaded', () that if I call request.get_json() the code executes before the headers are loaded.

Here are my code snippets:

JS

    document.addEventListener('DOMContentLoaded', () => {
        console.log('dom loaded')
        const playlistId = '{{ playlist.playlist_id }}';
        const width = window.innerWidth;
        const headers = {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
        };
        console.log('Headers being sent:', headers);
        fetch(`/playlist/${playlistId}`, {
            method: 'POST',
            headers: headers,
            body: JSON.stringify({ width: width })
        })
        .then(response => {
            console.log('Raw response:', response);
            return response.json();
        })
        .catch(error => {
            console.error('Error:', error);
        });
    });

playlist.html (jinja)

    {% if viewport >= 768 %}
        {% for graph in graphs %}
        <div class="features-graph">
            {{ graph[0]|safe }}
        </div>
        {% endfor %}
    {% else %}
        {% for graph in graphs %}
        <div class="features-graph">
            <img src="data:image/jpg;base64,{{ graph[1] }}">
        </div>
        {% endfor %}
    {% endif %}

app.py

@app.route('/playlist/<string:playlist_id>', methods=['POST', 'GET'])
def playlist_details(playlist_id):
    playlist = Playlist.query.filter_by(playlist_id=playlist_id).first_or_404()
    playlist_tracks = Track.query.filter_by(playlist_id=playlist_id).all()
    sorted_playlists = model_playlists(playlist_id)
    graphs = make_graphs(playlist_id)
    data = request.get_json()
    viewport_width = data['width']
    return render_template('playlist.html', playlist=playlist, playlist_tracks=playlist_tracks, model_playlists=sorted_playlists, graphs = graphs, viewport=viewport_width)

I’m also open to another way to do this without JS or without the POST request.

Can I have controller for custom html element (to get context buttons update and delete)?

not sure if I am asking correctly. But I understood that controller is probably what I need. I want to have the functionality of custom plugin number 4 called Dialog – http://suneditor.com/sample/html/customPlugins.html#dialog But I do not want to insert a link but custom element named for example customElement.

I can modify the code provided for the sample plugin to custom HTML element is inserted but then I will loose the context dialog to update, unlink, or remove the element.

I my case I want only the update and remove icons.

enter image description here

Is that possible in Suneditor?

You test with https://jsfiddle.net/radek/qjoevast/12/ the very first line defines what HTML element is going to be inserted.

for var customElement = 'a' I get the context buttons
for var customElement = 'customElement' the correct element is inserted but not context buttons

We need to move the subchart to the top using billboard.js

Can anyone find the solution of the problem that I want to move the chart to top then mainchart in browser.Please let us know how to resolve this

I want to move the subchart at the top then mainchart should display in browser.

var chart = bb.generate({
  data: {
    columns: [
    ["sample", 30, 200, 100, 400, 150, 250]
    ],
    type: "line", // for ESM specify as: line()
  },
  subchart: {
    show: true, // for ESM specify as: subchart()
    showHandle: true
  },
  bindto: "#subChart"
});

Difficulty Connecting to Supabase S3-Compatible Storage

I am trying to connect to Supabase’s S3-compatible storage but am encountering some difficulties. The Supabase endpoint I am working with is structured as follows:

https://xxxxxxxxxxxx.supabase.co/storage/v1/s3

Could you provide guidance or examples on how to establish a connection to this endpoint? Any help or documentation links would be greatly appreciated.

InvalidEndpointError: Invalid endPoint : xxxxxxxxxxxxxx.supabase.co/storage/v1/s3
    at new TypedClient (file:///home/node/.cache/deno/npm/registry.npmjs.org/minio/8.0.2/dist/esm/internal/client.mjs:58:13)
    at new Client (file:///home/node/.cache/deno/npm/registry.npmjs.org/minio/8.0.2/dist/esm/minio.mjs:32:8)

}
    this.client = new Client({
      endPoint: S3_ENDPOINT,
      port: S3_PORT,
      useSSL: S3_SSL,
      region: S3_REGION,
      accessKey: S3_ACCESS_KEY,
      secretKey: S3_SECRET_KEY,
      pathStyle: true,
    });

get 404 for external js file in vue js 3?

i have vue js project and i use adminlte template i set js file like that in my App.vue:

<script>


 export default {
  name: 'App',
  mounted(){
console.log(__filename)
const scriptsToLoad = [
  './template/bower_components/jquery/dist/jquery.min.js',
  './template/bower_components/jquery-ui/jquery-ui.min.js',
  './template/bower_components/bootstrap/dist/js/bootstrap.min.js',
  './template/bower_components/morris.js/morris.min.js',
  './template/bower_components/jquery-sparkline/dist/jquery.sparkline.min.js',
  './template/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js',
  './template/plugins/jvectormap/jquery-jvectormap-world-mill-en.js',
  './template/bower_components/jquery-knob/dist/jquery.knob.min.js',
  './template/bower_components/moment/min/moment.min.js',
  './template/bower_components/bootstrap-daterangepicker/daterangepicker.js',
  './template/bower_components/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js',
  './template/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js',
  './template/bower_components/jquery-slimscroll/jquery.slimscroll.min.js',
  './template/bower_components/fastclick/lib/fastclick.js',
  './template/dist/js/adminlte.min.js',
  './template/dist/js/pages/dashboard.js',
  './template/dist/js/demo.js'
];

scriptsToLoad.forEach(src => {
  const script = document.createElement('script');
  script.setAttribute("src",src);
  document.head.appendChild(script);
});
}

}


</script>

but i got this error for all files:
main.js:21

   GET http://localhost:8080/template/bower_components/jquery-sparkline/dist/jquery.sparkline.min.js net::ERR_ABORTED 404 (Not Found)

i put adminlte files in src folder

so what is problme?

How to find a DOM object by the text using JS/Chrome extension execution?

Currently trying to access DOM object by the ‘text’, and I can’t find this using standard javascript way – ‘evaluate’ or looping through all th object.

DOM object that I want to access is with textContent <target_text>
I have confirmed that <target_text> is unique across the whole page.

Executing this as part of Chrome extension.

Target element looks like this

<th class="MuiTableCell-root table-header-cell h-8 whitespace-pre-wrap align-middle text-left MuiTableCell-head MuiTableCell-sizeMedium css-1bz4y89" scope="col" style="width: 50%;">Target Text</th>

So there is not unique class or tag to point it by.
It’s parent look like

<tr class="MuiTableRow-root MuiTableRow-head css-16pe4ub"><th class="MuiTableCell-root table-header-cell h-8 whitespace-pre-wrap align-middle text-left MuiTableCell-head MuiTableCell-sizeMedium css-1bz4y89" scope="col" style="width: 50%;">Target Text</th><th class="MuiTableCell-root table-header-cell h-8 whitespace-pre-wrap align-middle text-left MuiTableCell-head MuiTableCell-sizeMedium css-1bz4y89" scope="col" style="width: 50%;">Finding</th><th class="MuiTableCell-root table-header-cell h-8 whitespace-pre-wrap align-middle text-left w-13 MuiTableCell-head MuiTableCell-sizeMedium css-1bz4y89" scope="col"></th></tr>
  const targetElements = document.querySelectorAll('th');
  const targetElement = Array.from(techConcernsElements).find(th => 
    th.textContent.trim() === '<target_text>'
  );

This returns nothing

  const targetElement = document.evaluate(
    "//th[text()='<target_text>']", // This is the Xpath directly.
    document,
    null,
    XPathResult.FIRST_ORDERED_NODE_TYPE, // FIRST_ORDERED_NODE_TYPE returns the first matching node
    // Other options include:
    // UNORDERED_NODE_ITERATOR_TYPE - Returns all matching nodes in arbitrary order
    // ORDERED_NODE_ITERATOR_TYPE - Returns all matching nodes in document order
    // UNORDERED_NODE_SNAPSHOT_TYPE - Returns snapshot of matches in arbitrary order
    // ORDERED_NODE_SNAPSHOT_TYPE - Returns snapshot of matches in document order
    // FIRST_ORDERED_NODE_TYPE - Returns first match in document order
    // ANY_UNORDERED_NODE_TYPE - Returns any single matching node
    // NUMBER_TYPE - Returns number value
    // STRING_TYPE - Returns string value
    // BOOLEAN_TYPE - Returns boolean value
    null
  );

Tried out the explicit selector found in the chrome page

#root > div.flex.flex-col.h-screen > main > div > div > div > div:nth-child(2) > div > div.MuiPaper-root.MuiPaper-elevation.MuiPaper-rounded.MuiPaper-elevation1.MuiCard-root.relative.overflow-visible.rounded-sm.w-full.max-w-6xl.xl:max-w-7xl.css-1kxnsga > div.[&_tbody_tr_td]:text-lg.[&_th]:text-base > div:nth-child(2) > table > thead > tr > th:nth-child(1)

via
const targetElement = document.querySelector('#root > div.flex.flex-col.h-screen > main > div > div > div > div:nth-child(2) > div > div.MuiPaper-root.MuiPaper-elevation.MuiPaper-rounded.MuiPaper-elevation1.MuiCard-root.relative.overflow-visible.rounded-sm.w-full.max-w-6xl.xl\:max-w-7xl.css-1kxnsga > div\[\&_tbody_tr_td\]\:text-lg\[\&_th\]\:text-base > div:nth-child(2)');

This also returns nothing

Why can if statement works using an object (like Map) with “.has()” and no working with “.includes”?

That’s my code to explain my idea better (I’m a non english speaker):

The “.includes()” method doesn’t work in this case

const sentence = "hello world hello boy";

let words = sentence.split(" ");

const quantWords = new Map();

for (let word of words) {  
    if (quantWords.includes(word)) {
        quantWords.set(word, + 1);
    } else {
        quantWords.set(word, 1);
    }
}
console.log(quantWords);

Otherwise, using “.has()”, it works

const sentence = "hello world hello boy";

let words = sentence.split(" ");

const quantWords = new Map();

for (let word of words) {  
    if (quantWords.has(word)) {
        quantWords.set(word, + 1);
    } else {
        quantWords.set(word, 1);
    }
}
console.log(quantWords);

Is there a way to get data from an API (eg. colors theme) and use them to update tailwind.config.js file with the new color theme from the API?

I’m currently building a project that’ll allow the user to choose their color scheme, which will be saved to an API (currently using a local dummy API). I’m looking to grab the data from the API and update the tailwind.config.js file with the new colors, but can’t seem to achieve this. I get the following error message:

[vite] Internal server error: [postcss] /Applications/MAMP/htdocs/CG/src/index.css:213:5: ‘colors.primary400’ was found but does not resolve to a string.

Below is my code so far…

http.js

export async function fetchClientData() {
    const response = await fetch("http://localhost:3000/client");
    const resData = await response.json();

    if (!response.ok) {
        throw new Error();
    }

    return resData.client;
}

clientDataStyling.js


import { fetchClientData } from "./http";

let FCDStylingObj;

async function fetchClientAPIStyling() {
    try {
        const FCDStyling = await fetchClientData();
        FCDStylingObj = {
            fetchPrimary400: FCDStyling[0].colors.primary400,
        }
        var getFCDStylingObj = await FCDStylingObj.fetchPrimary400;
        return getFCDStylingObj;

    } catch (error) {
        console.log('Error message | ' + error);
    }
}

let clientStyling = fetchClientAPIStyling();

clientStyling.then(function (result) {
    return result;
})

export const CLIENT_DATA = {
    colors: {
        primary400: clientStyling
    },
}

tailwind.config.js

/** @type {import('tailwindcss').Config} */

import { CLIENT_DATA } from './src/clientDataStyling';

console.log(CLIENT_DATA.colors.primary400);

export default {
    content: [
        "./index.html",
        "./src/**/*.{js,ts,jsx,tsx}",
    ],
    theme: {
        extend: {
            fontFamily: {
                title: "Poppins, sans-serif",
                body: "Poppins, sans-serif"
            },
            colors: {
                primary100: "#b8ace860",
                primary200: "#6e56a1c4",
                primary300: "#644b99",
                // primary400: "#392976",
                primary400: CLIENT_DATA.colors.primary400,
                secondary: "#e372a9",
                third: "#3eb392",
                success: "#3eb392",
                error: "#f94b4b"
            },

            borderWidth: {
                global: "1px"
            },

            borderRadius: {
                global: "5px"
            },

            transitionDuration: {
                global: "300ms"
            }
        },
    },
    plugins: [],
}

Any help would be grateful as I’ve been going around in circles these past couple of days! Or if there’s any other css framework that’ll work for what I’m trying to achieve. Thanks again!

How do I invoke my lang key using Handlebars JS inside a Javascript template literal

I’m trying to invoke my lang files (i.e. en.json, es.json, etc.) within a Javascript template literal however, when I call upon the lang file using Handlebars, it renders the lang call as a string instead of converting it into the text in my lang files. How do I change my code to make it pull from the lang files instead? Currently it is displaying the button with {{ lang product.quick_view }} as plain text.

Here is the HTML:

        <div class="quiz">
            <div id="quiz-container">
                <div id="question-container" class="question"></div>
                <ul id="options-container" class="productGrid"></ul>
            </div>
            <ul id="result-container" class="result">
            </ul>
        </div>
    <script src="{{cdn 'assets/js/autoselect-assist.js'}}"></script>

And here is my Javascript:

function displayResults() {
    questionContainer.textContent = "Your recommended product(s):";
    optionsContainer.innerHTML = "";
    
    if (filteredProducts.length > 0) {
        filteredProducts.forEach(result => {
            const productElement = document.createElement("li");
            productElement.classList.add("product");
            productElement.innerHTML += `
                <article class="card" data-event-type="list" data-name="${result.name} data-product-category="" data-product-brand="${result.brand} data-product-price="${result.price}>
                    <figure class="card-figure">
                        <a href="${result.url}" class="card-figure__link" target="_blank" aria-label="${result.name}, ${result.price}" data-event-type="product-click">
                            <div class="card-img-container">
                                <img src="${result.img}" class="card-image lazyautosizes ls-is-cached lazyloaded" alt="${result.name}" title="${result.name}" data-sizes="auto" srcset="${result.img} data-srcset="${result.img}" sizes="285px">
                            </div>
                        </a>
                        <figcaption class="card-figcaption">
                            <div class="card-figcaption-body">
                                <button type="button" class="button button--small card-figcaption-button quickview" data-event-type="product-click">{{ lang "products.quick_view" }}</button>
                                <label class="button button--small card-figcaption-button">
                                {{ lang "products.compare" }}
                                <input type="checkbox" name="products[]">
                                </label>
                                <a href="${result.url}" data-event-type="product-click" class="button button--small card-figcaption-button">{{ lang "products.choose_options" }}</a>
                            </div>
                        </figcaption>
                    </figure>
                    <div class="card-body">
                        <p class="card-text" data-test-info-type="brandName">${result.brand}</p>
                        <h3 class="card-title">
                            <a href="${result.url}" target="_blank">${result.name}</a>
                        </h3>
                        <div class="card-text" data-test-info-type="price">
                        <div class="price-section price-section--withoutTax">
                            <span class="price-label"></span>
                            <span class="price-now-label" style="display: none;"></span>
                            <span data-product-price-without-tax class="price price--withoutTax">$${result.price}</span>
                        </div>
                    </div>
                </article>`;
            optionsContainer.appendChild(productElement);
        });
    } else {
      optionsContainer.textContent = "No products match your criteria. Please try again!";
    }

    const restartButton = document.createElement("button");
    restartButton.textContent = "Restart Quiz";
    restartButton.addEventListener("click", restartQuiz);
    restartButton.classList.add("restart", "button", "button--primary");
    optionsContainer.appendChild(restartButton);
}

For reference, Handlebars calls lang like this: {{ lang "products.quick_view" }}

Trigger Script in Google Doc via Link

I have a current script in Google Docs that adds a header with collapsible list beneath it (on a pageless setup) underneath a specific section of the document.

I am looking for users to be able to trigger the script from within the document. I have been able to achieve this in Google Spreadsheets using links and Drawings (and using a custom menu, but that’s less ideal in this instance), but have not been able to achieve the same thing within Google Docs.

Ideally, a user would click a link, which would trigger the script that adds the following:
Example of the text script should input

Here’s the script I have so far:

function insertText() {
  var header = "Enter_Item_Title_Here"
  var bulletOneHeader = "Agenda Item Owner(s): ___________"
  var bulletTwoHeader = "Discussant: ___________"
  var bulletThreeHeader = "Discussion Date: ___________"
  var bulletFourHeader = "External follow up: ___________"
  var bulletFiveHeader = "Notes: ___________"
  var bulletSixHeader = "Action Items: ___________"
  var cursor = DocumentApp.getActiveDocument().getActiveTab().asDocumentTab().getBody();
  var pr = cursor.findText("New Items:").getElement().getParent();
  var i = cursor.getChildIndex(pr) + 1;
  cursor.insertParagraph(i, header).setHeading(DocumentApp.ParagraphHeading.HEADING3);
  cursor.insertListItem(i + 1, bulletOneHeader).setGlyphType(DocumentApp.GlyphType.BULLET).setAttributes({ [DocumentApp.Attribute.BOLD]: true });
  cursor.insertListItem(i + 2, bulletTwoHeader).setGlyphType(DocumentApp.GlyphType.BULLET).setAttributes({ [DocumentApp.Attribute.BOLD]: true });
  cursor.insertListItem(i + 3, bulletThreeHeader).setGlyphType(DocumentApp.GlyphType.BULLET).setAttributes({ [DocumentApp.Attribute.BOLD]: true });
  cursor.insertListItem(i + 4, bulletFourHeader).setGlyphType(DocumentApp.GlyphType.BULLET).setAttributes({ [DocumentApp.Attribute.BOLD]: true });
  cursor.insertListItem(i + 5, bulletFiveHeader).setGlyphType(DocumentApp.GlyphType.BULLET).setAttributes({ [DocumentApp.Attribute.BOLD]: true });
  cursor.insertListItem(i + 6, bulletSixHeader).setGlyphType(DocumentApp.GlyphType.BULLET).setAttributes({ [DocumentApp.Attribute.BOLD]: true });
}

Here’s an example google doc that includes the script I have so far.

I’ve been looking at and playing around with this existing question and also this one, but haven’t been able to figure it out.