ruby POS system. AJAX Adding an item executes twice

40 Views Asked by At

I'm kinda still new to web development and just started working on a POS system as a fun little project. I'm struggling really hard with my items page, I basically need all crud to be done on one page and I tried using AJAX to accomplish this, so far I have a button you click, and it shows the modal that has a form to add a new item, and it works but seems to execute twice, so I get two of the same item, but it only shows the extra one when I manually refresh the page. Everything I've seen points to how my javascript is loaded, but any help with be appreciated.

Here's my javascript:

document.addEventListener('turbolinks:load', () => {
  // Function to open the "New Item" modal
  newItemButton.addEventListener('click', () => {
    newItemModal.style.display = 'block';
  });

  // Function to open the "Edit Item" modal
  editItemButtons.forEach(button => {
    button.addEventListener('click', () => {
      const itemId = button.dataset.id;
      const formData = new FormData(editItemForm);

      // Use AJAX to fetch item details and populate the form
      fetch(`/items/${itemId}/update_item`, {
          method: 'PATCH', // Use PATCH method for updates
          headers: {
            'X-CSRF-Token': csrfToken,
            'Accept': 'application/json'
          },
          body: formData
        })
        .then(response => {
          if (!response.ok) {
            throw new Error('Network response was not ok');
          }
          return response.json();
        })
        .then(item => {
          const form = editItemModal.querySelector('form');
          form.action = `/items/${itemId}`;
          form.querySelector('[name="item[name]"]').value = item.name;
          form.querySelector('[name="item[cost_price]"]').value = item.cost_price;
          form.querySelector('[name="item[sale_price]"]').value = item.sale_price;
          form.querySelector('[name="item[category]"]').value = item.category;
          editItemModal.style.display = 'block';
        });
    });
  });

  // Function to close the modals when clicking outside of them
  window.addEventListener('click', event => {
    if (event.target === newItemModal || event.target === editItemModal) {
      newItemModal.style.display = 'none';
      editItemModal.style.display = 'none';
    }
  });

  closeButtons.forEach(button => {
    button.addEventListener('click', () => {
      newItemModal.style.display = 'none';
      editItemModal.style.display = 'none';
    });
  });

  newItemForm.addEventListener('submit', event => {
    event.preventDefault();

    const formData = new FormData(newItemForm);
    fetch('/items', {
        method: 'POST',
        headers: {
          'X-CSRF-Token': '<%= form_authenticity_token %>',
          'Accept': 'application/json'
        },
        body: formData
      })
      .then(response => response.json())
      .then(item => {
        // Append the new item to the list without reloading the page
        console.log("adding new item")
        const newRow = itemList.insertRow();
        newRow.innerHTML = `
          <td>${item.name}</td>
          <td>${item.price}</td>
          <td>${item.category}</td>
          <td>
            <button class="edit-item-button" data-id="${item.id}">Edit</button>
            <button class="delete-item-button" data-id="${item.id}">Delete</button>
          </td>
        `;

        // Reset the form and close the modal
        newItemModal.style.display = 'none';
      })
      .catch(error => console.error('Error:', error));
  });
});
class ItemsController < ApplicationController
  def index
    @items = current_user.items # Fetch items for the current user
  end

  def create
    puts 'Create Item action called'
    @item = current_user.items.new(item_params)
    respond_to do |format|
      if @item.save
        puts 'item saved'
        format.html { redirect_to items_path, notice: 'Item was successfully created.' }
        format.json { render json: @item, status: :created }
      else
        puts @item.errors.full_messages
        format.html { render :new }
        format.json { render json: @item.errors, status: :unprocessable_entity }
      end
    end
  end

  private

  def item_params
    params.require(:item).permit(:name, :cost_price, :sale_price, :category)
  end
end
0

There are 0 best solutions below