How to use v-carousel with multiple images per slide to create a product thumbnail and slider

I cannot seem to find an easy way to do this. I am trying to create a product image/slider in vuetify. The closest example of what I am trying to achieve is shown in this link:

https://flexy-vue3-main-admin.vercel.app/ecommerce/product/detail/1

I am struggling to figure out how to position multiple images in the slider and move them around into the the main image being in the center of the slider below. My first thought was to create a max slide count and use that to help predict the index of the image to show in the main screen. However, how this all comes together is not clicking for me. Its almost like in the example above there is a endless loop so that is confusing how to even implement. My code is as follows:

<template>
    <div>
        <v-row>
            <v-col class="ma-10">
                <v-row>
                    <v-carousel v-model="mainImgModel" hide-delimiters :show-arrows="false" class="rounded-lg ma-5">
                        <v-carousel-item v-for="(item,index) in data" :key="index"
                            :src="item['src']"
                            aspect-ratio = "1" cover>
                        </v-carousel-item>
                    </v-carousel>
                </v-row>
                <v-row>
                    <v-carousel v-model="thumbnailModel" hide-delimiters :show-arrows="false" class="ma-5">
                        <v-carousel-item v-for="(slide, index1) in numberOfSlides">
                            <v-row>
                                <v-col v-for="(item ,index2) in maxThumbnails">
                                    <v-img class="rounded-lg" aspect-ratio = "16/9" cover :src="data[index2+index1*maxThumbnails]['src']" @click="thumbnailAction((index2+index1*maxThumbnails))"></v-img>
                                </v-col>
                            </v-row>
                        </v-carousel-item>
                    </v-carousel>
                </v-row>
            </v-col>
            <v-col>
            
            </v-col>
        </v-row>
    </div>
</template>
<script lang="ts" setup>
    import { ref } from 'vue'

    const mainImgModel = ref<Number>(0);
    const thumbnailModel = ref<Number>(0);

    const maxThumbnails = 5;
    const data = [{src : "https://cdn.vuetifyjs.com/images/cards/docks.jpg"},
    {src : "https://cdn.vuetifyjs.com/images/parallax/material.jpg"},
    {src : "https://cdn.vuetifyjs.com/images/cards/docks.jpg"},
    {src : "https://cdn.vuetifyjs.com/images/cards/docks.jpg"},
    {src : "https://cdn.vuetifyjs.com/images/cards/docks.jpg"},
    {src : "https://cdn.vuetifyjs.com/images/cards/docks.jpg"},
    {src : "https://cdn.vuetifyjs.com/images/cards/docks.jpg"},
    {src : "https://cdn.vuetifyjs.com/images/cards/docks.jpg"},
    {src : "https://cdn.vuetifyjs.com/images/cards/docks.jpg"},
    {src : "https://cdn.vuetifyjs.com/images/cards/docks.jpg"}]
    const numberOfSlides = Math.floor(data.length/maxThumbnails);

    const thumbnailAction = (index : Number) => {
        //unsure what to do wih this info
        mainImgModel.value = index
    }
</script>

Console is throwing XML Parsing Errors when loading contents from one HTML file into another

I am using Firefox v123.0.1 (64-bit) to locally view the index.html for a static web page that I am developing, and I want to dynamically load the contents of another HTML file into a <div>. My goal with having several HTML files is to organize the contents of my web page so it is easier to maintain and to reduce the amount of data the client needs to load at once, all while not having to write duplicate code surrounding the <div> (e.g., by creating a web page for each <div> state).

When I write the contents directly into the <div>, I do not get XML Parsing Errors, but when I use jQuery 3.7.1 to load the contents from another HTML file, it has a problem with some void elements that are not explicitly closed like <br> instead of <br/> as well as some boolean attributes that are not explicitly defined like hidden instead of hidden='true'.

I would like to know:

  1. How do I stop these errors from occurring?
  2. Why do these errors happen?
  3. Is there a better way to accomplish my original goal?

I wrote some code in the spoiler below to demonstrate this problem. The errors are detailed as comments. Notice that there are no errors when the contents originate from index.html, but for some unexpected reason, an error occurs when the same contents originate from br.html or hidden.html.

index.html

<!DOCTYPE html>

<html lang='en'>

  <head>
    <link rel='stylesheet' href='app.css'>
    <title>Test</title>
  </head>

  <body>

    <button onclick='updateContainer("#container-with-br", "br.html");'>
      Load HTML containing &lt;br&gt;
    </button>
    <div id='container-with-br'>
      This HTML is from...<br>index.html
    </div>
    <!--
      XML Parsing Error: mismatched tag. Expected: </br>.
      Location: br.html:7:3
      Fixed by changing <br> to <br/>
    -->

    <br>

    <button onclick='updateContainer("#container-with-hidden", "hidden.html");'>
      Load HTML containing hidden element
    </button>
    <div id='container-with-hidden'>
      This HTML is from... index.html <span hidden>and this is hidden</span>
    </div>
    <!--
      XML Parsing Error: not well-formed
      Location: hidden.html:5:48
      Fixed by changing hidden to hidden='true'
    -->

    <script src='jquery-3.7.1.js'></script>
    <script>
      function updateContainer(container, filename) {
        $(container).load(filename);
      }
    </script>

  </body>

</html>

br.html

<!DOCTYPE html>

<html lang='en'>

  This HTML is from...<br>br.html

</html>

hidden.html

<!DOCTYPE html>

<html lang='en'>

  This HTML is from... hidden.html <span hidden>and this is hidden</span>

</html>

How to read value of a signal boolean in Angular17

I have a singal in service:

export class AuthService {
  constructor(private cookieService: CookieService) {}
  url = 'http://localhost:8000/api/v1/login';
  token: string = '';
  isAuthenticated = signal<Boolean>(false);
  changeIsAAuthenticated() {
    this.isAuthenticated.set(false);
    console.log(this.isAuthenticated);
  }
  getIsAAuthenticated() {
    return this.isAuthenticated;
  }

and in route guard i want to get its value:

 let authService = inject(AuthService);
 console.log(authService.isAuthenticated);

and i get:

function getter()

How to read a value of a singal?
I tried:
getValue, value, get or writing a getter but it didnt work.

console.log(authService.isAuthenticated);
  console.log(authService.getIsAAuthenticated());

return function getter()

I should have see the value just by console.log it, but it doesnt work.

Draw a ring using the HTML5 canvas without the straight line

I want to draw a ring with the canvas that doesn’t have the straight black line you see when you use the below code.

 var can = document.getElementById('canvas1');
 var ctx = can.getContext('2d');
 //ctx.arc(x,y,radius,startAngle,endAngle, anticlockwise);  
 ctx.beginPath()
 ctx.arc(100,100,100,0,Math.PI*2,false); // outer (filled)
 ctx.arc(100,100,55,0,Math.PI*2,true); // outer (unfills it)
 ctx.fillStyle='red';
 ctx.fill();
 ctx.strokeStyle='black';
 ctx.lineWidth=1;
 ctx.stroke();
<canvas id="canvas1" width="800" height="800"></canvas>

Why is my navigation menu working at any page size on Windows and Mac computers but not on iPad and Android phone?

I have made a Web site as a favour for a someone. The general code will likely disappoint but it’s been done this way as it has to work on some niche, legacy technology.

Anyway, it works well enough, except we’ve discovered an issue with the menu. You can drag and resize the window on a Windows or MacOS desktop computer and it works as desired, switching to the ubiquitous three-bar mobile menu when the window gets small enough. However, it doesn’t work at all on either my iPad or Android phone. This kind of navigation is new to me as I took a multi-year break from Web development, so I may be missing something laughably obvious.

Any ideas?

The development site is at: http://rcomp.michaelstubbs.uk

The CSS is in this file:

https://rcomp.michaelstubbs.uk/stylesheet.css

The navigation code included on each page is in this text file:

https://rcomp.michaelstubbs.uk/titlebar.txt

I was going to paste in only the relevant code but it occurred to me that maybe there’s something I don’t think is relevant but is, so just linked to the files instead.

React google places autocomplete returning only one place (Needing zip)

I’m attempting to use react google autocomplete, the issue I’m having is that for some reason both libraries react-google-places-autocomplete and react-places-autocomplete always return a single value from the search I make, which is wrong since when searching on google or with use-places-autocomplete it returns more values.

For example, when searching: 81237

The result I get from react-google-places-autocomplete and react-places-autocomplete array of 1:

[
    {
        "address_components": [
            {
                "long_name": "81237",
                "short_name": "81237",
                "types": [
                    "postal_code"
                ]
            },
            {
                "long_name": "Ohio City",
                "short_name": "Ohio City",
                "types": [
                    "locality",
                    "political"
                ]
            },
           ...
        ],
        "formatted_address": "Ohio City, CO 81237, USA",
        "geometry": {
           ...
        },
        "place_id": "ChIJJXK28KjiP4cRZNwTV9HTmB0",
        "types": [
            "postal_code"
        ]
    }
]

but from use-places-autocomplete array of 5:

[
    {
        "description": "Ohio City, CO 81237, USA",
        "matched_substrings": [
            {
                "length": 5,
                "offset": 14
            }
        ],
        "place_id": "ChIJJXK28KjiP4cRZNwTV9HTmB0",
        "reference": "ChIJJXK28KjiP4cRZNwTV9HTmB0",
        "structured_formatting": {
           ....
        },
        "terms": [
            {
                "offset": 0,
                "value": "Ohio City"
            },
            ...
        ],
        "types": [
            "postal_code",
            "geocode"
        ]
    },
    {
        "description": "81237 Geranium Avenue, Indio, CA, USA",
        "matched_substrings": [
            {
                "length": 5,
                "offset": 0
            }
        ],
        "place_id": "ChIJWQb2oxH42oAR_9paiGTudYc",
        "reference": "ChIJWQb2oxH42oAR_9paiGTudYc",
        "structured_formatting": {
          ...
        },
        "terms": [
            {
                "offset": 0,
                "value": "81237"
            },
            ...
        ],
        "types": [
            "premise",
            "geocode"
        ]
    },
    {
        "description": "81237 Victoria Lane, La Quinta, CA, USA",
        "matched_substrings": [
            {
                "length": 5,
                "offset": 0
            }
        ],
        "place_id": "ChIJv5gvO0RX2oARay4BYKgPMGA",
        "reference": "ChIJv5gvO0RX2oARay4BYKgPMGA",
        "structured_formatting": {
         ...
        },
        "terms": [
            {
                "offset": 0,
                "value": "81237"
            },
          ...
        ],
        "types": [
            "premise",
            "geocode"
        ]
    }
]

code logic:

import { geocodeByAddress } from 'react-google-places-autocomplete'

 const handleAddressOptionsFilter = async () => {
    try {
      if (!fieldAdrress) {
        setAddressOptions([])
        return
      }

      const formattedResults = data.map((result) => ({
        label: result.description,
        value: result,
      }))

      const rs = await geocodeByAddress(fieldAdrress)

      console.log('NewEvent: ', data, rs)

      setAddressOptions(formattedResults)
    } catch (error) {
      console.error('Error fetching geocode data:', error)
    }
  }

  const handleAddressOnChange = (
    event: React.ChangeEvent<HTMLInputElement>,
  ) => {
    form.setValue('address', event.target.value)
    setValue(event.target.value)
  }

  const handleAddressSelect = (option: Option) => {
    const street = option.value.terms[0].value
    const neighborhood = option.value.terms[1].value
    const city = option.value.terms[2].value
    const state = option.value.terms[3].value
    const country = option.value.terms[4].value

    if (street) form.setValue('address', street as string)
    if (city) form.setValue('city', city as string)
    if (state) form.setValue('state', state as string)
    // if (zip) form.setValue('zip', zip?.long_name as string)
  }

  return (
    <Base hideBg={true} bottomBar={false} allowFullHeight={true}>
      <div className="flex flex-1 mt-[18px] items-center h-full flex-col mb-[50px]">
        <form className="flex flex-col items-center">

              <Input
                type="autocomplete"
                placeholder="Address"
                className="mt-[18px]"
                register={form.register('address')}
                hasError={form.formState.errors.address?.message}
                form={form}
                onCompleteFunction={handleAddressOptionsFilter}
                onCompleteOptions={addressOptions}
                onChange={handleAddressOnChange}
                onSelect={handleAddressSelect}
              />
            

on the index.js I inserted the:

<script src="https://maps.googleapis.com/maps/api/js?key=MY_KEY=places"></script>

I need to use the libraries from react-google-places-autocomplete and react-places-autocomplete because use-places-autocomplete does not return a ZIP

Cookie based router guard doesnt work in Angular17 using canActivateFn

I have a button:

 <button
      type="submit"
      class="bg-blue-600 px-10 text-xl py-3 rounded-md text-white font-semibold"
      routerLink="/user-dashboard/main"
    >

a service:

export class AuthService {
  constructor(private cookieService: CookieService) {}
  url = 'http://localhost:8000/api/v1/login';
  token: string = '';
  isAuthenticated = signal<Boolean>(false);
  changeIsAAuthenticated() {
    this.isAuthenticated.set(false);
    console.log(this.isAuthenticated);
  }
  async login(formObject: any) {
    try {
      const res = await axios.post(`${this.url}`, formObject, {
        withCredentials: true,
      });
      console.log('http cookie set!');
    } catch (error) {
      console.error(error);
    }
  }

  verifyToken = async () => {
    try {
      const res = await axios.get(`${this.url}`, {
        withCredentials: true,
      });
      if (res.status !== 200) return;
      return true;
    } catch (error) {
      console.error(error);
      return false;
    }
  };
}

and a route guard:

export const loginAuthGuard: CanActivateFn = async (route, state) => {
  let authService = inject(AuthService);
  try {
    const isValid = await authService.verifyToken();
    if (!isValid) {
      return false;
    }
    return true;
    console.log('go next!');
  } catch (error) {
    console.error(error);
    return false;
  }
};

and a router:

 path: 'user-dashboard',
    component: UserDashboardComponent,
    title: 'user-dashboard',
    canActivate: [loginAuthGuard],
    children: 

if i enter the correct credentials, theres no console.log. If i enter the bad crenedtials, i go in anyway and theres 401 code in console, but i go in. Why does this guard doesnt work?

Difference of mouse wheel scrolling and touch pad scrolling (firefox)?

I’ve created a parallax background effect in my webpage using the scroll event. I know I shouldn’t do so due to asynchronous scrolling, it’s just for the fun of it. Now, when I use my mouse wheel there is no jumping and jittering but when scrolling with the touch pad there is.
I’ve tried researching but as that is more or less a new “area” I lack the technical therms an know how to find something even remotely answering some of my questions, which are:

Is touch pad scrolling processed asynchronously (firefox) while mouse wheel is not? And is there a way to “look” into the “processing process”? On what “level” does this “processing” occur (in the browser?)? Is there any way to change something from that “process”? Or am I not even looking in the right direction to find the reason in the scrolling difference?

I looked at the website in Chrome, Edge, Opera (all no jittering (or almost none), both with smooth scrolling enabled and disabled) as well as on firefox on another device (jittering on touch pad). So it’s probably browser related.

Direct answers or links to good explanations or even a hint to a word I can research would be nice, thanks.

Appendix (don’t know if that’s relevant): When scrolling with the touch-pad it only jitters while the fingers are on the pad, when the page is scrolling from the “remaining energy”, there is no jittering.

How to implement cookie based route guard using CanActivateFn?

I have a router guard:

import { CanActivateFn } from '@angular/router';
import axios from 'axios';

export const loginAuthGuard: CanActivateFn = (route, state) => {
  return true;
};

and service with verifyToken function:

import { Injectable } from '@angular/core';
import { CookieService } from 'ngx-cookie-service';
import axios from 'axios';
axios.defaults.withCredentials = true;
@Injectable({
  providedIn: 'root',
})
export class AuthService {
  constructor(private cookieService: CookieService) {}
  url = 'http://localhost:8000/api/v1/login';
  token: string = '';

  async login(formObject: any) {
    try {
      const res = await axios.post(`${this.url}`, formObject, {
        withCredentials: true,
      });
      console.log('http cookie set!');
    } catch (error) {
      console.error(error);
    }
  }

  async verifyToken() {
    try {
      const res = await axios.get(`${this.url}`, {
        withCredentials: true,
      });
    } catch (error) {
      console.error(error);
    }
  }
}

If i want to enter a resource, the request is send to the endpoint using validateCookie. If it is true, i can access it, if not, i cant. How to implement it using CanActivateFn?

Issues setting cookies in express and React application from google auth

I’ve encountered an issue while attempting to set cookies following successful login through Google authentication within my Node.js application. This application utilizes Google’s OAuth2 authentication flow to allow users to log in securely via their Google accounts. Upon successful authentication, the application should set cookies containing authentication tokens and user information before redirecting the user to the appropriate page.

The authentication process consists of several steps: when a user logs in using their Google account, they are redirected to Google’s authentication page, where they authenticate and authorize the application to access their information. Upon authorization, Google redirects the user back to the application’s callback URL along with an authentication code.

In the callback function, which handles this redirect, the application exchanges the authentication code for an access token by making a request to Google’s OAuth2 token endpoint (https://oauth2.googleapis.com/token). This token allows the application to retrieve the user’s information, such as email, name, and profile picture, from Google’s servers.

Following the user’s profile creation or update, the application generates JWT (JSON Web Token) authentication tokens for the user and a refresh token for future token refreshing. These tokens are then set as cookies in the HTTP response headers using the Set-Cookie header and the res.cookie() method provided by the Express framework.

Despite following due process and confirming that both the callback and initialization functions are functioning correctly, I’ve encountered an issue where the cookies containing the authentication tokens and user information are not being set before redirecting the user. This issue prevents users from being properly authenticated and accessing protected resources within the application.

Below is a snippet of the callback function responsible for handling the Google authentication:

googleSignUpCallback: RequestHandler = catchAsync(async (req, res, next) => {
    const { code } = req.query;

    const tokenUrl = 'https://oauth2.googleapis.com/token';
    const params: any = {
      code,
      client_id: ENV.GOOGLE_CLIENT_ID,
      client_secret: ENV.GOOGLE_CLIENT_SECRET,
      redirect_uri: ENV.GOOGLE_REDIRECT_URI,
      grant_type: 'authorization_code',
    };

    const response = await axios.post(tokenUrl, querystring.stringify(params), {
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
      },
    });

    const { id_token } = response.data;

    const { email, email_verified, picture, name } = jwt.decode(
      id_token,
    ) as JwtPayload;

    if (!email_verified) {
      return next(new AppError('Google account is not verified', 403));
    }

    const user = await User.findOneAndUpdate(
      { email: email },
      {
        email: email,
        name: name,
        image: picture,
        isEmailConfirmed: true,
      },
      { upsert: true, new: true },
    );

    this.createAndSendToken(user, 201, res, false);
    res.redirect(ENV.FRONTEND_URL);
  });

createAndSendToken = (
    user: any,
    statusCode: number,
    res: Response,
    sendRes: boolean,
  ) => {
    const token = this.signToken({ id: user.id, email: user.email });
    const refreshToken = this.signToken({ id: user.id }, true);
    const cookieExpireTime = ENV.JWT_COOKIE_EXPIRES_IN;

    // check if cookie expire time is available
    if (!cookieExpireTime)
      return new AppError('Cookie expire time not found', 400);

    // set cookie options
    const cookieOptions: ICookieOption = {
      maxAge: 900000,
      httpOnly: false,
      sameSite: 'none',
      secure: false,
    };

    // sends a secure jwt token to the browser that would be sent back to us upon every request
    // if (ENV.NODE_ENV === 'production') cookieOptions.secure = true;

    res.set('Set-Cookie', [token, refreshToken]);
    res.cookie('jwt', token, cookieOptions);
    res.cookie('refreshToken', refreshToken, cookieOptions);

    // this makes the password and active not show in the response it send to the browser
    user.password = undefined;

    if (sendRes) {
      return res.status(statusCode).json({
        status: 'success',
        token,
        refreshToken,
        user,
      });
    }
  };

How does morgan middleware always print the result to console after any other middleware

I am using express library and a logging library called morgan

I am attaching a working code below, to be able to reproduce this in nodejs:

const express = require('express')
const morgan = require('morgan')

const app = express()

app.use(express.json()) //middleware

const customFormat = (tokens, req, res) => {
    let rarr = [
        tokens.method(req, res),
        tokens.url(req, res),
        tokens.status(req, res),
        tokens.res(req, res, 'content-length'), '-',
        tokens['response-time'](req, res), 'ms'
    ]
    return rarr.join(' ')
  } 

app.use(morgan(customFormat))

app.use( (req, res, next) => {

    console.log("hello");
    next();
});

let data = [
    { 
      "id": 1,
      "name": "alpha"
    },
    { 
      "id": 2,
      "name": "beta", 
    },
    { 
      "id": 3,
      "name": "gamma"
    }
]

app.get("/api/persons", (request, response) => {
    response.send(data)
})

Why does in this case “hello” get printed after the output of Morgan middleware, ideally it should be in the order of middleware declaration?

Morgan middleware seems to be waiting for whole request to be completed, and is logged at the very end, does it have something to do with internals of morgan?

I have tried running different order of middleware, using async function inside app.use()

Cannot use relative folder structure in NPM packages.json

Im using the example flask/react app from this github https://github.com/Faruqt/React-Flask

Problem is I have the flask.exe in Project/venv/scripts folder
and the repository is in Project/React-Flask-master fodler

I edited the Prackges.json to

  "scripts": {
    "start": "react-scripts start",
    "temp": "cd ../",
    "start-backend": "cd backend && /../../venv/Scripts/flask run --no-debugger",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },

But no matter what I try, I cannot use the relative folder structure.

I added a “temp” lien that is supposed to go one folder up, and even that doesnt work

(venv) C:CodeProjectReact-Flask-master>npm run temp

> [email protected] temp
> cd ../


(venv) C:CodeProjectReact-Flask-master>

And

(venv) C:CodeaicodeAIbotscatgptReact-Flask-master>npm run start-backend

> [email protected] start-backend
> cd backend && /../../venv/Scripts/flask run --no-debugger

The system cannot find the path specified.

(venv) C:CodeaicodeAIbotscatgptReact-Flask-master>

I tried using “../../” and “/../../”

How to load picture in canvas only when nothing is loaded (js)

I have js function which runs every 40msecs (0.04sec) for animation purposes. In the function as you will see in the code below I load a picture in the html canvas elem. Obviously sometimes the picture is delayed to load the result is a flickering picture.The question is how to avoid that, probably to check if the picture has completed loading and then move it around by dx

Html <canvas id="graph"   style="border: 1px solid #0a2b02; position: absolute; z-index: 1;"></canvas>

js

    if (t == null){t  = setInterval(DrawBase, dt*1000;dx)}
    else          {terminatet();                      };
function DrawBase(dx){ 
img.onload = () => {context2.drawImage(img,0.1*canWidth+dx,0.1*canWidth,0.8*canWidth ,0.9*canWidth); };
img.src = "./img/oilRig.png";
}}

I tried to use if(img.complete){} and other like !img.loading but doesn’t seem to work

Optimizing Google Sheets Script for Adding Dropdowns and Formulas to Multiple Rows

I’m working on a Google Sheets script where I need to dynamically update a sheet with dropdown menus and apply specific formulas to rows based on certain conditions. My current approach involves iterating over an array of objects (maintainedProcesses), setting formulas for “Destination Unit” and “Responsible Manager” columns if they are not already set, and then updating the sheet with these changes. Additionally, I create dropdown menus for several columns using validation rules based on data fetched from another sheet (“Data Validations”).

Here’s the relevant portion of my code (simplified and generic for clarity):

maintainedProcesses.forEach((process, index) => {
  const rowIndex = index + 2; // Adjust for header row
  if (!process['Destination Unit']) {
    process['Destination Unit'] = `=IFERROR(VLOOKUP(C:C;'Data Validations'!A:B,2,0);"")`;
  }
  if (!process['Responsible Manager']) {
    process['Responsible Manager'] = `=IFERROR(IF(E${rowIndex}="Screening";AA${rowIndex};"");"")`;
  }
});

await sheetManager.updateSheet(maintainedProcesses);

// Fetch validation data
const validationData = await sheetManagerValidations.readToJson();
const judicialActions = [...new Set(validationData.map(item => item['Judicial Action']))];
const subjects = [...new Set(validationData.map(item => item['Subject']))];
// etc. for other dropdowns

// Set dropdown menus
await sheetManager.setDropdownMenu(judicialActions, 'Judicial Action');
await sheetManager.setDropdownMenu(subjects, 'Subject');
// etc. for other dropdowns

The setDropdownMenu method is defined as follows:

async setDropdownMenuOld(options, columnName) {
  // Validation and setup omitted for brevity
  const rule = SpreadsheetApp.newDataValidation().requireValueInList(options).build();
  this.sheet.getRange(firstLine + 1, columnId + 1, lastLine - 1, 1).setDataValidation(rule);
}

While this code works, the process of adding each dropdown menu sequentially feels slow, especially with a large number of rows or when multiple dropdowns are involved. I’m looking for ways to optimize this process, ideally allowing for faster execution and possibly adding all dropdowns in a more efficient manner.

Is there a better approach or best practice for applying these kinds of updates to a Google Sheets document via Apps Script, particularly for reducing the time it takes to add dropdowns and formulas across many rows?

Comments:

I’m particularly interested in any strategies that can batch these operations or make them more efficient.
My environment is Google Apps Script with access to the Google Sheets API.
Thank you for your insights!

Change box color for Cookie Script

I want to change the “Got it!” box color in this cookie script. I have changed all other colors.
I think the color is in the.js
Is there css code I can add to change that yellow box to another color?
By the way this is Blogger.

   <script type="text/javascript" id="cookieinfo"
src="//cookieinfoscript.com/js/cookieinfo.min.js"
data-bg="#645862"
data-fg="#FFFFFF"
data-link="#F1D600"
data-cookie="CookieInfoScript"
data-text-align="left"
   data-close-text="Got it!">
   </script>