issue on scheduler timeline view while grouping 2025

0 Answers 4 Views
Scheduler
naseer
Top achievements
Rank 1
naseer asked on 15 Jul 2025, 02:29 PM | edited on 15 Jul 2025, 02:38 PM

<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>
hi here i have inserted my code , i have workstation and technician two groups, and i want to show the workstation list under the workstation group and technician list under the techncian group, this works fine when i selecting the viewtype as T ot W but in B i have to give the both list but i mentioned the resourcetype as the list belongs to which group , but still calender is showing both list in both group , i am trying this implementation in 2025 version 

anyone please give me the solution for this 

No answers yet. Maybe you can help?

Tags
Scheduler
Asked by
naseer
Top achievements
Rank 1
Share this question
or