1. Is it hard to understand the version numbers of our releases? If yes, what makes them hard to understand them?
2. Would semantic versioning (SemVer) of our releases make it easier to understand our version numbers and what's behind them?
3. If we go with SemVer, we might need to start with version 3000.0.0 as we currently use 2022.x.x. Please share your thoughts about this approach and ideas for what number versioning would work best for you.
current chart is looking like this
I want to be able to scale the value axis based on the highest value in the data.
For example, if the highest value is 10,000
The value axis will show 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
The label to display Amount ($k)
<script>
// Global variables
var ArrWorkStationProductTaskMappingList = [];
var ArrTechncinList = [];
var scheduler;
var currentEditingEvent = null;
var localEvents = [];
var nextId = 1;
// Sample data for demonstration
var sampleWorkStationData = [
{ WorkStationID: "WS001", WorkStationName: "Wall 1", ProdCode: "PROD001", TaskID: "T001", TaskName: "Task 1", Duration: 2.5 },
{ WorkStationID: "WS002", WorkStationName: "Wall 2", ProdCode: "PROD002", TaskID: "T002", TaskName: "Task 2", Duration: 3.0 },
{ WorkStationID: "WS003", WorkStationName: "Floor (B)", ProdCode: "PROD003", TaskID: "T003", TaskName: "Task 3", Duration: 1.5 },
{ WorkStationID: "WS004", WorkStationName: "Black Front", ProdCode: "PROD004", TaskID: "T004", TaskName: "Task 4", Duration: 1.5 },
{ WorkStationID: "WS004", WorkStationName: "Floor (Light 1)", ProdCode: "PROD005", TaskID: "T005", TaskName: "Task 5", Duration: 1.5 }
];
var sampleTechnicianData = [
{ TechnicianName: "John Doe", TechnicianUserID: "USER001", TechnicianMail: "john@example.com" },
{ TechnicianName: "Jane Smith", TechnicianUserID: "USER002", TechnicianMail: "jane@example.com" },
{ TechnicianName: "Bob Johnson", TechnicianUserID: "USER003", TechnicianMail: "bob@example.com" }
];
// Initialize sample data
ArrWorkStationProductTaskMappingList = sampleWorkStationData;
ArrTechncinList = sampleTechnicianData;
// Initialize sample events
localEvents = [
{
ScheduleID: 1,
Status: "Active",
ScheduleBatchID: "BATCH001",
ResourceID: "WS001",
ResourceName: "Wall 1",
ResourceMappedForID: "T001",
ResourceMappedForName: "Task 1",
JobNo: "JOB001",
ProdCode: "PROD001",
JobDetailUniqueID: "JD001",
Prod_Name: "Product 1",
ScheduleCode: "SCH001",
FromDate: "2025/7/15",
ToDate: "2025/7/15",
FromTime: "09:00",
ToTime: "11:00",
title: "Workstation Task - Product 1",
IsAllDayEvent: false,
description: "Sample workstation task for Product 1",
TypeID: 1,
start: new Date("2025/7/15 09:00"),
end: new Date("2025/7/15 11:00"),
resource: "WS001",
resourceType: 1
},
{
ScheduleID: 2,
Status: "Active",
ScheduleBatchID: "BATCH002",
ResourceID: "USER001",
ResourceName: "John Doe",
ResourceMappedForID: "S001",
ResourceMappedForName: "Sample 1",
JobNo: "JOB001",
ProdCode: "PROD001",
JobDetailUniqueID: "JD002",
Prod_Name: "Product 1",
ScheduleCode: "SCH002",
FromDate: "2025/7/15",
ToDate: "2025/7/15",
FromTime: "10:00",
ToTime: "12:00",
title: "Technician Task - John Doe",
IsAllDayEvent: false,
description: "Sample technician task",
TypeID: 2,
start: new Date("2025/7/15 10:00"),
end: new Date("2025/7/15 12:00"),
resource: "USER001",
resourceType: 2
},
{
ScheduleID: 3,
Status: "Active",
ScheduleBatchID: "BATCH003",
ResourceID: "WS002",
ResourceName: "Wall 2",
ResourceMappedForID: "T002",
ResourceMappedForName: "Task 2",
JobNo: "JOB002",
ProdCode: "PROD002",
JobDetailUniqueID: "JD003",
Prod_Name: "Product 2",
ScheduleCode: "SCH003",
FromDate: "2025/7/15",
ToDate: "2025/7/15",
FromTime: "13:00",
ToTime: "15:00",
title: "Workstation Task - Product 2",
IsAllDayEvent: false,
description: "Another workstation task for Product 2",
TypeID: 1,
start: new Date("2025/7/15 13:00"),
end: new Date("2025/7/15 15:00"),
resource: "WS002",
resourceType: 1
}
];
$(document).ready(function () {
// Initialize controls
$("#ddlViewType").val($("#hdViewType").val());
$("#txtProductCodes").val($("#hdcurrentTestCodeToAllocate").val());
// Initialize scheduler
initializeScheduler();
populateResourceDropdown();
// Event handlers
$("#btnRefreshScheduler").click(function () {
$("#hdViewType").val($("#ddlViewType").val());
$("#hdcurrentTestCodeToAllocate").val($("#txtProductCodes").val());
refreshScheduler();
});
$("#btnSaveSchedule").click(saveScheduleEvent);
});
// Add this function to validate and fix event resourceType values
function validateAndFixEvents() {
console.log("Validating events...");
localEvents.forEach(function (event, index) {
var correctResourceType = null;
// Check if it's a workstation resource
var workstationData = getFilteredWorkstationData();
var isWorkstation = workstationData.some(function (ws) {
return ws.WorkStationID === event.ResourceID;
});
if (isWorkstation) {
correctResourceType = 1;
} else {
// Check if it's a technician resource
var isTechnician = ArrTechncinList.some(function (tech) {
return tech.TechnicianUserID === event.ResourceID;
});
if (isTechnician) {
correctResourceType = 2;
}
}
if (correctResourceType && event.resourceType !== correctResourceType) {
console.log("Fixing event " + index + " resourceType from " + event.resourceType + " to " + correctResourceType);
event.resourceType = correctResourceType;
event.resource = event.ResourceID; // Make sure resource field matches ResourceID
}
});
console.log("Events after validation:", localEvents);
}
function initializeScheduler() {
validateAndFixEvents();
var resources = buildResourcesArray();
var dataSource = buildDataSource();
if (scheduler && typeof scheduler.destroy === "function") {
scheduler.destroy();
$("#scheduler").empty(); // Optional
}
scheduler = $("#scheduler").kendoScheduler({
date: new Date("2025/7/15"),
startTime: new Date("2025/7/15 08:00"),
endTime: new Date("2025/7/15 18:00"),
height: 800,
eventHeight: 50,
majorTick: 60,
views: [
"day",
"week",
"month",
{
type: "timeline",
selected: true,
startTime: new Date("2025/7/15 08:00"),
endTime: new Date("2025/7/15 18:00"),
workDayStart: new Date("2025/7/15 08:00"),
workDayEnd: new Date("2025/7/15 18:00"),
majorTick: 60,
minorTickCount: 2,
showWorkHours: true
},
{
type: "timelineWeek",
startTime: new Date("2025/7/15 08:00"),
endTime: new Date("2025/7/15 18:00"),
workDayStart: new Date("2025/7/15 08:00"),
workDayEnd: new Date("2025/7/15 18:00"),
majorTick: 60,
minorTickCount: 2,
showWorkHours: true
}
],
timezone: "Etc/UTC",
dataSource: dataSource,
resources: resources,
group: {
resources: ["resourceType", "resource"],
orientation: "vertical"
},
/*eventTemplate: $("#event-template").html(),*/
add: function (e) {
e.preventDefault();
openScheduleModal(null, e.event);
},
edit: function (e) {
e.preventDefault();
openScheduleModal(e.event, null);
},
remove: function (e) {
if (confirm("Are you sure you want to delete this event?")) {
console.log("Deleting event:", e.event);
// The scheduler will handle the delete automatically
} else {
e.preventDefault();
}
},
dataBound: function (e) {
// Add tooltips
$(".k-event").each(function () {
var uid = $(this).attr("data-uid");
var event = scheduler.dataSource.getByUid(uid);
//if (event) {
// $(this).attr("title", buildTooltipContent(event));
//}
});
}
}).data("kendoScheduler");
}
function buildResourcesArray() {
var resources = [];
var viewType = $("#hdViewType").val();
console.log("Building resources for view type:", viewType);
// Build the resource type grouping first
var resourceTypeData = [];
if (viewType === "B" || viewType === "W") {
resourceTypeData.push({
text: "Workstation",
value: 1,
color: "#2572c0"
});
}
if (viewType === "B" || viewType === "T") {
resourceTypeData.push({
text: "Technician",
value: 2,
color: "#f8a398"
});
}
// Add resourceType as the first resource for grouping
resources.push({
field: "resourceType",
name: "resourceType",
title: "Resource Type",
dataSource: resourceTypeData
});
// Build individual resources with correct resourceType values
var allResources = [];
// Add workstations
if (viewType === "B" || viewType === "W") {
var workstationData = getFilteredWorkstationData();
console.log("Adding workstations:", workstationData);
workstationData.forEach(function (item) {
allResources.push({
text: item.WorkStationName,
value: item.WorkStationID,
color: "#2572c0",
resourceType: 1 // CRITICAL: This must match the resourceType value above
});
});
}
// Add technicians
if (viewType === "B" || viewType === "T") {
console.log("Adding technicians:", ArrTechncinList);
ArrTechncinList.forEach(function (item) {
allResources.push({
text: item.TechnicianName,
value: item.TechnicianUserID,
color: "#f8a398",
resourceType: 2 // CRITICAL: This must match the resourceType value above
});
});
}
// Add the individual resources
resources.push({
field: "resource",
name: "resource",
title: "Resource",
valuePrimitive: true,
dataSource: allResources,
group: "resourceType" // This tells Kendo to group by resourceType
});
console.log("Final resources array:", resources);
console.log("All individual resources:", allResources);
return resources;
}
function getFilteredWorkstationData() {
var productCodes = $("#hdcurrentTestCodeToAllocate").val();
var filteredData = ArrWorkStationProductTaskMappingList;
if (productCodes && productCodes.trim() !== "") {
var codes = productCodes.split(',').map(function (code) {
return code.trim();
});
filteredData = ArrWorkStationProductTaskMappingList.filter(function (item) {
return codes.indexOf(item.ProdCode) !== -1;
});
}
// Get distinct workstations
var distinctWorkstations = [];
var seen = {};
filteredData.forEach(function (item) {
var key = item.WorkStationID; // + "_" + item.TaskID;
if (!seen[key]) {
seen[key] = true;
distinctWorkstations.push(item);
}
});
return distinctWorkstations;
}
function buildDataSource() {
return new kendo.data.SchedulerDataSource({
batch: true,
transport: {
read: function (options) {
try {
options.success(localEvents);
} catch (error) {
console.error('Error reading events:', error);
options.error(error);
}
},
create: function (options) {
try {
var newEvents = options.data.models || [options.data];
newEvents.forEach(function (event) {
event.ScheduleID = nextId++;
localEvents.push(event);
});
options.success(newEvents);
} catch (error) {
console.error('Error creating events:', error);
options.error(error);
}
},
update: function (options) {
try {
var updatedEvents = options.data.models || [options.data];
updatedEvents.forEach(function (updatedEvent) {
var index = localEvents.findIndex(function (e) {
return e.ScheduleID === updatedEvent.ScheduleID;
});
if (index !== -1) {
localEvents[index] = updatedEvent;
}
});
options.success(updatedEvents);
} catch (error) {
console.error('Error updating events:', error);
options.error(error);
}
},
destroy: function (options) {
try {
var deletedEvents = options.data.models || [options.data];
deletedEvents.forEach(function (deletedEvent) {
var index = localEvents.findIndex(function (e) {
return e.ScheduleID === deletedEvent.ScheduleID;
});
if (index !== -1) {
localEvents.splice(index, 1);
}
});
options.success(deletedEvents);
} catch (error) {
console.error('Error deleting events:', error);
options.error(error);
}
}
},
schema: {
model: {
id: "ScheduleID",
fields: {
ScheduleID: { type: "number" },
title: { from: "title", defaultValue: "No title", validation: { required: true } },
start: { type: "date", validation: { required: true } },
end: { type: "date", validation: { required: true } },
resource: { nullable: true },
resourceType: { nullable: true },
isAllDay: { type: "boolean", from: "IsAllDayEvent", defaultValue: false },
description: { type: "string" },
Status: { type: "string" },
ScheduleBatchID: { type: "string" },
ResourceID: { type: "string" },
ResourceName: { type: "string" },
ResourceMappedForID: { type: "string" },
ResourceMappedForName: { type: "string" },
JobNo: { type: "string" },
ProdCode: { type: "string" },
JobDetailUniqueID: { type: "string" },
Prod_Name: { type: "string" },
ScheduleCode: { type: "string" },
FromDate: { type: "string" },
ToDate: { type: "string" },
FromTime: { type: "string" },
ToTime: { type: "string" },
TypeID: { type: "number" }
}
}
}
});
}
function refreshScheduler() {
initializeScheduler();
populateResourceDropdown();
}
function openScheduleModal(event, newEvent) {
currentEditingEvent = event;
// Populate resource dropdown
populateResourceDropdown();
if (event) {
// Edit mode
$("#modalTitle").text("Edit Schedule Event");
$("#eventId").val(event.ScheduleID);
$("#eventTitle").val(event.title);
$("#eventStart").val(formatDateTimeLocal(event.start));
$("#eventEnd").val(formatDateTimeLocal(event.end));
$("#eventResource").val(event.ResourceID);
$("#eventDescription").val(event.description || "");
$("#eventTypeId").val(event.TypeID);
$("#eventResourceId").val(event.ResourceID);
} else {
// Add mode
$("#modalTitle").text("Add Schedule Event");
$("#eventId").val("");
$("#eventTitle").val("");
$("#eventStart").val(formatDateTimeLocal(newEvent.start));
$("#eventEnd").val(formatDateTimeLocal(newEvent.end));
$("#eventResource").val("");
$("#eventDescription").val("");
$("#eventTypeId").val("");
$("#eventResourceId").val("");
}
$('#scheduleModal').modal('show');
}
function populateResourceDropdown() {
var dropdown = $("#eventResource");
dropdown.empty();
dropdown.append('<option value="">Select Resource</option>');
var resources = buildResourcesArray();
if (resources.length > 1) {
var groupedResources = {
Workstations: [],
Technicians: []
};
resources[1].dataSource.forEach(function (item) {
if (item.resourceType === 1) {
groupedResources.Workstations.push(item);
} else if (item.resourceType === 2) {
groupedResources.Technicians.push(item);
}
});
// Append Workstations
if (groupedResources.Workstations.length > 0) {
var wsGroup = $('<optgroup label="Workstations"></optgroup>');
groupedResources.Workstations.forEach(function (ws) {
wsGroup.append('<option value="' + ws.value + '">' + ws.text + '</option>');
});
dropdown.append(wsGroup);
}
// Append Technicians
if (groupedResources.Technicians.length > 0) {
var techGroup = $('<optgroup label="Technicians"></optgroup>');
groupedResources.Technicians.forEach(function (tech) {
techGroup.append('<option value="' + tech.value + '">' + tech.text + '</option>');
});
dropdown.append(techGroup);
}
}
}
function saveScheduleEvent() {
//if (!$("#scheduleForm")[0].checkValidity()) {
// $("#scheduleForm")[0].reportValidity();
// return;
//}
var startDate = new Date($("#eventStart").val());
var endDate = new Date($("#eventEnd").val());
var selectedResource = $("#eventResource").val();
// Determine TypeID based on selected resource
var typeId = 1; // default to workstation
var resourceName = "";
var resourceMappedForID = "";
var resourceMappedForName = "";
// Find the selected resource details
var resources = buildResourcesArray();
var resourceData = resources[1].dataSource.find(function (r) { return r.value === selectedResource; });
if (resourceData) {
typeId = resourceData.resourceType;
resourceName = resourceData.text;
if (typeId === 1) {
// Workstation
resourceMappedForID = resourceData.taskId;
resourceMappedForName = resourceData.taskName;
} else {
// Technician
resourceMappedForID = resourceData.technicianUserId;
resourceMappedForName = resourceData.text;
}
}
var eventData = {
ScheduleID: $("#eventId").val() || nextId++,
Status: "Active",
ScheduleBatchID: "BATCH" + new Date().getTime(),
ResourceID: selectedResource,
ResourceName: resourceName,
ResourceMappedForID: resourceMappedForID,
ResourceMappedForName: resourceMappedForName,
JobNo: $("#hdJobNo").val(),
ProdCode: $("#hdcurrentTestCodeToAllocate").val().split(',')[0] || "",
JobDetailUniqueID: $("#hdSelectedJobIDs").val().split(',')[0] || "",
Prod_Name: "Product Name",
ScheduleCode: "SCH" + new Date().getTime(),
FromDate: kendo.toString(startDate, "yyyy/M/d"),
ToDate: kendo.toString(endDate, "yyyy/M/d"),
FromTime: kendo.toString(startDate, "HH:mm"),
ToTime: kendo.toString(endDate, "HH:mm"),
title: $("#eventTitle").val(),
IsAllDayEvent: false,
description: $("#eventDescription").val(),
TypeID: typeId,
start: startDate,
end: endDate,
resource: selectedResource,
resourceType: typeId
};
if (currentEditingEvent) {
// Update existing event
var existingEvent = scheduler.dataSource.get(currentEditingEvent.ScheduleID);
for (var key in eventData) {
existingEvent.set(key, eventData[key]);
}
} else {
// Add new event
scheduler.dataSource.add(eventData);
}
$('#scheduleModal').modal('hide');
}
function formatDateTimeLocal(date) {
var d = new Date(date);
var month = ('0' + (d.getMonth() + 1)).slice(-2);
var day = ('0' + d.getDate()).slice(-2);
var hours = ('0' + d.getHours()).slice(-2);
var minutes = ('0' + d.getMinutes()).slice(-2);
return d.getFullYear() + '-' + month + '-' + day + 'T' + hours + ':' + minutes;
}
</script>
<input type="hidden" id="hdViewType" value="B" />
<input type="hidden" id="hdcurrentTestCodeToAllocate" value="PROD001,PROD002,PROD003,PROD004,PROD005" />
<input type="hidden" id="hdJobNo" value="JOB001" />
<input type="hidden" id="hdSelectedJobIDs" value="JD001,JD002" />
<div class="resource-controls">
<div class="row">
<div class="col-md-3">
<label for="ddlViewType">View Type:</label>
<select id="ddlViewType" class="form-control" style="height: 38px;">
<option value="B">Both (Workstation & Technician)</option>
<option value="W">Workstation Only</option>
<option value="T">Technician Only</option>
</select>
</div>
<div class="col-md-3" style="display:none">
<label for="txtProductCodes">Product Codes:</label>
<input type="text" id="txtProductCodes" class="form-control" placeholder="PROD001,PROD002,PROD003,PROD004,PROD005" />
</div>
<div class="col-md-3">
<button id="btnRefreshScheduler" class="btn btn-primary" style="margin-top: 25px;">Refresh Scheduler</button>
</div>
</div>
</div>
<div class="scheduler-container">
<div id="scheduler" style="width:100%"></div>
</div>
How do you set and change the height?
$('#gauge').kendoRadialGauge({ pointer: { value: 0, }, scale: { min: 0, max: 100, minorUnit: 5, startAngle: -30, endAngle: 210, gaugeArea: { height: 310, }, ranges: [ { from: 0, to: 20, color: "#bbf2df" }, { from: 21, to: 49, color: "#ffc700" }, { from: 50, to: 1000, color: "#fc4a4a" } ] } });
Still has the default height of 200px. Calling resize() after changing the css attribute also doesn't change the height.
$('#gauge').css({ height: '300px' }).data("kendoRadialGauge").resize(true);
Can you not make the gauges smaller than 200px?
categoryaxis.labels.font and seriesDefault.labels.font string set not apply
Hello,
I'm looking for a way to create a custom editor for a field in a Kendo Form.
I've created a partial view in my Shared/EditorTemplates folder. Also, I've applied the UIHint attribute with the name of the partial view on the property of my view model. But still it does not render as expected, the view does not show up on the form.
Is there any demo on how to do this. I really tried to search, but was not able to find something for this exact case.
Thanks!
Kiril
I have a recurring event with exceptions in one timezone and am trying to display the schedule in another timezone.
The events all display correctly with corresponding daylight saving adjustments however the exceptions get lost once the event timezone transitions into (or out of) summer time.
Running following code in the dojo correctly hides the 17th of April occurrence IF the timezone is set to "Europe/London" but displays the entry when set to "Pacific/Auckland".
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Kendo UI Snippet</title>
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"/>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/themes/11.0.2/default/default-ocean-blue.css"/>
<style>body {font-family: Helvetica, Arial, sans-serif;font-size: 14px}</style>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2025.2.520/js/kendo.all.min.js" ></script>
</head>
<body>
<div id="scheduler"></div>
<script>
var version = kendo.version;
$.getScript( 'https://kendo.cdn.telerik.com/'+version+'/js/kendo.timezones.min.js', function( data, textStatus, jqxhr ) {
$("#scheduler").kendoScheduler({
date: new Date("2025/3/20"),
height: 600,
views: ["week"],
editable: false,
//timezone: "Europe/London",
timezone: "Pacific/Auckland",
dataSource: [
{
title: "Event Europe/London",
start: new Date("2025-03-20T14:00:00.000Z"),
end: new Date("2025-03-20T14:30:00.000Z"),
startTimezone: "Europe/London",
endTimezone: "Europe/London",
recurrenceRule: "FREQ=WEEKLY;BYDAY=TH;WKST=MO;",
recurrenceException: "20250417T130000Z"
}
]
});
});
</script>
</body>
</html>