Using twig path within Javascript – twig ignores raw filter

first off I am well aware that twig is server- and JavaScript is clientside.
Still I would like to use twigs path() function within JavaScript and inject an Javascript variable as a RAW-String, but it gets escaped all the time and I am curious why the raw-filter does not apply?

I do have the following Javascript within my twig file (simplified):

// file.html.twig
<script>
print '<a href="{{ path('article_edit', {id: ("' + full['id'] + '"|raw)}) }}">Linktext</a>';
</script>

As the path for article_edit is /articles/{id}/edit, my expected serverside-output would be:

// Expected twig-render
<script>
print '<a href="/articles/' + full['id'] + '/edit">Linktext</a>';
</script>

Which would be rendered on clientside to <a href="/articles/1/edit">Linktext</a>

But still, even though I used the |raw filter, twig does escape the string. Resulting in the following output:

// Actual twig-render
<script>
print '<a href="/articles/%27%20+%20full%5B%27id%27%5D%20+%20%27/edit">Linktext</a>';
</script>

Why is twig ignoring the filter and does escape the JavaScript? Isn’t that what that filter is for, so I could built up an dynamic Javascript code within twig?

Also I can not build up the id within PHP as the id comes from another AJAX call. I currently use the hardcoded path as a workaround, but I am curious why the filter is ignored…

Thanks for any help

How to remove decimal from JavaScript function return

I was hoping someone could guide me maybe it can’t be done? I have a function and I’m trying to remove the decimal (I want a whole number return)

function studentsPerAdmin(students, teachers, helpers) {
  const average = students / (teachers + helpers);
  if (average > 10) {
    console.log(`There are on average ${average} students for each educator.`);
  } else {
    console.log('Unfortunately this class will be cancelled due to not having enough students enrolled.');
  }
  return average
}


studentsPerAdmin(41, 1, 2)

I’ve tried using the math functions such as math.round() but I’m still learning and I don’t think I’m using it correctly. So far the result is

There are on average 13.666666666666666 students for each educator.

How to enable a button when every checkbox in a table is checked

I need a button to be enabled when all the checkboxes in a table are checked and disabled otherwise.

Outer component with button:

import Box from "@mui/system/Box";
import Stack from "@mui/system/Stack";
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
import { useState } from "react";
import HRMButton from "../Button/HRMButton";
import ToDoTable from "./ToDoTable";
import { fonts } from "../../Styles";

export default function OnboardingTasks({style}) {
    const tasks = [
        {
            name: 'Discuss and set your first 30/60/90-day goals with your manager',
            done: false
        },
        {
            name: 'Complete personal info & documents on Bluewave HRM',
            done: false
        },
        {
            name: 'Sign and submit essential documents',
            done: false
        }
    ];

    const [allTasksComplete, setAllTasksComplete] = useState(false);

    function checkTasks(tasks) {
        return tasks.every((task) => task.done);
    }

    return (
        <Box sx={{...{
            border: "1px solid #EBEBEB",
            borderRadius: "10px",
            minWidth: "1003px",
            paddingX: "113px",
            paddingY: "44px",
            fontFamily: fonts.fontFamily
        }, ...style}}>
            <h4 style={{textAlign: "center", marginTop: 0}}>Complete your to-do items</h4>
            <p style={{textAlign: "center", marginBottom: "50px"}}>
                You may discuss your to-dos with your manager
            </p>
            <ToDoTable 
                tasks={tasks} 
                onChange={() => setAllTasksComplete(checkTasks(tasks))} 
                style={{marginBottom: "50px"}}
            />
            <Stack direction="row" alignContent="center" justifyContent="space-between">
                <HRMButton mode="secondaryB" startIcon={<ArrowBackIcon />}>Previous</HRMButton>
                //This button needs to be enabled
                <HRMButton mode="primary" enabled={allTasksComplete}>Save and next</HRMButton>
            </Stack>
        </Box>
    );
};

Table component:

import TableContainer from "@mui/material/TableContainer";
import Table from "@mui/material/Table";
import TableHead from "@mui/material/TableHead";
import TableBody from "@mui/material/TableBody";
import TableRow from "@mui/material/TableRow";
import TableCell from "@mui/material/TableCell";
import { styled } from "@mui/system";
import PropTypes from "prop-types";
import Checkbox from "../Checkbox/Checkbox";
import { fonts, colors } from "../../Styles";

export default function ToDoTable({tasks, onChange, style}) {
    //Custom style elements
    const TableHeaderCell = styled(TableCell)({
        color: colors.darkGrey,
        paddingTop: "10px",
        paddingBottom: "10px"
    });

    function handleChange(e, index, value) {
        console.log(tasks);
        tasks[index].done = value;
        onChange();
    }

    return (
        <TableContainer sx={{...{
            minWidth: "1003px",
            fontFamily: fonts.fontFamily
        }, ...style}}>
            <Table>
                <TableHead>
                    <TableRow sx={{backgroundColor: "#F9FAFB"}}>
                        <TableHeaderCell>
                            <b style={{color: colors.grey}}>To-Do</b>
                        </TableHeaderCell>
                        <TableHeaderCell align="right">
                            <b style={{color: colors.grey}}>Done</b>
                        </TableHeaderCell>
                    </TableRow>
                </TableHead>
                <TableBody>
                    {tasks.map((task, index) => (
                        <TableRow>
                            <TableCell>
                                {task.name}
                            </TableCell>
                            <TableCell align="right">
                                <Checkbox
                                    type="checkbox"
                                    id={`${task.name}-done`}
                                    name={`${task.name}-done`}
                                    value={`${task.name}-done`}
                                    size="large"
                                    onChange={(e) => handleChange(e, index, !task.done)}
                                />
                            </TableCell>
                        </TableRow>
                    ))}
                </TableBody>
            </Table>
        </TableContainer>
    );
};

When using React useState like in the code example given, the entire OnboardingTasks component rerenders every time the AllTasksComplete state is changed which resets the status of all the tasks back to false. When I use React useRef the button is not rerendered and doesn’t react to the change in AllTasksComplete.

How do I enable the button when all the checkboxes are checked while retaining the status of the tasks variable?

Buttons and checkboxes in this example are custom variations from MUI. If you need to run this code in your local machine, leave a comment and I’ll provide the code.

Clicking on a specific button by javascript – Auto refresh Plus extensions

I use the Auto Refresh Plus extension to refresh the Google Chrome page. This extension has a function called automatic click, which looks for the button we defined for it after every page refresh, and if it finds that button, it clicks on that button. In the settings of this extension, there is a function that we can use Java code Inject the script – after the initial click I need to click on another button that appears. But I don’t know how to write the js code to click on the second button.

Custom Scripts

Please help me write this code. This is the button that appears after the first click

Ticket

HTML canvas print is slow for large data:image/png but not numerous small ones

I have been stuck on this rendering issue for my video game for a few days now and I’m at a complete loss … I have terrain which is defined by a list of vertices, a center and a height. These terrain assets are pre-compiled to fill the areas and crop/transform the textures then convert them to a data:image/png which is stored then printed on the fly.

The problem is is that the walls you see have been exaggerated to includes almost 500 vertices which means 500 individual data images for just the walls. If I print JUST these walls (image 2) the time delay on my print loop is <= 1ms. However if I include the print of the terrain tops (image 1), which there are only about 10 of, the time delay shoots up to 25-40ms!!
At first I thought it may be related to the area that the data image takes up BUT I’ve created a terrain object that covers the ENTIRE screen with just its wall (image 3) and the runtime is still <= 1ms per frame o.O. I am completely lost. I’ve removed almost everything in the display driver and it still remains true that the runtime only goes up when the terrain tops are included … is it because the terrain top is a complex polygon while walls are always simpleish?? How do I work around it

Note: the frame drop occurs even when there are a reasonable number of walls as well, like 30 walls and 5 tops. Also crazy enough, the shadow stack and its associated clip / restore for shadows near the edge of terrain plays NO part in this delay. Removed or not the outcome of this scenario remains the same. UGHHH

The loop is as simple as…

let time = Date.now();

entities.map_print.forEach((V, index) => {
    if (V.type == 'terrain_wall') {
        this.printTerrainWall(V, ctx, half_width, half_height, computed_stash.camera_position);
    } else if (V.type == 'terrain_ground') {
        this.printTerrainTop(V, ctx, half_width, half_height, computed_stash.camera_position, computed_stash.shadow_stack[V.index_ref_to_map]);
    }
});

console.log(Date.now() - time);


printTerrainWall(V, ctx, half_width, half_height, camera_position) {
        // draw wall texture
        ctx.drawImage(
            V.src,
            precise(half_width + V.position.x - camera_position.x + V.first_vertice[0] - V.offset.x),
            precise(half_height - ((V.position.z - camera_position.z) + (V.position.y - camera_position.y) + V.first_vertice[1]) - V.offset.y)
        );
    }

printTerrainTop(V, ctx, half_width, half_height, camera_position, shadow_stack) {
        
        // draw top texture
        ctx.drawImage(
            V.src,
            precise(half_width + V.position.x - camera_position.x - V.offset.x),
            precise(half_height - ((V.position.z - camera_position.z) + (V.position.y - camera_position.y)) - V.offset.y)
        );
}

enter image description here

enter image description here

enter image description here

Javascript .map() an object of arrays

I’m trying to .map() an object of arrays to create a div for each key/value pair. Here is a sample of the object format:

const data = {
   year: ["2018", "2020"],
   make: ["Honda"],
   model: ["Accord", "Civic"],
   subModel: []
}

Here is what I have:

const filterChips = Object.entries(data)
        .flatMap(([key, value]) => [value].flat()
            .filter(v => v !== "" && v !== null)
            .map(v => [key, v]))
        .map(it => (<div>{it}</div>));

Which gives me the output:

<div>year2018</div>
<div>year2020</div>
<div>makeHonda</div>
<div>modelAccord</div>
<div>modelCivic</div>

Which is almost what I want, but I would like to be able to separate the key/value in each div so last line of code is:

.map(it => (<div>{it.key}: {it.value}</div>));

So that the output would be:

<div>year: 2018</div>
<div>year: 2020</div>
<div>make: Honda</div>
<div>model: Accord</div>
<div>model: Civic</div>

I feel like I’m close, but tuck on the last part…

Angular 17 refuses to instance component

I cannt reproduce it with anything, and I’m completely out of explanations for why it coudl be happening… I have the following component (with sideElementIs3d set to true, so it shows the threes-js app):

<div>
   <img src="assets/img/thumb/square.jpg" alt="">
   <div *ngIf="!sideElementIs3d" [ngStyle]="{'background-image':' url(assets/img/right.png)'}">
   </div>
   <app-three-js-interactive *ngIf="sideElementIs3d"></app-three-js-interactive>
</div>

And the app-three-js-interactive component:

<canvas #canvas></canvas>

I have spent roughly 5 hours now, trying to figure out why the app-three-js-interactive is not created, and my HTML inspector just looks like this with absolutely nothing inside the component. No constructor call, no ngInit, no ngAfterViewInit, nothing…

enter image description here

Even after removing all the code from the component it still does not instantiate anything


@Component({
  selector: 'app-three-js-interactive',
  templateUrl: './three-js-interactive.component.html'
})
export class ThreeJsInteractiveComponent implements AfterViewInit {

  @Input() scene!: THREE.Scene;

  @ViewChild('canvas', { static: false }) canvasRef!: ElementRef<HTMLCanvasElement>;

  dog!: AnimationController;

  constructor(private canvasParentRef: ElementRef, private threeService: ThreejsProviderService) { 
    console.log("help!")
  }

  ngAfterViewInit(): void {
    console.log("help!")
  }

The module is declared in the app.module.ts and I’ve done everything I can think of to get it working but I am completely out of ideas, if I make a new component it works just fine, but this one component just does not want to be created in the place I am trying. It does work in a different location which is puzzling me even more… Does anyone have any idea why this is happening, or any other info you need to help me figure out what is going on…

My Controller to DropdownList returns with failed to load resource: the serve responded with a status of 500 ()

I’m trying to make cascading dropdowns. The first one works fine but the second is not getting the data from the controller. The DeptID passes through to my GetStores parameter fine, but does not populate the second dropdown.

public ActionResult HistoryView()
{
  var model = new TemplateViewModel();
  model.Depts = _uow.Repository<Dept>().GetAll();

  ViewBag.listCompanies = new SelectList(_uow.Repository<Dept>().GetAll(),"DeptID","Dept_Name");

  return View(model);
}

public JsonResult GetStores( int DeptID)
{
  TemplateViewModel templateViewModel = new TemplateViewModel
  {
    Dept = _uow.Repository<Dept>().Get(x => x.DeptID == DeptID),
    Templates = _uow.Repository<Template>().GetAll().ToList()
  };
  return Json(templateViewModel, JsonRequestBehavior.AllowGet);
}
<div style="background-color:azure; border-color:black; border:solid">
  <br />
  <div>
    <b>Select your Company:</b>
  </div>
  <div>
    @Html.DropDownList("DeptID", (IEnumerable<SelectListItem>)ViewBag.listCompanies,String.Empty,  new {style = "width: 200px;"})
  </div>
  <br />
  <div>
    <b>Select Store</b>
    <div>
      @Html.DropDownList("TemplateID", new SelectList(string.Empty, "Value", "Text"), "--Select Store--", new { style = "width:200px;" } )
    </div>
  </div>
</div>
<script>
  $(document).ready(function() {
    $("#DeptID").change(function() {
      $("TemplateID").empty();
      $.getJSON('/HistoryLog/getstores', { DeptID: $('#DeptID').val() }, function(data) {
        $.each(data, function () {
          $('#TemplateID').append('<option value=' + this.Value + '>' + this.Text + '</option>');
        });
      });
    });
  });
</script>

enter image description here

ERROR: @firebase/firestore: Firestore (10.14.0): WebChannelConnection RPC ‘Write’ stream 0x5a330389 transport errored:

Help please.I got the error message while trying to post some data on firestore and recieved the error message that said: 400. That’s an error.Your client has issued a malformed or illegal request. Unknown SID That’s all we know. @firebase/firestore: Firestore (10.14.0): WebChannelConnection RPC ‘Write’ stream 0x5a330389 transport errored. I’m using nextJs with clerk auth this is the code of the problem file.`

"use client";
import React, { useState } from 'react';
import UploadImage from './UploadImage';
import { useUser } from '@clerk/nextjs';
import { getDownloadURL, getStorage, ref, uploadBytes } from "firebase/storage";
import UserTag from './UserTag';
import app from '../Shared/firebaseConfig';
import { doc, getFirestore, setDoc } from 'firebase/firestore';
import { useRouter } from 'next/navigation';
import Image from 'next/image';

function Form() {
    const { user } = useUser();
    const [title, setTitle] = useState('');
    const [desc, setDesc] = useState('');
    const [link, setLink] = useState('');
    const [file, setFile] = useState(null);
    const [loading, setLoading] = useState(false);
    const router = useRouter();

    const storage = getStorage(app);
    const db = getFirestore(app);

    const onSave = async () => {
        if (!file || !title || !desc || !link || !user) {
            alert("Please fill in all the fields and upload a file.");
            return;
        }
        setLoading(true);

        try {
            const storageRef = ref(storage, 'pinterest/' + file.name);
            await uploadBytes(storageRef, file);
            console.log("File Uploaded");

            const url = await getDownloadURL(storageRef);
            console.log("Download URL:", url);

            const postData = {
                title,
                desc,
                link,
                image: url,
                userName: user.fullName,
                email: user.emailAddresses[0]?.emailAddress,
                //userImage: user?.profileImageUrl,
                // Use a unique ID for each post
                id: Date.now().toString() // Generate a unique ID
            };

            console.log('Attempting to save postData:', postData);

            // Save the post data to Firestore
            await setDoc(doc(db, 'pinterest-posts', postData.id), postData);
            console.log("Post data saved successfully");

            router.push(`/${user?.emailAddresses[0]?.emailAddress}`);
        } catch (error) {
            console.error("Error during upload or saving post:", error.message);
            alert("Error saving data: " + error.message);
        } finally {
            setLoading(false);
        }
    };

    return (
        <div className='bg-white p-16 rounded-2xl'>
            <div className='flex justify-end mb-6'>
                <button onClick={onSave}
                    className='bg-red-500 p-2 text-white font-semibold px-3 rounded-lg'>
                    {loading ? 
                        <Image src="/loading-indicator.png" width={30} height={30} alt='loading' className='animate-spin' />
                        : <span>Save</span>
                    }
                </button>
            </div>
            <div className='grid grid-cols-1 lg:grid-cols-3 gap-10'>
                <UploadImage setFile={setFile} />
                <div className="col-span-2">
                    <div className='w-[100%]'>
                        <input type="text" placeholder='Add your title'
                            onChange={(e) => setTitle(e.target.value)}
                            className='text-[35px] outline-none font-bold w-full border-b-[2px] border-gray-400 placeholder-gray-400' />
                        <h2 className='text-[12px] mb-8 w-full text-gray-400'>
                            The first 40 characters are what usually show up in feeds
                        </h2>
                        <UserTag user={user} />
                        <textarea
                            onChange={(e) => setDesc(e.target.value)}
                            placeholder='Tell everyone what your pin is about'
                            className='outline-none w-full mt-8 pb-4 text-[14px] border-b-[2px] border-gray-400 placeholder-gray-400' />
                        <input type="text"
                            onChange={(e) => setLink(e.target.value)}
                            placeholder='Add a Destination Link'
                            className='outline-none w-full pb-4 mt-[90px] border-b-[2px] border-gray-400 placeholder-gray-400' />
                    </div>
                </div>
            </div>
        </div>
    );
}

export default Form;

Just tell me how to fix or other way to write my code

TypeError: Cannot read properties of undefined (reading ‘GuildText’)

I keep getting this error,

[AntiCrash] | [UncaughtExceptionMonitor_Logs] | [Start] : ===============
Uncaught exception monitor: TypeError: Cannot read properties of undefined (reading ‘GuildText’)
Exception origin: uncaughtException
[AntiCrash] | [UncaughtExceptionMonitor_Logs] | [End] : ===============
[AntiCrash] | [UncaughtException_Logs] | [Start] : ===============
Uncaught exception: TypeError: Cannot read properties of undefined (reading ‘GuildText’)
Exception origin: uncaughtException
[AntiCrash] | [UncaughtException_Logs] | [End] : ===============

const { SlashCommandBuilder } = require('@discordjs/builders');
const { ChannelType } = require('discord.js'); // Ensure you are importing this correctly
const fs = require('fs');
const jailedUsersPath = './src/jailedUsers.json';

// Load jailed users from the file
function loadJailedUsers() {
    return fs.existsSync(jailedUsersPath) ? JSON.parse(fs.readFileSync(jailedUsersPath)) : {};
}

function saveJailedUser(userId, guildId, roles) {
    const jailedUsers = loadJailedUsers();
    jailedUsers[userId] = { guildId, roles };
    fs.writeFileSync(jailedUsersPath, JSON.stringify(jailedUsers, null, 4));
}

module.exports = {
    data: new SlashCommandBuilder()
        .setName('jail')
        .setDescription('Jail a member')
        .addUserOption(option =>
            option.setName('user')
                .setDescription('The user to jail')
                .setRequired(true)),

    async execute(interaction) {
        const member = interaction.options.getMember('user');

        // Ensure the jail system has been set up
        const { jailRole, jailCategory, accessRole } = interaction.client.jailSetup || {};
        if (!jailRole || !jailCategory || !accessRole) {
            return interaction.reply({
                content: 'Jail system is not set up yet. Please run `/jail-setup` first.',
                ephemeral: true,
            });
        }

        try {
            // Save current roles
            const memberRoles = member.roles.cache.map(role => role.id);
            saveJailedUser(member.id, interaction.guild.id, memberRoles);

            // Assign jail role to the member
            await member.roles.set([jailRole]);

            // Create the jail channel
            const jailChannel = await interaction.guild.channels.create({
                name: `${member.user.username}-jail`,
                type: ChannelType.message.GuildText, // Ensure you are using the correct type reference
                parent: jailCategory, // Category ID
                permissionOverwrites: [
                    {
                        id: member.id,
                        allow: ['VIEW_CHANNEL', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'],
                    },
                    {
                        id: interaction.guild.id,
                        deny: ['VIEW_CHANNEL'], // Deny everyone else
                    },
                    {
                        id: accessRole,
                        allow: ['VIEW_CHANNEL', 'READ_MESSAGE_HISTORY'],
                        deny: ['SEND_MESSAGES'], // Allow access to see but not send messages
                    },
                ],
            });

            await jailChannel.send(`${member} has been jailed. Welcome to jail!`);

            await interaction.reply({ content: `${member.user.username} has been jailed.`, ephemeral: true });
        } catch (error) {
            console.error('Error jailing user:', error);
            await interaction.reply({ content: 'An error occurred while trying to jail the user.', ephemeral: true });
        }
    },
};

Facebook Like Button in website has no effect in pages

I have a facebook page and my own domain.
In my page on my own domain www.example.com, I want to have a facebook like button that is actually making people like my facebook page (www.facebook.com/example).

I got the code from https://developers.facebook.com/docs/plugins/like-button/

<div id="fb-root"></div>
<script async defer crossorigin="anonymous" src="https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v21.0&appId=MY_APP_ID"></script>

<div class="fb-like" data-href="https://www.facebook.com/example"  data-width="" data-layout="button_count" data-action="like" data-size="" data-share="false" data-show-faces="true"></div>

This used to work (years ago, I honestly don’t know when it stopped working).
Now it seems to have no effect at all. When I install it in my site, the button takes time to load and shows the correct like count that I can see in the fb page. However, when I click on it, nothing happens. It doesn’t compute my click and when I go to the fb page, it still shows that i didn’t “like” the page.

Any ideas how to solve this?

I don’t know what else to try, but I expect that when I click on the button on my domain, it will compute my like to the page in facebook.

How do I fix “Uncaught TypeError: player1[0] is undefined”?

I;m working on a project with the card game War, butI’m having an issue with a variable combined with an array. It says Uncaught TypeError: player1[0] is undefined.
I tried making player1[0][0] into player1[0,0], but to no avail, as it just says Uncaught DOMException: Node.appendChild: The new child is an ancestor of the parent, so honestly I have no idea.
I’m sorry for wasting your time if this is a mere typo or can’t be reproduced.

Here’s my code like before:

var player = [];
var computer = [];
var playedCards = [];
var cards = [];
var $player = $("#player");
var $playerNumber = $("#playerNumber");
var $playerSuit = $("#playerSuit");
var $computer = $("#computer");
var $computerNumber = $("#computernumber");
var $computerSuit = $("#computerSuit");
var $draw = $("#draw");
var $winner = $("#winner");
var $playerCards = $("#playerCards");
var $computerCards = $("#computerCards");
var number1;
var number2; 
var suit1;
var suit2;
var numberImg1;
var numberImg2;

for (i=1; i<14; i++){
    for (k=1; k<5; k++) {
        var j = [i,k];
    playedCards.push(j);
    }
}

cards.shuffle = function() {
    console.log("shuffle");
    var input = this
    for (var i = cards.length-1; i >=0; i--) {
        var randomIndex = Math.floor(Math.random()*(i+1));
        var itemAtIndex = cards[randomIndex][0];
        var itemAtSecond = cards[randomIndex][1];
        input[randomIndex][0] = input[i][0];
        input[randomIndex][1] = input[i][1];
        input[i][0] = itemAtIndex;
        input[i][1] = itemAtSecond;
  }
    return input
}

cards.shuffle();

function assign(){
    if(player.length == 0 || computer.length == 0){
        endgame();
    }
    $playerSuit.empty();
    $computerSuit.empty();
    var number1=player[0][0]; //This line has the error
    var number2=computer[0][0]; //If that one ^ does, then this one likely will too
    $playerNumber.html(number1);
    $computernumber.html(number2);
    suit1 = player[0][1]; //That also applies to this...
    suit2 = computer[0][1]; //...and this
    if (suit1 == 1) {
        suit1 = "<img src='resources/images/heart.png"
    }
    if (suit1 == 2) {
        suit1 = "<img src='resources/images/club.png"
    }
    if (suit1 == 3) {
        suit1 = "<img src='resources/images/diamond.png"
    }
    if (suit1 == 4) {
        suit1 = "<img src='resources/images/spade.png"
    }
    if (suit2 == 1) {
        suit2 = "<img src='resources/images/heart.png"
    }
    if (suit2 == 2) {
        suit2 = "<img src='resources/images/club.png"
    }
    if (suit2 == 3) {
        suit2 = "<img src='resources/images/diamond.png"
    }
    if (suit2 == 4) {
        suit2 = "<img src='resources/images/spade.png"
    } 

    if (number1<11){

        for (i=0; i<number1; i++) {
        
        $firstPlayerSuit.append(suit1);
        
        };
        
        } else {
        
        if (number1 == 11) {
        numberImg1 = "<img src='resources/images/jack.png'/>";
        $firstPlayerSuit.append(suit1);
        $firstPlayerNumber.html(numberImg1);
        }
        
        if (number1 == 12) {
        numberImg1 = "<img src='resources/images/queen.png'/>";
        $firstPlayerSuit.append(suit1);
        $firstPlayerNumber.html(numberImg1);    
        }
    
        if (number1 == 13) {
        numberImg1 = "<img src='resources/images/king.png'/>";
        $firstPlayerSuit.append(suit1);
        $firstPlayerNumber.html(numberImg1);
        }
        }
        if (number2<11){

            for (i=0; i<number2; i++) {
            
            $firstPlayerSuit.append(suit1);
            
            };
            
            } else {
            
            if (number2 == 11) {
            numberImg2 = "<img src='resources/images/jack.png'/>";
            $firstPlayerSuit.append(suit1);
            $firstPlayerNumber.html(numberImg2);
            }
            
            if (number2 == 12) {
            numberImg2 = "<img src='resources/images/queen.png'/>";
            $firstPlayerSuit.append(suit1);
            $firstPlayerNumber.html(numberImg2);    
            }
        
            if (number2 == 13) {
            numberImg2 = "<img src='resources/images/king.png'/>";
            $firstPlayerSuit.append(suit1);
            $firstPlayerNumber.html(numberImg2);
            }
            }
    for (i=0; i<number1; i++) {
        $playerSuit.append(suit1);
    };
    for (i=0; i<number2; i++) {
        $computerSuit.append(suit2);
    }

    playedCards.push(player[0]);
    playedCards.push(computer[0]);

    player.splice(0,1);
    computer.splice(0,1);

    console.log("call greater");
    greater();
}

function war(){
    $winner.html("Time for a war!")
    console.log("war");
        for (i=0; i<3; i++){
            playedCards.push(player[0]);
            playedCards.push(computer[0]);
            player.splice(0,1);
            computer.splice(0,1);
        }
        $playerSuit.css("display", "none");
        $computerSuit.css("display", "none");
        numberImg1 = "<img style='height:14rem;' src='resources/images/card.png'/>";
        numberImg2 = "<img style='height:14rem;' src='resources/images/card.png'/>";
        console.log("call greater");
        greater();
}

function greater(){
    console.log("greater");
    console.log("in greater how many played ", playedCards.length);
    if (number1 > number2) {
        $winner.html("Player Wins");
        for (i=0; i<playedCards.length; i++) {
            player.push(playedCards[i])
        }
    } else if (number1 < number2) {
        $winner.html("Computer Wins");
        for (i=0; i<playedCards.length; i++) {
            computer.push(playedCards[i])
        }
    } else if (number1 == number2) {
        console.log("call war");
        war();
        }
    playedCards = [];
    $playerCards.html(player.length);
    $computerCards.html(computer.length);
}

$draw.on("click", function() {
    assign();
})

function endgame(){
if(player.length == 0){
    $winner.html("Game over </br> You have no more cards </br> You lose");
    $computerNumber.html("Win");
    $playerNumber.html("Lose");
}
if(computer.length == 0){
    $winner.html("Game over </br> Computer has no more cards </br> You win");
    $computerNumber.html("Lose");
    $playerNumber.html("Win");
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div id="gameboard" class="flex">
<div class="flexColumn">
<h1>War</h1>
<h2 id="winner">Winner</h2>
<h3>Player has <span id="playerCards"></span> cards.</h3>
<h3>Computer has <span id="computerCards"></span> cards.</h3>
</div>
<div class="flex">
    <div id="player" class="flexColumn player">
        <h2>Player</h2>
        <div id="playerNumber" class="number">
        </div>
        <div id="playerSuit" class="suit">
        </div>
    </div>
<h2 id="draw">Draw</h2>
<div id="computer" class="flexColumn player">
    <h2>Computer</h2>
    <div id="computerNumber" class="number">
    </div>
    <div id="computerSuit" class="suit">
    </div>
   </div>
  </div>
 </div>
</div>

and a screenshot so you can see for yourself (unrelated, but this time I didn’t use such grating colors)
A screenshot of my project, including error messages

Javascript generate id dynamically inside innerHTML [closed]

I am dynamically building table data which has a button in a cell. I would like the button to have id of the corresponding row so that I can access them separately by their individual id.
So something like button0, button1 etc.
However, doing below doesn’t work so far.

function buildtable(json){
 for (var i = 0; i < json.data.length; i++) {
    const table = document.getElementById("mytesttable").getElementsByTagName('tbody')[0];
    const newRow = table.insertRow();
    const cell1 = newRow.insertCell(0);
    const cell2 = newRow.insertCell(1);

    cell1.innerHTML = json.data[i].emp_name;
    var btnId = "testbutton"+i;
     //alert(btnId); // displays testbutton0
    cell2.innerHTML = "<button id='${btnId}' onclick='doSmth()'>ClickMe</button>";
    }  
}
function doSmth(){
 alert(event.target.id);  // displays ${btdId} instead of testbutton0
}

JS Web Workers: Multiple workers vs. cooperative multitasking

I’m building web-based tool for math research that performs a few different kinds of client-side computations that can take minutes to complete, so I’m thinking dedicated Web Workers are appropriate. As the user interacts with the page, ongoing tasks can become irrelevant, and new tasks can be requested before old ones complete. I’m considering two possible strategies:

  • Thread pool style: The main thread manages a collection of workers running tasks in parallel and can terminate no-longer-needed ones and reuse idle ones. This seems pretty good except that it makes a network request for the worker’s js file (and presumably repeats parsing and startup work) every time a worker is created (see
    this question and this one).

  • Cooperative multitasking style: Have only one Worker instance, with long-running tasks implemented as generators so that a task manager in the worker thread can progress them in parallel and discard no-longer-needed ones. This is more complex to implement, and I suspect all the yielding will slow down my computations, but it avoids the problem above.

I’m leaning towards the thread pool style unless there are other reasons for my tasks to share a thread (like memoization of helper functions…although this could also be shared across threads with more effort and complexity). Maybe if my server serves the right caching headers for the script, browsers can be expected to optimize away the repeated downloads.

Any insights/experience/suggestions are appreciated!

Antd Slider not dragging via it’s tooltip on mobile devices (working on PC)

I am using the slider component from antd (version ^5.11.1): https://ant.design/components/slider

The issue I’m facing is that the slider is not dragging via the tooltip on touch screen devices, but it works fine when dragged using a mouse on laptops, computers, etc. I’m not sure what the problem is so any help would be greatly appreciated.

Slider component

     <Slider
        range={{ draggableTrack: false }}
        max={11}
        min={-1}
        defaultValue={[-1, 11]}
        value={[Number.parseInt(value[0]), Number.parseInt(value[1])]}
        step={1}
        tooltip={{
          open: true,
          zIndex: 100,
          arrow: false,
          rootClassName: "slider-pointer-event",
          className: "font-weight-bold ",
          color: "#28bdbb",
          placement: "bottom",
          autoAdjustOverflow: false,
          formatter: noformatter,
        }}
        onChange={onChange}
      />