Fixed column header in datatable ignoring background color

I have a table that shows data in two different units across 12 months for 4 different channels. I need that the first column, which contains the channel information, stays in place when I scroll to the right, so I can see what information I’m looking at. However, after I fixate the first column, it completely ignores the background-color argument, but not the color, which makes it completely white. I need it to have the same color as the rest of the header.

This is how it looks

how it looks

This is how I need it to be

what i need

This is my code

fix_doubled_months <- function(month){
  
  month_1 <- str_extract(month, "[0-9]{6}")
  
  month_final <- character(length(month))
  
  month_final[str_detect(month, "dollar")] <- month_1[str_detect(month, "dollar")]
  month_final[str_detect(month, "lbs")] <- paste0(" ", month_1[str_detect(month, "lbs")], " ")
  
  return(month_final)
  
}

distribution_summary <- tibble(
  date = rep(seq(from = as.Date("2023-01-01"), length.out = 12, by = "+1 month"), times = 8),
  channels = rep(rep(paste0("Channel ", 1:4), each = 12), 2),
  value = round(rnorm(96, 500, 100), 2),
  unit = rep(c("lbs", "dollars"), each = 48)
) |> 
  mutate(date = format(date, format = "%Y%m"),
         date_unit = paste0(date, "_", unit)) |> 
  select(-c(date, unit)) |> 
  pivot_wider(names_from = date_unit, values_from = value) |> 
  rename_at(vars(matches("^[0-9]{6}_")), fix_doubled_months)

container_summary <- withTags(table(
  class = "display",
  thead(
    tr(
      th(rowspan = 1, ""),
      th(colspan = (length(distribution_summary) - 2)/2, "Lbs"),
      th(colspan = (length(distribution_summary) - 2)/2, "$"),
    ),
    tr(
      lapply(names(distribution_summary), th)
    )
  )
))

distribution_summary |> 
  datatable(
    rownames = FALSE,
    extensions = "FixedColumns",
    container = container_summary,
    options = list(fixedColumns = list(leftColumns = 1),
                   scrollX = TRUE,
                   scrollY = FALSE,
                   dom = "t",
                   initComplete = JS(
                     "function(settings, json) {",
                     "$(this.api().table().header()).css({'background-color': '#4F2170', 'color': '#FFFFFF', 'white-space': 'nowrap'});",
                     "}"
                   ))) |>
  formatStyle(names(distribution_summary), "white-space" = "nowrap") |>
  formatStyle("channels", backgroundColor = "#4F2170", color = "#FFFFFF", fontWeight = "bold")

Does spyOn(console, ‘log’) check all the output? Did I find a bug?

In my console, I see this:

  console.log
    27 (>$-1 not safe, so NOT) buying 0.6573442493668066 XBTUSD at 62777 with leverage none to close at 63718.7 as 1747062777

My test code says:

await bot.report();
expect(consoleSpy).toHaveBeenCalledWith(
    expect.stringMatching(/buying 0.6573442493668066 XBTUSD at 62777/));

Jest test output says:

    expect(jest.fn()).toHaveBeenCalledWith(...expected)

Expected: StringMatching /buying 0.6573442493668066 XBTUSD at 62777/
Received
       1: ...

I run the test using npm test which refers to the line in my package.json that says:

"scripts": {
  "test": "node --experimental-vm-modules node_modules/jest/bin/jest --verbose",

My best theory about why this happens is that while Jest is actually spying on console output, there is something about Node.js and/or Jest that prevents it from seeing this line. In the “Jest output” section above I only listed “1: …” but there are three calls listed and they do reflect previous console.log output. I didn’t want to have to count how many outputs appear before what I’m looking for, but maybe toHaveBeenCalledWith only watches the first few logs. I’ll keep trying to figure this out, but if someone knows why it isn’t seeing the output that is plain to me reading the console output, please let me know!

GIRA Homeserver using xxAPI2 (Javascript issue)

I use a GIRA Homeserver for home automation.
To expand the visual presentation I use the xxAPI2 library, full “plug-in” can be found on Github.
One of the visual controls used by xxAPI2 is the NoUiSlider from refreshless.com
in the present xxapi2 version (2.044) the NOuislider version 7.xx is in use.
I’m working on an update to 15.x of the nouislider.
In the time from 7.xx to 15.xx the create call has been changed.
I Think under the hood some more …
Anyway I use the new call.
for example:

oarg.item.xxapi.slider = document.getElementById(oarg.item.uid);
noUiSlider.create(oarg.item.xxapi.slider, oarg.item.xxapi.slider_options);

Everything works fine so far, I can jump back and forward between pages etc.
But when I push the refresh button. Thinks go wrong….
When I want to display the slider again, the element can not be found.
I build in a test to check if the DOM is ready, even then getelementbyid returns null.
Even a time-delay of 5 second (should be enough to load) does not solve the problem.
When I close the tab, and open it again everything is fine again….

Any ideas on how to solve this problem.

Regards,

G.

Time Equation Ideas

I’m trying to create an equation for a time calculation but can’t figure out what I need to do. I have a time in minutes that is getting multiplied by .005 which that number is then subtracted by the time to create a new time number. I then need this to repeat x amount of times. Here is the excel version of it but I don’t know how to write it in code to make it work once you input the time number.

1

What I currently have is this:

var time = document.getElementById("buildTime").value;
var x = time * .005;

const timeReduction = () => {
  time * .005 = -x + time;
}

Rails 8: ‘import call expects one or two arguments’ How do I import this JS correctly?

I am trying to get my head around how to use javascript inside a Rails app. At the same time, I am following this tutorial.

I have placed the menu bar inside the <body> tag of application.html.erb. Right at the end, I link to burger-menu.js

#...
             </ul>
            </nav>
          </burger-menu>
        </div>
      </div>
    </header>

    <main id="main-content" tabindex="-1" class="wrapper">
      <%= yield %>
    </main>

    <%= javascript_include_tag "burger-menu.js", type: "module" %>
  </body>
</html>

burger-menu.js is located in app/javascript. I’ve wrapped it inside an event listener so that it works with turbo. Now, this script needs to import getFocusableElements.

import getFocusableElements from "get-focusable-elements";

document.addEventListener("turbo:load", () => {
  class BurgerMenu extends HTMLElement {
    constructor() {
      super();

      const self = this;

      #...

});

I’ve copied the JS from the tutorial into app/javascript/get-focusable-elements.js and have pinned it in importmap.rb

# Pin npm packages by running ./bin/importmap

pin "application"
pin "@hotwired/turbo-rails", to: "turbo.min.js"
pin "@hotwired/stimulus", to: "stimulus.min.js"
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
pin_all_from "app/javascript/controllers", under: "controllers"
pin "get-focusable-elements", to: "get-focusable-elements.js"

The entirety of the JS is this:


/**
 * Returns back a NodeList of focusable elements
 * that exist within the passed parnt HTMLElement
 *
 * @param {HTMLElement} parent HTML element
 * @returns {NodeList} The focusable elements that we can find
 */
export default parent => {
  if (!parent) {
    console.warn('You need to pass a parent HTMLElement');
    return [];
  }

  return parent.querySelectorAll(
    'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"]):not([disabled]), details:not([disabled]), summary:not(:disabled)'
  );
};

All good? No. I get the following error in the browser: SyntaxError: Unexpected identifier ‘getFocusableElements’. import call expects one or two arguments.

It points to this line: import getFocusableElements from "get-focusable-elements"; in burger-menu.js

I expect I’ve failed to do something obvious. Why won’t my JS work? Why the error?

Using Object property keys as Flag keys

I’m working on a module for FoundryVTT and I have an object inside a class in which I store all my flags in the form of strings. It looks like this:

static FLAGS = {
    ACTOR_FLAGS: {
        mana_system_flag: "mana_system",
        mana_system: {
            mana_flag: "mana_system.mana",
            mana: {
                current: "mana_system.mana.current",
                max: "mana_system.mana.max",
            }
        }
    },
}

And I can get a flag simply by calling properties with a _flag prefix.

Seeing as my flags get even more complicated and deeply nested, it occured to my that it would be much easier if I could simply get the flag by calling the flags like so:

FLAGS.ACTOR_FLAGS.mana_system instead of FLAGS.ACTOR_FLAGS.mana_system_flag

This would mean that I could avoid adding extra properties to my object. I tried doing this with a Proxy but it does not seem to return the desired result.

const FLAGS = {
  ACTOR_FLAGS: {
    mana_system: {
      mana: {
        current: 0,
        max: 0,
      }
    }
  }
}

let p = new Proxy(FLAGS, {
    get(target, prop) {

      if (typeof target[prop] === 'object' && target[prop] !== null) {
        return target[prop];
      }

      return String(prop);
    }
  });

console.log(p.ACTOR_FLAGS.mana_system.mana); //desired output: mana_system.mana

However, the actual output I get is this:

 {
   mana_system: {
     mana: { ... }
   }
 }

Are there any alternative methods of achieving this functionality that I have overlooked?
If not, then how can I make it so that my code detects certain properties such as ACTOR_FLAGS and returns any requested child properties as a string so that:

p.ACTOR_FLAGS //undefined
p.ACTOR_FLAGS.mana_system //"mana_system"
p.ACTOR_FLAGS.mana_system.mana //"mana_system.mana"
p.ACTOR_FLAGS.mana_system.power //undefined

Thank you reading my question, and for your help.

How can I properly add an event listener to a series of asynchronous functions in Javascript/JQuery?

I’m struggling with the order of operations with asynchronous functions and event listeners in Javascript. I have a script with a function that fetches a list of publicly-traded companies from an API endpoint (‘api/company_list’). After the data is returned, it dynamically updates a dropdown menu with the list of company symbols and names, and also displays the name of the first company in the data array on the webpage. Finally, it passes that first company’s symbol as a template literal to another URL in order to fetch that company’s price data from a second API endpoint and display it on a chart.

I can accomplish the above by simply grabbing the first returned company from the company list data using it’s index (data[0].symbol) when the page loads.

But what I need to know is – how do I incorporate an event listener so that when a different company is selected from the dropdown, it updates both the company name on the webpage and passes the newly-selected symbol to the second URL (‘api/price_data’) to select the chart data?

And can I do this all in the same script?

I can do one script that runs the code below when the page loads and a second script that runs the same code encapsulated inside of a function that runs when the dropdown selection changes, but this seemed highly duplicative. There’s got to be a way to streamline it.

I’ve tried adding an onChange event listener for my dropdown (“mySelect”) in the code below, but since the dropdown is populated dynamically as part of a promise, the data isn’t yet available to use when I tried to grab the newly-selected value and pass it to both the page and the second URL. Clearly I’m misunderstanding the flow async functions.

I feel like this is probably a fairly simple fix, but so far I’ve been unable to find a solution. Thanks in advance for your help. I’d be happy to provide additional information or answer any questions.

function getData(url) {
    return fetch(url)
        .then(response => {
            if(!response.ok) {
                throw new Error('Bad Network Request');
            }
            return response.json();
        })
        .catch(error => {
            console.error('Fetch error:', error);
            throw error;
        });
}

//fetch the list of companies from an API endpoint and dynamically populate the dropdown list:
getData('/api/company_list')
        .then(function myFunction(data) {
        let option = '';            
        for (let i = 0; i < data.length; i++) {
            option += '<option value="' + data[i].symbol + '">' + data[i].stock_rank + ' - ' + data[i].company_name + '  (' + data[i].symbol + ')' + '</option>';
        }
        
        const inputElement = $("#mySelect");
        inputElement.append(option);
        
    
        let firstCompany = data[0].symbol;
        
        $("company").html(data[0].company_name);
        
        const priceUrl = `/api/price_data/?symbol=${firstCompany}`;
        
        getData(priceUrl)
            .then(function myFunction(priceData) {
                
                //add the price data to a chart
            });
});

How can I create zoom functionality for Sankey Networks using networkD3 and htmlwidgets?

As i the title says. I would like to zoom interactively on Sankey networks, as it is for example possible for Force networks. I assume that it would work by adding a htmlwidgets::onRender() call, containing JS().

I would like to do so via a wrapper around sankeyNetwork() as i have done (badly) with a custom hover tooltip. When i try to use this aproach for zooming i get a lot of uncaught errors; I am a JS noob.

My code is a mess and my question is so general that I belive that no reprex is necessary. If it is necessary, please ask.

Example of (bad) wrapper:

sankeyNetworkWithAge <- function(Links, Nodes, Source, Target, Value, 
                                 NodeID, NodeGroup = NodeID, 
                                 LinkGroup = NULL, ...) {
  # Print debug information
  print("Creating base widget...")
  
  # Create the base widget with tryCatch to catch any errors
  widget <- tryCatch({
    sankeyNetwork(
      Links = Links,
      Nodes = Nodes,
      Source = Source,
      Target = Target,
      Value = Value,
      NodeID = NodeID,
      NodeGroup = NodeGroup,
      LinkGroup = LinkGroup,
      ...
    )
  }, error = function(e) {
    print(paste("Error creating widget:", e$message))
    return(NULL)
  })
  
  # Check if widget creation was successful
  if (is.null(widget)) {
    stop("Failed to create base widget")
  }
  
  print("Adding custom data...")
  
  # Add custom data
  widget$x$options$median_age <- Links$median_age
  
  print("Adding custom JavaScript...")
  
  # Add custom JavaScript
  widget <- htmlwidgets::onRender(
    widget,
    '
        function(el, x) {
            console.log("Running custom JavaScript");
            var medianAges = x.options.median_age;
            
            d3.select(el)
                .selectAll(".link")
                .each(function(d, i) {
                    d.median_age = medianAges[i];
                })
                .select("title")
                .text(function(d) {
                    return d.source.name + " → " + d.target.name + "\n" +
                           d.value + " Candidates\n" +
                           "Median Age: " + d.median_age;
                });
        }
        '
  )
  
  print("Returning widget...")
  return(widget)
}

Is there a way to have a single page change by a link in html? [closed]

I want to have a page called character_template.html and I want this page to change depending on a link clicked earlier on a page called characters.html, but I don’t know how. I have looked into sql and php but it is like looking at something from another planet. Is there any way to do this maybe with just html, css, and js?

I have tired sql and php but it doesn’t seem to work. Note: I am using an acer computer chromeOS version 130.0.6723.126.

Device information from web browser using navigator.userAgent [closed]

I came across the following thread:
Detect if device is ios

In my specific use case, I wanted to detect iOS devices on Microsoft Edge. I noticed that the userAgent (alert(window.navigator.userAgent)) property in Edge clearly indicates if the device is an iPad.
enter image description here
I’m curious whether this behavior is a recent addition by Edge or if it’s related to changes in the latest versions of iOS.

Next Auth v5 logout if any API is throwing 401 error

I am using Next 14 and Next Auth v5 for authentication using credentials provider. I want to handle a case where if an API throws a 401 error from the backend, then logout the user in the background and refresh the page.

I am handling all the API calls within a single util file and using it across the application.

Apiclient.js

import { getSession } from "@/lib/utils";

async function apiClient({
  path,
  options = {},
  headers = {},
  tags,
  cache = "force-cache",
}) {
  const session = await getSession();
  const token = session?.user?.accessToken;
  console.log(token);
  try {
    // Merge default and user options
    const mergedOptions = {
      headers: {
        "Content-Type": "application/json",
        ...(token && { Authorization: `Bearer ${token}` }),
        isGuest: token ? false : true,
        ...headers,
      },
      ...options,
      cache: cache,
      ...(tags && { next: { tags: [tags] } }),
    };

    // Trigger API call
    const response = await fetch(path, mergedOptions);
  
    const data = await response.json();
    return data;
  } catch (error) {
    console.error(error);
    /* throw new Error(
      `Please check if your server is running and you set all the required tokens.`
    ); */
  }
}

export default apiClient;

Below is one of the example where I am using this client with server action functions.

"use server";
import Link from "next/link";
import { cookies } from "next/headers";
import {
  NavBar,
  Logo,
  UserDropdown,
  NavMobile,
  CategoryMenu,
} from "@/components/common";
import { Search, LocaleSwitcher } from "@/components/ui";
import { CartIcon, MiniCart } from "@/components/cart";
import { getUserSessionServer } from "@/lib/utils/getUserSessionServer";
import { getCart } from "@/framework/server-actions/cart";
import { getNavigation } from "@/framework/server-actions/menu";
import {
  WishlistProducts,
  RefreshUserSession,
  HeaderWrapper,
} from "@/components/common";

const Header = async () => {
  const cartId = cookies().get("cartId");
  const sessionPromise = await getUserSessionServer();
  const cartPromise = cartId && (await getCart());
  const menuPromise = await getNavigation();

  const [session, cart, menu] = await Promise.all([
    sessionPromise,
    cartPromise,
    menuPromise,
  ]);

  return (
    <HeaderWrapper>
      <div className="md:relative">
        <div className="md:max-w-screen-xl mx-auto">
          <div className="flex items-center justify-between">
            <div className="hidden sm:block">
              {/* TODO: Move below menu code to a separate component */}
              <ul className="space-x-8 text-white text-sm sm:flex rtl:space-x-reverse">
                <li>
                  <CategoryMenu links={menu} />
                </li>
                <li>
                  <Link href={"/cms/about-us"}>About</Link>
                </li>
                <li>
                  <Link href={"/contact-us"}>Contact</Link>
                </li>
              </ul>
            </div>
            <div className="md:absolute md:start-1/2 md:-translate-x-1/2 rtl:md:translate-x-1/2 top-0">
              <Logo />
            </div>
            <div className="">
              <div className="flex items-center">
                <Search />
                <LocaleSwitcher />
                <CartIcon cartTotalsInfo={cart} />
                <UserDropdown session={session} />
                <NavMobile links={menu} />
              </div>
            </div>
          </div>
        </div>
      </div>

      {/*
        <NavBar links={menu} />
        */}

      <MiniCart
        session={session}
        cartTotalsInfo={cart}
        WishlistProducts={
          <WishlistProducts
            session={session}
            className="embla__product__minicart embla__product__container__minicart"
          />
        }
      />
      <RefreshUserSession />
    </HeaderWrapper>
  );
};

export default Header;

I have tried adding this to my apiClient and handling the logout on client side

if (response.status === 401 || response.status === 403) {
      console.log("response.status", response.status);
      //throw new Error("Unauthorized request. Logging out.");
      return "unauthorized";
    }
"use client";
import { useContext, useCallback } from "react";
import { usePathname } from "next/navigation";
import { Link } from "@/i18n/routing";
import { IconBagWhite } from "@/assets";
import { CartContext } from "@/contexts/CartContext";
import { logout } from "@/framework/server-actions/account/access";

const CartIcon = ({ cartTotalsInfo }) => {
  const isCheckout = usePathname() === "/checkout";
  const { setShowMiniCart } = useContext(CartContext);
  const { itemsQuantity } = cartTotalsInfo || {};

  const handleOpenMiniCart = useCallback(
    () => setShowMiniCart(true),
    [setShowMiniCart]
  );

  if (cartTotalsInfo === "unauthorized") {
    console.log("cartTotalsInfo is", cartTotalsInfo);
    logout();
    console.log("logged out, router refresh", cartTotalsInfo);
  }

  return (
    <>
      {isCheckout ? (
        <Link href="/cart" className="block relative">
          <IconBagWhite />
          {itemsQuantity > 0 && (
            <div className="absolute -top-2 h-[20px] w-[20px] rounded-full bg-red-600 -end-1 ">
              <div className="flex h-full items-center justify-center text-[11px] font-bold text-white">
                {itemsQuantity}
              </div>
            </div>
          )}
        </Link>
      ) : (
        <>
          <button
            className="relative items-center px-2 hidden sm:flex"
            onClick={handleOpenMiniCart}
          >
            <IconBagWhite />
            {itemsQuantity > 0 && (
              <div className="absolute -top-2 h-[20px] w-[20px] rounded-full bg-red-600 -end-1 ">
                <div className="flex h-full items-center justify-center text-[11px] font-bold text-white">
                  {itemsQuantity}
                </div>
              </div>
            )}
          </button>
          <Link href="/cart" className="block relative sm:hidden">
            <IconBagWhite />
            {itemsQuantity > 0 && (
              <div className="absolute -top-2 h-[20px] w-[20px] rounded-full bg-red-600 -end-1 ">
                <div className="flex h-full items-center justify-center text-[11px] font-bold text-white">
                  {itemsQuantity}
                </div>
              </div>
            )}
          </Link>
        </>
      )}
    </>
  );
};

export default CartIcon;

After logout I want to fetch all the data again

How can I pass a token from my app to a third party app

Im trying to build an app that will run on a third party clients’ apps, injected by a script.

This app should communicate with our BE, but I don’t know what is the best approach to pass token’s data from My app to third party app.

The flow goes like this:

  1. Client opens a form inside my app and do something
  2. he wants to show how the something affects his app, so he provides inside an input the url of his app
  3. he clicks on a button and then his app will be opened in a new tab. In this point I ask to be authenticated to our BE and I don’t know how to do that.

I thought about postMessage process but I wanted to know if there is any other suggested approach.

Thanks in advance

I tried to put the token inside the url of the script that I inject in the third party app, but Security department is not allow me to continue with this approach so I have to find something else

Use both ‘textContent’ and ‘setAttribute’ without declaring a variable

This is of course a simple question, but I wasn’t lucky enough to figure it out myself.

The following example works fine:

const el = document.getElementById('greeting')
el.textContent = 'hello, world!'
el.setAttribute('style', 'background-color: red; color: white;')

But here there is an error:

document.getElementById('greeting')
    .textContent = 'hello, world!'
    .setAttribute('style', 'background-color: red; color: white;')

Why?

How could I check if the URL/route in the browser is related to the path mask?

My goal is to try to create an ID rule that allows you to check in the HTML where it is within a category (id), it must mark the menu, this id is replicated for several different routes, but it has to validate the ID and the route with the URL that is being accessed, it being the same URL that is within the routes file and having the same ID, the menu that has the type that I pass as ID, it will return true.

When accessing the link: page/id/1234

I need to identify data => id => 'page-data-x'

In my routes module I have this structure:

{
    path: 'page',
    children: [
 {
        path: 'id/:id',
        component: PageComponent,
        canActivate: [AuthGuard],
        data: {
            id: 'page-data-x',
            
        }
    },
     {
        path: 'category/:id/id/:id',
        component: PageComponent,
        canActivate: [AuthGuard],
        data: {
            id: 'page-data-y',
            
        }
    }]
}

Inside the class I have a constructor that receives the ID and the current URL:

 contentID: any; 
 currentURL: string;

 constructor(
        private router: Router, 
        private route: ActivatedRoute) {
        //ACCESS to ID
        this.contentID = this.route.snapshot.data?.id;
        //Current route
        this.currentURL = this.route.snapshot.pathFromRoot[0]['_routerState'].url
        
 }

These are my failed attempts:

isActiveRoute(type: string): boolean {
        // Gera a rota esperada em formato string
        const targetRoute = this.routerLink(type);
        const targetRouteString = Array.isArray(targetRoute) ? targetRoute
        .filter(segment => typeof segment !== 'object')
        .join('/')
        .replace(////gi, '/') : targetRoute;

        const currentRoute = this.router.url.split('?')[0].split(';')[0];

        const children = (this.route.snapshot.routeConfig?.children || []).filter(
                (child) => child.data?.id
        );

        const isMatchingPath = (child: any): boolean => {
                if(child.path) {
                    const regexPattern = '^' + child.path.replace(/:[^/]+/g, '[^/]+') + '$';
                    const regex = new RegExp(regexPattern);
                    return regex.test(currentRoute) && child.data?.id === type;
                }
            };


        const matchingChild = children.find(child => isMatchingPath(child));

        if (matchingChild) {
                return true;
        }


        const routeDataId = this.route.snapshot.data?.id;
        const routePath = this.route.snapshot.routeConfig?.path;

        if (routeDataId === type && routePath && currentRoute.includes(routePath)) {
           return true;
        }

        return currentRoute.includes(targetRouteString);

}



 routerLink(type: string) {

        this.queryParams = this.routerParams[type];

        switch (type) {
          case 'dashboard':
            return ['page', 'dasnboard'];
         ...
        }
}
      

Encode searchParams [closed]

Currently I am working on a beginner project that requires us to have a search input that would filter an array onChange – when the user writes a keyword into the search input field, only the items that have those keywords in their names are being mapped.
Using react-input-mask I have restricted the field to not contain certain characters (e.g. zalgo text). The problem is that the restricted characters can still be entered into url after the “?search=” part of it and page crashes in certain instances. Is there a way to prevent special characters from slipping into the webpage like this? The input on the page is sanitized, but the restrictions do not apply to the URL that.