Our pure JavaScript Scheduler component


Post by fergus_ugle »

I am trying to have my scheduler column pre-filtered using a default value and the .filterable attribute.

I use the .filterable attribute to set my custom filter function and filterField as seen below (VueJS function):

            this.scheduler.columns.getById('room_column').filterable = {
                filterFn: ({value, record}) =>
                    ... filter logic
                ,
                filterField: {
                    type: 'combo',
                    filterOperator: '*',
                    multiSelect: true,
                    items: [...roomGroups, ...rooms],
                },
            };

I have been able to set the default value in the filter using the 'value' attribute in filterable.filterField. I have also been able to set the default value using

     [code] filterFeature: {property: 'name', value: 'Test Group'}[/code]

on my main scheduler config as decriped in the docs here: https://bryntum.com/products/schedulerpro/docs/api/Grid/feature/FilterBar

Even through I have been able to pre-populate the value field, my custom filter does not get applied when the page is loaded. When I click on a dropdown list item in my column filter, the custom filter is applied with the item i clicked on AND my pre-populated value as expected.

What I need is a way to have my filter function called on the value i pre-populate the filter with (simulate clicking on the predefined value in the drop down list). I have tried everything in the docs but nothing has worked.

Any help is appreciated!


Post by marcio »

Hey fergus_ugle,

Thanks for reaching out and welcome to our forums.

Just to confirm, are you using the filterBar with the filter feature?

If so, that will lead to unexpected behavior, as you can see at the end of the Filter bar documentation

Note: This feature cannot be used together with filter feature, they are mutually exclusive.

Is this correct or are you using only one of the features?

If you're using only one, could you provide a test case for us to debug? You can get one of our demos and adapt it to match your scenario. You can get more info on that checking our guidelines here https://www.bryntum.com/forum/viewtopic.php?f=1&t=772

Best regards,
Márcio


Post by fergus_ugle »

Thanks for the quick reply.

I have modified this basic demo to highlight the problem: https://bryntum.com/products/schedulerpro/examples-scheduler/basic/

Post my code contained in the attached zip file into the editor.

Then in the UI, go to the custom filter on the name column.
See that there is a pre-populated value in the filter bar, but that list has not been filtered.
(I want the list to be filtered when the page is loaded).

Then try adding another name into the filter and see that the filter is then applied using both names.

It should be easy to tell where in the code i have made my modifications.

Thanks,

Attachments
filter_example.zip
(1.11 KiB) Downloaded 12 times

Post by ghulam.ghous »

Hi there,

Applying default filter worked for me. I have just added the following line as shown in the first code snippet here https://bryntum.com/products/scheduler/docs/api/Grid/feature/Filter.

// Using default filter
const scheduler = new Scheduler({
  features : {
    filter : { property : 'city', value : 'Gavle' }
  }
});

For me you zipped example worked with this code:

const resources = [
        { id : 'r1', name : 'Mike' },
        { id : 'r2', name : 'Linda' },
        { id : 'r3', name : 'Don' },
        { id : 'r4', name : 'Karen' },
        { id : 'r5', name : 'Doug' },
        { id : 'r6', name : 'Peter' },
        { id : 'r7', name : 'Sam' },
        { id : 'r8', name : 'Melissa' },
        { id : 'r9', name : 'John' },
        { id : 'r10', name : 'Ellen' }
    ],
    names = resources.map((resource) => resource.name),
    events = [
        {
            id         : 1,
            resourceId : 'r1',
            startDate  : new Date(2017, 0, 1, 10),
            endDate    : new Date(2017, 0, 1, 12),
            name       : 'Click me',
            iconCls    : 'b-fa b-fa-mouse-pointer'
        },
        {
            id         : 2,
            resourceId : 'r2',
            startDate  : new Date(2017, 0, 1, 12),
            endDate    : new Date(2017, 0, 1, 13, 30),
            name       : 'Drag me',
            iconCls    : 'b-fa b-fa-arrows-alt'
        },
        {
            id           : 3,
            resourceId   : 'r3',
            startDate    : new Date(2017, 0, 1, 14),
            duration     : 2,
            durationUnit : 'h',
            name         : 'Double click me',
            eventColor   : 'purple',
            iconCls      : 'b-fa b-fa-mouse-pointer'
        },
        {
            id         : 4,
            resourceId : 'r4',
            startDate  : new Date(2017, 0, 1, 8),
            endDate    : new Date(2017, 0, 1, 11),
            name       : 'Right click me',
            iconCls    : 'b-fa b-fa-mouse-pointer'
        },
        {
            id         : 5,
            resourceId : 'r5',
            startDate  : new Date(2017, 0, 1, 15),
            endDate    : new Date(2017, 0, 1, 17),
            name       : 'Resize me',
            iconCls    : 'b-fa b-fa-arrows-alt-h'
        },
        {
            id         : 6,
            resourceId : 'r6',
            startDate  : new Date(2017, 0, 1, 16),
            endDate    : new Date(2017, 0, 1, 19),
            name       : 'Important meeting (read-only)',
            iconCls    : 'b-fa b-fa-exclamation-triangle',
            eventColor : 'red',
            readOnly   : true
        },
        {
            id         : 7,
            resourceId : 'r6',
            startDate  : new Date(2017, 0, 1, 6),
            endDate    : new Date(2017, 0, 1, 8),
            name       : 'Sports event',
            iconCls    : 'b-fa b-fa-basketball-ball'
        },
        {
            id         : 8,
            resourceId : 'r7',
            startDate  : new Date(2017, 0, 1, 9),
            endDate    : new Date(2017, 0, 1, 11, 30),
            name       : "Dad's birthday!",
            iconCls    : 'b-fa b-fa-birthday-cake',
            // Custom styling from data
            style      : 'background-color : teal; font-size: 18px',
            // Prevent default styling
            eventStyle : 'none'
        }
    ];

//endregion

const scheduler = new Scheduler({
    appendTo         : 'container',
    resources,
    events,
    startDate        : new Date(2017, 0, 1, 6),
    endDate          : new Date(2017, 0, 1, 20),
    viewPreset       : 'hourAndDay',
    rowHeight        : 50,
    barMargin        : 5,
    multiEventSelect : true,
    features         : {
        filter : { property : 'name', value : 'Mike' }
    },
    columns : [
        {
            text       : 'Name',
            field      : 'name',
            width      : 130,
            filterable : {
                filterFn    : ({ value, record }) => value.includes(record.name),
                filterField : {
                    type           : 'combo',
                    filterOperator : '*',
                    multiSelect    : true,
                    items          : [...names]
                }
            }
        }
    ]
});

I hope this is what you were looking for.

Regards,
Ghous


Post by fergus_ugle »

I got that to work in the demo too, thanks.

However, my code still does not work.

I am using VueJS, when I add

field: 'room',

to my column (as needed to match with 'property' from features.filter).

It removes all of the items from my list. I don't know why.

If i comment out

field: 'room'

my scheduler works fine but the filter is not applied.

This is the config for my scheduler, called from my VueJS file:

useSchedulerProConfig: function () {
            let self = this

        return {
            timeZone: 'Europe/London',
            autoRescheduleTasks: false,
            zoomOnTimeAxisDoubleClick: false,
            eventStyle: 'colored',
            allowOverlap: false,
            weekStartDay: 1,
            columns: [
                {
                    id: 'room_column',
                    // field: 'room',
                    type: 'resourceInfo',
                    text: 'Room',
                    width: 200,
                    showEventCount: false,
                    showImage: false,
                    showRole: true,
                    readOnly: true,
                    filterable: {
                        filterFn: ({value, record}) =>
                            value.length === 0 ||
                            value.includes(record.name) ||
                            record.groups.some(group => value.includes(group))
                        ,
                        filterField: {
                            type: 'combo',
                            filterOperator: '*',
                            multiSelect: true,
                            items: ['Test Group'],
                        },
                    }
                }
            ],
            scrollable: {
                overflowX: true,
                overflowY: true
            },
            subGridConfigs: {
                locked: {
                    width: 300
                },
                normal: {
                    flex: 1
                }
            },
            flex: 4,
            crudManager: {
                autoLoad: true,
                autoSync: true,

                validateResponse: false,
                eventStore: {
                    storeClass: BookingStore,
                },
                resourceStore: {
                    modelClass: CustomResourceModel
                },
                transport: {
                    load: {
                        url: ...
                    },
                    sync: {
                        url: ...,
                        requestConfig: {
                            headers: {'X-Xsrf-Token': getCookie('XSRF-TOKEN')}
                        }
                    }
                },
            },

            tbar: [
                'Booking Scheduler',
                '->',

                {
                    type: 'button',
                    text: 'Create Event',
                    onAction: 'up.onCreateEventClick'
                },
                {
                    icon: 'b-icon b-fa-caret-left',
                    onAction: 'up.onPreviousDayClick'
                },
                {
                    type: 'button',
                    text: 'Today',
                    onAction: 'up.onTodayClick'
                },
                {
                    icon: 'b-icon b-fa-caret-right',
                    onAction: 'up.onNextDayClick'
                },
                {
                    id: 'select-day',
                    clearable: true,
                    type: 'datefield',
                    format: 'DD/MM/YYYY',
                    width: '9em',
                    icon: 'b-icon b-fa-caret-right',
                    onChange: 'up.onSelectDate'
                },
                {
                    type: 'textfield',
                    ref: 'filterByName',
                    icon: 'b-fa b-fa-filter',
                    placeholder: 'Find bookings by name',
                    clearable: true,
                    width: '15em',
                    keyStrokeChangeDelay: 100,
                    triggers: {
                        filter: {
                            align: 'start',
                            cls: 'b-fa b-fa-filter'
                        }
                    },
                    onChange({value}) {
                        value = value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');

                        // Replace all previous filters and set a new filter
                        self.scheduler.eventStore.filter({
                            filters: event => event.name.match(new RegExp(value, 'i')),
                            replace: true
                        });

                    }
                },

                {
                    type: 'viewpresetcombo',
                    presets: ['customHourAndDay', 'customDayAndWeekTwoDays', 'customDayAndWeekThreeDays', 'customDayAndWeek_shiftWeek', 'customDayAndMonth']
                },

                {
                    id: 'start-day',
                    placeholder: 'Start',
                    type: 'numberfield',
                    min: 0,
                    max: 23,
                    step: 1,
                    width: '70px',
                    onChange({value}) {
                        if (value) {
                            if (!self.scheduler.tbar.getWidgetById('end-day').value) {
                                self.scheduler.tbar.getWidgetById('end-day').value = 23
                            } else if (value >= self.endTimeField) {
                                self.scheduler.tbar.getWidgetById('end-day').value = value + 1
                            }
                            self.startTimeField = value

                            if (self.scheduler.viewPreset.name === '1 day') {
                                self.scheduler.setTimeSpan(self.scheduler.timeAxis.data[0].startDate)
                            } else {
                                self.scheduler.shift(0)
                            }
                        }
                    }
                },
                {
                    id: 'end-day',
                    placeholder: 'End',
                    type: 'numberfield',
                    min: 1,
                    max: 24,
                    step: 1,
                    width: '70px',
                    onChange({value}) {
                        if (value) {
                            if (!self.scheduler.tbar.getWidgetById('start-day').value) {
                                self.scheduler.tbar.getWidgetById('start-day').value = 0
                            } else if (value <= self.startTimeField) {
                                self.scheduler.tbar.getWidgetById('start-day').value = value - 1
                            }
                            if (value <= self.startTimeField) {
                                self.scheduler.tbar.getWidgetById('start-day').value = value - 1
                            }
                            self.endTimeField = value
                            if (self.scheduler.viewPreset.name === '1 day') {
                                self.scheduler.setTimeSpan(self.scheduler.timeAxis.data[0].startDate)
                            } else {
                                self.scheduler.shift(0)
                            }
                        }
                    }
                },

                {
                    id: 'toggle-unscheduled',
                    type: 'button',
                    toggleable: true,
                    icon: 'b-fa-calendar',
                    pressedIcon: 'b-fa-calendar-check',
                    text: '',
                    tooltip: 'Show/Hide unscheduled bookings',
                    cls: 'reschedule-button',
                    async onToggle({pressed}) {
                        if (self.unplannedGrid.isVisible) {
                            self.unplannedGrid.hide();
                        } else {
                            await self.fetchUnscheduledBookings();
                            self.unplannedGrid.show();
                        }
                    }
                },
            ],

            timeRangesFeature: true,
            features: {
                filter: {property: 'room', value: 'Test Group'},
            },
            filterFeature: true,
            stripeFeature: true,
            scheduleContextMenuFeature: false,

            eventMenuFeature: false,
            eventDragCreateFeature: {
                validatorFn({eventRecord, resourceRecord, startDate, endDate}) {
                    return validateEventTime(eventRecord, self.scheduler, resourceRecord, startDate, endDate)
                }
            },
            eventResizeFeature: {
                validatorFn({eventRecord, resourceRecord, startDate, endDate}) {
                    return validateEventTime(eventRecord, self.scheduler, resourceRecord, startDate, endDate)
                }
            },
            eventDragFeature: {
                validatorFn({eventRecords, newResource, startDate, endDate}) {
                    const task = eventRecords[0]
                    return validateEventTime(task, self.scheduler, newResource, startDate, endDate)
                }
            },
            viewPreset: presets[0].id,
            presets,
            timeAxis: {
                continuous: false,
                generateTicks(start, end, unit, increment) {
                    const ticks = [];
                    self.currentPreset = this.viewPreset.name

                    let startDate = new Date(start)
                    let endDate = new Date(end)

                    if (this.viewPreset.name === '1 day' || this.viewPreset.name === '2 days' || this.viewPreset.name === '3 days') {
                        endDate = new Date(start)

                        self.currentDay = startDate
                        let daysNumber = 1

                        if (this.viewPreset.name === '2 days') {
                            daysNumber = 2
                        } else if (this.viewPreset.name === '3 days') {
                            daysNumber = 3
                        }

                        for (let day = 1; day <= daysNumber; day++) {
                            startDate.setHours(self.startTimeField, 0, 0, 0)
                            endDate.setHours(self.endTimeField, 0, 0, 0)

                            for (let date = startDate; date < endDate;) {
                                const tickEnd = DH.add(date, 1, 'hour');
                                ticks.push({
                                    startDate: date,
                                    endDate: tickEnd
                                });

                                date = tickEnd
                            }
                            startDate = DH.add(startDate, 1, 'day');
                            endDate = DH.add(endDate, 1, 'day');
                        }


                    } else {
                        self.currentDay = new Date()

                        for (let date = startDate; date < endDate;) {


                            const tickStart = new Date(date)
                            const tickEnd = new Date(date)

                            tickStart.setHours(self.startTimeField, 0, 0, 0)
                            tickEnd.setHours(self.endTimeField, 0, 0, 0)

                            ticks.push({
                                startDate: tickStart,
                                endDate: tickEnd
                            });

                            date = DH.add(date, 1, 'day');
                        }
                    }

                    if (self.scheduler) {
                        self.scheduler.crudManager.loadUrl = '/api/scheduler/bookings?start=' + start.toISOString().split('T')[0] + '&end=' + end.toISOString().split('T')[0]
                        self.scheduler.crudManager.load()
                    }

                    return ticks

                }
            },

        };
    }

Post by ghulam.ghous »

Hi there,

Thanks for sharing the complete config. I believe that I found the issue with your config. You are using both FilterFeature and feature:{ filter: {.....}} inside your config. Please use either of them. As it is a framework I suggest you to use filterFeature config:

        filterFeature: {property: 'room', value: 'Test Group'},

It works with field: 'room' on the column as well. You do not need to comment it out.

Regards,
Ghous


Post by fergus_ugle »

Hi,

So this is my config now.

useSchedulerProConfig: function () {
            let self = this

        return {
            timeZone: 'Europe/London',
            autoRescheduleTasks: false,
            zoomOnTimeAxisDoubleClick: false,
            eventStyle: 'colored',
            allowOverlap: false,
            weekStartDay: 1,
            columns: [
                {
                    id: 'room_column',
                    field: 'room',
                    type: 'resourceInfo',
                    text: 'Room',
                    width: 200,
                    showEventCount: false,
                    showImage: false,
                    showRole: true,
                    readOnly: true,
                    filterable: {
                        filterFn: ({value, record}) =>
                            value.length === 0 ||
                            value.includes(record.name) ||
                            record.groups.some(group => value.includes(group))
                        ,
                        filterField: {
                            type: 'combo',
                            filterOperator: '*',
                            multiSelect: true,
                            items: ['Test Group'],
                        },
                    }
                }
            ],
            scrollable: {
                overflowX: true,
                overflowY: true
            },
            subGridConfigs: {
                locked: {
                    width: 300
                },
                normal: {
                    flex: 1
                }
            },
            flex: 4,
            crudManager: {
                autoLoad: true,
                autoSync: true,

                validateResponse: false,
                eventStore: {
                    storeClass: BookingStore,
                },
                resourceStore: {
                    modelClass: CustomResourceModel
                },
                transport: {
                    load: {
                        url: '/api/scheduler/bookings?withResources=1'
                    },
                    sync: {
                        url: '/api/scheduler/bookings/sync',
                        requestConfig: {
                            headers: {'X-Xsrf-Token': getCookie('XSRF-TOKEN')}
                        }
                    }
                },
            },

            tbar: [
                'Booking Scheduler',
                '->',

                {
                    type: 'button',
                    text: 'Create Event',
                    onAction: 'up.onCreateEventClick'
                },
                {
                    icon: 'b-icon b-fa-caret-left',
                    onAction: 'up.onPreviousDayClick'
                },
                {
                    type: 'button',
                    text: 'Today',
                    onAction: 'up.onTodayClick'
                },
                {
                    icon: 'b-icon b-fa-caret-right',
                    onAction: 'up.onNextDayClick'
                },
                {
                    id: 'select-day',
                    clearable: true,
                    type: 'datefield',
                    format: 'DD/MM/YYYY',
                    width: '9em',
                    icon: 'b-icon b-fa-caret-right',
                    onChange: 'up.onSelectDate'
                },
                {
                    type: 'textfield',
                    ref: 'filterByName',
                    icon: 'b-fa b-fa-filter',
                    placeholder: 'Find bookings by name',
                    clearable: true,
                    width: '15em',
                    keyStrokeChangeDelay: 100,
                    triggers: {
                        filter: {
                            align: 'start',
                            cls: 'b-fa b-fa-filter'
                        }
                    },
                    onChange({value}) {
                        value = value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');

                        // Replace all previous filters and set a new filter
                        self.scheduler.eventStore.filter({
                            filters: event => event.name.match(new RegExp(value, 'i')),
                            replace: true
                        });

                    }
                },

                {
                    type: 'viewpresetcombo',
                    presets: ['customHourAndDay', 'customDayAndWeekTwoDays', 'customDayAndWeekThreeDays', 'customDayAndWeek_shiftWeek', 'customDayAndMonth']
                },

                {
                    id: 'start-day',
                    placeholder: 'Start',
                    type: 'numberfield',
                    min: 0,
                    max: 23,
                    step: 1,
                    width: '70px',
                    onChange({value}) {
                        if (value) {
                            if (!self.scheduler.tbar.getWidgetById('end-day').value) {
                                self.scheduler.tbar.getWidgetById('end-day').value = 23
                            } else if (value >= self.endTimeField) {
                                self.scheduler.tbar.getWidgetById('end-day').value = value + 1
                            }
                            self.startTimeField = value

                            if (self.scheduler.viewPreset.name === '1 day') {
                                self.scheduler.setTimeSpan(self.scheduler.timeAxis.data[0].startDate)
                            } else {
                                self.scheduler.shift(0)
                            }
                        }
                    }
                },
                {
                    id: 'end-day',
                    placeholder: 'End',
                    type: 'numberfield',
                    min: 1,
                    max: 24,
                    step: 1,
                    width: '70px',
                    onChange({value}) {
                        if (value) {
                            if (!self.scheduler.tbar.getWidgetById('start-day').value) {
                                self.scheduler.tbar.getWidgetById('start-day').value = 0
                            } else if (value <= self.startTimeField) {
                                self.scheduler.tbar.getWidgetById('start-day').value = value - 1
                            }
                            if (value <= self.startTimeField) {
                                self.scheduler.tbar.getWidgetById('start-day').value = value - 1
                            }
                            self.endTimeField = value
                            if (self.scheduler.viewPreset.name === '1 day') {
                                self.scheduler.setTimeSpan(self.scheduler.timeAxis.data[0].startDate)
                            } else {
                                self.scheduler.shift(0)
                            }
                        }
                    }
                },

                {
                    id: 'toggle-unscheduled',
                    type: 'button',
                    toggleable: true,
                    icon: 'b-fa-calendar',
                    pressedIcon: 'b-fa-calendar-check',
                    text: '',
                    tooltip: 'Show/Hide unscheduled bookings',
                    cls: 'reschedule-button',
                    async onToggle({pressed}) {
                        if (self.unplannedGrid.isVisible) {
                            self.unplannedGrid.hide();
                        } else {
                            await self.fetchUnscheduledBookings();
                            self.unplannedGrid.show();
                        }
                    }
                },
            ],

            timeRangesFeature: true,
            filterFeature: {property: 'room', value: 'Test Group'},
            stripeFeature: true,
            scheduleContextMenuFeature: false,

            eventMenuFeature: false,
            eventDragCreateFeature: {
                validatorFn({eventRecord, resourceRecord, startDate, endDate}) {
                    return validateEventTime(eventRecord, self.scheduler, resourceRecord, startDate, endDate)
                }
            },
            eventResizeFeature: {
                validatorFn({eventRecord, resourceRecord, startDate, endDate}) {
                    return validateEventTime(eventRecord, self.scheduler, resourceRecord, startDate, endDate)
                }
            },
            eventDragFeature: {
                validatorFn({eventRecords, newResource, startDate, endDate}) {
                    const task = eventRecords[0]
                    return validateEventTime(task, self.scheduler, newResource, startDate, endDate)
                }
            },
            viewPreset: presets[0].id,
            presets,
            timeAxis: {
                continuous: false,
                generateTicks(start, end, unit, increment) {
                    const ticks = [];
                    self.currentPreset = this.viewPreset.name

                    let startDate = new Date(start)
                    let endDate = new Date(end)

                    if (this.viewPreset.name === '1 day' || this.viewPreset.name === '2 days' || this.viewPreset.name === '3 days') {
                        endDate = new Date(start)

                        self.currentDay = startDate
                        let daysNumber = 1

                        if (this.viewPreset.name === '2 days') {
                            daysNumber = 2
                        } else if (this.viewPreset.name === '3 days') {
                            daysNumber = 3
                        }

                        for (let day = 1; day <= daysNumber; day++) {
                            startDate.setHours(self.startTimeField, 0, 0, 0)
                            endDate.setHours(self.endTimeField, 0, 0, 0)

                            for (let date = startDate; date < endDate;) {
                                const tickEnd = DH.add(date, 1, 'hour');
                                ticks.push({
                                    startDate: date,
                                    endDate: tickEnd
                                });

                                date = tickEnd
                            }
                            startDate = DH.add(startDate, 1, 'day');
                            endDate = DH.add(endDate, 1, 'day');
                        }


                    } else {
                        self.currentDay = new Date()

                        for (let date = startDate; date < endDate;) {


                            const tickStart = new Date(date)
                            const tickEnd = new Date(date)

                            tickStart.setHours(self.startTimeField, 0, 0, 0)
                            tickEnd.setHours(self.endTimeField, 0, 0, 0)

                            ticks.push({
                                startDate: tickStart,
                                endDate: tickEnd
                            });

                            date = DH.add(date, 1, 'day');
                        }
                    }

                    if (self.scheduler) {
                        self.scheduler.crudManager.loadUrl = '/api/scheduler/bookings?start=' + start.toISOString().split('T')[0] + '&end=' + end.toISOString().split('T')[0]
                        self.scheduler.crudManager.load()
                    }

                    return ticks

                }
            },

        };
    }

When I load the page my valid predefined filter is set i see the following:

Screenshot from 2024-02-23 16-35-45.png
Screenshot from 2024-02-23 16-35-45.png (22.13 KiB) Viewed 119 times
Screenshot from 2024-02-23 16-35-37.png
Screenshot from 2024-02-23 16-35-37.png (24.47 KiB) Viewed 119 times

When I remove my filter I see the rows but the row titles are missing:

Screenshot from 2024-02-23 16-36-35.png
Screenshot from 2024-02-23 16-36-35.png (24.84 KiB) Viewed 119 times

Post by ghulam.ghous »

This is a pretty odd behaviour. I can not what is wrong there. Can you please provide us a runnable test case where we can reproduce this issue. You can use this example code https://bryntum.com/products/scheduler/examples/frameworks/vue/javascript/simple/dist/ and add your minimum config to reproduce the issue. You can add pass a small set of data there. This will help us to debug you and assist you in a better way. Please see the guidelines about runnable test case here viewtopic.php?f=35&t=772).

Regards,
Ghous


Post Reply