blank

mrfdn.com – Kali ini saya sedang belajar Solidjs.

Di sini saya ingin submit dan fetch data secara otomatis dari dan ke google sheet.

Saya menggunakan Astro, dan menjalankan SolidJS sebagai component.

Komponen ini yang saya buat ini digunakan untuk menghandle kirim ucapan / komentar untuk web invitation.

Di sini saya dibantu oleh ChatGPT untuk generate codingan solid js.

Langsung saja begini caranya:

Install package solidjs#

Pastikan sudah install solid di projekan astro

settingan tambahan astro akan otomatis regenerate di file astro.config.mjs

Folder structure#

sekarang kita hanya perlu bekerja di file berikut:

src/
├── pages
│   ├── index.astro
└── solid
├── app.jsx
└── form.jsx

Componen solid disimpan pada foler /src/solid/.

Buat komponen utama SolidJS : App.jsx#

// App.jsximport { createSignal, onCleanup } from 'solid-js';import KonfirmasiHadir from './form.jsx';// Define the URL of the CSV endpointconst csvEndpoint = "https://docs.google.com/spreadsheets/d/asdfasdfadsfak/export?format=csv";// SolidJS componentfunction App() { // State to hold the JSON data const [jsonData, setJsonData] = createSignal(null); // Function to fetch CSV data and convert it to JSON async function fetchAndConvert() { try { // Make an HTTP request to the CSV endpoint using the built-in fetch function const response = await fetch(csvEndpoint); // Check if the request was successful (status code 200) if (!response.ok) { throw new Error(`HTTP error! Status:${response.status}`); } // Get the CSV data as text const csvData = await response.text(); // Parse CSV text directly (replace with your own CSV parsing logic) const jsonArray = parseCsvText(csvData); // Process the resulting JSON array console.log(jsonArray); // Update the component state with the JSON data setJsonData(jsonArray); } catch (error) { console.error('Error fetching or converting data:', error.message); } } // Callback function to be passed to KonfirmasiHadir component const handleDataSubmitted = () => { // Fetch data in App component when form is submitted fetchAndConvert(); }; // Function to parse CSV text into a JSON array function parseCsvText(csvText) { // Replace this logic with your own CSV parsing implementation const lines = csvText.split('\n'); const headers = lines[0].split(','); const jsonArray = []; for (let i = 1; i < lines.length; i++) { const values = lines[i].split(','); const entry = {}; for (let j = 0; j < headers.length; j++) { entry[headers[j]] = values[j]; } jsonArray.push(entry); } return jsonArray; } // Fetch data when the component mounts fetchAndConvert(); // Cleanup function to cancel any ongoing fetch when the component unmounts onCleanup(() => { // Any cleanup logic, e.g., cancelling ongoing requests }); // Render the component return ( <div> {jsonData() ? ( // Render your JSON data as needed <> <KonfirmasiHadir onDataSubmitted={handleDataSubmitted} /> <ul style="padding:0;"> {jsonData().map((item, index) => ( <li style="list-style:none;" key={index}> <p style="font-weight:bold;">{item.nama}</p> <i>{item.pesan}</i> <hr/> </li> ))} </ul> </> ) : ( // Render a loading indicator or other UI while fetching data <p>Loading...</p> )} </div> );}export default App;

Buat komponen Form.jsx#

import { createSignal } from 'solid-js';function KonfirmasiHadir({ onDataSubmitted }) { const [hadirChecked, setHadirChecked] = createSignal(false); const [loading, setLoading] = createSignal(false); const [formSubmitted, setFormSubmitted] = createSignal(false); const scriptURL = 'https://script.google.com/macros/s/asdfasdgasdfagasdf/exec'; const handleSubmit = async (event) => { event.preventDefault(); setLoading(true); try { const form = event.target; const formData = new FormData(form); const response = await fetch(scriptURL, { method: 'POST', body: formData }); if (response.ok) { console.log('Success!', response); setFormSubmitted(true); // Reset the form form.reset(); // Trigger the callback function if (onDataSubmitted) { onDataSubmitted(); } } else { console.error('Error!', response.statusText); } } catch (error) { console.error('Error!', error.message); } finally { setLoading(false); } }; const handleHadirChange = () => { setHadirChecked(!hadirChecked()); }; return ( <form class="" name="submit-form" onSubmit={handleSubmit} > <label class=""> Nama lengkap <input name="nama" type="text" class="" required /> </label> <div class="my-6"> <label for="hadir" class=""> <input type="radio" id="hadir" name="konfirmasi" value="yes" checked={hadirChecked()} onChange={handleHadirChange} class="text-black" required /> Ya, saya akan datang </label> <label for="tidakhadir" class="block font-bold"> <input type="radio" id="tidakhadir" name="konfirmasi" value="no" checked={!hadirChecked()} onChange={handleHadirChange} class="text-black" required /> Tidak, saya tidak bisa datang </label> </div> <div id="hadirberapa" style={{ display: hadirChecked() ? "block" : "none" }} class="block font-bold"> <label for="floatingPassword" class="block font-bold"> Berapa orang? <input type="text" inputmode="numeric" pattern="[0-9]+" name="jumlah" class="" /> </label> </div> <div class=""> <label for="ucapan" class="block font-bold"> Isi ucapan <input name="pesan" type="text" class="" /> </label> </div> <button class={`bg-blue-400${loading() ? "hidden" : "block"} bg-white/20 p-4 font-bold`} type="submit" disabled={loading()}> Kirim </button> <button class={`bg-red-400${loading() ? "" : "hidden"} bg-white/20 p-4 font-bold`}>Loading</button> {/*<button type="submit" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" disabled={loading()} > {loading() ? 'Loading...' : 'Kirim'} </button> {formSubmitted() && ( <p class="text-green-500 font-bold mt-4">Terima kasih, data Anda telah terkirim!</p> )}*/} </form> );}export default KonfirmasiHadir;

Panggil komponennya di halaman astro: index.astro#

---import App from "../solid/app.jsx";---<html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> <meta name="viewport" content="width=device-width" /> <meta name="generator" content={Astro.generator} /> <title>Komentar</title> </head> <body> <App client:load /> </body></html>

Jangan lupa set client:load supaya astro bisa load fungsi pada komponen tersebut.

Kesimpulan#

Jadi pada form ini, setelah menekan tombol kirim, maka akan mengirim data dulu ke google sheet kemudian secara otomatis komponen utama (App.jsx) akan fetch data lagi dari google sheet.

Semoga bermanfaat.

PakarPBN

A Private Blog Network (PBN) is a collection of websites that are controlled by a single individual or organization and used primarily to build backlinks to a “money site” in order to influence its ranking in search engines such as Google. The core idea behind a PBN is based on the importance of backlinks in Google’s ranking algorithm. Since Google views backlinks as signals of authority and trust, some website owners attempt to artificially create these signals through a controlled network of sites.

In a typical PBN setup, the owner acquires expired or aged domains that already have existing authority, backlinks, and history. These domains are rebuilt with new content and hosted separately, often using different IP addresses, hosting providers, themes, and ownership details to make them appear unrelated. Within the content published on these sites, links are strategically placed that point to the main website the owner wants to rank higher. By doing this, the owner attempts to pass link equity (also known as “link juice”) from the PBN sites to the target website.

The purpose of a PBN is to give the impression that the target website is naturally earning links from multiple independent sources. If done effectively, this can temporarily improve keyword rankings, increase organic visibility, and drive more traffic from search results.

Jasa Backlink

Download Anime Batch

Leave a Reply

Your email address will not be published. Required fields are marked *

TOP