I have a restaurant menu web application, where the restaurant owners can manage their menus and have a specific menu page where the customer browse the menu item, now the customer want to have a mobile app for menu page only, to be installed on Android tablet.
What would be best solution implement pwa on the menu page or develop a new app for it
Category: javascript
Category Added in a WPeMatico Campaign
Paddle-js cannot be developed and tested in the local environment
I am trying to integrate Paddle payment into the website, and I have implemented the basic payment link according to the official tutorial.
https://developer.paddle.com/build/checkout/build-overlay-checkout
But localhost:5173 keeps showing an error
[Report Only] Refused to frame 'https://sandbox-buy.paddle.com/' because an ancestor violates the following Content Security Policy directive: "frame-ancestors http://localhost".
Understand this errorAI
5Chrome is moving towards a new experience that allows users to choose to browse without third-party cookies.Understand this warningAI
userscript.html?name=%25E8%25A7%25A3%25E9%2599%25A4%25E7%25BD%2591%25E9%25A1%25B5%25E9%2599%2590%25E5%2588%25B6.user.js&id=a185c09c-803f-4809-a5c0-eb7522366be2:364 key: {"type":"domain","url":"sandbox-buy.paddle.com"}
4.0f9ea896.chunk.js:2
POST https://sandbox-checkout-service.paddle.com/transaction-checkout 400 (Bad Request)
(anonymous) @ 4.0f9ea896.chunk.js:2
(anonymous) @ 4.0f9ea896.chunk.js:2
(anonymous) @ 4.0f9ea896.chunk.js:2
e.exports @ 4.0f9ea896.chunk.js:2
e.exports @ 4.0f9ea896.chunk.js:2
Promise.then
l.request @ 4.0f9ea896.chunk.js:2
r.forEach.l.<computed> @ 4.0f9ea896.chunk.js:2
(anonymous) @ 4.0f9ea896.chunk.js:2
(anonymous) @ main.44ffb68e.chunk.js:1
l @ 4.0f9ea896.chunk.js:2
(anonymous) @ 4.0f9ea896.chunk.js:2
(anonymous) @ 4.0f9ea896.chunk.js:2
r @ 4.0f9ea896.chunk.js:2
u @ 4.0f9ea896.chunk.js:2
(anonymous) @ 4.0f9ea896.chunk.js:2
(anonymous) @ 4.0f9ea896.chunk.js:2
(anonymous) @ main.44ffb68e.chunk.js:1
(anonymous) @ 4.0f9ea896.chunk.js:2
(anonymous) @ main.44ffb68e.chunk.js:1
l @ 4.0f9ea896.chunk.js:2
(anonymous) @ 4.0f9ea896.chunk.js:2
(anonymous) @ 4.0f9ea896.chunk.js:2
r @ 4.0f9ea896.chunk.js:2
u @ 4.0f9ea896.chunk.js:2
(anonymous) @ 4.0f9ea896.chunk.js:2
(anonymous) @ 4.0f9ea896.chunk.js:2
e @ main.44ffb68e.chunk.js:1
(anonymous) @ main.44ffb68e.chunk.js:1
(anonymous) @ main.44ffb68e.chunk.js:1
Ic @ 4.0f9ea896.chunk.js:2
t.unstable_runWithPriority @ 4.0f9ea896.chunk.js:2
qi @ 4.0f9ea896.chunk.js:2
Pc @ 4.0f9ea896.chunk.js:2
(anonymous) @ 4.0f9ea896.chunk.js:2
D @ 4.0f9ea896.chunk.js:2
_.port1.onmessage @ 4.0f9ea896.chunk.js:2Understand this errorAI
client:223 [vite] hot updated: /components/Sponsor.vue
Sponsor.vue:15 Paddle initialized
Send client side data to prisma [closed]
const onSubmit = (data)=>{
console.log(data);
}
this is an onSubmit function that is having data from react-hook-form.
Please help me send this to prisma to create a new task in my database.
How can I get CorelDRAW host Application Object on webview?
When I use IE mode, I can obtain the host object of CorelDRAW through the following API
window.external.Application;
, But when I switched to Webview mode, I couldn’t retrieve the object,
screenshot: https://i.sstatic.net/JN8xM72C.png
Here is my AppUI.xslt core code,
<xsl:template match="uiConfig/items">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
<itemData guid="50da125a-a3e2-4038-85ef-04a4e3ab1b8f"
type='browserEdge'
suppressDialogs='false'
openExternal="true"
href="[VGAppAddonsDir]/PopupHtmlAddon/index.html"
enable="true" />
</xsl:copy>
</xsl:template>
Why is the “let” lookahead different between for-in and for-of loops in ECMAScript?
The ForInOfStatement production in the specification for ECMAScript is defined as follow for the cases I’m confused about:
for ( [lookahead ≠ let [] LeftHandSideExpression in Expression ) Statement
for ( [lookahead ∉ { let, async of }] LeftHandSideExpression of AssignmentExpression )
Disregard the “async of” difference, that is already well documented.
Why is there a difference in the let
vs let [
negative lookahead?
The for-in has let [
as negative lookahead, my assumption is to avoid this syntax to be covered by the line above:
for (let[a] in [1]) ;
If this was covered by the line above, it would mean “assign the key of [1]
to (let)[a]
“.
Instead, that syntax is covered by another row that makes it a let declaration with a array destruction pattern.
Which makes sense.
This is covered, and valid, by the line above in the for-in case:
for (let.a in [1]) ;
I.e. assign the key of [1]
to let.a
.
But this is not allowed for the for-of case:
for (let.b of [1]) ;
Firefox says:
Uncaught SyntaxError: an expression X in ‘for (X of Y)’ must not start with ‘let’
Node and chrome says:
SyntaxError: The left-hand side of a for-of loop may not start with ‘let’.
There must be some more unambiguity for the for-of loop that makes the restrictions wider for that one, what is that unambiguity?
How can I upload a file when updating a onChange event?
I am using Nextjs and Resend to send emails from different forms. All my forms send the data without problems except for one which involves uploading a file.
This is how I build my forms.
I have a FormGroup component:
"use client";
import { useEffect, useState } from "react";
type FormGroupProps = {
label?: string;
inputType?: "input" | "textarea" | "select" | "file";
inputProps?:
| React.InputHTMLAttributes<HTMLInputElement>
| React.TextareaHTMLAttributes<HTMLTextAreaElement>;
selectOptions?: Array<{ value: string; label: string }>;
error?: string;
};
export default function FormGroup({
label,
inputType = "input",
inputProps,
selectOptions = [],
error,
}: FormGroupProps) {
const [hasError, setHasError] = useState(false);
useEffect(() => {
setHasError(error !== undefined);
}, [error]);
return (
<div
className={`form-group flex flex-col h-full gap-2.5 ${
inputProps?.className || ""
}`}
>
{label && (
<label
className="text-xs md:text-sm text-[#393E4F]"
htmlFor={inputProps?.id}
>
{label}
</label>
)}
{inputType === "input" && (
<input
type="text"
className={`border ${
hasError ? "border-red-500" : "border-gray-300"
} rounded w-full px-2 py-2 md:px-4 focus:outline-none focus:border-lightblue-primary`}
{...(inputProps as React.InputHTMLAttributes<HTMLInputElement>)}
/>
)}
{error && <div className="text-red-500 text-[10px] mt-1">{error}</div>}
{inputType === "textarea" && (
<textarea
className="border border-gray-300 rounded w-full px-2 py-2 md:px-4 h-24 focus:outline-none focus:border-lightblue-primary"
{...(inputProps as React.TextareaHTMLAttributes<HTMLTextAreaElement>)}
/>
)}
{inputType === "file" && (
<input
type="file"
className="border border-gray-300 rounded w-full px-2 py-2 md:px-4 focus:outline-none focus:border-lightblue-primary"
{...(inputProps as React.InputHTMLAttributes<HTMLInputElement>)}
/>
)}
{inputType === "select" && (
<div className="flex flex-wrap gap-2">
{selectOptions?.map((option) => (
<label key={option.value} className="flex items-center gap-2">
<input
type="radio"
value={option.value}
name={inputProps?.name}
onChange={inputProps?.onChange}
className="form-radio"
/>
{option.label}
</label>
))}
</div>
)}
</div>
);
}
Then I have a GenericForm component:
"use client";
import React, { useState } from "react";
import FormGroup from "./FormGroup";
import FormTitle from "./FormTitle";
interface GenericFormProps<T extends FormData> {
title: string;
fields: Array<{ label: string; inputType: string; name: keyof T }>;
onSubmit: (data: T) => void;
errors: { [key in keyof T]?: string };
handleChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
}
interface FormData {
nombre: string;
apellido: string;
dni: string;
celular: string;
mail: string;
comentarios: string;
cv?: {
name: string;
type: string;
base64: string;
};
}
function GenericForm<T extends FormData>({
title,
fields,
onSubmit,
errors,
handleChange,
}: GenericFormProps<T>) {
const initialFormData = {} as T;
const [formData, setFormData] = useState<T>(initialFormData);
const combinedHandleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
if (handleChange) {
handleChange(event);
}
const { name, value, files } = event.target as HTMLInputElement & {
files: FileList | null;
};
setFormData((prevData) => ({
...prevData,
[name]: files ? files[0] : value,
}));
};
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
onSubmit(formData);
if (!Object.values(errors).some((error) => error !== undefined)) {
setFormData(initialFormData);
}
};
return (
<>
<FormTitle title={title} />
<div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 form-container">
{fields.map((field, index) => (
<div
key={index}
className={`${
fields.length % 2 !== 0 && index === fields.length - 1
? "md:col-span-2"
: ""
}`}
>
<FormGroup
label={field.label}
inputType={field.inputType}
inputProps={{
value: formData[field.name] || "",
onChange: combinedHandleChange,
name: field.name,
}}
selectOptions={field.selectOptions}
error={errors[field.name]}
/>
</div>
))}
</div>
<div className="flex justify-center mt-4">
<button
type="submit"
onClick={handleSubmit}
className="bg-[#00ADEE] w-full text-white py-2 px-8 rounded-[8px] focus:outline-none"
>
Enviar
</button>
</div>
</div>
</>
);
}
export default GenericForm;
And the form that is failing is TrabajaConNosotros.tsx:
"use client";
import GenericForm from "./GenericForm";
import TrabajaConNosotrosSchema from "@/schemes/trabaja-con-nosotros.scheme";
import handleSubmit from "@/utils/submitForm";
import { useState } from "react";
const TrabajaConNosotros = () => {
const fields = [
{ label: "Nombre", inputType: "input", name: "nombre" },
{ label: "Apellido", inputType: "input", name: "apellido" },
{ label: "DNI (sin puntos)", inputType: "input", name: "dni" },
{ label: "Celular", inputType: "input", name: "celular" },
{ label: "Mail", inputType: "input", name: "mail" },
{ label: "Comentarios", inputType: "textarea", name: "comentarios" },
{ label: "Adjuntar CV", inputType: "file", name: "cv" },
];
const [errors, setErrors] = useState({});
const [selectedFile, setSelectedFile] = useState<File | null>(null);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (file) {
setSelectedFile(file);
}
};
const readFileAsync = (file: File): Promise<string> =>
new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result as string);
reader.onerror = reject;
reader.readAsDataURL(file);
});
const onSubmit = async (data: FormData) => {
if (selectedFile) {
try {
const base64 = await readFileAsync(selectedFile);
const formDataWithCV = {
...data,
cv: {
name: selectedFile.name,
type: selectedFile.type,
base64: base64.split(',')[1],
},
};
await handleSubmit(formDataWithCV, TrabajaConNosotrosSchema, 'trabajar_con_nosotros');
setErrors({});
} catch (err) {
console.error(err);
}
} else {
try {
await handleSubmit(data, TrabajaConNosotrosSchema, 'trabajar_con_nosotros');
setErrors({});
} catch (err) {
if (err.inner) {
const formErrors = err.inner.reduce((acc, currentError) => {
acc[currentError.path] = currentError.message;
return acc;
}, {});
setErrors(formErrors);
} else {
setErrors({ general: "Ha ocurrido un error desconocido" });
}
}
}
};
return (
<GenericForm
title="Trabajá con nosotros"
fields={fields}
onSubmit={onSubmit}
errors={errors}
handleChange={handleChange}
/>
);
};
export default TrabajaConNosotros;
The error occurs when I select a file to upload and inmediately have the following error in my screen:
Uncaught DOMException: An attempt was made to use an object that is not, or is no longer, usable
From this error message I assume it has something to do with the onChange event but I have no clue how to fix it.
Trying to show all events in fullCalendar EXCEPT the events that have ID “except_date”
I am trying to get a form showing when a date is clicked in fullCalendar. I want all the events available on that date to show up in the form, EXCEPT those dates that have the title “excursion name . “+ Except Date”” and id “except_date”. So I want the form to show all of the events except the events that I have given id “except_date”.
var eventsOnDate = allEvents.filter(function(event) {
var eventStart = event.startStr; // Event start date (ISO string)
var eventEnd = event.endStr; // Event end date (ISO string, exclusive)
var except_dates = calendar.getEventById("except_date");
return info.dateStr >= eventStart && info.dateStr < eventEnd && event.id !== except_dates.id ;
});
The problem is that I get Uncaught SyntaxError: '#' not followed by identifier
when I try to run it in my browser.
This is my full code
global $wpdb;
$table_name = 'wp_booking_seasons';
//select all rows from the database
$results = $wpdb->get_results("SELECT * FROM $table_name");
ob_start(); // Start output buffering
?>
<div id="calendar"></div>
<div id="date-selection-form" style="display:none;">
<h3>Select Date Information</h3>
<form id="date-form">
<label for="event-title">Event Title:</label>
<input type="text" id="event-title" name="event-title" readonly style="width:400px"><br><br>
<!input type="text" id="event-title" name="event-title" required><br><br>
<input type="hidden" id="selected-date" name="selected-date">
<div id="time-slots">
<!-- Time slots will be dynamically inserted here -->
</div><br>
<input type="submit" value="Submit">
</form>
</div>
<script>
// show fullcalendar
document.addEventListener('DOMContentLoaded', function() {
// show calendar within the calendar div
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
//Set month view of the calendar
initialView: 'dayGridMonth',
//start the events array
events: [
<?php
//initialize an empty events array
$events= [];
//iterate through each row of events
foreach ($results as $row){
//INSERT SEASONAL EVENTS
//insert into events array the json_encoded (string version) of the title, startdate and end date. These correspond to the season in which the excursions are available for booking
$events[]= json_encode([
//fetch each row value from the database
'title'=> $row->excursion_name,
'start'=> $row->start_date,
'end'=> $row->end_date,
'timeSlots' => esc_js($row->time_slots)
]);
//INSERT EXCEPT DATES INTO THE CALENDAR
//check if the except_dates row is empty
if (!empty($row->except_dates)) {
$except_dates = json_decode($row->except_dates, true);
if (is_array($except_dates)) {
//fetch the values from the except_dates array
foreach ($except_dates as $key => $date) {
$events[] = json_encode([
//give except dates a new name
'id' => "except_date",
'title' => $row->excursion_name . " - Except Date",
'start' => $date,
'end' => $date,
]);
}
}
}
}
//join together all of the events with , into the events array
echo implode(",n", $events); ?>
],
dateClick: function(info) {
var dateForm = document.getElementById('date-selection-form');
dateForm.scrollIntoView({ behavior: 'smooth', block: 'start' });
document.getElementById('selected-date').value = info.dateStr;
document.getElementById('date-selection-form').style.display = 'block';
// Get all events on the calendar
var allEvents = calendar.getEvents();
// Filter events that match the clicked date
var eventsOnDate = allEvents.filter(function(event) {
var eventStart = event.startStr; // Event start date (ISO string)
var eventEnd = event.endStr; // Event end date (ISO string, exclusive)
var except_dates = calendar.getEventById("except_date");
return info.dateStr >= eventStart && info.dateStr < eventEnd && event.id !== except_dates.id ;
});
// Get the "Event Title" input field
var eventTitleInput = document.getElementById('event-title');
var timeSlotsDisplay = document.getElementById('time-slots');
// Display the event titles in the input field
if (eventsOnDate.length > 0) {
var eventTitles = [];
var timeSlots = [];
eventsOnDate.forEach(function(event) {
eventTitles.push(event.title);
// Extract time slots if available
if (event.extendedProps.timeSlots) {
var slots = event.extendedProps.timeSlots.split(","); // Assuming CSV format
timeSlots.push(...slots);
}
});
// Populate the event title and time slots
eventTitleInput.value = eventTitles.join(", ");
timeSlotsDisplay.innerHTML = "<strong>Available Time Slots:</strong><ul><li>" + timeSlots.join("</li><li>") + "</li></ul>";
} else {
// Clear fields if no events
eventTitleInput.value = "";
timeSlotsDisplay.innerHTML = "<strong>No time slots available for the selected date.</strong>";
}
//alert("Date clicked: " + info.dateStr); // Date string from FullCalendar
}
});
calendar.refetchEvents();
calendar.render();
});
</script>
<?php
return ob_get_clean(); // Return the buffered content
Event loop in Node JS for Promises
I was going through the event loop in JavaScript and how it makes the JS to perform asynchronous operations even though it is a single threaded language. In that I learnt that the microtasks or process.nextTick run whenever the call stack is empty and between every phase.
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('first timeout');
resolve('1');
},1000);
console.log('2');
setTimeout(() => {
console.log('3');
},1000);
});
myPromise.then((value) => {
console.log("First then received:", value);
setTimeout(() => {
console.log('5');
},0);
}).catch((error) => {
console.log("Caught in catch:", error);
});
In the above code I was expecting the output to be
2
first timeout
First then received: 1
3
5
because the setTimeout-5 function will be pushed to the macroTask queue after the setTimeout-3 because “only resolving object will be mictoTask” and microTasks will execute after the synchronous code executes.
but the output when I try to run in node version 23 is
2
first timeout
First then received: 1
5
3
Is there a fault in my understanding? where am I missing?
Hide complete field(label and options) based on the id
I am trying to hide the below question(both title and options) using the id “fe3739” using javascript. When I try to hide using the id(fe3739), it only hides options. I know there is one more id “formElement64” which can be used for hiding the complete question but my requirement was to hide using the id “fe3739”.
$("#fe3739").hide();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class="row">
<div class="grid-layout-col">
<div class="layout-col col-sm-12 col-xs-12">
<div id="formElement64" class="field-style form-element-layout row">
<div style="text-align:left;" class="col-sm-12 col-xs-12">
<label class="elq-label " for="fe3739">How would you describe your data domain?</label>
</div>
<div class="col-sm-12 col-xs-12">
<div class="row">
<div class="col-xs-12">
<div class="field-control-wrapper">
<select class="item-select" id="fe3739" name="dropdownMenu17" style="width:100%;" data-value="">
<option value="">Please Select</option>
<option value="Fraud & Risk">Fraud & Risk</option>
<option value="Marketing">Marketing</option>
<option value="Product">Product</option>
<option value="Sales">Sales</option>
<option value="Other">Other</option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
The below one just hides the options not the complete question including title
$("#fe3739").hide();
Error in IQoption API trying to execute trade via api
“Trade API response: (False, ‘Cannot purchase an option (active is suspended)’) (‘Cannot purchase an option (active is suspended)’,)”
Have been receiving this error on my iqoption api on trying to execute a trade
Tried updating to newer version of IqOption Library but the error persists
unable to zoom to given geojson data in cesium
I am unable to zoom to given geojson data in cesium primarily because data is also not visible on cesium.
I am using the following code:
const geoJsonUrl = 'visibility.geojson';
Cesium.GeoJsonDataSource.load(geoJsonUrl).then(function (dataSource) {
viewer.dataSources.add(dataSource);
console.log(dataSource);
// Zoom to the data once loaded
viewer.zoomTo(dataSource);
});
I am expecting on opening the screen it should zoomed me to given geojson location, where geojson data is also visible
How to load an SVG from a string in Pixi.js
This works:
const texture = await Assets.load('/pin.svg')
But I want to include the SVG in the JS file as a string, like:
const svgString = '...'
const texture = await Assets.load(svgString)
But Assets.load()
doesn’t support SVG as a string, which I find incredibly weird. Is there a workaround?
Soundcloud API: delay in audio playing on iPhone
I am using the SoundCloud widget in this game:
https://tuneepuzzle.github.io/play
I haven’t been able to make it work properly on Apple products, especially on iPhone. SC.Widget.play() has a delay of a few hundred milliseconds, which in the context of this game is fatal. Strangely, the SC.Widget.Events.PLAY event fires at the expected time, it’s just the sound itself that starts late. This happens with either Safari or Chrome on iPhone.
I’m encountering a similar issue with Safari on Macbook, with a slightly smaller delay. Chrome and Firefox on Macbook work fine with no noticeable lag. Chrome on Android also works fine.
To recap:
iOS: about 500ms delay between the PLAY event and the sound, with any browser
Safari on Mac: about 300ms delay
Other browsers on Mac: no delay
Chrome on Android: no delay
I noticed the delay is present in other applications using the widget, like the Heardle family of games, only for them it’s not as critical.
Any suggestions for remedies?
Tried to minimize the number of play() calls and the stuff the happens in the PLAY event listener, but it doesn’t seem to matter.
Detect Command+R and Command+H in Safari
I would like my webapp to do certain tasks when pressing Ctrl+R (Windows) or Command+R (Mac), just like native apps do.
It works fine in all browsers (e.g. Firefox on Windows, Chrome on Mac, …) except of Safari on Mac.
In Safari on Mac, Command+R always reloads a website. Is there a way a website can prevent it? My current code is here: https://jsfiddle.net/p45f44zb/14/ I use
Event.preventDefault();
but it seems like it does not help 🙁
Streaming a large zip file from NodeJS, Express
I want to downaload a large zip file of 3GB consisting 2000 or more images with their thumbnails to mobile application depending on user’s request from my NodeJS Express server using a route.
Zip file is created using archiver inside a worker. it works fine up to this point.
On my local machine it is too-good but on production, sometimes it works really fast when streaming and sometimes it takes too-long that it reaches timeout after 5 to 10% of download only. Even at that time there no such load on server.
Following is something like my implementation. I can’t figure out the actual problem.
Is it beacuse when my internet is slow, the server sends data very slowly to match my download speed or it’s something else??
const fs = require('fs');
const fsPromises = require('fs/promises');
const crypto = require('crypto');
const path = require('path');
const { logger } = require('config/winston');
const downloadZip = async (req, res) => {
// Create archive
const fnm = 'file_' + crypto.randomBytes(8).toString('hex');
const zipName = fnm + 'zip';
const zipFilePath = path.join('tmpfolder', zipName);
// Get archive from worker
try {
const images = await getImages();
zipStatus = await zipWorker(images);
} catch (err) {
throw `Error in creating zip.`;
}
// Get stats
let zipSize = 0;
try {
const zipStats = await fsPromises.stat(zipFilePath);
zipSize = zipStats.size || 0;
} catch (err) {
throw `Zip stats not found.`;
}
// Download
logger.verbose(`Preparing to download.`);
res.setHeader('Content-Type', 'application/zip');
res.setHeader('Content-Disposition', `attachment; filename=images.zip`);
res.setHeader('Content-Length', zipSize);
const resFile = fs.createReadStream(zipFilePath);
resFile.pipe(res);
resFile.on('error', err => {
logger.error(`Error in streaming zip.`);
res.end();
});
// Print downloading percent on server
let bytesSent = 0;
resFile.on('data', chunk => {
if (zipSize > 0) {
bytesSent += chunk?.length;
const percentage = ((bytesSent / zipSize) * 100).toFixed(2);
logger.verbose(`Downloading ${percentage}%`); // <== Downloading completed in %
}
});
// If completed
resFile.on('end', () => {
logger.verbose(`Images downloaded.`);
});
res.on('close', () => {
resFile.destroy(); // Close the file stream immediately
});
res.on('finish', () => {
logger.verbose(`File streamed successfully.`);
});
};