Setting a PHP Cookie within an AJAX Call [duplicate]

I’m pretty new to AJAX so I’m struggling a little with my functionality for my WordPress site.

I have a dropdown list of countries and when a user selects a different country, I would like to update the cookie (which is already set) and therefore the page should load the new cookie without reloading the page.

At the moment I have to hit refresh for this to show the correct country code from using the code below, whereas I’d have hoped AJAX would do this without refreshing the page:

<?php echo "Value is: " . $_COOKIE['country']; ?>

My code is below, but I’m sure some of it may not be needed or is wrong.

JS

$('.single-country-select').on("change", function (e) {
    var country_code_value = $('.single-country-select').val();
    var sendData = {
        action: 'country_change_ajax_function',
        country_code_value: country_code_value
    };

    $.ajax({
        url: ajaxadminurl.ajaxurl,
        type: 'POST',
        data: sendData,
        dataType: 'html',
        cache: false,
        success: function(data) {
            // SET COOKIE HERE??
        }
    });
});

functions.php

function country_change_ajax_function() {
    $country_code_value = $_POST['country_code_value'];
    setcookie('country', $country_code_value, time() + (86400 * 30), '/');
    exit;
}
add_action('wp_ajax_country_change_ajax_function', 'country_change_ajax_function');
add_action('wp_ajax_nopriv_country_change_ajax_function', 'country_change_ajax_function');

I’ve also got some code at the top of my header that sets the cookie automatically:

if(!isset($_COOKIE['country'])) {
    $get_user_country_code = simplexml_load_file("http://www.geoplugin.net/xml.gp?ip=".getRealIpAddr());
    if ($get_user_country_code === false) {
        $user_country_code = 'GB';
        setcookie('country', 'GB', time() + (86400 * 30), '/');
    } else {
        $user_country_code = $get_user_country_code->geoplugin_countryCode;
        setcookie('country', $user_country_code, time() + (86400 * 30), '/');
    }
}

Any help would be much appreciated. Thanks!

What are the differences between .toSorted() and .sort() methods in JavaScript?

I’m trying to understand the differences between the .toSorted() and .sort() methods in JavaScript.

From my research and understanding, here’s what I know so far:

.sort():

The .sort() method sorts the array in place and returns the reference to the same array, meaning the original array is mutated. It accepts an optional compare function to determine the sorting order.

Example:

    const arr = [3, 1, 2];
    arr.sort((a, b) => a - b);
    console.log(arr); // output : [1, 2, 3]

.toSorted():

Based on MDN, the .toSorted() method, returns a sorted copy of the array, leaving the original array intact. Like .sort(), it can take an optional compare function, but it does not mutate the original array.

Example:

    const arr = [3, 1, 2];
    const sortedArr = arr.toSorted((a, b) => a - b);  //returns a new sorted array
    console.log(arr);        // output: [3, 1, 2]  (original array is unchanged !)
    console.log(sortedArr);  // output: [1, 2, 3]

Besides immutability, are there any other significant differences between these two methods?

JSON.stringify surrounding arrays with quotes

I’m trying to send data via REST API from a client to a server, the client is just an HTML page with JavaScript and HTMX in it, the server is Spring Boot. The endpoint accepts POST requests with an object:

public record FileMetadataDTO(Integer availabilityTime, FileDTO[] files) {}

public record FileDTO(String name, String extension, Integer sizeMB) {}

On the client side I have a button that sends the request to the server:

<button id="upload-button"
                hx-post="http://localhost:8080/api/v1/upload/metadata"
                hx-headers='{"Content-Type": "application/json"}'
                hx-ext="json-enc"
                hx-vals='js:{"availabilityTime": 1, "files": getFilesDTO()}'
                style="display: none;">Upload</button>
        <label for="upload-button" style="border: 1px solid #ccc; padding: 6px 12px; cursor: pointer;">Upload files</label>

The getFilesDTO() function returns a stringified array:

function getFilesDTO() {
            let filesDTO = [];
            for (let i = 0; i < tuckedFiles.length; i++) {
                filesDTO.push({
                    name: tuckedFiles[i].name,
                    extension: tuckedFiles[i].name.split('.').pop(),
                    sizeMB: tuckedFiles[i].size / 1024 / 1024
                });
            }
            return JSON.stringify(filesDTO);
        }

But JSON.stringify surrounds the array with quotes and the server cannot deserialize it:

{"availabilityTime":"1","files":"[{"name":"a.txt","extension":"txt","sizeMB":0.00022220611572265625},{"name":"another_file.txt","extension":"txt","sizeMB":0.000003814697265625}]"}

A valid payload would be:

{"availabilityTime":"1","files":[{"name":"a.txt","extension":"txt","sizeMB":0.00022220611572265625},{"name":"another_file.txt","extension":"txt","sizeMB":0.000003814697265625}]}

But I can’t make JSON.stringify do it like that no matter what. I tried it in the console of Chrome and Edge to see if my code is at fault, but JSON.stringify([]) in the console of both browsers returns '[]'.

How can I fix this? I’ve been on multiple websites and can’t find a solution.

jQuery multiselect.js selects all options even they are not visible

  1. I use this plugin to make multiselect more comfortable – http://loudev.com/.
  2. I have also integrated search via quicksearch plugin.
  3. And I have set optgroup can be selected

But I would need, if any query is searched and optgroup is selected, to select only options which were found. If item is not match searched query, it is hidden via style="display: none", so I thought best practice to filter them out is to use :visible selector, but it does not work. I’ve also tried :not(:hidden), but it does not work either.

This is the code, which selects all options when optgroup is clicked.

$selectableOptgroup.find('.ms-optgroup-label').on('click', function(){
  var values = $optgroup.children(':not(:selected, :disabled)').map(function(){ return $(this).val();}).get();
  that.select(values);
});

And I’ve tried to edit this way, but still all options are selected.

$selectableOptgroup.find('.ms-optgroup-label').on('click', function(){
  var values = $optgroup.children(':not(:selected, :disabled, :hidden)').map(function(){ return $(this).val();}).get();
  that.select(values);
});

json_encoded array ajax response interpreted as text

My ajax response seems to be interpreted as text even though the ajax request contains datatype: "json". My understanding is that header line in the php script below should have no effect, and yet it fixes my problem.

Can anyone explain this behavior?

I am calling the following javascript function:

async function ajaxTest() {
  $.ajax({
    url: 'test_ajax_response.php',
    type: 'POST',
    datatype: "json",
    data: {
      'foo': 'bar'
    },
    success: function(response) {
      console.log('first element of returned array: ' + response[0]);
      console.log('length of returned array: ' + response.length);
    }
  });
}

Here is test_ajax_response.php:

<?php
header("Content-Type: application/json", true);                               
$bar = $_POST['foo'];
$my_arr = array($bar);
echo json_encode($my_arr);
?>

The console output is

first element of returned array: bar
length of returned array: 1

If I comment the header line the console output is

first element of returned array: [
length of returned array: 7

Same behavior in Chrome and Firefox.

How to determine the height of word-wrapped text in pdf-lib?

In pdf-lib, it is possible to auto-word-wrap text using a technique outlined here: https://stackoverflow.com/a/77436904/1766230

import { PDFDocument, StandardFonts } from 'pdf-lib';
const doc = await PDFDocument.create();
const font = await doc.embedFont(StandardFonts.TimesRoman);
const page = doc.addPage();
// This will word-wrap fine:
page.drawText(someLongText, { font, size: 20, lineHeight: 25, maxWidth: 200, wordBreaks: [' '] });
// But now what?
// page.moveDown(???);

The problem is you may need to either…

  • Move the y cursor down so that you can write the next line to the page. (page.moveDown)
  • Detect when a new page might be needed — i.e., the height of this wrapped text would go off the bottom of the page — so that you can split up the text and add a new page (doc.addPage).

But there does not seem to be any functions in the documentation that let’s you determine the height of the word-wrapped text you are drawing to the page. font.heightAtSize(size) just gets the height of the font. What can be done?

My Component in React JS application don’t read the Headers from REST-Api – Headers is Empty [duplicate]

I created a Web application built with React.Js and Asp.Net core with C#.

When I do Request from Postman or Swagger I have the headers from Response.
From Swagger:

Request and Response from Swagger

And for the postman is the same result.

In React.js I call my endpoint with the following code:

const res = await fetch(url, options);
const data = await res.json();
console.log("Head " ,res);

My console.log from inspect in app is( the headers is empty):
enter image description here

I do fetch my endpoint with options for Authorization but the Response have empty Headers. Why??

From libary with path node_modulestypescriptliblib.dom.d.tsfetch
And my Fetch:
enter image description here

My program.json

{
  "name": "linkedin",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "start": "vite preview",
    "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview",
    "build": "vite build --watch"
  },
  "dependencies": {
    "@cloudinary/react": "^1.13.0",
    "@cloudinary/url-gen": "^1.20.0",
    "@fortawesome/fontawesome-free": "^6.6.0",
    "@fortawesome/fontawesome-svg-core": "^6.6.0",
    "@fortawesome/free-solid-svg-icons": "^6.6.0",
    "@fortawesome/react-fontawesome": "^0.2.2",
    "@react-icons/all-files": "^4.1.0",
    "axios": "^1.6.8",
    "cloudinary": "^2.4.0",
    "cors": "^2.8.5",
    "express": "^4.19.2",
    "mssql": "^10.0.2",
    "multer": "^1.4.5-lts.1",
    "path": "^0.12.7",
    "primeicons": "^7.0.0",
    "primereact": "^10.8.2",
    "react": "^18.2.0",
    "react-datepicker": "^7.3.0",
    "react-dom": "^18.2.0",
    "react-icons": "^5.1.0",
    "react-router-dom": "^6.23.1",
    "watch": "^0.13.0"
  },
  "devDependencies": {
    "@types/react": "^18.2.66",
    "@types/react-dom": "^18.2.22",
    "@vitejs/plugin-react": "^4.2.1",
    "eslint": "^8.57.0",
    "eslint-plugin-react": "^7.34.1",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.4.6",
    "vite": "^5.4.0",
    "webpack-dev-server": "^5.0.4"
  }
}

Do you have any solution for my problem?

returning a pdf (TCPDF) with a laravel api

I am moving a laravel app to a laravel api and I have a functionality to create pdfs with TCPDF in the laravel app it works without any problem but when I try to move this functionality to an api I am getting several errors.

  1. the pdf comes empty (this should not be happenning)

  2. the pdf comes without the name (it seems to be)

    //laravel controller code: 
    
     $filename = $odp_volumetrica->codigo . ' L ' . $odp_volumetrica->lote . '.pdf';
     $filename = str_replace(' ', '_', $filename); 
    
     header('Content-Type: application/pdf');
     header('Content-Disposition: inline; filename="' . $filename . '"');
     header('Access-Control-Allow-Origin: *');
     $pdf->Output($filename, 'I'); 
    
    
    //react client code:
         authorizedRequest
         .get('/odps/13/printCoa')
         .then(({ data }) => {
             const blob = new Blob([data], { type: 'application/pdf' });
             window.open(URL.createObjectURL(blob));
         })
         .catch((error) => {
             console.log(error);
         });
    

I would like to know if there is a way to return these pdfs and open them in a new tab in the browser and if possible its name is not a random string.

How to Track User Progress in SCORM Content Embedded via an iFrame from AWS S3?

I have embedded a SCORM package hosted in an AWS S3 bucket into my website using an iFrame. The SCORM content displays correctly, but I would like to track the user’s progress—specifically which slides the user has completed and how far they’ve progressed through the content.

<iframe id="scormPlayer" src="https://scorm-package.s3.eu-west-2.amazonaws.com/scorm/hurak-learning/fire-marshal-fire-warden-online/Introduction/index.html" width="100%" height="600" frameborder="0"></iframe>

How can I track which slides the user has completed and their overall progress within the SCORM content? I’m using SCORM 2004 and would prefer to manage the data within my own system without relying on third-party services.

Any help or suggestions would be greatly appreciated!

Matching a post with a memberId WIX

I’m trying to input the logged member ID into a CMS in Wix. I can’t find a way to do this without using code, and when I try to use code, it works but creates an additional item in the database just for the member ID insert.

I believe this happens because the other data I send im using the no-code method connecting the inputs to the specific table from the database for every input on the screen. The only way I found to insert the current logged member ID into the CMS is through JavaScript, but it’s sending twice: once via the no-code method sending all the data and once via code sending only the memberId. I can’t find a way to ensure everything is sent only once without creating 2 items in the database.

here is my code to send the memberId:

export function buttonSubmit_click(event) {
    currentMember.getMember()
    .then(member => {
        if (member) {
            const userId = member._id;

                const toInsert = { "userId": userId };

                wixData.insert("Empresas1", toInsert)
                .then(result => {
                    console.log("Item inserido com sucesso:", result);
                })
                .catch(err => {
                    console.error("Erro ao inserir o item:", err);
                });
        } else {
            console.log("Nenhum membro logado.");
        }
    })
    .catch(err => {
        console.error("Erro ao obter o membro:", err);
    });
}

Importing highlight.js as a CDN resource in a typescript project?

The highlight.js project provides CDN assets that provide ES6 modules.

And I’m trying to import the hljs module like this in a typescript project (In order to get around this issue).

import hljs from 'https://unpkg.com/@highlightjs/[email protected]/es/highlight.min.js';

However doing the import like this produces the linting error:

Cannot find module ‘https://unpkg.com/@highlightjs/[email protected]/es/highlight.min.js’ or its corresponding type declarations.ts(2307)
Follow link (cmd + click)

Any ideas on how to get around this?

Creating a thumbnail from existing base64 encoded image and put it as data URI

In my React project, I first pull the full image from database as Base64 encoded string, and then display it in a webpage, like the following:

...react code...
return {
    <img src='data:image/jpeg;base64, /9j/4A.../>
}

I want to create a simply function that can take base64 encoded image as input, and output a new base64 encoded image with smaller size as the thumbnail, something like:

...react code...
return {
    <img src={createThumbnail('data:image/jpeg;base64, /9j/4A...)}/>
}

I found examples such as Creating thumbnail from existing base64 image, and base on which I tried something like below but the image will not get a src at all because the reason stated in the 1st post.

const createThumbnail = (base64Image, callback = x => {return x;}) => {
    console.log(base64Image)
    const img = new Image();
    img.src = base64Image;
    img.onload = () => {
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      ctx.drawImage(img, 0, 0, 100, 100);
      const thumbnail = canvas.toDataURL('image/jpeg');
      console.log(thumbnail)
      callback(thumbnail);
      
    }
  }

I do not understand why I need to use canvas or img.onload(...), since I have the base64 string already, how can I just open it as an image, shrink its size, and return the new image as base64?

DevExtream Show popup on datagird row click

I want to show display the pop up (app-process-enrollment) on row click rather than the button click (process column):

I’ve tried using (onRowClick) on the grid, but cannot get the data to properly load in the popup.

conn-item.component.html

<dx-data-grid *ngIf="sessions && sessions.length > 0" id="sessions" [dataSource]="sessions" keyExpr="Id"
    [columnAutoWidth]="true" [allowColumnResizing]="true" [hoverStateEnabled]="true" [showBorders]="false"
    [showColumnLines]="false" [showRowLines]="true">

    <dxi-column dataField="S.CD" caption="Created" dataType="date" sortOrder="desc"></dxi-column>
    <dxi-column *ngIf="c.t== 0" dataField="Summary.pc" caption="PCCost"></dxi-column>
    <dxi-column *ngIf="c.t == 0" caption="View" cellTemplate="process"></dxi-column>

    <div *dxTemplate="let data of 'process'">
        <app-en [s]="decaudates"></app-en>
    </div>
</dx-data-grid>

app-en.component.html

<ng-container *ngIf="mode == 'button'">
    <span class="" (click)="showImportUtility()"></span>    
</ng-container>

<!-- full screen enrollment process tool -->
<app-dialog #dialog [toolbarTitle]="screenTitle" [fullScreenOnLoad]="true" [showCloseButton]="true"
    [dragEnabled]="false" [visible]="showTool" (dialogClosed)="onDialogClosed()">
    ...
    ...
</app-dialog>

app-en.component.ts:

showImportUtility(): void {
    this.sId = this.s.ISId;
    this.PSC = this.s.PSC;
    this.showTool = true;
}