Applying styles using CSS based on information stored in Google Sheets

I am currently creating a customizable web application, and I would like to be able to define the color scheme for the app using a google sheet. While I have managed to achieve this by following the steps below, I am hoping someone can provide a more efficient solution that allows the correct colors to be displayed upon initial load without waiting for JavaScript to execute.

For instance, to set the background color, I utilize a google sheet with the background color specified in hexadecimal format in cell "B1" on the "Data" sheet. The script attached to the sheet consists of four files: Code.gs, page.html, page-css.html, and page-js.html.

Code.gs:

function doGet() {
 
  const html = HtmlService.createTemplateFromFile("page");  
  return html.evaluate();
  
}

function getColours(){
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const dataSheet = ss.getSheetByName("Data");
  const colourData = {"background": dataSheet.getRange(1,2).getValue()};
  return colourData;
}

function include(filename){
  return HtmlService.createHtmlOutputFromFile(filename).getContent();
}

page.html:

<!DOCTYPE html>
<html>
  <head>
    <?!= include("page-css"); ?>
  </head>
  <body>
    <div class="container">
    </div>
    <?!= include("page-js"); ?>
  </body>
</html>

page-css.html:

<style>
  :root{
    --background: black;
    --text: white;
  
  }

  .container {
    height: 200px;
    width: 100%;
    background-color: var(--background);
    color:var(--text);
  }

</style>

page-js.html:

<script>
  var r = document.querySelector(":root");
  google.script.run.withSuccessHandler(setColours).getColours();

  function setColours(colourData){
    r.style.setProperty("--background", colourData.background);
  }
</script>

I would appreciate any suggestions for improving this process.

Answer №1

You can incorporate a scriptlet directly into your CSS.

Update the following:

--background: black;

Change it to:

--background: <?!= retrieveColor(); ?>

Don't forget to modify your include function as well.

function include(filename){
  return HtmlService.createTemplateFromFile(filename).evaluate().getContent();
}

CSS Code:

<style>
  :root{
    --background: <?!= retrieveColor(); ?>;
    --text: white;

  }

  .container {
    height: 200px;
    width: 100%;
    background-color: var(--background);
    color:var(--text);
  }

</style>

Google Sheets Function

function retrieveColor(){
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const dataSheet = ss.getSheetByName("Data");
  var colorData = dataSheet.getRange(1,2).getValue();

  if (!colorData) {
    colorData = "black";
  }

  return colorData;
}

You can now remove the code within the script tag.

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

Developing a JavaScript Set within an Array constructor

Just a heads up: For those who are wondering, I am fully aware that adding methods to JavaScript built-in objects is generally considered to be a bad practice. However, I'm currently in the process of adding a new method to the array prototype for a ...

The hunt is on for greater value within the index

My requirement is to check the text content of a box. If it matches any value stored in an ARRAY, then I have to execute a specific action. var ARRAY1 = ["Saab", "Volvo", "BMW"]; if (select[i].innerHTML.indexOf('ARRAY1') != -1){//code here} ...

Issue with displaying current date and time dynamically (JavaScript/JQuery)

In order to create a real-time chat using websockets, I want to show the time of a message posted in this format: "% sec/min/hour/day now". After conducting some research, I came across two functions that I have modified : // Get the TimeStamp va ...

Upon the initial hover, the data added to the title tag following an Ajax call is not appearing

I am currently working on an ajax request that retrieves information such as username, email, and user_id. Once the ajax call is successful, I use jQuery to append this data to the title tag. The main issue I am facing is that the data is only displayed af ...

What is the process for generating a submatch for this specific expression?

Trying to extract account status information using a regular expression in the DOM. Here is the specific string from the page: <h3>Status</h3><p>Completed</p> Current regular expression being used: <h3>Status</h3>[&bs ...

Stop useEffect from triggering during the first render

I'm working on implementing a debounce functionality for a custom input, but I'm facing an issue where the useEffect hook is triggered during the initial render. import { useDebouncedCallback } from "use-debounce"; interface myInputProps { ge ...

What is the best way to incorporate a search function into a modal pop-up?

When triggering the pop-up browse form, this is what I see: form modal This is the result after entering search input: result Please assist in resolving this issue. Thank you. Controller In this form, I am using a partial view to call the modal form: ...

Would it be considered improper to apply ID's to DOM elements for the purpose of automation, as it may transform their CSS classes into individual entities?

Just thinking about the best approach for Automation (such as Selenium). I've been advised against using IDs on elements, as it could result in JS errors (in case of duplicate IDs) and make CSS classes unique. While I see the point, not having IDs can ...

The issue lies in the alignment of the navbar at the top

After retrieving this script: <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"> <nav class="navbar bg-light navbar-expand-sm justify-content-center"> <a class="navbar-brand" ...

I need to position a Vue component at the top of the page for a specific view only

How can I ensure that the component SiteHead only appears at the very top of the HomeView page, above the SiteNavigation component? If I place the SiteHead component within the HomeView.vue code, it ends up below SiteNavigation. Here is my App.vue code: & ...

Tips for creating a vertical tabbed menu display

I've been struggling for hours to convert my horizontal tabbed menu into a vertical one, but without any success. http://jsfiddle.net/u42vvvq2/ (Updated jsfiddle source code link: Fiddle) // JavaScript code here... /* CSS styles go ...

Received undefined instead of a Promise or value from the function in Nodemailer

I'm currently exploring cloud functions and trying to implement email notifications for document creation triggers in Firestore. I found a helpful tutorial that guided me through the process, but I encountered an error while analyzing the cloud functi ...

Problem with pseudo element hover effect on margin and padding

I designed four interactive boxes, where clicking or hovering on one box increases the padding or margin, causing it to overlap with the adjacent boxes. I attempted the following CSS: .marketing-service.active { margin: 0; } and .marketing-service. ...

"Oops! Looks like there is an issue with the configuration of the builder. Try running `npm run storybook

Encountering an error when attempting to execute npm run storybook following what seems like a smooth installation of Alpha 7. Any suggestions on where to begin troubleshooting this issue? https://i.sstatic.net/EEFx4.png ...

What are the possibilities of utilizing a variable that is stated within composition to enable dynamic rendering?

I'm working on a Vue.js v3 project using the composition API. I have defined a variable in my setup like this: setup() { const showInvoiceItemForm = true; return { showInvoiceItemForm }; }, Now, I want to show a form when a button is click ...

Mastering smooth zoom and scroll effects in JavaScript without any flickering

My web application has a zoom feature that scales some absolutely positioned DIVs while keeping the scroll position intact. However, during the animated zooming, there is a noticeable flickering effect where the boxes seem to jump up and down slightly. I a ...

After entering just one character, the focus on the input field in Vue.js is lost

Currently, I am facing an issue with a view that contains an input field. When a character is entered, the input field loses focus, requiring an additional click to resume typing. Does anybody have any insight into what might be causing this problem? Here ...

Issue with ng-repeat in select tag causing an additional blank option in AngularJS

I am encountering an issue with the select tab while using it in ng-repeat. I have searched on Stackoverflow for solutions related to my problem, but I have been unable to resolve it. Here is a snippet of my code: At the top of the page, I declare my cont ...

What is the best way to activate JavaScript once a Silverlight applet has finished loading?

Currently, I am immersed in a project that requires extensive interaction between JavaScript and managed code. Specifically, my JS application must seamlessly communicate with the Silverlight application on the webpage from the get-go. This necessitates th ...

Display the jQuery validation message in the final td cell of the table

JavaScript Animation Library rules:{ gender: { required: true }, }, messages:{ gender: { required: "Please indicate your gender" }, }, errorPlacement: function (error, element) { if (element.attr("type") == "radio") { ...