JavaScript UI Libraries & Blazor Components Suite – Smart UI › Forums › Gantt › Add task click not working
- This topic has 1 reply, 2 voices, and was last updated 2 years ago by svetoslav_borislavov.
-
AuthorPosts
-
November 8, 2022 at 3:16 pm #103981Jénnifer VillalobosParticipant
Hey there!
I’m trying to add a an add task button to my project and it keeps failing 🙁
The error I’me receiving is:
Error ImageMy current code is:
import React, { LegacyRef } from "react"; import ReactDOM from "react-dom"; import { Button, RepeatButton, ToggleButton, PowerButton, } from "smart-webcomponents-react/button"; import { GanttChart } from "smart-webcomponents-react/ganttchart"; import { MultilineTextBox } from "smart-webcomponents-react/multilinetextbox"; import { TextBox } from "smart-webcomponents-react/textbox"; import { t } from "@lingui/macro"; import { MinusIcon, PlusIcon } from "@heroicons/react/outline"; class Gantt2 extends React.Component { ganttchart: LegacyRef<GanttChart> | undefined; description: any; dayInput: LegacyRef<TextBox> | undefined; deleteBtn: LegacyRef<Button> | undefined; cancelBtn: React.RefObject<unknown>; saveBtn: React.RefObject<unknown>; task: null; eventPicker: null; taskLabel: null; dayPicker: null; monthPicker: null; yearPicker: null; dayIncrementBtn: null; dayDecrementBtn: null; totalDate: null; constructor(props:any) { super(props); this.ganttchart = React.createRef(); this.deleteBtn = React.createRef(); this.cancelBtn = React.createRef(); this.saveBtn = React.createRef(); this.dayInput = React.createRef(); this.description = React.createRef(); this.task = null; this.taskLabel = null; this.eventPicker = null; this.dayPicker = null; this.monthPicker = null; this.yearPicker = null; this.dayIncrementBtn = null; this.dayDecrementBtn = null; this.totalDate = null; } durationUnit = "day"; view = "month"; treeSize = "30%"; dateStart = "2021-04-01"; taskColumns = [ { label: t<code>Machines</code>, value: "label", size: "35%", }, { label: t<code>Rent ID</code>, value: "rent_id", }, { label: "Duration", value: "duration", formatFunction: (date: string) => parseInt(date), }, { label: t<code>Supplier</code>, value: "supplier", }, { label: t<code>Client</code>, value: "client", }, { label: 'Add', value: 'addTask', min: 35, formatFunction: function () { return '<span class="add-task-button">+</span>'; } } ]; dataSource = [ { label: "Haulotte HA18PX", synchronized: true, rent_id: "", expanded: true, type: "project", supplier: "", client: "", tasks: [ { label: "Arriendo 1", rent_id: 1, expanded: true, synchronized: true, dateStart: "2021-01-01", duration: 30, type: "project", supplier: "Televa", client: "Armando Ayala Flores", tasks: [ { label: "Entrega", rent_id: "", type: "milestone", dateStart: "2021-01-01", supplier: "", client: "", class: "delivery", }, { label: "En uso", rent_id: "", type: "task", dateStart: "2021-01-09", duration: 20, supplier: "", client: "", }, { label: "Mantenimiento", rent_id: "", type: "task", dateStart: "2021-01-12", duration: 3, supplier: "", client: "", }, { label: "Retiro", rent_id: "", type: "milestone", dateStart: "2021-01-30", supplier: "", client: "", class: "withdraw", }, ], }, { label: "Arriendo 2", rent_id: 1, expanded: true, synchronized: true, dateStart: "2021-02-01", duration: 15, type: "project", supplier: "Televa", client: "Armando Ayala Flores", tasks: [ { label: "Entrega", rent_id: "", type: "milestone", dateStart: "2021-02-01", supplier: "", client: "", class: "delivery", }, { label: "En uso", rent_id: "", type: "task", dateStart: "2021-02-02", duration: 10, supplier: "", client: "", }, { label: "Retiro", rent_id: "", type: "milestone", dateStart: "2021-02-15", supplier: "", client: "", class: "withdraw", }, ], }, ], }, ]; updateTotalDate() { let newDateEnd = new Date( parseInt(this.yearPicker.value), parseInt(this.monthPicker.value), parseInt(this.dayPicker.value) ); newDateEnd.setDate( newDateEnd.getDate() + parseInt(this.dayInput.current.value) ); if (isNaN(newDateEnd.getTime())) { this.totalDate.innerHTML = ""; return; } this.totalDate.innerHTML = newDateEnd.toDateString(); } deleteTask() { const gantt = this.ganttchart.current; gantt.removeTask(this.task); gantt.closeWindow(); this.task = undefined; } cancelTask() { this.ganttchart.current.closeWindow(); } saveTask() { const gantt = this.ganttchart.current; let dateStart = new Date( parseInt(this.yearPicker.value), parseInt(this.monthPicker.value), parseInt(this.dayPicker.value) ), duration = parseInt(this.dayInput.current.value); let type let taskClass switch (this.eventPicker.value) { case 'Entrega': type = 'milestone' taskClass = 'delivery' break; case 'En uso': type = 'task' taskClass = '' break; case 'Retiro': type = 'milestone' taskClass = 'withdraw' break; default: break; } gantt.updateTask(this.task, { label: this.eventPicker.value, dateStart: dateStart, duration: duration, type: type, class: taskClass }); gantt.closeWindow(); this.task = undefined; } handleDayIncrementBtn() { const that = this; this.dayInput.current.value = Math.min( 31, (parseInt(this.dayInput.current.value) || 0) + 1 ).toString(); that.updateTotalDate(); } handleDayDecrementBtn() { const that = this; this.dayInput.current.value = Math.max( 1, (parseInt(this.dayInput.current.value) || 0) - 1 ).toString(); that.updateTotalDate(); } popupWindowCustomizationFunction(target, type, targetTask) { const that = this, gantt = that.ganttchart.current; if (type === "task" && targetTask) { //Hide the header target.headerPosition = "none"; target.footerPosition = "none"; //Create the content if (!that.description.current) { target.clear(); const template = document.getElementById("myTemplate"); target.appendChild(template?.content); ReactDOM.render( <MultilineTextBox ref={this.description} id="description" ></MultilineTextBox>, document.getElementById("multilineTextBoxContainer"), function () { that.description.current.value = targetTask.label; } ); ReactDOM.render( <section> <RepeatButton id="dayDecrementBtn" onClick={this.handleDayDecrementBtn.bind(this)} > <MinusIcon className="h-4 w-4" /> </RepeatButton> <TextBox ref={this.dayInput} id="dayInput"></TextBox> <RepeatButton id="dayIncrementBtn" onClick={this.handleDayIncrementBtn.bind(this)} > <PlusIcon className="h-4 w-4" /> </RepeatButton> </section>, new DocumentFragment(), function () { that.dayInput.current.value = targetTask.duration.toString(); while (this.children.length) { document .getElementById("buttonContainer") .appendChild(this.firstChild); } } ); ReactDOM.render( <section> <Button className="text-red normal-case" ref={this.deleteBtn} id="deleteBtn" onClick={this.deleteTask.bind(this)} > Borrar </Button> <Button className=" normal-case" ref={this.cancelBtn} id="cancelBtn" onClick={this.cancelTask.bind(this)} > Cancelar </Button> <Button className="ml-4 inline-flex justify-center border border-transparent shadow-sm text-sm rounded-md text-white bg-primary focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-orange-500 normal-case" ref={this.saveBtn} id="saveBtn" onClick={this.saveTask.bind(this)} > Guardar </Button> </section>, new DocumentFragment(), function () { while (this.children.length) { document?.getElementById("buttonContainer2").appendChild(this.firstChild); } } ); } that.eventPicker = document.getElementById("eventPicker"); that.taskLabel = document.getElementById("taskLabel"); that.dayPicker = document.getElementById("dayPicker"); that.monthPicker = document.getElementById("monthPicker"); that.yearPicker = document.getElementById("yearPicker"); that.dayIncrementBtn = document.getElementById("dayIncrementBtn"); that.dayDecrementBtn = document.getElementById("dayDecrementBtn"); that.totalDate = document.getElementById("totalDate"); that.task = targetTask; //Configure the content const dateStart = targetTask.dateStart, dateEnd = targetTask.dateEnd; if (!dateStart || !dateEnd) { that.taskLabel.innerHTML = ""; } else { that.taskLabel.innerHTML = dateStart.toLocaleDateString(gantt.locale) + " - " + dateEnd.toLocaleDateString(gantt.locale); } console.log(targetTask.type) that.dayPicker.value = dateStart.getDate().toString(); that.monthPicker.value = dateStart.getMonth().toString(); that.yearPicker.value = dateStart.getFullYear().toString(); that.totalDate.innerHTML = targetTask.dateEnd.toDateString(); that.eventPicker.value = targetTask.label } if (that.dayInput.current) { that.dayInput.current.value = targetTask.duration.toString(); } const dateControls = target.querySelector( ".custom-window-content-section.date-control" ); if (dateControls) { if (targetTask.type === "project" && targetTask.synchronized) { dateControls.setAttribute("disabled", true); } else { dateControls.removeAttribute("disabled"); } } } init() { const template = document.createElement("template"); template.id = "myTemplate"; template.innerHTML =
<div class=”custom-window-content”>
<div class=”custom-window-content-section”>
<label id=”taskLabel”></label>
</div>
<div>
<div class=”custom-window-content-section”> <b>Evento</b>
</div>
<div class=”custom-window-content-section w-full type-control”>
<select id=”eventPicker” class=”w-full”>
<option value=”Entrega”>Entrega</option>
<option value=”En uso”>En uso</option>
<option value=”Retiro”>Retiro</option>
</select>
</div><div class=”grid grid-cols-2″>
<div>
<div class=”custom-window-content-section”>
<b>Start date</b>
</div>
<div class=”custom-window-content-section”>
<div class=”custom-window-content-section date-control”>
<select id=”dayPicker”>
<option value=”1″>1</option>
<option value=”2″>2</option>
<option value=”3″>3</option>
<option value=”4″>4</option>
<option value=”5″>5</option>
<option value=”6″>6</option>
<option value=”7″>7</option>
<option value=”8″>8</option>
<option value=”9″>9</option>
<option value=”10″>10</option>
<option value=”11″>11</option>
<option value=”12″>12</option>
<option value=”13″>13</option>
<option value=”14″>14</option>
<option value=”15″>15</option>
<option value=”16″>16</option>
<option value=”17″>17</option>
<option value=”18″>18</option>
<option value=”19″>19</option>
<option value=”20″>20</option>
<option value=”21″>21</option>
<option value=”22″>22</option>
<option value=”23″>23</option>
<option value=”24″>24</option>
<option value=”25″>25</option>
<option value=”26″>26</option>
<option value=”27″>27</option>
<option value=”28″>28</option>
<option value=”29″>29</option>
<option value=”30″>30</option>
<option value=”31″>31</option>
</select>
<select id=”monthPicker”>
<option value=”0″>January</option>
<option value=”1″>February</option>
<option value=”2″>March</option>
<option value=”3″>April</option>
<option value=”4″>May</option>
<option value=”5″>June</option>
<option value=”6″>July</option>
<option value=”7″>August</option>
<option value=”8″>September</option>
<option value=”9″>October</option>
<option value=”10″>November</option>
<option value=”11″>December</option>
</select>
<select id=”yearPicker”>
<option value=”2013″>2016</option>
<option value=”2014″>2017</option>
<option value=”2015″>2018</option>
<option value=”2016″>2019</option>
<option value=”2020″>2020</option>
<option value=”2021″>2021</option>
<option value=”2021″>2021</option>
<option value=”2020″>2020</option>
<option value=”2021″>2021</option>
<option value=”2022″>2022</option>
<option value=”2022″>2023</option>
<option value=”2022″>2024</option>
<option value=”2022″>2025</option>
<option value=”2022″>2026</option>
<option value=”2022″>2027</option>
</select>
</div>
</div>
</div>
<div>
<div class=”custom-window-content-section”>
<b>Qty. of days</b>
</div>
<div class=”custom-window-content-section flex items-center gap-1″ id=”buttonContainer”></div>
<div class=”custom-window-content-section”>
<label id=”totalDate”></label>
</div>
</div>
</div>
<div class=”custom-window-content-section”> <b>Description</b>
</div>
<div class=”custom-window-content-section” id=”multilineTextBoxContainer”></div>
</div>
<div class=”custom-window-content-section buttons” id=”buttonContainer2″></div>
</div>
`;document.body.appendChild(template);
}handleGanttClick(event:any) {
const ganttChart = document.getElementById(‘gantt’);
console.log(event.target)
const eventDetails = event.detail,
target = event.target;console.log(eventDetails.item)
if (target.classList.contains(‘add-task-button’)) {
const itemIndex = parseInt(ganttChart.getItemPath(eventDetails.item).split(‘.’).slice(-1)[0]) + 1,
itemProject = ganttChart.getItemPath(ganttChart.getTaskProject(eventDetails.item));//Add a new Task
const newItemId = ganttChart.insertTask({
label: ‘New Task’,
dateStart: ganttChart.dateStart
}, itemProject, itemIndex);//Open the Editor to configure
ganttChart.openWindow(newItemId);
}
}componentDidMount() {
this.init();
}render() {
return (
<div>
<GanttChart
ref={this.ganttchart}
id=”gantt”
durationUnit={this.durationUnit}
dataSource={this.dataSource}
view={this.view}
treeSize={this.treeSize}
dateStart={this.dateStart}
taskColumns={this.taskColumns}
popupWindowCustomizationFunction={this.popupWindowCustomizationFunction.bind(
this
)}
onClick={this.handleGanttClick.bind(this)}
></GanttChart>
</div>
);
}
}export default Gantt2;
`
November 9, 2022 at 3:14 pm #103985svetoslav_borislavovParticipantHi,
You are using the onClick event in which there isn’t event.detail or event.detail.item.
You should you onItemClick and also get the target from here: event.detail.originalEvent.targetHere is the desired method:
handleGanttClick(event: CustomEvent) {
const ganttChart = this.ganttchart?.current;
const eventDetails = event.detail;
const target = event.detail.originalEvent.target;
if (target.classList.contains(‘add-task-button’)) {
const itemIndex = parseInt(
ganttChart?.getItemPath(eventDetails.item).split(‘.’).slice(-1)[0]) + 1,
itemProject = ganttChart?.getItemPath(ganttChart.getTaskProject(eventDetails.item)
);
//Add a new Task
const newItemId = ganttChart?.insertTask(
{
label: ‘New Task’,
dateStart: ganttChart.dateStart
},
itemProject,
itemIndex
);
//Open the Editor to configure
ganttChart?.openWindow(newItemId);
}
}I hope this helps!
Best Regards,
Svetoslav BorislavovSmart UI Team
https://www.htmlelements.com/- This reply was modified 2 years ago by svetoslav_borislavov.
-
AuthorPosts
- You must be logged in to reply to this topic.