How to toggle ::after properties with JS [duplicate]

I am making a website and there is a subscription page where there are four buttons. I have a circle on the top right of the container containing the button. the circle is made of a ::before element that is always shown there is also a ::after element that I want to toggle when the button is clicked so that it marks for which subscription is the information shown but I can’t think of a way for the ::after element display to be toggled to block with JS.

function openCity(evt, cityName){
  var i, tabcontent;

  tabcontent = document.getElementsByClassName("tabcontent");
  for (i = 0; i < tabcontent.length; i++) {
    tabcontent[i].style.display = "none";
  }

  document.getElementById(cityName).style.display = "block";
}
.tab{
  display:flex;
  flex-direction: row;
  justify-content: space-evenly;
  margin-top: 4rem;
}

.tablinks{
  all: unset;
  background: #111111;
  padding: 2rem;
  width: 10rem;
  border-radius: 10px;
  text-align: center;
  font-size: 1.5rem;
  position: relative;
  cursor: pointer;
}

.container{
  position: relative
}

.circle{
  position: absolute;
  top: 10px;
  right: 10px;
  width: 30px;
  height: 30px;
}

.circle::before{
  content: '';
  position: absolute;
  top: 50%;
  right: 2.5px;
  transform: translate(0%, -50%);
  border-radius: 50%;
  width: 25px;
  height: 25px;
  background-color: #e8f1f2;
}

.circle::after{
  content: '';
  position: absolute;
  display: none;
  top: 50%;
  right: 7.5px;
  transform: translate(0%, -50%);
  border-radius: 50%;
  width: 15px;
  height: 15px;
  background-color: var(--secondary-color);
}

.tabcontent{
  display: none;
}
<div class="tab">
    <div class="container">
      <button class="tablinks" onclick="openCity(event, '1')">1</button>
      <div class="circle"></div>
    </div>
    <div class="container">
      <button class="tablinks" onclick="openCity(event, '3')">3</button>
      <div class="circle"></div>
    </div>
    <div class="container">
      <button class="tablinks" onclick="openCity(event, '6')">6</button>
      <div class="circle"></div>
    </div>
    <div class="container">
      <button class="tablinks" onclick="openCity(event, '12')">12</button>
      <div class="circle"></div>
    </div>
  </div>
  
  <div class="showplace">
    <div id="1" class="tabcontent">1</div>
    <div id="3" class="tabcontent">3</div>
    <div id="6" class="tabcontent">6</div>
    <div id="12" class="tabcontent">12</div>
  </div>

Simple raster editor with OpenLayers

I want to build a simple raster editor web tool. Ideally with OpenLayers. I can’t find an example in examples that helps me, and chatgpt is going completely nuts.

What I want to start with is very simple: on the server, there is a .tif file. on the client side, the user can edit it by: drawing a polygon -> selecting a value -> modify (all pixels inside the polygon gets that value).

Any hints ?

Javascript / Apps Script / Google Sheet POST Issue

I am attempting to update a specific row in a google sheet from HTML/Javascript web page using Apps Script, based on it’s key value. However, the body is empty when the apps script is triggered and the row is not updated. Am I missing something based on my code below?

N.B. The google apps script is confirmed working as I am able to trigger it using an android app which updates the google sheet successfully.

Google Apps Script Code:

function updateOrder(e)
{
  var orderNumber = e.parameter.orderNumber;
  var orderStatus = e.parameter.orderStatus;
  var sheetRange = ss.getDataRange();
  var rangeData = sheetRange.getValues();
  var numRows = sheetRange.getNumRows();

  for(var i = 2; i <= numRows; i++)
  {
    var rowOrderNumber = sheetRange.getCell(i, 1).getValue();
    if(rowOrderNumber == orderNumber)
    {
      console.log(rowOrderNumber);
      ss.getRange(i, 2).setValue(orderStatus);
     
      return ContentService.createTextOutput(JSON.stringify(e.parameters)).setMimeType(ContentService.MimeType.JSON);
    }
  }

  return ContentService.createTextOutput(JSON.stringify(e.parameters)).setMimeType(ContentService.MimeType.JSON);
}

Javascript Code:

function updateOrderStatusInGSheet(orderNumber, orderStatus)
        {
            orderParams = {
                "action": "updateOrder",
                "orderNumber": orderNumber, 
                "orderStatus": orderStatus
            };

            return fetch("apps script url", {
                redirect:"follow",
                method: "POST",
                body: JSON.stringify(orderParams),
                headers: {
                    'Content-Type': 'text/plain;charset=utf-8',
                }
            }).then(response => {
                console.log("success:", response);
                return response.json();
            }).catch(err => {
                console.log("Error:" + err);
            });
        }

Electron ready event fire Twice?

I’m building an electron app and when testing the app i wnated to minify the main.js using UglifyJS and the ready event in the minified version fire twice for some reason,

the main code is fine when i run it, it’s just the minified version that does the bug.

uglify command uglifyjs src/electron/main.js -o src/electron/main.min.js --compress drop_console=true,passes=3 --mangle --module

main.js:

import { app, BrowserWindow as Window, WebContentsView as View } from "electron/main";
import { showNotification, setupTray, handleProtocolUrl } from "../supervisor/supervisor.js"
import { config as denv } from "dotenv"; denv();
import path from "node:path";
import fs from "node:fs";


/** @type {Protocol} */ export const __appProtocol = 'myapp';
/** @type {Path} */ const __dirname = import.meta.dirname;
global.win = null;
global.app = app;


// Ensure only a single instance of the app is running
const gotLock = app.requestSingleInstanceLock();

if (!gotLock) {
    app.quit();
} else {
    if (app.isPackaged) {
        app.setAsDefaultProtocolClient(__appProtocol);
    } else {
        app.setAsDefaultProtocolClient(__appProtocol, process.execPath, [
            path.resolve(process.argv[1]),
        ]);
    }

    app.on('second-instance', (evt, argv) => {
        // for xml notification handling
        const url = argv.find(arg => arg.startsWith(`${__appProtocol}://`));
        url ? handleProtocolUrl(url) : null;
        windowExist();
    });

    app.whenReady().then(() => {
        console.log('App is ready');

        // Check if the app was started with --supervisor
        const isSupervisor = process.argv.includes('--supervisor');
        if (!isSupervisor) {
            console.log('not supervised')
            windowExist();
        }
        setupTray();

        const url = process.argv.find(arg => arg.startsWith(`${__appProtocol}://`));
        url ? handleProtocolUrl(url) : null;

        // test
        showNotification();
    });

    app.on('open-url', (evt, url) => {
        evt.preventDefault();
        handleProtocolUrl(url);
    });

}

export function createWindow() {
    global.win = new Window({
        width: 975,
        height: 660,
        title: 'Campus',
        icon: "./assets/icon.ico",
        titleBarStyle: 'hidden',
        titleBarOverlay: {
            symbolColor: '#74b1be',
            color: '#2f3241',
            height: 55,
            ////width: 120,
        },
        webPreferences: {
            //devTools: false,
            nodeIntegration: false,
            contextIsolation: true,
            enableRemoteModule: false,
            sandbox: true,
            preload: path.join(__dirname, 'preload.cjs')
        }
    });

    global.win.webContents.setUserAgent(process.env.userAgent);

    // example
    const hiddenContent = new View();
    hiddenContent.webContents.setUserAgent(process.env.userAgent);
    hiddenContent.setBounds({ x: 0, y: 0, width: 400, height: 600 });
    hiddenContent.webContents.loadURL('https://google.com/');

    //win.setContentView()
    global.win.loadURL('https://google.com/').catch(console.error);
    global.win.contentView.addChildView(hiddenContent)

    global.win.on('close', () => {
        global.win = null;
    });

    return global.win;
}

function windowExist() {
    !global.win ? global.win = createWindow() : global.win.show();
}

I event tryed switshing app.whenReady with app.once('ready') and same result

Uncaught SyntaxError: Unexpected end of JSON input at JSON.parse () at dashboard/:110:27 django python

i am working on a chart that shows data on the dashbord.
it’s taking the data from the db and trying to make a json from that but in the html code it’s not working. showing Uncaught SyntaxError: Unexpected end of JSON input at JSON.parse ()

this is the view

def dashboard(request):
    mood_data = MentalHealthSurvey.objects.values(
        'mood').annotate(count=Count('mood'))
    stress_data = MentalHealthSurvey.objects.values(
        'stress_level').annotate(count=Count('stress_level'))

    # Serialize data for JavaScript
    mood_data_json = json.dumps(list(mood_data))
    stress_data_json = json.dumps(list(stress_data))

    context = {
        'mood_data_json': mood_data_json,
        'stress_data_json': stress_data_json,
    }

    
    return render(request, 'employees/dashboard.html', {'context': context})

this is the template code.

{% extends 'employees/base_generic.html' %}
{% block title %}
  Employee Dashboard
{% endblock %}
{% block content %}
  <div class="container">
    <h2>Survey Data</h2>
    <canvas id="moodChart"></canvas>
    <canvas id="stressChart"></canvas>
  </div>
{% endblock %}

{% block scripts %}
  <script>
    const moodData = JSON.parse('{{ mood_data_json|safe }}')
    console.log('moodData:', moodData)
    const stressData = JSON.parse('{{ stress_data_json|safe }}')
    
    const moodLabels = (moodData || []).map((item) => item.mood || 'Unknown')
    const moodCounts = (moodData || []).map((item) => item.count || 0)
    
    const stressLabels = (stressData || []).map((item) => item.stress_level || 'Unknown')
    const stressCounts = (stressData || []).map((item) => item.count || 0)
    
    const moodChart = new Chart(document.getElementById('moodChart'), {
      type: 'pie',
      data: {
        labels: moodLabels,
        datasets: [
          {
            data: moodCounts,
            backgroundColor: ['#28a745', '#ffc107', '#dc3545', '#17a2b8', '#6f42c1']
          }
        ]
      }
    })
    
    const stressChart = new Chart(document.getElementById('stressChart'), {
      type: 'bar',
      data: {
        labels: stressLabels,
        datasets: [
          {
            data: stressCounts,
            backgroundColor: ['#28a745', '#ffc107', '#dc3545']
          }
        ]
      }
    })
  </script>
{% endblock %}

Error (not allowed) when trying to hit the backend

Hi I uploaded my MERN (BTW I am using Mysql instead of mongo DB) app to the VPS everything was working fine in my local environment but when I deployed it on the VPS and try to communicate with the Backend Like getting the data from the API it gives me 405 not allowed error in my console you can try https://courierlink.com.au/CalQuote fill the details and click on get quote and in the console it gives me the 405 not allowed error how can I fix that and why it is happening I checked the other questions related to that on stackoverflow but nothing seems to work

Here is my nginx config file see if that helps

 server {
    server_name courierlink.com.au www.courierlink.com.au;

    location / {
        root /var/www/CourierWorld/frontend/build;
        try_files $uri /index.html;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/courierlink.com.au/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/courierlink.com.au/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
 server {
    if ($host = courierlink.com.au) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    server_name courierlink.com.au www.courierlink.com.au;
    return 404; # managed by Certbot


}

Why does the initial step not show when going from step 2 back to step 1

So I am trying to click on radio buttons and then use the click to continue to the next one. It works fine until you go back from step 2 to step 1 where then the radio buttons in step 1 don’t show.

My code is

<?php
// At the top of the file, add a unique class to avoid conflicts
$blockClass = 'request-a-quote-no-next-' . uniqid();
?>

<div class="<?php echo $blockClass; ?>">
    <pre id="debug-info" style="position: fixed; bottom: 0; right: 0; background: #f5f5f5; padding: 10px; max-height: 200px; overflow: auto; z-index: 9999;">
Debug Information:
</pre>

    <div class="request-a-quote-2 request-a-quote-no-next" style='
                            padding-top: <?php the_field('pt'); ?>px!important; 
                            padding-bottom: <?php the_field('pb'); ?>px!important;
                            padding-right: <?php the_field('pr'); ?>px!important;
                            padding-left: <?php the_field('pl'); ?>px!important;
                            '>
        <section class="request-a-quote-steps-2 request-a-quote-steps-no-next contact-us-header page-header">
            <div class="container-fluid">
                <?php $count = 0; if (have_rows('steps')): while (have_rows('steps')) : the_row(); $count++; endwhile; endif; ?>
                <div class="row justify-content-center">
                    <div class="col-12 col-lg-7 col-xl-7 d-flex flex-column align-items-center justify-content-end padding-v-10 text-center margin-top-100 margin-lg-top-140">
                        <h1 class="weight-normal header-heading text-white">
                            <span class="text-yellow">Request</span> a quote
                        </h1>
                        <div class="progress margin-bottom-10 margin-top-5">
                            <div class="progress-bar progress-bar-no-next" style=""></div>
                        </div>
                        <div class="step-number-counter">Step <span id="current-step-no-next">1</span> of <span id="total-steps-no-next"><?php echo $count; ?></span></div>
                    </div>

                    <?php
                    $step_number = 0;
                    if (have_rows('steps')):
                        while (have_rows('steps')) :
                            the_row();
                            $step_number++;
                            ?>
                            <div class="col-12 text-center">
                                <div class="row justify-content-center current-item current-item-no-next step-<?php echo $step_number; ?>"
                                    style="display: <?php echo $step_number === 1 ? 'block' : 'none'; ?>;">
                                    <input type="hidden" id="steps-count-no-next" value="<?php echo $count; ?>">
                                    <div class="col-12 text-center">
                                        <h2 class="headings weight-medium text-center <?php echo "step-$step_number"; ?>" 
                                            style='font-size: <?php the_sub_field('title_ft'); ?>px!important;'>
                                            <?php the_sub_field('title'); ?>
                                        </h2>
                                        <?php if (get_sub_field('subtitle')): ?>
                                            <h3 class="sub-headings weight-normal <?php echo "step-$step_number"; ?>" 
                                                style='font-size: <?php the_sub_field('subtitle_ft'); ?>px!important;'>
                                                <?php the_sub_field('subtitle'); ?>
                                            </h3>
                                        <?php endif; ?>
                                    </div>

                                    <div class="col-12 margin-bottom-40 request-step-options login-options-wrap margin-top-20 margin-lg-top-40 d-flex justify-content-center <?php echo "step-$step_number"; ?>">
                                        <?php
                                        if (have_rows('options')):
                                            while (have_rows('options')) :
                                                the_row();
                                                $image_alt = get_sub_field('option_image_alt');
                                                ?>
                                                <div class="col-6 col-md-6 col-lg-3 text-center margin-bottom-30">
                                                    <a href="#" class="custom-card custom-card-no-next" data-target="<?php the_sub_field('data-target'); ?>">
                                                        <div class="card-steps padding-v-10 padding-lg-v-30 h-100 d-flex flex-column">
                                                            <div class="card-body">
                                                                <input type="radio" class="card-radio"
                                                                    name="step-<?php echo $step_number; ?>"
                                                                    value="<?php the_sub_field('data-target'); ?>" />
                                                                <?php if (get_sub_field('option_image')): ?>
                                                                    <img loading="lazy" decoding="async" class="img-set-height margin-bottom-15"
                                                                        src="<?php the_sub_field('option_image'); ?>" 
                                                                        alt="<?php echo $image_alt['alt']; ?>">
                                                                <?php endif; ?>
                                                            </div>
                                                            <h3 class="margin-bottom-0 margin-top-auto">
                                                                <?php the_sub_field('option_text'); ?>
                                                            </h3>
                                                        </div>
                                                    </a>
                                                </div>
                                            <?php
                                            endwhile;
                                        endif;
                                        ?>
                                    </div>
                                </div>
                            </div>
                        <?php
                        endwhile;
                    endif;
                    ?>

                    <div class="col-12 text-center margin-bottom-30">
                        <div>
                            <button id="back-button-no-next" class="btn btn-yellow back-button" style="display: none;">
                                &lt; Back
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </section>
    </div>
</div>
<?php
if($_POST['quote_page_id']){
    // santize the data

    $name = sanitize_text_field($_POST['NAME']);
    $email = sanitize_email($_POST['EMAIL']);
    $page_id = sanitize_text_field($_POST['quote_page_id']);
    $message = sanitize_textarea_field($_POST['MESSAGE']);
    $number = sanitize_text_field($_POST['NUMBER']);
    $business_address = sanitize_text_field($_POST['BUSINESS-ADDRESS']);
    $postcode = sanitize_text_field($_POST['POSTCODE']);
    $company = sanitize_text_field($_POST['COMPANY']);
    $city = sanitize_text_field($_POST['CITY']);
    

    $message = "";
    // have rows by page id
    
    if (have_rows('steps')):
        while (have_rows('steps')) :
            the_row();

            $step_title = get_sub_field('title', $step);
            $message .= '<h3>'.$step_title."</h3> <br>";
            if (have_rows('options')):
                while (have_rows('options')) :
                    the_row();
                    $option_name = get_sub_field('data-target');
                    $value = sanitize_text_field($_POST[$option_name]);
                    $option_text = get_sub_field('option_text');
                    $message .= $option_text." = ".$value." <br>";
                endwhile;
            endif;
        endwhile;
    endif;


    
    wp_mail( $to, $subject, $message, $headers, $attachments );

}
?>
<script>
document.addEventListener('DOMContentLoaded', function () {
    const stepsCountElement = document.getElementById('steps-count-no-next');
    const totalSteps = parseInt(stepsCountElement.value) || 0;
    const progressBar = document.querySelector('.progress-bar-no-next');
    const currentStepDisplay = document.getElementById('current-step-no-next');
    const backButton = document.getElementById('back-button-no-next');
    let currentStep = 1;

    function updateProgress(step) {
        const initialPercentage = 33.33; // Set your desired initial percentage here
        const progress = step === 1 ? initialPercentage : ((step - 1) / (totalSteps - 1)) * (100 - initialPercentage) + initialPercentage;
        const roundedProgress = Math.round(progress * 100) / 100; // Round to two decimal places
        progressBar.style.width = `${roundedProgress}%`;
        currentStepDisplay.textContent = step;
    }

    function resetStep(step) {
        const stepItems = document.querySelectorAll(`.current-item-no-next.step-${step}`);
        stepItems.forEach(item => {
            item.classList.remove('visible');
            item.classList.add('hidden');
            item.style.display = 'none'; // Ensure it is hidden
        });
    }

    function showStep(step) {
        const stepItems = document.querySelectorAll(`.current-item-no-next.step-${step}`);
        stepItems.forEach(item => {
            item.classList.remove('hidden');
            item.classList.add('visible');
            item.style.display = step === 1 ? 'flex' : 'block'; // Set display to flex for step 1
        });
    }

    document.querySelectorAll('.custom-card-no-next').forEach(card => {
        card.addEventListener('click', function (event) {
            event.preventDefault();

            // Toggle active class for the clicked card
            this.classList.toggle('active');

            const radio = this.querySelector('input[type="radio"]');
            if (radio) {
                radio.checked = !radio.checked; // Toggle the radio button state

                // Check if any card is selected to proceed to the next step
                const anySelected = Array.from(document.querySelectorAll(`.step-${currentStep} .custom-card-no-next`))
                    .some(c => c.classList.contains('active'));

                if (anySelected) {
                    resetStep(currentStep);
                    const nextStep = currentStep + 1;

                    if (nextStep <= totalSteps) {
                        currentStep = nextStep;
                        showStep(currentStep);
                        updateProgress(currentStep);

                        backButton.style.display = currentStep > 1 ? 'inline-block' : 'none';
                    }
                }
            }
        });
    });

    backButton.addEventListener('click', function () {
        if (currentStep > 1) {
            resetStep(currentStep); // Hide the current step
            currentStep--; // Move to the previous step
            showStep(currentStep); // Show the previous step

            // Ensure Step 1 cards are reset properly
            if (currentStep === 1) {
                document.querySelectorAll('.custom-card-no-next').forEach(card => {
                    card.classList.remove('active');
                    const radio = card.querySelector('input[type="radio"]');
                    if (radio) radio.checked = false;
                });
            }

            updateProgress(currentStep);
            backButton.style.display = currentStep > 1 ? 'inline-block' : 'none';
        }
    });

    // Initialize first step
    showStep(1);
    updateProgress(1);
});
</script><style>
.hidden {
    display: none;
}

.visible {
    display: block;
}
</style>


I have tried removing the inline styling added but that does not help and the odd thing is that if you go from step 3 to step 2 the back button works as it should do. I also want to make the JS as simple as possible in order to keep the code maintained but I need to get it working first before I can do that

Struggling to deploy a firebase function

The code seems fine, the modules needed seem up to date, the link to firebase is correct. However the function will not deploy and gives error…

TypeError: functions.database.ref is not a function

I removed gameinfo section as it’s just setting variables and shouldn’t impact at all

I apologise for probably not presenting this problem as is the norm. Please be kind and i will try again

const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
const db = admin.database();

exports.matchmaker = functions.database.ref("/matchmaking/{playerId}")
    .onCreate(async (snap, context) => {
      const gameId = generateGameId();
      let secondPlayerKey = null;

      const snapshot = await db.ref("matchmaking").once("value");
      const players = snapshot.val();

      Object.keys(players).forEach((key) => {
        if (key !== context.params.playerId && !players[key].gameId) {
          secondPlayerKey = key;
        }
      });

      if (secondPlayerKey === null) {
        return null;
      }

      const matchmakingRef = db.ref("matchmaking");
      const transactionResult = await matchmakingRef.
          transaction((matchmaking) => {
            if (!matchmaking ||
              !matchmaking[context.params.playerId] ||
              !matchmaking[secondPlayerKey] ||
              matchmaking[context.params.playerId].gameId ||
              matchmaking[secondPlayerKey].gameId) {
              return matchmaking;
            }

            matchmaking[context.params.playerId].gameId = gameId;
            matchmaking[secondPlayerKey].gameId = gameId;
            return matchmaking;
          });

      if (!transactionResult ||
        transactionResult.snapshot.child(`${context.params.playerId}/gameId`).
            val() !== gameId) {
        return null;
      }

      const game = {
        gameInfo: {
          

      await db.ref(`games/${gameId}`).set(game);
      console.log("Game created successfully!");

      return null;
    });

I have tried checking compatibility of firebase functions and admin are okay.

I have re-installed the entire program and reset everything.

I have put these errors into chatG and followed the steps to the extent that i have exhausted its options provided (hence here).

Obviously, I simply want the function to deploy

When should I use HTMLAttributes vs ComponentProps in React TypeScript?

I understand that ComponentProps is generally recommended over HTMLAttributes for typing React components. However, I’m unsure about the specific use cases where HTMLAttributes would be more appropriate.

Here’s a simplified example of my current implementation:

import { type HTMLAttributes, type ReactElement } from "react";

type PressableProps = HTMLAttributes<HTMLElement> & {
  "aria-pressed": boolean;
};

type WrapperProps = {
  children: ReactElement<PressableProps>;
};

function PressableEffect({ children }: WrapperProps) {
  // ... implementation with event handlers
  return cloneElement(children, {
    ...children.props,
    "aria-pressed": true,
    onPointerDown: handlePointerDown,
  });
}

If I were to use ComponentProps instead, it would look like this:

import { type ComponentProps, type ReactElement } from "react";

type PressableProps = ComponentProps<any> & {
  "aria-pressed": boolean;
};

When is HTMLAttributes the more appropriate choice over ComponentProps?

Javascript works on second click but not the first

By Default the textarea = ‘Test’, If I change to ‘Test1’ and click on the “Send Email To Selected Merchants” the first time.. It still passes ‘Test’ in the out div, but then when I click on ‘No’ on the confirm box… and click on “Send Email To Selected Merchants” second time it passes ‘Test1’ correctly.

<script type="text/javascript">     
   
 var confirmed = false;      

    function confirmfinish(){
        if(!confirmed){ 
  
            var content = document.getElementById('query').value;
            document.getElementById('out').innerHTML = content;
            document.getElementById('out').style.display = "block";
            document.getElementById('confirmationDiv').style.display='block'; 
           return false;
        } else {
            return true;
  
        }
    }

</script>
<div id="confirmationDiv" class="confirmationDiv">
<table class="minimalistBlack">
<thead>
<tr>
<th>Are you sure all the below information is correct?</th>
</tr>
</thead>
<tbody>
<tr>
<td bgcolor="white">

 <div id="out" style="display:none;">
</td></tr>
<tr>
<tr>
<td>
<input type="submit" name="Submit3" value="Yes" onclick="confirmed = true; document.getElementById('form').submit();">
    <input type="button" value="No" onclick="document.getElementById('confirmationDiv').style.display='none'; return false;">
</td></tr>
</tbody>
</tr>
</table>
</div>
<form name="form" method="post" action="" onsubmit="return (ValidateForm(this,'enquiry') && confirmfinish() && ShowLoading())">
<textarea  style="height:700px;" name="query" cols="170" rows="60" id="query">Test</textarea>
<input type="submit" name="Submit3" value="Send Email To Selected Merchants"></td>
</form>

React accessibility issues

I have a question regarding the screen reader reading React pages. Say, on the home page, it renders component A. When clicking a button on the page, the route changes and it switches to another page, which renders component B. The component B has buttons, links, textboxes, etc. The SR reads those buttons, etc. as pure text.

component B

return <button onClick={...} ...>Click me</button>

When the page loads, the screen reader reads it as text “click me” instead of “button – click me”
When tabbing to the button, the screen reader reads it correctly as button.

One solution is to set focus to those buttons,etc. But it’s not ideal. I am wondering if there are any other solutions?

Any help/suggestion is appreciated.

How do I pass my html element to Javascript?

I have a TextArea and a <span> in my ASP.NET MVC code:

<div>
    @Html.TextAreaFor(m => m.Note, 4, 20,
    new {
        id = "Note",
        name = "textareaNote",
        maxlength = "250",
        @class = "text-danger form-control",
        placeholder = "Enter note here - limited to 250 characters",
        onkeyup = "showRemaining(Note, remainingC, 250)"
    })
    <span id="remainingC"></span>
    @Html.ValidationMessageFor(m => m.Note, "", new { @class = "text-danger" })
</div>

Whenever onkeyup fires, it has an error with the “remainingC” span:

<script type="text/javascript">
    function showRemaining(itemX, statusX, maxchar) {
        var len = itemX.value.length;
        if (maxchar < len) {
            return false;
        } else if (0 < len) {
            statusX.html('Remaining: ' + maxchar - len);
        } else {
            statusX.html('Remaining: ' + maxchar);
        }
    }
</script>

Every time I try typing into my textArea, I get this error:

Uncaught TypeError: statusX.html is not a function

screenshot

I struggle with Javascript.

What do I need to do to get this working?

React JS TablePagination showing all the rows

I have a Material IU Component in a Reactjs project that has table data. Everything works except the number of rows is not being applied to the display. My service is returning the data and it looks good and no errors. Just the TablePagination is not working.
The correct number of rows is displayed as text but the actual table has all the rows.

import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableCell from '@mui/material/TableCell';
import TableContainer from '@mui/material/TableContainer';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';
import Paper from '@mui/material/Paper';
import TablePagination from '@mui/material/TablePagination';

class Fields extends Component {
  constructor(props) {
    super(props);
    this.state = {
      redirect: null,
      dataReady: false,
      finishedLoading: false,
      equipmentList: null,
      page:0,
      rowsPerPage:10,
      currentUser: { username: "" }
    };
    }

  componentDidMount() {
    console.log('fields');
    const currentUser = AuthService.getCurrentUser();
    if (!currentUser) this.setState({ redirect: "/login" });
    EquipmentService.getEquipment(currentUser.customerId).then(
      data => this.setState({
        currentUser: currentUser,
        dataReady: true,
        finishedLoading: true,
        equipmentList: data, 
        page:0,
        rowsPerPage:10
      })
    )
  }
  render() {
    const handleChangePage = (event, newPage) => {
      this.page = newPage;
    };
    const handleChangeRowsPerPage = (event) => {
      this.rowsPerPage = +event.target.value;
      this.page = 0;
    };
    const { equipmentList } = this.state;
    const { finishedLoading } = this.state;
    const { page } = this.state;
    const { rowsPerPage } = this.state;

    if (this.state.redirect) {
      return <Navigate to={this.state.redirect} />
    }

    return (
      <div className="container">
        <div>
        <br/><strong>Fields</strong><br/>
        {(this.state.finishedLoading) ?

          <Paper sx={{ width: '100%', overflow: 'hidden' }}>
          <TableContainer sx={{ maxHeight: 440 }}>
          <Table stickyHeader aria-label="sticky table">
             <TableHead>
              <TableRow>
                <TableCell>Name</TableCell>
                <TableCell align="right">Position</TableCell>
                <TableCell align="right">Office</TableCell>
                <TableCell align="right">Start Date</TableCell>
                <TableCell align="right">Salary</TableCell>
              </TableRow>
            </TableHead>
            <TableBody>
              {equipmentList.data.map((row) => (
                <TableRow key={row.name} sx={{ '&:last-child td, &:last-child th': { border: 0 } }}>
                  <TableCell component="th" scope="row">{row.name}</TableCell>
                  <TableCell align="right">{row.position}</TableCell>
                  <TableCell align="right">{row.office}</TableCell>
                  <TableCell align="right">{row.start_date}</TableCell>
                  <TableCell align="right">{row.salary}</TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
          </TableContainer>
          <TablePagination
            rowsPerPageOptions={[10, 25, 100]}
            component="div"
            count={equipmentList.data.length}
            rowsPerPage={rowsPerPage}
            page={page}
            onPageChange={handleChangePage}
            onRowsPerPageChange={handleChangeRowsPerPage}
          />          
          </Paper>
      : null}
      </div>
      </div>

    );
  }
}
export default withRouter(Fields);

Audio speed and fast forward option in MediaElement.js

I’m using MediaElement.js to play an audio from a File that is returned from the server. Below is my code.

<!DOCTYPE html>
<html>
<head>
    <title>Audio Player</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mediaelement/4.2.16/mediaelementplayer.min.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/mediaelement/4.2.16/mediaelement-and-player.min.js"></script>
</head>
<body>
    <div class="container">
        <h1></h1>
        <audio id="player" controls>
            <source src="/source" type="video/webm">
        </audio>
    </div>
    <script>
        document.addEventListener('DOMContentLoaded', function () {
            console.log('Initializing MediaElementPlayer');
            const player = new MediaElementPlayer('player', {
                features: ['playpause', 'progress', 'volume', 'fullscreen', 'current', 'duration', 'speed'],
                speed: {
                    speeds: ['0.75', '1.00', '1.25', '1.50', '2.00'],
                    defaultSpeed: '1.00',
                    speedChar: 'x',
                    speedText: 'Speed'
                },
                success: function (mediaElement, originalNode, instance) {console.log('MediaElementPlayer initialized successfully');},
                error: function (mediaElement) {
                    fetch(mediaElement.src)
                        .then(response => {
                            if (!response.ok) {
                                return response.text().then(text => { throw new Error(text); });
                            }
                        })
                        .catch(error => {
                            document.getElementById('error-message').innerText = error.message;
                            document.getElementById('error-message').style.display = 'block';
                        });
                }
            });
        });
    </script>
</body>
</html>

The file is in .webm format. I want to enable fast forward and speed selector in the audio player but its not showing. Can anyone assist me with this.