Skip to content

Instantly share code, notes, and snippets.

@chriswitko
Created September 11, 2024 02:15
Show Gist options
  • Save chriswitko/671f8dbc0d6165fc7bf6e56e314a60ee to your computer and use it in GitHub Desktop.
Save chriswitko/671f8dbc0d6165fc7bf6e56e314a60ee to your computer and use it in GitHub Desktop.

Revisions

  1. chriswitko created this gist Sep 11, 2024.
    126 changes: 126 additions & 0 deletions rating.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,126 @@
    class RatingComponent extends HTMLElement {
    constructor() {
    super();
    this.attachShadow({ mode: 'open' });
    this.code = this.getAttribute('code') || '';
    this.render();
    }

    get open() {
    return this.hasAttribute('open');
    }

    set open(value) {
    if (value) {
    this.setAttribute('open', '');
    } else {
    this.removeAttribute('open');
    }
    this.render();
    }

    connectedCallback() {
    this.render();
    }

    render() {
    this.shadowRoot.innerHTML = `
    <style>
    :host { display: ${this.open ? 'block' : 'none'}; }
    .modal {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 300px;
    background-color: white;
    border: 1px solid #ccc;
    box-shadow: 0 4px 8px rgba(0,0,0,0.1);
    padding: 16px;
    z-index: 1000;
    }
    .stars {
    display: flex;
    cursor: pointer;
    margin-bottom: 10px;
    }
    .star {
    font-size: 24px;
    color: #ccc;
    }
    .star.selected {
    color: gold;
    }
    .comment-box {
    width: 100%;
    margin-bottom: 10px;
    }
    .modal-footer {
    display: flex;
    justify-content: space-between;
    }
    </style>
    <div class="modal">
    <div class="stars">
    ${[1, 2, 3, 4, 5].map((i) => `
    <span class="star" data-value="${i}">&#9733;</span>
    `).join('')}
    </div>
    <textarea class="comment-box" placeholder="Leave a comment..." rows="3"></textarea>
    <div class="modal-footer">
    <button class="close-btn">Close</button>
    <button class="submit-btn">Submit</button>
    </div>
    </div>
    `;

    this.shadowRoot.querySelectorAll('.star').forEach(star => {
    star.addEventListener('click', (e) => this.selectRating(e));
    });

    this.shadowRoot.querySelector('.close-btn').addEventListener('click', () => this.close());
    this.shadowRoot.querySelector('.submit-btn').addEventListener('click', () => this.submit());
    }

    selectRating(e) {
    const value = e.target.getAttribute('data-value');
    this.selectedRating = value;

    this.shadowRoot.querySelectorAll('.star').forEach(star => {
    star.classList.toggle('selected', star.getAttribute('data-value') <= value);
    });
    }

    close() {
    this.open = false;
    this.dispatchEvent(new CustomEvent('close'));
    }

    submit() {
    const comment = this.shadowRoot.querySelector('.comment-box').value;
    const rating = this.selectedRating;

    if (rating) {
    const payload = {
    rating,
    comment,
    code: this.code
    };
    console.log('Submitting:', payload);

    // Simulate sending data to the server
    this.dispatchEvent(new CustomEvent('submit', { detail: payload }));

    // Close the modal after submission
    this.close();
    } else {
    alert('Please select a rating.');
    }
    }
    }

    customElements.define('rating-component', RatingComponent);