DistributorConferenceEditDialog = function( options ) { this.dataURL = $("link#appDataURL").attr( "href" ); let instance = this; instance.onReturn = null; instance.data = options.data; if( options ) { if( options.onReturn ) { instance.onReturn = options.onReturn; } } instance.showLoadPanel(); instance.cdr_recordId = instance.data.cdr_recordId; instance.eventId = instance.data.eventId; instance.surveyId = instance.data.surveyId; instance.apptDurationMinutes = instance.data.apptDurationMinutes; instance.startDate = instance.data.startDate; instance.endDate = instance.data.endDate; instance.startDateTime = new Date (instance.data.startDate); instance.startDateTime.setHours(6); instance.endDateTime = new Date (instance.data.endDate); instance.endDateTime.setHours(24); instance.eventFormsBoothsStore = null; //instance.eventFormsPromise = $.Deferred(); instance.eventFormsBoothsPromise = $.Deferred(); let eventFormsBoothsDS = Fse.Data.newDataSource( { object : 'CDR.conferenceBooths', keyField : "linkId", paginate : false } ); eventFormsBoothsDS.filter( [ [ "linkId", "=", instance.eventId ]] ); eventFormsBoothsDS.load().done( function( conferenceBooths ) { instance.eventFormsBoothsStore = new DevExpress.data.ArrayStore ( { data : conferenceBooths, key : "linkId" } ); instance.eventFormsBoothsStore = conferenceBooths; instance.eventFormsBoothsPromise.resolve(); }) instance.eventFormsQuestionsStore = null; instance.eventFormsQuestionsPromise = $.Deferred(); let eventFormsQuestionsDS = Fse.Data.newDataSource( { object : 'CDR.conferenceQuestions', keyField : "surveyId", paginate : false } ); eventFormsQuestionsDS.filter( [ [ "eventId", "=", instance.eventId ]] ); eventFormsQuestionsDS.load().done( function( conferenceQuestions ) { instance.eventFormsQuestionsStore = new DevExpress.data.ArrayStore ( { data : conferenceQuestions, key : "surveyId" } ); instance.eventFormsQuestionsStore = conferenceQuestions; instance.eventFormsQuestionsPromise.resolve(); }) instance.eventFormsAppointmentsStore = null; instance.eventFormsAppointmentsPromise = $.Deferred(); let eventFormsAppointmentsDS = Fse.Data.newDataSource( { object : 'CDR.conferenceAppointments', keyField : "eventId", paginate : false } ); eventFormsAppointmentsDS.filter( [ [ "eventId", "=", instance.eventId ]] ); eventFormsAppointmentsDS.load().done( function( conferenceSAppointments ) { instance.eventFormsAppointmentsStore = new DevExpress.data.ArrayStore ( { data : conferenceSAppointments, key : "eventId" } ); instance.eventFormsAppointmentsStore = conferenceSAppointments; instance.eventFormsAppointmentsPromise.resolve(); }) } DistributorConferenceEditDialog.prototype.constructor = DistributorConferenceEditDialog; DistributorConferenceEditDialog.prototype.show = function() { let instance = this; const eventName = this.data.eventName; $.when(instance.eventFormsBoothsPromise, instance.eventFormsQuestionsPromise, instance.eventFormsAppointmentsPromise, instance.salesRepListPromise).done( function( ){ instance.loadPanel.hide(); instance.popup = $("
").dxPopup( { title : `Edit ${eventName} Conference`, width : 700, contentTemplate : function() { let multiViewItems = []; let addDistributorToolbarItems = []; addDistributorToolbarItems.push( { toolbar : "bottom", location : "after", widget : "dxButton", options : { text : "Save Changes", type : "default", onClick : function( e ) { instance.updateEvent(); } } }); addDistributorToolbarItems.push( { toolbar : "bottom", location : "before", widget : "dxButton", options : { text : "Details", type : "normal", onClick : function( e ) { instance.switchPerspective( 0 ); } } }); addDistributorToolbarItems.push( { toolbar : "bottom", location : "before", widget : "dxButton", options : { text : "Appointments", type : "normal", onClick : function( e ) { instance.switchPerspective( 1 ); } } }); multiViewItems.push( { id : "editEventForm", template : function() { return instance.editConferenceTemplate() }, toolbarItems : addDistributorToolbarItems }, { id : "appointmentsForm", template : function() { return instance.appointmentsTemplate() }, toolbarItems : addDistributorToolbarItems }, ); instance.multiView = $("
").dxMultiView( { swipeEnabled : true, selectedIndex : 0, deferRendering : false, // this is so that all view are rendered before they are needed, so that one can reference the other items : multiViewItems, onContentReady : function( e ) { let item = e.component.option( "selectedItem" ); instance.popup.option( "toolbarItems", item.toolbarItems ); }, onSelectionChanged : function( e ) { let item = e.component.option( "selectedItem" ); instance.popup.option( "toolbarItems", item.toolbarItems ); } }).dxMultiView( "instance" ); instance.multiView.option( "selectedIndex", 0 ); return instance.multiView.element(); }, hideOnOutsideClick : false, onHidden : function( e ) { e.component.element().remove(); e.component.dispose(); }, onShown : function( e ) { let item = instance.multiView.option( "selectedItem" ); } }).dxPopup("instance"); instance.popup.element().appendTo( "body" ); instance.popup.show(); }) } DistributorConferenceEditDialog.prototype.editConferenceTemplate = function() { let instance = this; //let appointmentItems = []; let questionItems = []; let communicationItems = []; let eventItems = [ { dataField : "eventId", visible : false, editorType : "dxTextBox", editorOptions : { value : instance.eventId, readOnly: true, } }, { dataField : "surveyId", visible : false, editorType : "dxTextBox", editorOptions : { value : instance.surveyId, readOnly: true, } }, { dataField : "cdr_recordId", visible : false, editorType : "dxTextBox", editorOptions : { value : instance.cdr_recordId, readOnly: true, } }, { dataField : "schedulerData", visible : false, editorType : "dxTextBox", editorOptions : { value : '', readOnly: true, } }, { dataField : "conferenceName", label : { location : "left", text : "Conference Name" }, isRequired : true, editorType : "dxTextBox", editorOptions : { maxLength : 150, xwidth : 200, value : instance.data.eventName, } }, { dataField : "startDate", label: "Start Date", isRequired : true, editorType : "dxDateBox", type: "date", editorOptions : { maxLength : 150, xwidth : 200, value : instance.data.startDate, disabled: true, } }, { dataField : "endDate", label: "End Date", isRequired : true, editorType : "dxDateBox", type: "date", editorOptions : { maxLength : 150, xwidth : 200, value : instance.data.endDate, disabled: true, } }, ] let booths = instance.eventFormsBoothsStore; for ( let [num, objBooth] of booths.entries()) { let boothDisplayNum = num+1; let boothValue = objBooth.calendarName; let calendarId = objBooth.calendarId; let eleRequired = num == 0 ? true : false; eventItems.push( { dataField : `booth${calendarId}`, label : { location : "left", text : `Booth #${boothDisplayNum}` }, isRequired : eleRequired, editorType : "dxTextBox", editorOptions : { maxLength : 50, value : boothValue } }, ) } let hoursDatasource = []; for(i=0;i<23;i++){ let num = i+1; let meridiem = "AM"; meridiem = num >= 12 ? meridiem = "PM" : meridiem = "AM"; num = i >= 12 ? num-12 : num; hoursDatasource.push( { text : `${num}:00${meridiem}`, value : `${num}:00${meridiem}` }) } let startTime = instance.data.startTime; if (startTime != ''){ if( startTime.search(':00') == -1 ){ startTime = `${startTime}:00` } else { startTime } }; startTimePeriod = instance.data.startTimePeriod; startTime = startTime.concat(startTimePeriod); eventItems.push( { dataField : "startTime", label : { text : "Appointment Start Time", location : "left" }, editorType : "dxSelectBox", editorOptions : { dataSource :hoursDatasource, displayExpr : "text", valueExpr : "value", value : startTime, width : 100, disabled : true, } }, { dataField : "apptDuration", label : { location : "left", text : "Appointment Duration (minutes)" }, isRequired : true, editorType : "dxTextBox", editorOptions : { maxLength : 4, width : 50, value : instance.data.apptDurationMinutes, disabled : true, } }, ) let eleNum = 0; let questionsElements = [1,2,3,4,5,6,7,8]; let eleRequired = false; let questionPrompt = null; let sortRank = null; let numOfQuestion = instance.eventFormsQuestionsStore.length-1; for (const num of questionsElements) { eleRequired = num == 1 ? true : false; sortRank = num * 10; eleNum = num-1; if( eleNum <= numOfQuestion){ questionPrompt = instance.eventFormsQuestionsStore[eleNum].questionPrompt; questionId = instance.eventFormsQuestionsStore[eleNum].questionId; sortRank = instance.eventFormsQuestionsStore[eleNum].sortOrder; }else{ questionPrompt = null; questionId = `_add_${num}`; } questionItems.push( { dataField : `question${questionId}`, label : { location : "left", text : `Question #${num}` }, isRequired : eleRequired, editorType : "dxTextArea", editorOptions : { maxLength : 512, height : 60, value : questionPrompt, } }, { dataField : `sortrank${questionId}`, label : { location : "left", text : `Sortrank #${num}` }, isRequired : eleRequired, editorType : "dxTextBox", editorOptions : { maxLength : 10, height : 20, width : 50, value : sortRank, } }, ) } communicationItems = []; communicationItems.push( { dataField : "emailRecipients", label : { location : "left", text : "Email Recipients" }, editorType : "dxDropDownBox", editorOptions : Fse.UI.multiSelectDropDownBoxEditorOptions( { dataSource : Fse.Data.newDataSource( { dataURL : instance.dataURL, object : "CRM.salesRepList", keyField : "valueId" } ), //dataSource : instance.salesRepListStore, searchExpr : "valueName", searchMode : "contains", displayExpr : "valueName", multipleSelectedDisplay : "Multiple Email Recipients Selected", valueExpr : "valueId", keyExpr : "valueId", title : "Select Email Recipients" }) }, { dataField : "localManagers", label : { location : "left", text : "Local Managers" }, editorType : "dxCheckBox", editorOptions : { value : instance.data.ccDivisionManager == 'Y' ? true : false, } }, { dataField : "divisionManagers", label : { location : "left", text : "Division Managers" }, editorType : "dxCheckBox", editorOptions : { value : instance.data.ccDivisionManager == 'Y' ? true : false, } }, ) instance.editEventForm = $("
").dxForm( { validationGroup : "editEventForm", items : [ { itemType : "tabbed", tabPanelOptions : { deferRendering : false }, // this is so all of the fields are rendered at the start tabs : [ { title : "Event Detail", items : [ { itemType: "group", items : eventItems }, ] }, { title : "Questions", items : [ { itemType: "group", items : questionItems }, ] }, { title : "Communication", items : [ { itemType: "group", items : communicationItems }, ] }, ] } ], onFieldDataChanged : function( e ) { let customEditors = e.component.option( "customEditors" ); if( customEditors && customEditors[e.dataField] ) { // push the data into the custom editor customEditors[e.dataField].option( "value", e.value ); } e.component.getEditor("") } }).dxForm( "instance" ); //}); if(instance.data.emailRecipients != null ){ let preslctRecipients = [] instance.data.emailRecipients.split(",").forEach( function( s ) { preslctRecipients.push( parseInt(s) ) } ) instance.editEventForm.updateData( {emailRecipients : preslctRecipients } ) } return instance.editEventForm.element(); } DistributorConferenceEditDialog.prototype.showLoadPanel = function( v ) { let instance = this; instance.loadPanel = $("
").dxLoadPanel( { message : "Loading...", hideOnOutsideClick : false, onHidden : function( e ) { e.component.element().remove(); e.component.dispose(); } }).appendTo( $("body") ).dxLoadPanel( "instance" ) instance.loadPanel.show(); } DistributorConferenceEditDialog.prototype.appointmentsTemplate = function() { let instance = this; let appointments = instance.eventFormsAppointmentsStore; let boothResources = instance.eventFormsBoothsStore; instance.editEventScheduler = $("
").dxScheduler( { dataSource: appointments, XrecurrenceRuleExpr: "recurrence", startDateExpr : "startTime", endDateExpr : "endTime", currentDate : instance.startDate, currentView : "day", views: ['day'], shadeUntilCurrentTime : true, showAllDayPanel: false, startDayHour : instance.data.startTime, endDayHour : 24, allowDeleting : true, cellDuration : instance.apptDurationMinutes, maxAppointmentsPerCell : 2, allDay : false, allowTimeZoneEditing : true, onAppointmentRendered: function(e) { //e.appointmentElement.height(75); }, dataCellTemplate(itemData, itemIndex, itemElement) { let apptStartTime = new Date (itemData.startDate); let apptEndTime = new Date (itemData.endDate); if ( apptStartTime < instance.startDateTime || apptStartTime > instance.endDateTime ) { itemElement[itemIndex].on("click", function(){return false} ); //stops appointment form const element = $('
'); element.addClass('disable-date'); return itemElement.append(element); } }, onAppointmentUpdated( e ){ return instance.updateAppointmentTemplate( e ); }, appointmentTooltipTemplate( e ){ return instance.displayAppointmentTemplate( e ); }, onAppointmentAdded( e ){ return instance.updateAppointmentTemplate( e ); }, appointmentTemplate(model) { return instance.updateAppointmentTemplate( model ); }, onAppointmentFormOpening( data ){ const form = data.form; let dspStartDate = new Date (data.appointmentData.startTime); let dspEndDate = new Date (data.appointmentData.endTime); let dspStartTime = instance.formatTimeString(dspStartDate) let dspEndTime = instance.formatTimeString(dspEndDate) let dspCaption = `Appointment Details ${dspStartTime} - ${dspEndTime}`; if( form.option( "items" ).find( function( e ) { return i.caption == dspCaption } ) ) return; // customize the form let distributor = []; distributor.push( { dataField : "partnerId", label : { text : "Distributor" }, editorType : "dxSelectBox", isRequired : true, editorOptions : { dataSource : Fse.Data.newDataSource( { object : "CDR.distributors", keyField : "cdr_recordId", objectParams : {displayExpr : "cdr_dstName" } }), displayExpr : "cdr_dstName", searchEnabled : true, searchExpr : "cdr_dstName", valueExpr : "cdr_recordId", placeholder : "Select", showClearButton : true, searchEnabled : true, } } ) distributor.push( { dataField : "calendarId", label : { text : "Booth" }, editorType : "dxSelectBox", isRequired : true, editorOptions : { dataSource : boothResources, displayExpr : "calendarName", searchEnabled : true, searchExpr : "calendarName", valueExpr : "calendarId", placeholder : "Select", showClearButton : true, searchEnabled : true, } } ) let items = [{ itemType: "group", colSpan : 2, alignItemLabels : true, caption: dspCaption, items: distributor, }] // apply the form customizations form.option( { items : items, labelLocation : "left", showColonAfterLabel : true, onFieldDataChanged : function( fdc ) { if( fdc.dataField == "partnerId" ) { let distributorSelectBox = fdc.component.getEditor( "partnerId" ); let selectedDistributor = distributorSelectBox.option( "selectedItem" ); if(selectedDistributor){ fdc.component.updateData( { cdr_recordId : selectedDistributor.cdr_recordId, cdr_dstName : selectedDistributor.cdr_dstName }) } } if( fdc.dataField == "calendarId" ) { let boothSelectBox = fdc.component.getEditor( "calendarId" ); let selectedBooth = boothSelectBox.option( "selectedItem" ); if(selectedBooth){ fdc.component.updateData( { boothId : selectedBooth.calendarId, boothName : selectedBooth.calendarName }) } } } } ) } }).dxScheduler( "instance" ) return instance.editEventScheduler.element(); } DistributorConferenceEditDialog.prototype.formatTimeString = function( dateTime ) { meridium = function( hour ){ return hour < 12 ? "am" : "pm"; } standardHours = function( hour ){ return hour <= 12 ? hour : hour-12; } let dspHour = standardHours(dateTime.getHours()); let dspMin = dateTime.getMinutes(); dspMin = dspMin == "0" ? "00" : dspMin; sMeridium = meridium(dateTime.getHours()); let dspTime = `${dspHour}:${dspMin}${sMeridium}` return dspTime } DistributorConferenceEditDialog.prototype.updateAppointmentTemplate = function( model ) { let instance = this; let boothName = model.appointmentData.boothName; let distributor = model.appointmentData.cdr_dstName; let apptStartTime = new Date(model.appointmentData.startTime); let apptEndTime = new Date(model.appointmentData.endTime); const startTimeString = instance.formatTimeString(apptStartTime) const endTimeString = instance.formatTimeString(apptEndTime) let container = $("
" ).css( { padding : "2px", width : "100%", height: "100px"} ); let deleteDiv = $("
" ).css( { width : "30%", "float" : "right", "text-align" : "right:"} ); deleteBtn = $("
").dxButton({ icon: "trash", onClick: function () { instance.deleteAppointment(model.appointmentData.appointmentId) } }).css( { "float" : "right"}); deleteDiv.append(deleteBtn); let clientDataDiv = $("
" ).css( { padding : "2px", width : "100%"} ); let clientData = $("
").css( { width : "70%", "float" : "left"}); clientData.append( $("
").html( `${distributor} | ${startTimeString} - ${endTimeString}` ).css( { "font-weight" : "bold", height: "15px", "text-align" : "left"})); //clientData.append( $("
").html( `${distributor}` ).css( { "font-weight" : "bold", height: "15px", "text-align" : "left"})); //let apptTimeSpan = $("" ).css( { "font-size" : "smaller", height: "12px", padding : "2px", width : "100%"} ); //apptTimeSpan.append( $("").text( `Time : ${startTimeString} - ${endTimeString}` )); //clientData.append(apptTimeSpan) //clientData.append( $("
").text( `Time : ${startTimeString} - ${endTimeString}` ).css( { "font-size" : "smaller", height: "12px", "text-align" : "left" })); clientData.append( $("
").text( `Booth : ${boothName}` ).css( { "font-size" : "smaller", height: "12px", "text-align" : "left" })); clientDataDiv.append(clientData); container.append(deleteDiv) container.append(clientDataDiv) return container } DistributorConferenceEditDialog.prototype.displayAppointmentTemplate = function( model ) { let instance = this; const popup = instance.popup; let boothName = model.appointmentData.boothName; let distributor = model.appointmentData.cdr_dstName; let apptStartTime = new Date(model.appointmentData.startTime); let apptEndTime = new Date(model.appointmentData.endTime); const startTimeString = instance.formatTimeString(apptStartTime); const endTimeString = instance.formatTimeString(apptEndTime); let container = $("
" ).css( { padding : "2px", width : "100%", height: "100px"} ); let clientDataDiv = $("
" ).css( { padding : "2px", width : "100%"} ); let clientData = $("
").css( { width : "70%", "float" : "left"}); clientData.append( $("
").html( `${distributor}` ).css( { "font-weight" : "bold", height: "15px", "text-align" : "left"})); clientData.append( $("
").text( `Time : ${startTimeString} - ${endTimeString}` ).css( { "font-size" : "smaller", height: "12px", "text-align" : "left" })); clientData.append( $("
").text( `Booth : ${boothName}` ).css( { "font-size" : "smaller", height: "12px", "text-align" : "left" })); clientDataDiv.append(clientData); container.append(clientDataDiv) return container } DistributorConferenceEditDialog.prototype.deleteAppointment = function( appointmentId ) { let instance = this; for ( let [num, objAppointment] of instance.editEventScheduler.appointmentDataProvider.dataSource._items.entries()) { if(objAppointment.appointmentId == appointmentId){ instance.editEventScheduler.deleteAppointment( instance.editEventScheduler.appointmentDataProvider.dataSource._items[ num ] ) break; } } } DistributorConferenceEditDialog.prototype.isDisableDate = function( appointmentDate ) { let instance = this; let startDate = new Date (instance.startDate); startDate.setHours(0); let endDate = new Date (instance.endDate); endDate.setHours(24); let disableDate = appointmentDate < startDate || appointmentDate > endDate ? true : false; return disableDate; } DistributorConferenceEditDialog.prototype.updateEvent = function( dupActionData) { let instance = this; let vr = DevExpress.validationEngine.validateGroup( "editEventForm" ); //console.log('vr',vr); if( vr.isValid ) { // TODO - get this to protect the page until the load operation is complete let loadPanel = $("
").dxLoadPanel( { message : "Working...", deplay : 0, hideOnOutsideClick : false, hideOnParentScroll : false, container : instance.popup.element(), onHidden : function( e ) { e.component.element().remove(); e.component.dispose(); } }).appendTo( $("body") ).dxLoadPanel( "instance" ); let apptData = instance.editEventScheduler.option("dataSource"); // remove timezone info or the hours will shift apptData.forEach(function( data ){ data.startTime = new Date(data.startTime).toString(); data.endTime = new Date(data.endTime).toString(); }) instance.editEventForm.option( "formData" ).schedulerData = instance.editEventScheduler.option("dataSource"); let dataToSend = $.extend( true, {}, instance.editEventForm.option( "formData" ) ); loadPanel.show(); Fse.Ajax.performAction( { object : "CDR.eventUpdate", data : dataToSend }).done( function( updateEventResult ) { loadPanel.hide(); //instance.element().remove(); instance.popup.dispose(); if( instance.onReturn ) { instance.onReturn(); } }) } else { let message = vr.brokenRules[0].message; if( vr.brokenRules.length > 1 ) { message = `'${message}' plus ${vr.brokenRules.length-1} more`; } DevExpress.ui.notify( message, "warning", 1000 ); vr.brokenRules[0].validator.focus(); } } DistributorConferenceEditDialog.prototype.createMultiviewToolbar = function() { let instance = this; let multiviewToolbarItems = []; multiviewToolbarItems.push({ toolbar : "top", location : "before", widget : "dxButton", options : { text : "Details", hint : "Conference Details", onClick : function( te ) { instance.showDetailsPerspective(); } } }) multiviewToolbarItems.push({ toolbar : "top", location : "before", widget : "dxButton", options : { text : "Appointments", hint : "Conference Appointments", onClick : function( te ) { instance.showAppointmentsPerspective(); } } }) instance.toolbar = $("
").dxToolbar( { items : multiviewToolbarItems, }).addClass( "fx-toolbar" ).dxToolbar("instance"); return instance.toolbar } DistributorConferenceEditDialog.prototype.switchPerspective = function( idx ) { let instance = this; instance.multiView.option( "selectedIndex", idx ); }