#astro.js button onclick attribute

1 messages · Page 1 of 1 (latest)

onyx flickerBOT
#

Hi @steep echo. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

In Astro, you can't directly use the onclick attribute with JavaScript code as you might in plain HTML. This is because Astro components are templates that run once during the rendering step, and they don't have built-in reactivity for client-side interactions.

Instead, you can achieve this functionality by using a client-side script to add the event listener. Here's how you can do it:

  1. First, add a unique identifier to your button, such as a data attribute:
<button data-copy-button="${item.code}">Copy Link</button>
  1. Then, add a <script> tag to your Astro component to handle the click event:
<script>
  document.querySelectorAll('[data-copy-button]').forEach((button) => {
    button.addEventListener('click', () => {
      const code = button.getAttribute('data-copy-button');
      navigator.clipboard.writeText(`<https://site.fr/${code}`>);
    });
  });
</script>

This approach is recommended in Astro for handling client-side interactivity, as explained in the Scripts and event handling guide.

Remember that the script will run for all buttons with the data-copy-button attribute on the page, so you can reuse this component multiple times if needed.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@steep echo Kapa.ai is still learning and improving, please let me know how I did by reacting below.

#

Let me check the knowledge base for you again. One moment! :books:

#

D'accord, je vais mettre à jour le composant pour intégrer la solution que j'ai proposée précédemment. Voici le composant mis à jour :

---
// StackedList.astro

// Importer les données JSON directement en tant que module
import linksData from '@data/links.json' assert { type: 'json' };

interface Item {
  url: string;
  code: string;
  description: string;
  date: string;
}

// Les données sont maintenant directement disponibles dans linksData
const items = linksData as Item[];
---

<section class="bg-smalt-100 dark:bg-smalt-800 py-12 md:py-16">
  <div class="container mx-auto px-4 md:px-6">
    <div class="max-w-2xl mx-auto space-y-6">
      <div class="bg-white dark:bg-smalt-950 rounded-lg shadow-sm">
        <div class="px-6 py-5 border-b border-gray-200 dark:border-gray-800">
          <h3 class="text-lg text-smalt-700 font-extrabold font-titre">All My Links</h3>
        </div>
        <div class="space-y-4 p-6">
          {items.map(item => (
            <div>
              <div class="flex items-center justify-between">
                <a href={item.url} class="text-smalt-900 dark:text-smalt-800 font-texte">
                  sbsb.fr/<b class="font-medium truncate">{item.code}</b>
                </a>
                <button
                  data-copy-button={item.code}
                  title="Copier"
                  class="block w-full rounded bg-smalt-600 px-12 py-3 text-sm font-medium text-white shadow hover:bg-smalt-700 focus:outline-none focus:ring active:bg-smalt-500 sm:w-auto font-texte"
                >
                  Copier
                </button>
              </div>
              <div class="text-smalt-500 dark:text-smalt-400 text-sm truncate font-texte">{item.description}</div>
            </div>
          ))}
        </div>
      </div>
    </div>
  </div>
</section>
#

<script>
document.querySelectorAll('[data-copy-button]').forEach((button) => {
button.addEventListener('click', () => {
const code = button.getAttribute('data-copy-button');
navigator.clipboard.writeText(<https://site.fr/${code}>);
});
});
</script>


Dans cette mise à jour, j'ai apporté les modifications suivantes :

1. J'ai remplacé l'attribut `onclick` du bouton par un attribut `data-copy-button` qui contient le code de l'item :

```astro
<button
  data-copy-button={item.code}
  title="Copier"
  class="block w-full rounded bg-smalt-600 px-12 py-3 text-sm font-medium text-white shadow hover:bg-smalt-700 focus:outline-none focus:ring active:bg-smalt-500 sm:w-auto font-texte"
>
  Copier
</button>
  1. J'ai ajouté un script à la fin du composant qui gère l'événement de clic pour tous les boutons avec l'attribut data-copy-button :
<script>
  document.querySelectorAll('[data-copy-button]').forEach((button) => {
    button.addEventListener('click', () => {
      const code = button.getAttribute('data-copy-button');
      navigator.clipboard.writeText(`<https://site.fr/${code}`>);
    });
  });
</script>

Cette approche est conforme aux meilleures pratiques d'Astro pour la gestion des scripts côté client, comme décrit dans le guide sur les scripts et la gestion des événements.

Ce code ajoutera un écouteur d'événements à chaque bouton "Copier", et lorsqu'un bouton est cliqué, il copiera l'URL correspondante dans le presse-papiers.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@steep echo Kapa.ai is still learning and improving, please let me know how I did by reacting below.

#

Let me check the knowledge base for you again. One moment! :books:

#

Je m'excuse pour la confusion. Vous avez raison, il est plus facile de copier-coller le code lorsqu'il est présenté séparément en markdown. Voici le code du composant mis à jour en format markdown pour faciliter le copier-coller :

---
// StackedList.astro

// Importer les données JSON directement en tant que module
import linksData from '@data/links.json' assert { type: 'json' };

interface Item {
  url: string;
  code: string;
  description: string;
  date: string;
}

// Les données sont maintenant directement disponibles dans linksData
const items = linksData as Item[];
---
#

<section class="bg-smalt-100 dark:bg-smalt-800 py-12 md:py-16">
<div class="container mx-auto px-4 md:px-6">
<div class="max-w-2xl mx-auto space-y-6">
<div class="bg-white dark:bg-smalt-950 rounded-lg shadow-sm">
<div class="px-6 py-5 border-b border-gray-200 dark:border-gray-800">
<h3 class="text-lg text-smalt-700 font-extrabold font-titre">All My Links</h3>
</div>
<div class="space-y-4 p-6">
{items.map(item => (
<div>
<div class="flex items-center justify-between">
<a href={item.url} class="text-smalt-900 dark:text-smalt-800 font-texte">
sbsb.fr/<b class="font-medium truncate">{item.code}</b>
</a>
<button
data-copy-button={item.code}
title="Copier"
class="block w-full rounded bg-smalt-600 px-12 py-3 text-sm font-medium text-white shadow hover:bg-smalt-700 focus:outline-none focus:ring active:bg-smalt-500 sm:w-auto font-texte"
>
Copier
</button>
</div>
<div class="text-smalt-500 dark:text-smalt-400 text-sm truncate font-texte">{item.description}</div>
</div>
))}
</div>
</div>
</div>
</div>
</section>

<script>
document.querySelectorAll('[data-copy-button]').forEach((button) => {
button.addEventListener('click', () => {
const code = button.getAttribute('data-copy-button');
navigator.clipboard.writeText(<https://site.fr/${code}>);
});
});
</script>


Vous pouvez maintenant facilement copier-coller ce code dans votre fichier Astro.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------