skip to Main Content

I have a grid structure like this (for a weekly calendar):

<div className="grid flex-auto grid-cols-1 grid-rows-1">
  {/* Horizontal lines */}
  <div
    className="col-start-1 col-end-2 row-start-1 grid divide-y divide-gray-100"
    style={{ gridTemplateRows: 'repeat(48, minmax(3.5rem, 1fr))' }}
  >
    <div className="sticky left-0 z-20 -ml-14 -mt-2.5 w-14 pr-2 text-right text-xs leading-5 text-gray-400">
      12AM
    </div>
    <div />
    <div className="sticky left-0 z-20 -ml-14 -mt-2.5 w-14 pr-2 text-right text-xs leading-5 text-gray-400">
      1AM
    </div>
    {/* More rows here like this for 24 hours */}
  </div>

  {/* Vertical lines */}
  <div className="col-start-1 col-end-2 row-start-1 hidden grid-cols-7 grid-rows-1 divide-x divide-gray-100 sm:grid sm:grid-cols-7">
    <div className="col-start-1 row-span-full" />
    <div className="col-start-2 row-span-full" />
    <div className="col-start-3 row-span-full" />
    <div className="col-start-4 row-span-full" />
    <div className="col-start-5 row-span-full" />
    <div className="col-start-6 row-span-full" />
    <div className="col-start-7 row-span-full" />
    <div className="col-start-8 row-span-full w-8" />
  </div>

  <Events events={params.events} />
</div>

I am trying to add a click event that will capture where in the grid I clicked (so I know the time and day) and that will open a Dialog for further action.

If I add the event to specific time, then I dont know the day of the week, and if I add event to day of week, I don’t know the time.

Any ideas on how to approach capturing both of these onClick?

Added Codepen: https://codepen.io/eventslooped/pen/KKbbpBw

2

Answers


  1. To capture the grid where you clicked, Add an onClick event to the grid element. In handleGridClick function, We can use the event.clientX and event.clientY properties to get the click coordinates with that you can get the respective grid where you clicked.

     handleGridClick(event) {
      const gridOffsetX = 0;
      const gridOffsetY = 0;
      const columnWidth = 100;  // width of each column
      const rowHeight = 40; // height of each row
      const clickX = event.clientX;
      const clickY = event.clientY;
    
      const gridColumn = Math.floor((clickX - gridOffsetX) / columnWidth) + 1;
      const gridRow = Math.floor((clickY - gridOffsetY) / rowHeight) + 1;
      
      console.log(` gridColumn: ${gridColumn}, gridRow: ${gridRow}`);
    }
    
    <div className="grid flex-auto grid-cols-1 grid-rows-1" onClick={this.handleGridClick}>
    ...
    </div>
    
    Login or Signup to reply.
  2. Fixed it. Check it at https://codepen.io/rachitiitr/pen/eYbbpgG?editors=0010

    Added the below onClick to the entire grid, then figured out where the user clicked (x,y) relative to grid and used grid’s height and width to figure out the rowIndex and colIndex where click happened.

    Then rowIndex can tell the time while colIndex can tell the day of week.

    const onClick = (event) => {
        const x = event.clientX - event.currentTarget.getBoundingClientRect().left;
        const y = event.clientY - event.currentTarget.getBoundingClientRect().top;
    
        const rect = event.currentTarget.getBoundingClientRect();
        // Calculate the column (day) and row (time) based on the click coordinates
        const numColumns = 7; // Number of days in a week
        const numRows = 48;   // Number of time slots in a day
        const column =  Math.floor((x / rect.width) * numColumns);
        const row = Math.floor((y / rect.height) * numRows);
    
        // Determine the day of the week based on the column
        const daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
        const dayOfWeek = daysOfWeek[column];
    
        // Calculate the time based on the row
        const hour = Math.floor(row / 2);
        const minute = (row % 2) * 30;
    
        console.log(`Clicked on ${dayOfWeek}, ${hour}:${minute}`);
        // openDialog(dayOfWeek, hour, minute);
      };
    
            <div className="grid flex-auto grid-cols-1 grid-rows-1" onClick={onClick}>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search