fullcalendar V3 how to add JET Context Menu - javascript

I am trying to incorporate context menu from https://www.oracle.com/webfolder/technetwork/jet/jetCookbook.html?component=menu&demo=contextMenu
using full calender io events and i am unable to understand how to plug in oj component under fullcalender io events.
I am aware that context menus can be accomplised using jquery ui context menu, but i want to know how to use jet code from fullcalendar io events.
Can you please let me know how i can plug in the jet context menu in the below code?
JET
require(['ojs/ojoffcanvas','knockout','ojs/ojbootstrap','ojs/ojarraydataprovider','jquery','ojs/ojknockout',
'fullCalendar','moment','jqueryui','jquerycontextmenu',
'ojs/ojknockout', 'ojs/ojdiagram','ojs/ojformlayout','ojs/ojbutton',
'ojs/ojmenu', 'ojs/ojoption','ojs/ojinputtext','ojs/ojselectcombobox'],
function (ko, Bootstrap,ArrayDataProvider,$) {
function ChartModel() {
var self = this;
self.addressBookData = ko.observableArray([]);
self.columns = ko.observableArray([
{ headerText : 'title', field : 'title'},
{ headerText : 'start', field : 'start'},
{ headerText : 'end', field : 'end'},
{ headerText : 'QuantityOrdered', field : 'QuantityOrdered'},
{ headerText : 'QuantityCompleted', field : 'QuantityCompleted'}
])
this.dataprovider = new ArrayDataProvider(self.addressBookData, { keyAttributes: 'title'});
}
function getE1Data(self,callback) {
var input = {
aliasNaming: true,
findOnEntry: "TRUE",
maxPageSize: "100",
targetName: "XXX",
aliasNaming : true,
targetType: "view",
dataServiceType: "BROWSE",
returnControlIDs: "TABLEX.DOCO|TABLEX.DL01|TABLEX.LITM|TABLEX.STRT|TABLEX.DRQJ|TABLEX.UORG|TABLEX.SOQS|TABLEX.SOCN|TABLEX.SRST"
};
callAISService(input, DATA_SERVICE, function(response) {
if (response.message) {
callback("failed");
} else {
renderData($,self,response.fs_DATABROWSE_V4801C.data.gridData.rowset);
callback("success");
}
});
}
function renderData($,self,data) {
self = this;
this.events = [];
data.forEach(element => {
const obj ={};
const extendedProps ={};
var teststr1 = (element.TABLEX_LITM.value).concat(" - ",(element.TABLEX_DOCO.value));
var teststr2 = (element.TABLEX_DL01.value).concat(" - ",teststr1);
obj.title = teststr2,
obj.start = new Date(element.TABLEX_DRQJ.value),
obj.end= new Date(element.TABLEX_STRT.value),
extendedProps.QuantityOrdered = element.TABLEX_UORG.value,
extendedProps.QuantityCompleted = element.TABLEX_SOQS.value,
extendedProps.QuantityScrapped = element.TABLEX_SOCN.value,
extendedProps.WOStatus = element.TABLEX_SRST.value,
obj.extendedProps = extendedProps,
events.push(obj);
});
this.calendar = $ ('#calendar').fullCalendar(
{
editable: true,
weekends : true,
selectable: true,
selectHelper:true,
timeFormat: 'H(:mm)',
displayEventTime: false,
header:{
left : 'prev,next,today',
center : 'title',
right : 'month,agendaWeek,agendaDay'
},
events: events,
eventClick: function(self,events) {
console.log(events.extendedProps.QuantityOrdered);
console.log(events.extendedProps.QuantityCompleted);
},
eventRender: function (events, element) {
element.attr('href', 'javascript:void(0);');
element.click(function() {
$("#startTime").html(formatDate(events.start));
$("#endTime").html(formatDate(events.end));
$("#QuantityOrdered").html(events.extendedProps.QuantityOrdered);
$("#QuantityCompleted").html(events.extendedProps.QuantityCompleted);
$("#QuantityScrapped").html(events.extendedProps.QuantityScrapped);
$("#WOStatus").html(events.extendedProps.WOStatus);
$("#eventContent").dialog({ modal: true, resizable: true ,effect: "explode",title: events.title, width:350});
});
}
});
}
$(document).ready(function() {
var chartModel = new ChartModel();
getE1Data(chartModel,(status)=>{
ko.applyBindings(chartModel, document.getElementById('calendar'));
});
});
});
JET
HTML
<body
<br />
<div class = "container">
<div id = "calendar"> </div>
</div>
</body>
HTML
Please find the below sample HTML, which used JET libraries like oj-menu using which context menu is acheived:
<body id="content">
<oj-input-text id="filter" class="oj-form-control-max-width-md" label-hint="Filter" label-edge="inside"
placeholder="Type to filter" on-raw-value-changed="[[handleValueChanged]]" value="{{filter}}" clear-icon="always">
</oj-input-text>
<oj-input-text id="filter1" class="oj-form-control-max-width-md" label-hint="Filter1" label-edge="inside"
placeholder="Type to filter" on-raw-value-changed="[[handleValueChanged1]]" value="{{filter1}}" clear-icon="always">
</oj-input-text>
<oj-input-text id="filter2" class="oj-form-control-max-width-md" label-hint="Filter1" label-edge="inside"
placeholder="Type to filter" on-raw-value-changed="[[handleValueChanged2]]" value="{{filter2}}" clear-icon="always">
</oj-input-text>
<oj-table id='table' aria-label='Departments Table'
data='[[dataprovider]]'
scroll-policy='loadMoreOnScroll'
columns-default.sortable='disabled'
columns='{{columns}}'
style='width:100%; height: 1000px;'>
<oj-menu id="ctxMenu" slot="contextMenu" aria-label="Match Edit">
<oj-option value="Action 1">Work Centre Details</oj-option>
<oj-option value="Action 12">Resource Units</oj-option>
<oj-option value="Action 13">Work Day Calendar</oj-option>
</oj-menu>
<div id="eventContent" title="Event Details">
<div id="eventInfo"></div>
</div>
</oj-table>
</body>

Related

How to implement heritage with knockoutJS objects

I have a model consisting of a project object, a text object and a setting object. The settings object can hold values for both projects and texts.
A text is always coupled to a project. Thus it should inherit the projects settings (if any). However if the text itself has settings, the user should be able to choose between using the project default or the text-specific settings.
The problem I'm having in my project is that updating the text local setting is also updating the project default settings. I guess this has to do with the observables relation, but so far I have been unable to find the connection.
Here's my code:
Text = function (data) {
var self = this;
self.textID = data.textID;
self.title = ko.observable(data.title);
self.projectID = data.projectID;
// settings
self.settings = ko.observable(); // initiated with "each" loop hook-up in viewmodel.
self.project = ko.observable(); // initiated with "each" loop hook-up in viewmodel.
self.projectSettings = ko.computed(function () {
var project = self.project();
if (project) {
var proset = project.settings();
return proset;
}
return null;
});
self.useProjectSettings = ko.observable(data.useProjectSettings || true);
self.hasLocalSettings = ko.observable(false); // initiated with each loop hook-up in viewmodel.
self.activeSettings = ko.computed(function () {
return self.useProjectSettings() ? self.projectSettings() : self.settings();
});
return self;
};
Project = function (data) {
var self = this;
self.projectID = data.projectID;
self.title = ko.observable(data.title);
// settings
self.settings = ko.observable();
return self;
};
Setting = function (data) {
var self = this;
self.settingID = data.settingID;
self.projectID = data.projectID;
self.textID = data.textID;
self.isVisible = ko.observable(data.isVisible);
self.isProjectDefault = ko.observable(data.isProjectDefault || true);
return self;
};
ViewModel = function (myprojects, mysettings, mytexts) {
var self = this,
koEach = ko.utils.arrayForEach, koFirst = ko.utils.arrayFirst, koFilter = ko.utils.arrayFilter;
self.selectedText = ko.observable();
//data - load
self.Projects = ko.observableArray(
ko.utils.arrayMap(myprojects, function (item) {
return new Project(item);
}));
self.Settings = ko.observableArray(
ko.utils.arrayMap(mysettings, function (item) {
return new Setting(item);
}));
self.Texts = ko.observableArray(
ko.utils.arrayMap(mytexts, function (item) {
return new Text(item);
}));
//alert("self.Projects()[0].projectID=" + self.Projects()[0].projectID );
// hook up 'settings' on 'project'
koEach(self.Settings(), function (s) {
if (s.isProjectDefault()) {
var project = koFirst(self.Projects(), function (p) {
return p.projectID === s.projectID;
});
if (project) {
project.settings(s);
}
}
});
//alert("self.Texts()[0].textID=" + self.Texts()[0].textID + ", self.Texts()[0].title()=" + self.Texts()[0].title() );
//hook up 'project' on 'texts'
koEach(self.Texts(), function (t) {
var project = koFirst(self.Projects(), function (p) {
return p.projectID === t.projectID;
});
t.project(project);
// initiate default publishingSettings for textbatch
var initsettings = project.settings();
t.settings(initsettings);
});
// hook up 'settings' on 'text'
koEach(self.Settings(), function (s) {
if (!s.isProjectDefault()) {
var text = koFirst(self.Texts(), function (t) {
return t.textID === s.textID;
});
if (text) {
text.settings(s);
}
}
});
};
// console log
var consoleLine = "<p class=\"console-line\"></p>";
console = {
log: function (text) {
$("#console-log").append($(consoleLine).html(text));
}
};
// input
var projects = [{ projectID: 0, title: 'project 0' }, { projectID: 1, title: 'project 1' }];
var settings = [
{ settingID: 0, projectID: 1, textID: null, isVisible: true, isProjectDefault: true },
{ settingID: 1, projectID: null, textID: 0, isVisible: true, isProjectDefault: false },
{ settingID: 2, projectID: 1, textID: 1, isVisible: false, isProjectDefault: false }
];
var texts = [{ textID: 0, projectID: 0, title: 'first text' }, { textID: 1, projectID: 1, title: 'second text' }];
// binding
ko.applyBindings(new ViewModel(projects, settings, texts));
HereĀ“s my HTML:
<select data-bind="options: $root.Texts, optionsCaption: 'choose...', optionsText: 'title', value: selectedText"></select>
<br/>
Selected: <span data-bind="text: $root.selectedText().title"></span><br>
Selected2: <span data-bind="text: $root.selectedText().title"></span><br>
TextID: <span data-bind="text: selectedText().textID"></span><br>
<hr/>
<div data-bind="with: $root.selectedText">
<h2 data-bind="text:title"></h2>
<div class="form-group">
<div class="checkbox">
<label>
<input type="checkbox" data-bind="checked: useProjectSettings" />Use project settings
</label>
</div>
</div>
Settings for text '<span data-bind="text: title"></span>' (id='<span data-bind="value: textID"></span>').<br/><br/>
<div class="pubset" data-bind="css: {'unabled' : useProjectSettings() }">
<div class="form-group">
<div class="checkbox">
<label>
<input type="checkbox" data-bind="enable: !useProjectSettings(),checked: activeSettings().isVisible"/>
Show text
</label>
</div>
</div>
</div>
</div>
With my example code here, it seems I also have another problem, as it's not progressing to the second <span> node. Fiddle here.

Add table to my dojo code

I have a dojo dialog function and want to be able to add a table with 5 rows to it. How can I do this? Below is the code I have.
dojo.require("dijit.Dialog");
dojo.require("dijit.form.TextBox");
dojo.require("dojox.grid.EnhancedGrid");
dojo.addOnLoad(function() {
popup = new dijit.Dialog({
title: "Non-Spatial Permanent Feature Deductions...",
style: "width: 750px; height: 400px",
content: "<input dojoType='dijit.form.Button' type='button' name='name' id='name' label='OK'>"
});
popup.show()
});
If your table row is fixed i.e 5 than you may be do one simply thing that create a html file have table of 5 rows and call that file inside dialog.
popup = new dijit.Dialog({
title: "Non-Spatial Permanent Feature Deductions...",
style: "width: 750px; height: 400px",
href:"table.html"
});
When I need a dialog that has a bunch of dijits or custom functionality I end up making a custom dialog dijit. Here's one of my from a current project.
define([
"dojo/_base/declare",
"dijit/_Widget",
"dijit/_TemplatedMixin",
"dijit/_WidgetsInTemplateMixin",
"dojo/i18n!magic/nls/common",
"dojo/text!./templates/emrSelection.html",
"dojo/dom-construct",
"dojo/on",
"dojo/Evented",
"dojo/_base/connect",
"dojo/query",
"dojo/_base/lang",
"dijit/Dialog",
"dijit/form/CheckBox"
],
function (declare, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, i18n, template, domConstruct, on, Evented, connect, query, lang, Dialog, CheckBox) {
return declare("project.customDialog", [Dialog], {
title: i18n.customDialog.title,
emrIds: [],
constructor: function(/*Object*/ kwArgs) {
lang.mixin(this, kwArgs);
var contentWidget = new (declare([_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
closeLabel: i18n.close,
templateString: template,
baseClass: "customDialog"
}));
contentWidget.startup();
this.content = contentWidget;
},
postCreate: function() {
this.inherited(arguments);
},
startup: function() {
this.inherited(arguments);
this._createTable();
},
_createTable : function() {
var that = this;
var i = 0;
var tr = null;
this.store.query().forEach(lang.hitch(this, function(emr){
var state = that.emrIds.indexOf(emr.id) != -1;
if(i++%3 == 0) {
tr = domConstruct.create("tr");
domConstruct.place(tr, that.content.tableBody);
}
var td1c = domConstruct.create("td", {'class':"checkBox"}, tr);
var td1l = domConstruct.create("td", {'class':"label"}, tr);
var box = that._createCheckBox(emr.name, state, emr.id);
domConstruct.place(box.domNode, td1c);
domConstruct.place("<label for='checkbox'>"+emr.name+"</label>", td1l);
}));
},
_createCheckBox : function(name, checked, id) {
var box = CheckBox({
name: name,
value: name,
checked: checked,
emr_id: id,
onChange: lang.hitch(this, function(state){
var id = box.get('emr_id');
var name = box.get('name');
this.emit("tick", {emrId:id, name:name, state:state});
})
}, domConstruct.create("div"));
box.startup();
return box;
}
});
the template
<div class="${baseClass}" data-dojo-attach-point="container" >
<table>
<tbody data-dojo-attach-point="tableBody"></tbody>
</table>
<div class="buttonContainer">
<button class="button" data-dojo-type="dijit.form.Button" data-dojo-attach-point="saveButton">${closeLabel}</button>
</div>
</div>
and then i call it with and use on() to get events from it.
this.dialog = new emrSelection({store: this.emrStore, emrIds: this.emrIds});
this.dialog.startup();
this.dialog.show();

angularjs, select, add option

I am trying to add an option to a select element. The value is being given by a user form in a jquery ui modal.
When I use Chrome Developer tools, I can see that the bound object array is indeed getting the new object, but it's not showing up in the select element.
I used $('#company').scope().vendors in the console to bring up the array. It shows items being added to the array, but they aren't showing in the select box.
Here is what I have:
app.js
app.factory('Vendors', function(){
var Vendors = {};
Vendors.list = [
{
id: 1,
name: 'Company 1'
},
{
id: 2,
name: 'Company 2'
},
{
id: 3,
name: 'Company 3'
}
]
return Vendors;
})
app.controller('companyCtrl', function($scope, Vendors){
$scope.vendors = Vendors;
$scope.selectedVendor = 0;
$scope.companySelect = function(){
alert("You chose " + $scope.selectedVendor.name)
}
$scope.addCompany = function(name){
var maxId = 0;
for(var i=0; i<$scope.vendors.list.length; i++){
maxId = $scope.vendors.list[i].id;
}
newVendor = {id:++maxId, name:name};
$scope.vendors.list.push(newVendor)
$scope.selectedVendor = newVendor;
}
})
HTML
<div class="row">
<div class="grid_12" ng-controller="companyCtrl" id="company">
<span>Company</span>
<select ng-model="selectedVendor" ng-change="companySelect()" ng-options="v.name for v in vendors.list">
<option value="">-- Choose Company --</option>
</select>
<small><button onclick="openModal('addCompany');">Add</button></small>
</div>
</div>
Inline JS
$( "#addCompany" ).dialog({
autoOpen: false,
width: 350,
modal: true,
buttons: {
"Create new company": function() {
var name = $('#name').val();
if(name != ''){
$('#company').scope().addCompany(name);
}
$( this ).dialog( "close" );
},
Cancel: function() {
$( this ).dialog( "close" );
}
},
close: function() {
$('#name').val( "" );
}
});
function openModal(id){
$('#'+id).dialog('open');
}
I tried creating a jsFiddle, but I guess I'm not too sure how to get everything on there to work yet. But here is my try anyway: http://jsfiddle.net/aPXxe/
Try this:
$scope.$apply(function(){
$scope.vendors.list.push(newVendor);
$scope.selectedVendor = newVendor;
});

knockoutjs bindings issue

I'm having issues with my knockoutjs implementation. Seems to be working fine on Chrome and Safari IE and FF have thrown a hissy fit.
The message which I encounter is as follows:
Unable to parse bindings. Message: TypeError: 'AccountName' is
undefined; Bindings value: value: AccountName
The issue is happening within a script tag which serves as a knockout template:
<div id="newAccountDialog" class="dialog" data-bind="dialog: { autoOpen: false, resizable: false, modal: true, width: 350, title: 'Exchange Account'}, template: { name: 'dialogFormTemplate', data: CurrentAccount }, openDialog: IsNew"></div>
<script id="dialogFormTemplate" type="text/html">
<form id="dialogForm">
<h1>Exchange Account Manager</h1>
<p>Add new or edit an existing exchange account settings.</p>
<label for="AccountName">
Account
</label>
<input id="AccountName" name="AccountName" type="text" data-bind="value: AccountName, valueUpdate: 'afterkeydown'" class="ui-widget-content ui-corner-all" />
<div class="buttonsContainer floatRight">
<button id="Save" data-bind="click: $root.SaveAccount, dialogcmd: { id: 'newAccountDialog', cmd: 'close'}, jqButton: { icons: { primary: 'ui-icon-disk' } }">Save & Close</button>
</div>
</form>
</script>
I assume some sort of early binding is being triggered on the template
data : CurrentAccount
where an undefined / null is being passed into CurrentAccount. I have seen this issue outside of script tags, but only if the observable is not defined or null.
My viewmodel looks as following:
var AccountModel = function () {
var self = this;
self.Accounts = ko.observableArray([]);
self.CurrentAccount = ko.observable(null);
self.IsNew = ko.observable(false);
self.LoadAccounts = function () {
$account.invoke("GetAccounts", {}, function (data) {
var mapped = $.map(data, function (item) {
var account = new Account(item);
var innerMapped = $.map(item.Mailboxes, function (mailbox) {
return new Mailbox(mailbox);
});
account.Mailboxes(innerMapped);
return account;
});
self.Accounts(mapped);
});
}
self.EditAccount = function (data) {
self.CurrentAccount(data);
self.IsNew(true);
}
self.SaveAccount = function () {
if (self.CurrentAccount().Id() <= 0) {
$account.invoke('AddAccount', ko.toJS(self.CurrentAccount()), function (data) {
self.Accounts.push(new Account(data));
self.CurrentAccount(new Account(data));
self.IsNew(true);
});
} else {
$account.invoke('UpdateAccount', ko.toJS(self.CurrentAccount()), function (data) {
//self.CurrentAccount(new Account(data));
});
}
}
self.CreateAccount = function () {
self.IsNew(true);
var account = { Id: 0, AccountName: '', IsNTLM: -1, Email: '', Password: '', Domain: 'mydomain', ExchangeVersion: 1, Mailboxes: [] };
self.CurrentAccount(new Account(account));
}
};
My dialog bindingHandler is defined as follows:
ko.bindingHandlers.dialog = {
init: function (element, valueAccessor) {
var options = ko.utils.unwrapObservable(valueAccessor()) || {};
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$(element).dialog('destroy');
});
$(element).dialog(options);
}
};
I have ommited the Account object, as it is possibly not required in this context.
I would appreciate any help.
Thank you in advance.
There is no "early" binding in Knockout. Everything is bound when you call ko.applyBindings. But certain bindings can stop or delay binding of their descendant elements. template is one of those when you use the if or ifnot options. In your case, you can use the if option like this:
template: { name: 'dialogFormTemplate', data: CurrentAccount, 'if': CurrentAccount }
Note: The quotes around if are required in some older browsers.

slickgrid custom dropdown editor

I am working a on slickgrid where one cell needs to show a dropdown (selectlist) with values coming from a restful service. These values are different for each row.
I should be able to select one value from this list (dropdown) and it should persist the value in the cell.
I would be glad if someone could help with this problem.
this.productColumns = [
{
id: 'statusid',
name: 'Status',
field: 'statusid',
width: 65,
sortable: true
},
{
id: 'grade',
name: 'Grade',
field: 'grade',
width: 80,
sortable: true
},
{
id: 'position',
name: 'Position',
field: 'originalPosition',
width: 80,
sortable: true
},
{
id: 'tyresize',
name: 'Tyre Size',
field: 'tyreSize',
editable: true,
width: 140,
sortable: true
},
{
id: 'tyredetail',
name: 'Tyre Detail',
field: 'tyredetail',
editable: true,
width: 125,
editor: this.selectRangeEditor
}
]
selectRangeEditor: function (args) {
var $select = $("");
var defaultValue = "";
var scope = this;
this.init = function () {
var tyreOptionsList = new TyreOptionsModel(args.item.id);
tyreOptionsList.deferred.done(function () {
var opt_values = tyreOptionsList.toJSON();
var count = 0;
for (var cnt in opt_values) {
if (opt_values.hasOwnProperty(cnt)) {
count++;
}
}
option_str = ""
var i ;
for (i = 0; i < count-1; i++) {
val = opt_values[i].tyreOptionId;
txt = opt_values[i].tyreDetail;
option_str += "<OPTION value='" + val + "'>" + txt + "</OPTION>";
}
$select = $("<SELECT tabIndex='0' class='editor-select'>" + option_str + "</SELECT>");
$select.appendTo(args.container);
$select.focus();
});
};
this.destroy = function () {
$(args.container).empty();
};
this.focus = function () {
$select.focus();
};
this.serializeValue = function () {
return $select.val();
};
this.applyValue = function (item, state) {
item.attributes[args.column.field] = state;
};
this.loadValue = function (item) {
defaultValue = item.attributes[args.column.field];
$select.val(defaultValue);
};
this.isValueChanged = function () {
return ($select.val() != defaultValue);
};
this.validate = function () {
return {
valid: true,
msg: null
};
};
this.init();
return $select.val();
}
Did you see my answer to this question ?
If you are able to get the options from the rest service for each row while generating the page, you can just use my solution at the client side ...
As I understand from you comment, the problem is how to postback the changes made in the grid after the user changed some fields ...
I solved this by adding the following piece of code, notice the JS code for the form submit, handle this incoming data at the server side, to save it using the RESTfull service.
<div id="myGrid" style="width:90%;height:250px;"></div>
<form action="" method="POST">
<input id="save_grid_changes" disabled="disabled" type="submit" value="Save changes to {{obj_type}}(s)">
<input type="hidden" name="obj_type" value="{{obj_type}}">
<input type="hidden" name="data" value="">
</form>
<script>
$(document).ready(function() {
grid = new Slick.Grid($("#myGrid"), griddata, columns, options);
$("form").submit(
function() {
// commit the last edit ...
grid.getEditController().commitCurrentEdit();
grid.resetCurrentCell();
$("input[name='data']").val( $.toJSON(griddata) );
// ("input[name='data']").val($.param(data));
});
});
</script>

Categories

Resources