Hi!
We are trying to customize the scheduler form editor, but the field is not showing up. Any ideas why? Screenshots of the SchedulerForm's editor and what we see in the UI below:
What we see: (text area input doesn't show up):
*note that we have tried other field types (e.g. dropdown and datepicker) with similar results
Thank you!
Script below (note we are using a cdn only method highlighted in this post):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>KendoReact</title>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.2.2/axios.min.js"></script>
<script src="https://unpkg.com/react@18/umd/react.production.min.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js" crossorigin></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.7.2/prop-types.min.js"></script>
<script src="https://unpkg.com/@progress/kendo-react-common/dist/cdn/js/kendo-react-common.js"></script>
<script src="https://unpkg.com/@progress/kendo-date-math/dist/cdn/js/kendo-date-math.js"></script>
<script src="https://unpkg.com/@progress/kendo-drawing/dist/cdn/js/kendo-drawing.js"></script>
<script src="https://unpkg.com/@progress/kendo-licensing/dist/index.js"></script>
<script>
KendoLicensing.setScriptKey(
'xxx' +
'yyy' +
'zzz' +
'000'
);
</script>
<script src="https://unpkg.com/@progress/kendo-react-intl/dist/cdn/js/kendo-react-intl.js"></script>
<script src="https://unpkg.com/@progress/kendo-react-all/dist/cdn/js/kendo-react-all.js"></script>
<script src="https://unpkg.com/@progress/kendo-react-scheduler/dist/cdn/js/kendo-react-scheduler.js"></script>
<script src="https://unpkg.com/@progress/kendo-react-dropdowns/dist/cdn/js/kendo-react-dropdowns.js"></script>
<script src="https://unpkg.com/@progress/kendo-react-form/dist/cdn/js/kendo-react-form.js"></script>
<script src="https://unpkg.com/@progress/kendo-react-labels/dist/cdn/js/kendo-react-labels.js"></script>
<script src="https://unpkg.com/@progress/kendo-react-inputs/dist/cdn/js/kendo-react-inputs.js"></script>
<script src="https://unpkg.com/@progress/kendo-react-dateinputs/dist/cdn/js/kendo-react-dateinputs.js"></script>
<script src="https://unpkg.com/@progress/kendo-react-dialogs/dist/cdn/js/kendo-react-dialogs.js"></script>
<link rel="stylesheet" href="https://unpkg.com/@progress/kendo-theme-default@latest/dist/all.css"></link>
<!--link rel="stylesheet" href="https://kendo.cdn.telerik.com/themes/5.8.0/default/default-ocean-blue.css"></link-->
<!--link rel="stylesheet" href="https://unpkg.com/@progress/kendo-theme-material/dist/all.css"></link-->
<link rel="stylesheet" href="https://cdn.kendostatic.com/themes/6.0.3/default/default-ocean-blue.css"></link>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<style>
body {
position: relative;
}
html,
body {
height: 100%;
}
my-app {
display: block;
width: 100%;
height: 100%;
overflow: auto;
min-height: 800px;
box-sizing: border-box;
padding: 30px;
}
@keyframes k-loading-animation {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.k-i-loading.k-example-loading {
font-size: 64px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: rgb(144, 152, 165);
}
.k-i-loading.k-example-loading::before,
.k-i-loading.k-example-loading::after {
position: absolute;
top: 50%;
left: 50%;
display: inline-block;
content: "";
box-sizing: inherit;
border-radius: 50%;
border-width: .05em;
border-style: solid;
border-color: currentColor;
border-top-color: transparent;
border-bottom-color: transparent;
background-color: transparent;
}
.k-icon.k-i-loading.k-example-loading::before,
.k-icon.k-i-loading::after {
content: "";
}
.k-i-loading.k-example-loading::before {
margin-top: -0.5em;
margin-left: -0.5em;
width: 1em;
height: 1em;
animation: k-loading-animation .7s linear infinite;
}
.k-i-loading.k-example-loading::after {
margin-top: -0.25em;
margin-left: -0.25em;
width: .5em;
height: .5em;
animation: k-loading-animation reverse 1.4s linear infinite;
}
.example-wrapper {
min-height: 280px;
align-content: flex-start;
}
.example-wrapper p,
.example-col p {
margin: 20px 0 10px;
}
.example-wrapper p:first-child,
.example-col p:first-child {
margin-top: 0;
}
.example-col {
display: inline-block;
vertical-align: top;
padding-right: 20px;
padding-bottom: 20px;
}
.example-config {
margin: 0 0 20px;
padding: 20px;
background-color: rgba(0, 0, 0, .03);
border: 1px solid rgba(0, 0, 0, .08);
}
.event-log {
margin: 0;
padding: 0;
max-height: 100px;
overflow-y: auto;
list-style-type: none;
border: 1px solid rgba(0, 0, 0, .08);
background-color: white;
}
.event-log li {
margin: 0;
padding: .3em;
line-height: 1.2em;
border-bottom: 1px solid rgba(0, 0, 0, .08);
}
.event-log li:last-child {
margin-bottom: -1px;
}
</style>
</head>
<body>
<my-app>
<span class="k-icon k-i-loading"></span>
</my-app>
</body>
<script type="text/babel">
const baseDataSet = '[baseDataSet]';
const baseData = JSON.parse(baseDataSet);
console.log(baseData);
/*[{
"TaskID": 119,
"OwnerID": 3,
"Title": "Helpdesk weekly meeting",
"Description": "",
"StartTimezone": null,
"Start": "2013-12-05T15:00:00.000Z",
"End": "2013-12-05T16:00:00.000Z",
"EndTimezone": null,
"RecurrenceRule": "FREQ=WEEKLY;BYDAY=WE",
"RecurrenceID": null,
"RecurrenceException": null,
"isAllDay": false
}, {
"TaskID": 120,
"OwnerID": 3,
"Title": "Website upload",
"Description": "",
"StartTimezone": null,
"Start": "2013-12-07T07:00:00.000Z",
"End": "2013-12-07T08:30:00.000Z",
"EndTimezone": null,
"RecurrenceRule": "",
"RecurrenceID": null,
"RecurrenceException": null,
"isAllDay": false
}];*/
const customModelFields = {
id: 'TaskID',
title: 'Title',
description: 'Description',
start: 'Start',
end: 'End',
recurrenceRule: 'RecurrenceRule',
recurrenceId: 'RecurrenceID',
recurrenceExceptions: 'RecurrenceException'
};
const currentYear = new Date().getFullYear();
const parseAdjust = eventDate => {
const date = new Date(eventDate);
date.setFullYear(currentYear);
return date;
};
const randomInt = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
const displayDate = new Date();
//const displayDate = new Date(Date.UTC(currentYear, 5, 24));
const sampleData = baseData.map(dataItem => ({
id: dataItem.TaskID,
start: parseAdjust(dataItem.Start),
startTimezone: dataItem.startTimezone,
end: parseAdjust(dataItem.End),
endTimezone: dataItem.endTimezone,
isAllDay: dataItem.isAllDay,
title: dataItem.Title,
description: dataItem.Description,
recurrenceRule: dataItem.RecurrenceRule,
recurrenceId: dataItem.RecurrenceID,
recurrenceExceptions: dataItem.RecurrenceException,
roomId: dataItem.RoomID,
ownerID: dataItem.OwnerID,
personId: dataItem.OwnerID
}));
const sampleDataWithResources = baseData.map(dataItem => ({
id: dataItem.TaskID,
start: parseAdjust(dataItem.Start),
startTimezone: dataItem.startTimezone,
end: parseAdjust(dataItem.End),
endTimezone: dataItem.endTimezone,
isAllDay: dataItem.isAllDay,
title: dataItem.Title,
description: dataItem.Description,
recurrenceRule: dataItem.RecurrenceRule,
recurrenceId: dataItem.RecurrenceID,
recurrenceExceptions: dataItem.RecurrenceException,
roomId: randomInt(1, 2),
personId: randomInt(1, 2)
}));
const sampleDataWithCustomSchema = baseData.map(dataItem => ({
...dataItem,
Start: parseAdjust(dataItem.Start),
End: parseAdjust(dataItem.End),
PersonIDs: randomInt(1, 2),
RoomID: randomInt(1, 2)
}));
console.log(sampleDataWithCustomSchema);
const App = () => {
console.log(window);
const Scheduler = window.KendoReactScheduler.Scheduler
const SchedulerForm = window.KendoReactScheduler.SchedulerForm
const SchedulerFormEditor = window.KendoReactScheduler.SchedulerFormEditor
const AgendaView = window.KendoReactScheduler.AgendaView
const TimelineView = window.KendoReactScheduler.TimelineView
const DayView = window.KendoReactScheduler.DayView
const WeekView = window.KendoReactScheduler.WeekView
const MonthView = window.KendoReactScheduler.MonthView
const timezoneNames = window.KendoDateMath.timezoneNames
const DropDownList = window.KendoReactDropdowns.DropDownList
const guid = window.KendoReactCommon.guid
const FormElement = window.KendoReactForm.FormElement
const Field = window.KendoReactForm.Field
const Label = window.KendoReactLabels.Label
const Error = window.KendoReactLabels.Error
const TextArea = window.KendoReactInputs.TextArea
const DatePicker = window.KendoReactDateinputs.DatePicker
const DateTimePicker = window.KendoReactDateinputs.DateTimePicker
const Dialog = window.KendoReactDialogs.Dialog
const [view, setView] = React.useState("month");
const [date, setDate] = React.useState(displayDate);
const [timezone] = React.useState("Etc/UTC");
const [orientation] = React.useState("horizontal");
const [data, setData] = React.useState(sampleDataWithCustomSchema);
const handleViewChange = React.useCallback(
(event) => {
setView(event.value);
},
[setView]
);
const handleDateChange = React.useCallback(
(event) => {
setDate(event.value);
},
[setDate]
);
const handleDataChange = React.useCallback(
({ created, updated, deleted }) => {
for(var projTask of updated) {
axios.post(`https://tstdrv1967913.app.netsuite.com/app/site/hosting/scriptlet.nl?script=2165&deploy=1&recordaction=update&firstParam=${projTask.TaskID}`,
{
firstName: 'first',
lastName: 'last'
}
).then(
(response) => {
setData((old) =>
old.map(
(item) =>
updated.find((current) => current.TaskID === item.TaskID) || item
)
)
}
);
}
for(var projTask of created) {
axios.post(`https://tstdrv1967913.app.netsuite.com/app/site/hosting/scriptlet.nl?script=2165&deploy=1&recordaction=create&firstParam=${projTask.TaskID}`,
{
firstName: 'first',
lastName: 'last'
}
).then(
(response) => {
console.log(response.data.id);
setData((old) =>
old.concat(
created.map((item) =>
Object.assign({}, item, {
//TaskID: guid()
TaskID: response.data.id
})
)
)
);
}
);
}
},
[setData]
);
// Custom Form - START
const teammembers = [{
value: 1,
text: 'Erwin'
}, {
value: 2,
text: 'Don'
}, {
value: 3,
text: 'Neil'
}];
const AssignedToEditor = props => {
const handleChange = event => {
if (props.onChange) {
props.onChange.call(undefined, {
value: event.value.value
});
}
};
return <DropDownList onChange={handleChange} value={teammembers.find(t => t.value === props.value)} data={teammembers} dataItemKey={'value'} textField={'text'} />;
};
const CustomDialog = props => {
return <Dialog {...props} title={'Project Action'} />;
};
const CustomFormEditor = (props) => {
return (
<FormElement horizontal={true}>
<div className="k-form-field">
<Label>Notes</Label>
<div className="k-form-field-wrap">
<Field name={"Notes"} component={TextArea} rows={1} />
</div>
</div>
</FormElement>
);
};
const FormWithCustomEditor = props => {
const requiredValidator = React.useCallback(value => value === undefined || value === null || value === '' ? 'Field is required.' : undefined, []);
const formValidator = (_dataItem, formValueGetter) => {
let result = {};
//result.Patient = [requiredValidator(formValueGetter('Patient'))].filter(Boolean).reduce((current, acc) => current || acc, '');
//result.Treatment = [requiredValidator(formValueGetter('Treatment'))].filter(Boolean).reduce((current, acc) => current || acc, '');
return result;
};
return <SchedulerForm
{...props}
editor={CustomFormEditor}
dialog={CustomDialog}
validator={formValidator}
/>;
};
// Custom Form - END
return (
<div>
<div className="example-config">Hello</div>
<Scheduler
data={data}
onDataChange={handleDataChange}
view={view}
onViewChange={handleViewChange}
date={date}
onDateChange={handleDateChange}
editable={true}
timezone={timezone}
modelFields={customModelFields}
group={{
orientation
}}
height={900}
form={FormWithCustomEditor}
>
<TimelineView title="TimeTime" />
<DayView />
<WeekView />
<MonthView />
</Scheduler>
</div>
);
};
ReactDOM.render(<App />, document.querySelector('my-app'));
</script>
</html>