toggleEditMode 不是函数 TypeError:toggleEditMode 不是函数

toggleEditMode is not a function TypeError: toggleEditMode is not a function

提问人:Rakesh Yadav 提问时间:9/5/2023 更新时间:9/5/2023 访问量:23

问:

我使用 AG-Grid 来显示我的表格,我想通过单击按钮来显示和编辑数据(这里我有两个按钮编辑和保存),当我单击编辑按钮时,将显示编辑按钮隐藏和保存按钮,所有单元格都是可编辑的,当我单击保存按钮时,更改数据将被提交并通过 API 发送。

我使用了两个页面,其中我制作了一个页面作为组件,用于我显示列表的主页。

我希望我单击编辑按钮,所有字段都变得可编辑,并且应该显示保存按钮

import React, {useState, useEffect, useMemo } from 'react';
import Sidebar from '../../sidebar/sidebar.component';
import AddSubSpaceStageComponent from './add-sub-space-stage.component';
import BtnCellRenderer from './view-sub-space-stage-button.component';
import { AgGridReact } from 'ag-grid-react';
import '../css/ag-grid.css';
import '../css/ag-theme-alpine.css';
import Skeleton from '@mui/material/Skeleton';
import Box from '@mui/material/Box';
import _ from 'lodash';
import './style.styles.css';
import API_URL from '../../../config';
import { useStageContext } from '../../../contexts/StageContext';
import { useTemplateIdContext } from '../../../contexts/lookupTemplateIdContext';
import axios from 'axios';
import { useParams } from 'react-router-dom';

const SubSpaceStageComponent = () => {
  const [editModeRowId, setEditModeRowId] = useState(null);
  const [isEditing, setIsEditing] = useState(false);
  const [userMap, setUserMap] = useState({});
  const [isLoading, setIsLoading] = useState(true);
  const [rowData, setRowData] = useState([]);
  const { id } = useParams();
  const { stages } = useStageContext();
  const { ContextTemplateId } = useTemplateIdContext();
  const [changesMade, setChangesMade] = useState(false);


  const defaultColDef = useMemo(
    () => ({
      resizable: true,
      sortable: true,
      flex: 1,
      minWidth: 140,
      filter: true,
      floatingFilter: true,
      enablePivot: true,
      enableCellChangeFlash: true,
      suppressMenu: true,
      suppressMovable: true,
    }),
    []
  );

  useEffect(() => {
    
  console.log('Effect triggered');
    const fetchData = async (subSpaceId) => {
      const userToken = localStorage.getItem('token');
      try {
        const response = await axios.get(`${API_URL}SpcLstStg?spaceListId=${subSpaceId}&spaceListStageId=0`, {
          headers: {
            'Authorization': `${userToken}`,
          },
        });
        const rowData = response.data;
        console.log(rowData);
        console.log(JSON.stringify(rowData));
        // Add the isEditing property to each row
        const initialRowData = response.data.map(row => ({
          ...row,
          isEditing: false, // Initially set to false
        }));
        setRowData(initialRowData);
        setIsLoading(false);
      } catch (error) {
        console.error('Error fetching data:', error);
        setIsLoading(false);
      }
    };

    fetchData(id);
  }, [id]);

  const toggleEditMode = () => {
    setIsEditing((prevIsEditing) => !prevIsEditing);
  };
  

  const formatDate = (dateString) => {
    if (!dateString) {
      return "Not Updated";
    }
    const date = new Date(dateString);
    const options = {
      day: "2-digit",
      month: "2-digit",
      year: "numeric",
    };
    const formattedDate = date.toLocaleDateString(undefined, options);
    const formattedTime = date.toLocaleTimeString();
    return `${formattedDate} || ${formattedTime}`;
  };

  const getUsername = (Name) => {
    return userMap[Name] || Name;
  };



  const handleSaveClick = async (row) => {
    await handleCellValueChanged({ data: row });
  };

  console.log('Stages:', stages.map(stage => ((stage.id))));
  console.log('template:', ContextTemplateId);

  const columnDefs = [
    {
      field: 'Edit',
      headerName: 'Action',
      maxWidth: 80,
      editable: false,
      cellRendererFramework: BtnCellRenderer,
      // cellRendererParams: {
      //   isEditMode: editModeRowId == null, 
      // },
    },
    { 
      field: 'stageName', 
      headerName: 'Stage Name',
      editable: isEditing,
      cellEditor: 'agSelectCellEditor', 
      cellEditorParams: {
        values: stages.map(stage => ((stage.name)))
      },
      valueGetter: (params) => params.data.stageName,
      valueSetter: (params) => {
        const selectedStageName = params.newValue;
        console.log('1', selectedStageName );
        const selectedStage = stages.find(stage => stage.name === selectedStageName);
        console.log('2', selectedStage);
        if (selectedStage) {
          params.data.stageId = selectedStage.id; // Set the stageId based on the selected stageName
          params.data.stageName = selectedStageName;
          console.log('3', params.data.stageId);
        } else {
          // Handle the case where the selected stageName doesn't match any in the options
          console.error(`Selected stageName "${selectedStageName}" not found in options.`);
        }
    
        return true; // Return true to indicate a successful update
      },
    },
    
    { field: 'remark', headerName: 'Stage Remark' , editable: isEditing,},

    { 
      field: 'templateName', 
      headerName: 'Stage Template', 
      editable: isEditing,
      cellEditor: 'agSelectCellEditor', 
      cellEditorParams: {
        values: ContextTemplateId.map(Template => ((Template.name)))
      },
      valueGetter: (params) => params.data.templateName,
      valueSetter: (params) => {
        const selectedTemplateName = params.newValue;
        console.log('1', selectedTemplateName );
        const selectedTemplate = ContextTemplateId.find(Template => Template.name === selectedTemplateName);
        console.log('2', selectedTemplate);
        if (selectedTemplate) {
          params.data.templateId = selectedTemplate.id; // Set the TemplateSelId based on the selected stageName
          params.data.templateName = selectedTemplateName;
          console.log('3', params.data.templateId);
        } else {
          // Handle the case where the selected stageName doesn't match any in the options
          console.error(`Selected TemplateName "${selectedTemplateName}" not found in options.`);
        }
    
        return true; // Return true to indicate a successful update
      },
    },
    { field: 'inOrder', headerName: 'Stage Order' , editable: isEditing, },

  ];
console.log('columndef ' , columnDefs);
const handleCellValueChanged = async (event) => {
  const storedUserData = localStorage.getItem('userSession');
    const userData = JSON.parse(storedUserData);
    const userID = userData.id;
    const currentTime = new Date().toISOString();
    const updatedRowData = rowData.map(async (row) => {

  if (event.data && event.data.id) {
    const updatedData = event.data;
    console.log('event data', event.data);
    // Find the corresponding spaceListId for the given stageId
  

    const payload = {
      id: Number(updatedData.id),
      stageId: updatedData.stageId,
      spaceListId: updatedData.spaceListId,
      remark: updatedData.remark,
      templateId: updatedData.templateId,
      inOrder: updatedData.inOrder,
      updatedBy: userID,
      updatedOn: currentTime,
      isActive: updatedData.isActive,
    };
    console.log(JSON.stringify(payload));
    try {
      const userToken = localStorage.getItem('token');
      const response = await axios.post(
        `${API_URL}SpcLstStg/UpdateSpcLstStg`,
        payload,
        {
          headers: {
            'Authorization': `${userToken}`,
          },
        }
      );
      console.log(JSON.stringify(payload), `${userToken}`);
      console.log('Data updated successfully:', response.data);
    } catch (error) {
      console.error('Error updating data:', error);
    }
  }
});
};

  

  return (
    <div>
      <div className="d-flex justify-content-start p-0">
        <Sidebar />
        <div className="mainContainConatiner">
          <div className='container-fluid'>
            <div className='row'>
              <div className='col-12 mb-3 mt-3 d-flex justify-content-between'>
              {isLoading ? (
                  <Skeleton variant="text" width={200} height={40} animation="wave" />
                ) : (
                  <h2>{rowData.length > 0 ? `${rowData[0].spaceListName} Stage List` : 'No Data Available'}</h2>
                )}
                <AddSubSpaceStageComponent />
              </div>
            </div>
          </div>
          <div className='container-fluid'>
            <div className='row'>
              {isLoading ? (
                <Box sx={{ width: '100%' }} className="p-4">
                  <Skeleton variant="rectangular" className='mb-1' width={'100%'} height={'15vh'} animation="wave" />
                  <Skeleton variant="rectangular" width={'100%'} height={'65vh'} animation="wave" />
                </Box>
              ) : (
                rowData && rowData.length === 0 ? (
                  <Box sx={{ width: '100%' }} className="p-4">
                    <Box sx={{ width: '100%' }} className="p-4 border border-danger border-2 text-danger fw-bold d-flex justify-content-center align-items-center">
                      No Data Available
                    </Box>
                  </Box>
                ) : (
                  <div className="ag-theme-alpine" style={{ width: '100%', height: '85vh' }}>
                    <AgGridReact
                      animateRows="true"
                      style={{ height: '75vh' }}
                      columnDefs={columnDefs}
                      defaultColDef={defaultColDef}
                      rowData={rowData}
                      domLayout="autoHeight"
                      frameworkComponents={{
                        btnCellRenderer: (param) =>(
                          <BtnCellRenderer
                            data={param.data}
                            toggleEditMode={toggleEditMode}
                          />
                        ) ,
                      }}
                      onCellValueChanged={handleCellValueChanged}
                    />
                  </div>
                )
              )}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

<BtnCellRenderer/>

export default SubSpaceStageComponent;

组件代码

import React, { useState, useEffect, useCallback } from 'react';
import axios from 'axios';
import Button from '@mui/material/Button';
import API_URL from '../../../config';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faEdit } from '@fortawesome/free-solid-svg-icons';

const BtnCellRenderer = ({ data , toggleEditMode  }) => {
  const [Name] = useState(localStorage.getItem('Name'));
  const [isLoading, setIsLoading] = useState(true);
  const [ModuleRights, setModuleRights] = useState([]);
  const [isEditMode, setIsEditMode] = useState(false);

  useEffect(() => {
    const fetchData = async () => {
      const userToken = localStorage.getItem('token');
      const RoleIDMY = localStorage.getItem('RoleIDMY');
      const selectedCategoryModuleId = localStorage.getItem('selectedCategoryModuleId');

      try {
        const response = await axios.get(
          `${API_URL}Users/ModuleAction?moduleId=${selectedCategoryModuleId}&roleId=${RoleIDMY}`,
          {
            headers: {
              Authorization: `${userToken}`,
            },
          }
        );
        const moduleRights = response.data;
        setModuleRights(moduleRights);
        setIsLoading(false);
      } catch (error) {
        console.error('Error fetching data:', error);
        setIsLoading(false);
      }
    };

    fetchData();
  }, []);


  const onBtSaveEditing = useCallback(() => {
    setIsEditMode(false);
    // Implement the logic for saving editing
  }, []);

  const onBtStartEditing = useCallback(() => {
        toggleEditMode();
  }, [toggleEditMode]);

  console.log('clicked' , toggleEditMode );

  const btnClickedHandler = (action) => {
    console.log('Button clicked with action:', action);
    switch (action) {
      case 'edit':
        toggleEditMode();
        console.log('Edit button clicked');
        break;
      case 'save':
        setIsEditMode(false);
        console.log('Save button clicked');
        break;
      case 'lock':
        console.log('Lock button clicked');
        break;
      default:
        break;
    }
  };





  const buttonMap = {
    'E': (
      <div>
        {isEditMode ? (
          <Button
            key="saveButton"
            className="p-0"
            variant="outline"
            style={{ minWidth: '40px', height: '44px' }}
            onClick={onBtSaveEditing}
          >
            Save
          </Button>
        ) : (
          <Button
            key="edit"
            className="p-0"
            variant="outline"
            style={{ minWidth: '40px', height: '44px' }}
            onClick={onBtStartEditing}
          >
            <FontAwesomeIcon
              className="text-primary"
              icon={faEdit}
              style={{ fontSize: '16px', margin: '5px', color: 'blue' }}
            />
          </Button>
        )}
      </div>
    ),
  };

  return (
    <span
      className="d-flex justify-content-between align-items-center"
      style={{ height: "44px" }}
      onClick={() => btnClickedHandler(data.spaceListId, 'edit')}
    >
      {ModuleRights.map(permission => {
        const { Code, IsApplicable } = permission;
        if (IsApplicable && buttonMap[Code]) {
          return buttonMap[Code];
        }
        return null;
      })}
      {ModuleRights.every(permission => {
        const { Code, IsApplicable } = permission;
        return !IsApplicable || !buttonMap[Code];
      }) && <p>N/A</p>}
    </span>
  );
};

export default BtnCellRenderer;

reactjs ag-grid 反应函数组件

评论

0赞 Community 9/5/2023
请修剪您的代码,以便更轻松地找到您的问题。请遵循这些准则,以创建最小的可重现示例

答: 暂无答案