How to Dynamically Trigger __doPostBack Using UniqueID in WebForms with JavaScript? [duplicate]

I’m working with ASP.NET WebForms and need to trigger a postback dynamically after a successful reCAPTCHA validation.

function checkCaptcha(buttonId) {
  console.log("Button UniqueID:", buttonId);

  __doPostBack(buttonId, '');    // Doesn't work
  __doPostBack(buttonId.id, ''); // Doesn't work

  console.log("Trying with 'this':", this);
  __doPostBack(this, '');        // Doesn't work
  __doPostBack(this.UniqueID, ''); // this.UniqueID is undefined
}

I need to dynamically trigger a postback for different buttons using their UniqueID, but __doPostBack does not work as expected.

How can I properly use __doPostBack with UniqueID in WebForms using JavaScript?

javascrip indexOf not working with underscore=

Hi so I’m a bit confused. As far as I understand the indexOf method uses strict equality which in my mind means that if i have a object

animal = {id: 1, name: 'bison'}

the statement
animal.name === 'bison'
would be true which it is.

What I don’t understand is that why indexOf() in the below example will return a index for both “bison” and “bison_ox” which in my mind means that it does not follow strict equality or am i missing something?

const beasts = ['bison', 'camel', 'duck', 'bison_ox'];

const tmp = [{id: 1, name: 'bison'}, {id: 2, name: 'camel'}, {id: 3, name: 'duck'}, {id: 4, name: 'bison_ox'}]

// Expected output: 1
for(let i = 0; i< beasts.length; i++) {
  tmp.forEach(item => {
    if(beasts[i].indexOf(item.name) !== -1) {
      console.log('index: ' + i + ' item: ' + item.name + ' beast: ' + beasts[i])
    }
  })
}

gives the following output

> "index: 0 item: bison beast: bison"
> "index: 1 item: camel beast: camel"
> "index: 2 item: duck beast: duck"
> "index: 3 item: bison beast: bison_ox"
> "index: 3 item: bison_ox beast: bison_ox"

why do indexOf get the first index (bison) when the searchElement is bison_ox

OneTrust Consent groups not working as expected through subdomains

Needs: I need to avoid the banner reappearing (if the user has already accepted) when navigating from site A to B and vice versa, using OneTrust.

Setup:

  • Non-authenticated side, it’s two public sites.
  • Consent group enabled on OT and configuration done with public key HS256.
  • Let’s say that site A is wwwtest.example.com and site B is .test.example.com.
  • Since there’s no authentication, site A or site B will save an ID into cookies if not present.
  • To fetch preferences, each client will generate a JWT based on the ID and public key.

Actual Situation:

  • The flow is working as expected from B to A, but NOT from A to B.
  • When not working, the ID is correctly shared and read from the client.
  • When not working, the cookie managed by OneTrust:
    • OptanonConsent is working as expected.
    • OptanonAlertBoxClosed is not working as expected.

The OptanonAlertBoxClosed cookie is present once I land on site B, but when the OT script is loaded, it’s canceled and the banner reappears.

Setup notes:

  • The fetch preferences are always made with the correct ID.
  • The anomaly is that once I go from A to B, the flow is not working on landing, but if I refresh, everything works as expected. The cookie that I do not find is not managed directly by me.
  • The variable OneTrust is correctly injected before the main OT script into the head.
  • The web application is done with NEXT JS using both client and server components, and the scripts are loaded from a client component.

I verified that the configuration on the OT dashboard is correctly done and everything is working as expected only from B to A.

Below is the script:

<Script id="ot-consent-group">
  {`
    var OneTrust = {
      dataSubjectParams: {
        id: "${userId}",
        isAnonymous: false,
        token: '${token}'
      }
    };
  `}
</Script>

Here is the main OT script:

<Script src={XXXXX} data-domain-script={XXXXXX} />
<Script>{`function OptanonWrapper() {}`}</Script>

Has anyone been in this situation? Can be a setup problem?

Vanilla JS – Catching reload events to show custom modal

Sorry for the lengthy post but this needs some context.

Context

I’m building an app for academic papers publishing. The stack is Laravel + vanilla JS and I use Etherpad to edit the papers. It is embedded in the last step of a two-part form.
Because of this configuration (that I cannot change), here’s the process :

  • the data given in the first part of the form is stored through laravel
  • Etherpad is prepared to show an empty pad in the second part of the form and creates its own stuff in its own database
  • the second part is submitted : Etherpad updates its stuff, I populate a mapping table in my database, and then I do other stuff relevant to my app only.

Issue

The first part of the form is submitted via ajax for various usability reasons; thus, if the user is on the second part and reloads the page, they return to the first step and part of my work is lost – it creates inconsistencies in my database and lets unnecessary stuff created in Etherpad’s.

Need

Therefore I need to catch any and all ways to reload the page and show a custom confirmation modal. This allows me to clean up the data properly.

Approach 1

I’ve tried a manual approach : catch keydown events (F5, CTRL+R, CTRL+SHIFT+R), catch links click (such as a go back link), catch back/forward mouse buttons, … I realized I can’t catch the browser’s reload button which is unfortunate.

Approach 2

I switched to an approach using performanceNavigationTiming, with the beforeunload event :

window.addEventListener('beforeunload', (event) => {
    if (performance.getEntries()[0].type == "reload") {
        Shared.cancelForm(false);

        window.addEventListener('unload', (event) => {
            Shared.cancelForm(false);
        });
    }
});

It works like a charm but the browser keeps showing me its own confirm modal, which I can’t customize or remove, as far as I know. When the user click “Stay on the page”, it shows my own cancelForm modal. I added the unload listener to try and catch the fact that the user might click “Leave the page” in the browser’s modal, but it doesn’t seem to work either.

Next possible approach

I was wondering if a PerformanceObserver could help, but I’m not sure how to use it properly, nor if it will be of any use in my case. My understanding is quite limited on this point.

Any help in the use of PerformanceObserver (for my purpose or more generally), or regarding the feature I’m trying to implement, is happily welcome !!

React-query v5 query data contains an empty object when using persistence

I’ve noticed that many users of my app get unexpected runtime errors because react-query (v5.64.2) query data contains an empty object (and my backend never returns empty objects). I’ve also noticed it happens only with queries that are persisted (localStorage).

These errors occur randomly and I don’t understand why some queries end up with an empty object ({}) in their data.

Use FullCalendar eventClick info in SweetAlert2 JSP condition

I’m using FullCalendar API for a calendar page in my website that’s supposed to track a maintenance schedule of equipment. I also used SweetAlert2 as the popup modal for when an eventClick happens.

eventClick: function(info) {   
                var eventTitleParts = info.event.title.split('for');
                var eventCat = eventTitleParts.length > 1 ? eventTitleParts[1].trim() : '';
                console.log(eventCat);
                    Swal.fire({
                    title: info.event.title,
                    icon: 'info',
                    showConfirmButton: true,
                    html: `
                        <table style="width: 100%; text-align: left; border-collapse: collapse;">
                            <tr>
                                <td style="font-weight: bold; padding: 8px; border-bottom: 1px solid #ddd;">Date:</td>
                                <td style="padding: 8px; border-bottom: 1px solid #ddd;">`+info.event.start.toLocaleDateString()+`</td>
                            </tr>
                            <tr>
                                <td style="font-weight: bold; padding: 8px; border-bottom: 1px solid #ddd;">Location/s:</td>
                                <td style="padding: 8px; border-bottom: 1px solid #ddd;">
                                    <c:set var="eCat" value="` + eventCat + `"/>
                                    <c:set var="eCat2" value="Aeration Blower"/>
                                    <c:set var="eCat3" value="${eventCat}"/>
                                    <div>${eCat} test</div>
                                    <div>${eCat2} test2</div>
                                    <div>${eCat3} test3</div>
                                    <div>${eventCat} test4</div>
                                 </td>
                            </tr>
                        </table>
                    `,
                    confirmButtonText: 'Close'
                  });
                }

Assuming info.event.title is Annual Maintenance for Chiller, the outputs should be as follow:

Chiller test
Aeration Blower test2
Chiller test3
Chiller test4

However, the output is currently like this:

 test
Aeration Blower test2
 test3
 test4

I want to be able to use eCat, or just eventCat in general as a condition for a c:forEach loop I want to implement later. For now, I’m just trying to get them to properly be put in jsp variables. I’ve tried using sessions, mixed up concatenations just like in eCat, and reordering the code but it doesn’t display no matter what.

How to Integrate Plivo SDK in Laravel?

Plivo SDK in Laravel
I am integrating Plivo in Laravel to create a “click to call” function on my web app page. I want to provide features such as call, hangup, mute, and unmute on this page. I also want a feature that allows users to talk directly through the web. So, when the user clicks the “Call” button, the user can immediately speak to someone through the browser.

I have created codes like the following, but I get an error message: “Failed to load Plivo SDK: Plivo SDK failed to load”.

show.blade.php

@extends('layouts.app')
@section('title', "Contact: {$contact->first_name} {$contact->last_name}")
@section('styles')
<script type="text/javascript" src="https://cdn.plivo.com/sdk/browser/v2/plivo.min.js"> </script>
<style>
    .call-interface {
    padding: 20px;
    border: 1px solid #ddd;
    border-radius: 8px;
    margin-bottom: 20px;
    }
    .call-status {
    font-size: 18px;
    margin-bottom: 15px;
    }
    .call-controls button {
    margin-right: 10px;
    margin-bottom: 10px;
    }
    .call-timer {
    font-size: 24px;
    font-weight: bold;
    margin: 15px 0;
    }
    .call-logs {
    margin-top: 30px;
    }
</style>
@endsection
@section('content')
<div class="col-md-4">
    <div class="card mb-3">
        <div class="card-header">
            <h5 class="card-title mb-0">
                Contact Details
            </h5>
        </div>
        <div class="card-body">
            <div class="mb-1">
                <strong>Name:</strong> {{ $contact->first_name }} {{ $contact->last_name }}
            </div>
            <div class="mb-1">
                <strong>Phone:</strong> {{ $contact->phone }}
            </div>
        </div>
        <div class="card-footer">
            <div class="row g-3 align-items-center">
                <div class="col-12">
                    <label for="note" class="form-label">Note</label>
                    <textarea name="note" class="form-control" id="note" rows="3">{!! $disposition ? $disposition->note : '' !!}</textarea>
                </div>
                <div class="col-auto">
                    <select name="disposition" class="form-select" id="disposition">
                        <option value="">Select disposition</option>
                        @foreach (config('data.disposition_status') as $key => $item)
                        <option value="{{ $key }}" {{ $disposition && $disposition->status === $key ? 'selected' : '' }}>{{ $item }}</option>
                        @endforeach
                    </select>
                </div>
                <div class="col-auto">
                    <button onclick="makeCall('{{ $contact->phone }}')" class="btn btn-dark">Call</button>
                </div>
            </div>
        </div>
    </div>
</div>
<div class="col-md-8">
    <div class="card">
        <div class="card-header">
            <h3>Call Interface</h3>
        </div>
        <div class="card-body">
            <div class="call-interface">
                <div id="call-status" class="call-status alert alert-info">
                    Ready
                </div>
                <div class="call-timer" id="call-timer">
                    00:00:00
                </div>
                <div class="call-controls">
                    <button id="makeCall" class="btn btn-success" disabled>
                    <i class="fas fa-phone"></i> Call
                    </button>
                    <button id="hangupCall" class="btn btn-danger" disabled>
                    <i class="fas fa-phone-slash"></i> Hangup
                    </button>
                    <button id="muteCall" class="btn btn-warning" disabled>
                    <i class="fas fa-microphone-slash"></i> Mute
                    </button>
                    <button id="unmuteCall" class="btn btn-info" disabled>
                    <i class="fas fa-microphone"></i> Unmute
                    </button>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection
@push('scripts')
<script>
    let client;
    let currentCall = null;
    let callTimer = null;
    let callStartTime = null;
    
    async function initializePlivoClient() {
        try {
            console.log('Initializing Plivo client...');
            
            if (typeof window.plivoBrowserSdk === 'undefined') {
                throw new Error('Plivo Browser SDK not loaded');
            }
    
            const response = await fetch('{{ route("plivo.token") }}');
            const data = await response.json();
            
            if (data.error) {
                throw new Error(data.error);
            }
            
            console.log('Token received, initializing client...');
    
            try {
                const options = {
                    debug: "DEBUG",
                    permOnClick: true,
                    enableTracking: true,
                    audioConstraints: {
                        optional: [
                            { echoCancellation: true },
                            { noiseSuppression: true }
                        ]
                    }
                };
    
                // Create client using the correct SDK reference
                client = new window.plivoBrowserSdk.Client(options);
                
                console.log('Client created, attempting login...');
                
                // Login
                await client.login(data.username, data.password);
                
                console.log('Login successful');
                document.getElementById('makeCall').disabled = false;
                document.getElementById('call-status').innerHTML = 'Ready to call';
                document.getElementById('call-status').className = 'alert alert-success';
                
                setupEventListeners();
                
            } catch (error) {
                throw new Error(`Client initialization failed: ${error.message}`);
            }
    
        } catch (error) {
            console.error('Failed to initialize Plivo client:', error);
            document.getElementById('call-status').innerHTML = 'Failed to initialize phone: ' + error.message;
            document.getElementById('call-status').className = 'alert alert-danger';
        }
    }
    
    // Wait for SDK to load
    function waitForPlivoSDK() {
        return new Promise((resolve, reject) => {
            let attempts = 0;
            const maxAttempts = 20;
            
            const checkSDK = setInterval(() => {
                if (typeof window.plivoBrowserSdk !== 'undefined') {
                    clearInterval(checkSDK);
                    resolve();
                } else {
                    attempts++;
                    if (attempts >= maxAttempts) {
                        clearInterval(checkSDK);
                        reject(new Error('Plivo SDK failed to load'));
                    }
                }
            }, 250);
        });
    }
    
    // Initialize when document is ready
    document.addEventListener('DOMContentLoaded', async () => {
        try {
            await waitForPlivoSDK();
            await initializePlivoClient();
        } catch (error) {
            console.error('Initialization failed:', error);
            document.getElementById('call-status').innerHTML = 'Failed to load Plivo SDK: ' + error.message;
            document.getElementById('call-status').className = 'alert alert-danger';
        }
    });
    
    function setupEventListeners() {
        if (!client) {
            console.error('Client not initialized');
            return;
        }
    
        client.on('onLogin', () => {
            console.log('Successfully logged in to Plivo');
            document.getElementById('call-status').innerHTML = 'Ready to make calls';
            document.getElementById('call-status').className = 'alert alert-success';
        });
    
        client.on('onLoginFailed', (error) => {
            console.error('Login failed:', error);
        });
    
        client.on('onCallRemoteRinging', () => {
            document.getElementById('call-status').innerHTML = 'Ringing...';
            document.getElementById('call-status').className = 'alert alert-warning';
        });
    
        client.on('onCallAnswered', () => {
            document.getElementById('call-status').innerHTML = 'Call in progress';
            document.getElementById('call-status').className = 'alert alert-success';
            document.getElementById('hangupCall').disabled = false;
            document.getElementById('muteCall').disabled = false;
            startCallTimer();
        });
    
        client.on('onCallTerminated', () => {
            resetCallInterface();
            logCall('completed');
        });
    
        client.on('onCallFailed', (error) => {
            console.error('Call failed:', error);
            resetCallInterface();
            logCall('failed');
        });
    }
    
    function startCallTimer() {
        callStartTime = new Date();
        callTimer = setInterval(() => {
            const now = new Date();
            const diff = new Date(now - callStartTime);
            const hours = diff.getUTCHours().toString().padStart(2, '0');
            const minutes = diff.getUTCMinutes().toString().padStart(2, '0');
            const seconds = diff.getUTCSeconds().toString().padStart(2, '0');
            document.getElementById('call-timer').innerHTML = `${hours}:${minutes}:${seconds}`;
        }, 1000);
    }
    
    function resetCallInterface() {
        currentCall = null;
        document.getElementById('call-status').innerHTML = 'Ready';
        document.getElementById('call-status').className = 'alert alert-info';
        document.getElementById('hangupCall').disabled = true;
        document.getElementById('muteCall').disabled = true;
        document.getElementById('unmuteCall').disabled = true;
        document.getElementById('call-timer').innerHTML = '00:00:00';
        
        if (callTimer) {
            clearInterval(callTimer);
            callTimer = null;
        }
        callStartTime = null;
    }
    
    async function logCall(status) {
        try {
            await fetch('/api/call-logs', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
                },
                body: JSON.stringify({
                    contact_id: '{{ $contact->id }}',
                    status: status,
                    start_time: callStartTime,
                    end_time: new Date(),
                    duration: callStartTime ? Math.round((new Date() - callStartTime) / 1000) : 0
                })
            });
        } catch (error) {
            console.error('Failed to log call:', error);
        }
    }
    
    // Initialize when page loads
    document.addEventListener('DOMContentLoaded', initializePlivoClient);
    
    // Call button event listener
    document.getElementById('makeCall').addEventListener('click', async () => {
        try {
            currentCall = await client.call('{{ $contact->phone }}');
            document.getElementById('call-status').innerHTML = 'Calling...';
            document.getElementById('call-status').className = 'alert alert-warning';
        } catch (error) {
            console.error('Error making call:', error);
            document.getElementById('call-status').innerHTML = 'Call failed: ' + error.message;
            document.getElementById('call-status').className = 'alert alert-danger';
        }
    });
    
    // Hangup button event listener
    document.getElementById('hangupCall').addEventListener('click', () => {
        if (currentCall) {
            currentCall.hangup();
        }
    });
    
    // Mute button event listener
    document.getElementById('muteCall').addEventListener('click', () => {
        if (currentCall) {
            currentCall.mute();
            document.getElementById('muteCall').disabled = true;
            document.getElementById('unmuteCall').disabled = false;
        }
    });
    
    // Unmute button event listener
    document.getElementById('unmuteCall').addEventListener('click', () => {
        if (currentCall) {
            currentCall.unmute();
            document.getElementById('muteCall').disabled = false;
            document.getElementById('unmuteCall').disabled = true;
        }
    });
</script>
@endpush

PlivoController.php

<?php

namespace AppHttpControllers;

use AppModelsCall;
use PlivoRestClient;
use IlluminateSupportStr;
use IlluminateHttpRequest;

class PlivoController extends Controller
{
    protected $client;

    public function __construct()
    {
        $this->client = new RestClient(
            config('services.plivo.auth_id'),
            config('services.plivo.auth_token')
        );
    }

    public function getToken()
    {
        try {
            $endpointId = config('services.plivo.endpoint_id');
            $username = 'user_' . time();

            $token = $this->generateToken($username);

            return response()->json([
                'username' => $username,
                'password' => $token
            ]);

        } catch (Exception $e) {
            Log::error('Plivo Token Error', [
                'error' => $e->getMessage()
            ]);

            return response()->json([
                'error' => $e->getMessage()
            ], 500);
        }
    }

    private function generateToken($username)
    {
        $authId = config('services.plivo.auth_id');
        $authToken = config('services.plivo.auth_token');

        $iat = time();
        $exp = $iat + 3600; // Token berlaku 1 jam

        $payload = [
            "iss" => $authId,
            "sub" => $username,
            "iat" => $iat,
            "exp" => $exp,
            "jti" => Str::uuid()->toString()
        ];

        $header = json_encode(['typ' => 'JWT', 'alg' => 'HS256']);
        
        $base64UrlHeader = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($header));
        $base64UrlPayload = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode(json_encode($payload)));
        
        $signature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlPayload, $authToken, true);
        $base64UrlSignature = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($signature));
        
        return $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature;
    }

    public function handleCallEvent(Request $request)
    {
        Log::info('Call Event Received', $request->all());
        return response()->json(['status' => 'success']);
    }
}

web.php

Route::get('/plivo/token', [PlivoController::class, 'getToken'])->name('plivo.token');
Route::post('/plivo/call-event', [PlivoController::class, 'handleCallEvent'])->name('plivo.call-event');

What is the correct way to integrate Plivo in Laravel?

I can not implement Node program in Browser (WebRTC Peer reference is not defined) [closed]

I made some WebRTC server, https://github.com/AAlex-11/WebRTCpeer/blob/main/server.js, this is now not full code, start only. Goal of this server is testing my Android application based on WebRTC.
Schema of this WebRTC server now looking more or less workable, because I can connect to this server with Node.JS client – https://github.com/AAlex-11/WebRTCpeer/blob/main/client.js and receive start point to going farther in this project, because server write

Received ICE candidate: {
  type: 'candidate',
  candidate: {
    candidate: 'candidate:841689039 1 udp 2122260223 10.0.2.16 53036 typ host generation 0 ufrag 7l5I network-id 1',
    sdpMLineIndex: 0,
    sdpMid: '0'
  }
}
Received ICE candidate: {
  type: 'candidate',
  candidate: {
    candidate: 'candidate:1204296370 1 udp 2122194687 192.168.0.13 53037 typ host generation 0 ufrag 7l5I network-id 2',
    sdpMLineIndex: 0,
    sdpMid: '0'
  candidate: {
    candidate: 'candidate:1204296370 1 udp 2122194687 192.168.0.13 53037 typ host generation 0 ufrag 7l5I network-id 2',
    sdpMLineIndex: 0,
    sdpMid: '0'
  }
}
....

Similar positive result write my Node.JS client.
BUT, if I try to implement the same client scheme on Browser https://github.com/AAlex-11/WebRTCpeer/blob/main/WebRTC-test.html I receive absolutely unexpected result

 ReferenceError : Peer is not defined

on this line (line 42)

 peer = new Peer({ initiator: true, trickle: true, config: { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] } });

Its looking strange, code in browser very simple and just copy my workable test in Node.js, I can not detect reason of this issue. Can anybody take me advice?

Can’t seem to preserve inline elements such as , with custom blot

I’ve created a customblot, to handle span conversion but for some reason any text after <span> is being treated as a span too and causing the following:

Uncaught s: [Parchment] Unable to create [object HTMLSpanElement] blot

this is the test case i’ve been using

<p id="x4uqkat" class="x4uqkat--text__typography a98db97--highlight__border">this is text <span class="test">is here</span>   replaceable</p> 
</div>

Code below does preserve but it’s incorrectly converting replaceable

var Inline = Quill.import('blots/inline');

var Delta = Quill.import('delta');
class CustomSpan extends Inline {
    static blotName = 'customSpan';
    static tagName = 'span';

    static formats(domNode) {
        const className = domNode.getAttribute('class');
        console.log('Formats called with:', className, domNode);
        return className ? { customSpan: className } : {};
    }

    format(name, value) {
        if (name === 'customSpan') {
            if (value) {
                this.domNode.setAttribute('class', value);
            } else {
                this.domNode.removeAttribute('class');
            }
        } else {
            super.format(name, value);
        }
    }
}
    
    
Quill.register(CustomSpan,false);
   
const quill = new Quill("#editor", {
    modules: {
        toolbar: false,
    }, 
    theme: "snow" ,
});

quill.clipboard.addMatcher('SPAN', function(node, delta) {
    const className = node.getAttribute('class');
    console.log('Processing span with class:', className);

    if (!className) return delta; // Ignore spans without class

    let newDelta = new Delta();

    // Apply customSpan format only to the text inside the span
    delta.ops.forEach(op => {
        if (typeof op.insert === 'string') {
            newDelta.insert(op.insert, { customSpan: className });
        } else {
            newDelta.insert(op.insert);
        }
    });
    
    return newDelta;
});

JSFiddle

Filter within Nested Array of objects [duplicate]

I have got an array of objects and inside that array of objects there is one more array of objects. I wanted to filter the array according to the genre as the genres object is inside the movielist array of objects.

I have tried this code so far:

const output = movieList.map((movie) => ({
  ...movie,
  genres: movie.genres.filter((movieGenre) => movieGenre.name === genre),
}));

When the code runs, I get the filtered list as per the genre, however, I am still getting the empty array of genre which didn’t have the selected genre.

This is the movieList array

MovieList

and this is the result I got after filtering

Filtered movie List

Quill.js, can’t seem to preserve inline elements such as , with custom blot

I’ve created a customblot, to handle span conversion but for some reason any text after <span> is being treated as a span too and causing the following:

Uncaught s: [Parchment] Unable to create [object HTMLSpanElement] blot

this is the test case i’ve been using

<p id="x4uqkat" class="x4uqkat--text__typography a98db97--highlight__border">this is text <span class="test">is here</span>   replaceable</p> 
</div>

Code below does preserve but it’s incorrectly converting replaceable

var Inline = Quill.import('blots/inline');

var Delta = Quill.import('delta');
class CustomSpan extends Inline {
    static blotName = 'customSpan';
    static tagName = 'span';

    static formats(domNode) {
        const className = domNode.getAttribute('class');
        console.log('Formats called with:', className, domNode);
        return className ? { customSpan: className } : {};
    }

    format(name, value) {
        if (name === 'customSpan') {
            if (value) {
                this.domNode.setAttribute('class', value);
            } else {
                this.domNode.removeAttribute('class');
            }
        } else {
            super.format(name, value);
        }
    }
}
    
    
Quill.register(CustomSpan,false);
   
const quill = new Quill("#editor", {
    modules: {
        toolbar: false,
    }, 
    theme: "snow" ,
});

quill.clipboard.addMatcher('SPAN', function(node, delta) {
    const className = node.getAttribute('class');
    console.log('Processing span with class:', className);

    if (!className) return delta; // Ignore spans without class

    let newDelta = new Delta();

    // Apply customSpan format only to the text inside the span
    delta.ops.forEach(op => {
        if (typeof op.insert === 'string') {
            newDelta.insert(op.insert, { customSpan: className });
        } else {
            newDelta.insert(op.insert);
        }
    });
    
    return newDelta;
});

JSFiddle

Filter within Nested Array of objects

I have got an array of objects and inside that array of objects there is one more array of objects. I wanted to filter the array according to the genre as the genres object is inside the movielist array of objects.

I have tried this code so far:

const output = movieList.map((movie) => ({
  ...movie,
  genres: movie.genres.filter((movieGenre) => movieGenre.name === genre),
}));

When the code runs, I get the filtered list as per the genre, however, I am still getting the empty array of genre which didn’t have the selected genre.

This is the movieList array

MovieList

and this is the result I got after filtering

Filtered movie List

Uncaught TypeError: _TodoList__WEBPACK_IMPORTED_MODULE_2__.default.map is not a function in reactJS [closed]

import React, { useState } from 'react';

import TodoInput from ‘./TodoInput’;
import TodoList from ‘./TodoList’

function App(){
const [listTodo, setListTodo] = useState([”]);

let addList = (inputText)=>{
 setListTodo([...listTodo, inputText]);
}

 return(
      <> 
           <TodoInput addList={addList} />

           {TodoList.map((listItem, i)=>{
                return(

                     <TodoList key={i} item={listItem} />
                )
           })
           
           }
      </>
 )

}

export default App;

import React,{useState} from 'react'

function TodoInput(props){

const [inputText, setInputText] = useState('');

return(
    <>
        <h1>Todo List</h1>
        <input type='text' placeholder='Please fill your Task' value={inputText}
        onChange={(e)=>{setInputText(e.target.value)}} />


        <button className="btn" 
        onClick={()=>{props.addList(inputText)
        setInputText('')
        }}> +</button>
      
    </>
)

}

export default TodoInput;

import React from 'react';

function TodoList(props) {

    return(
        <div>
            <li className='list-item'>
                {props.item}
                <span>
                 <i class="fa-solid fa-trash-can"></i>
                </span>
            </li>

         </div>
    )

}

export default TodoList;

PDF Not Displaying in Iframe When Password-Protected

<script th:inline="javascript">
    let pdfBase64 = /*[[${pdfBase64}]]*/'';
    let blob = base64ToBlob(pdfBase64, 'application/pdf');

    const blobUrl = URL.createObjectURL(blob);

    // Display PDF in iframe
    const iframe = document.getElementById('viewDoc');
    
    function base64ToBlob(base64String, contentType) {
        contentType = contentType || '';
        var sliceSize = 1024;
        var byteCharact
ers = atob(base64String);
var byteArrays = [];

        for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
            var slice = byteCharacters.slice(offset, offset + sliceSize);

            var byteNumbers = new Array(slice.length);
            for (var i = 0; i < slice.length; i++) {
                byteNumbers[i] = slice.charCodeAt(i);
            }

            var byteArray = new Uint8Array(byteNumbers);
            byteArrays.push(byteArray);
        }

        return new Blob(byteArrays, { type: contentType });
    }

    iframe.src = blobUrl;
</script>

<iframe id="viewDoc" width="100%" height="500px"></iframe>

I am trying to display a PDF in an using JavaScript and Thymeleaf (th:inline=”javascript”) in a Spring Boot application. The PDF is passed as a Base64 string from the backend.

My code works fine for regular PDFs, but when the PDF requires a password, it does not open on mobile browsers (while it works on some desktop browsers).