I'm trying to create a handsontable context menu with different types. This site is linked to from the handsontable docs (for 0.16.1) http://swisnl.github.io/jQuery-contextMenu/docs/items.html however it doesn't seem to be working (code below). The context menu has two main items, and when I click on Font Size, the console logs its name but doesn't act like an input.
contextMenu: {
callback: function (key, options) {
console.log(key);
},
items: {
"status": {
name: 'Status',
submenu: {
items: [{
key: 'status:pnc',
name: 'Private and Confidential'
},
{
key: 'status:fxd',
name: 'Fixed'
}]
},
},
"fontsize": {
name: "Font Size",
type: 'text',
value: '14',
events: {
keyup: function(e) {
console.log(e.keycode);
}
}
}
}
},
For me the console.log works in chrome if i use your definition. I do see a broken submenu. If you look at the documentation a submenu you see the syntax is a bit different. You dont define an array, just another items object definition.
contextMenu: {
callback: function(key, options) {
console.log(key);
},
items: {
"status": {
name: 'Status',
submenu: {
items: {
{
key: 'status:pnc',
name: 'Private and Confidential'
},
{
key: 'status:fxd',
name: 'Fixed'
}
}
},
},
"fontsize": {
name: "Font Size",
type: 'text',
value: '14',
events: {
keyup: function(e) {
console.log(e.keycode);
}
}
}
}
},
See: http://swisnl.github.io/jQuery-contextMenu/demo/sub-menus.html
When i fixed the submenu, i and no problems with the fontsize item being shown as an input.
Related
I have the following ContextualMenu structure inside my SPFx Extension build with Fluent UI React:
const menuProps: IContextualMenuProps = {
items: [
{
key: 'Access',
itemType: ContextualMenuItemType.Section,
sectionProps: {
topDivider: true,
bottomDivider: true,
title: 'Sites you have access to',
items: [
{ key: 'DynamicValue1.1', text: 'DynamicValue1.2' },
{ key: 'DynamicValue2.1', text: 'DynamicValue2.2' },
],
},
},
],
};
I also a MS Graph call running getting me some SharePoint Sites & Teams.
I would now like to push those dynamic responses to the to the menuProps at the right place.
So basically add the dynamic array into the nested items object.
items: [
{ key: 'DynamicValue1.1', text: 'DynamicValue1.2' },
{ key: 'DynamicValue2.1', text: 'DynamicValue2.2' },
],
How can I target that "object"? (hope I understand correctly and items is an object...)
Is there a way to do this using array.push()?
To make this library agnostic, it would look something like this:
const obj = {
items: [
{
key: 'Access',
itemType: '',
sectionProps: {
topDivider: true,
bottomDivider: true,
title: 'Sites you have access to',
items: [
{ key: 'DynamicValue1.1', text: 'DynamicValue1.2' },
{ key: 'DynamicValue2.1', text: 'DynamicValue2.2' },
],
},
},
],
};
obj.items[0].sectionProps.items.push({ key: 'DynamicValue3.1', text: 'DynamicValue3.2' })
console.log(obj.items[0].sectionProps.items)
Your console.log would return this:
[
{ key: 'DynamicValue1.1', text: 'DynamicValue1.2' },
{ key: 'DynamicValue2.1', text: 'DynamicValue2.2' },
{ key: 'DynamicValue3.1', text: 'DynamicValue3.2' }
]
If you can access menuProps: IContextualMenuProps, then just replace obj with the necessary variable.
I am using selectize to provide inline cell editing in slickgrid. I am able to load this component within cell. But when dropdown options container pops up and it goes beyond the slickgrid viewport, dropdown options container is getting truncated by slickgrid boundary. It should come over the grid. How can I bring the dropdown options container to the top.
var grid;
var columns = [
{ id: 'title', name: 'Title', field: 'title' },
{ id: 'duration', name: 'Duration', field: 'duration' },
{ id: '%', name: '% Complete', field: 'percentComplete' },
{ id: 'start', name: 'Start', field: 'start' },
{ id: 'finish', name: 'Finish', field: 'finish' },
{
id: 'effort-driven',
name: 'Effort Driven',
field: 'effortDriven',
editor: IEditor
},
];
var options = {
enableCellNavigation: true,
enableColumnReorder: false,
editable: true,
autoHeight: true
};
function IEditor(args) {
var selectElement = $('<input type="text"/>');
args.container.append(selectElement[0]);
selectElement.selectize({
create: false,
maxElements: 1,
options: [
{
name: 'A',
value: 'a'
},
{
name: 'B',
value: 'b'
},
{
name: 'C',
value: 'c'
},
{
name: 'D',
value: 'd'
},
{
name: 'E',
value: 'e'
},
{
name: 'F',
value: 'f'
},
],
labelField: 'name',
valueField: 'value'
});
/*********** REQUIRED METHODS ***********/
this.destroy = function() {
// remove all data, events & dom elements created in the constructor
};
this.focus = function() {
// set the focus on the main input control (if any)
};
this.isValueChanged = function() {
// return true if the value(s) being edited by the user has/have been changed
return false;
};
this.serializeValue = function() {
return '';
};
this.loadValue = function(item) {
};
this.applyValue = function(item, state) {
};
this.validate = function() {
return { valid: false, msg: 'This field is required' };
};
}
$(function() {
var data = [];
for (var i = 0; i < 3; i++) {
data[i] = {
title: 'Task ' + i,
duration: '5 days',
percentComplete: Math.round(Math.random() * 100),
start: '01/01/2009',
finish: '01/05/2009',
effortDriven: i % 5 == 0,
};
}
grid = new Slick.Grid('#myGrid', data, columns, options);
grid.init();
});
I have added selectize drop down in Effort Driven column in this plunker
I used to use chosen as my enhanced select but I ran into exactly this problem, and it wasn't solvable due to the HTML it used.
I had to jump ship to Select2. There are examples for this here - check out 'Select2 javascript drop-down editor' and 'Select2 Multiselect javascript drop-down editor'.
Make sure your z-index is bigger than the ones SlickGrid uses. If I remember correctly SlickGrid's highest one was 11 or 12, so with a 13 you should be good to go. Also check the overflow of the cells' css classes; it might happen that your context menu is simply cut off.
I am trying to use the Inspector's when parameter in a list item. In this particular case, I want to hide the body text field of an item when the user uses a toggle button:
inputs: {
mylist: {
type: 'list',
label: 'List of items',
item: {
type: 'object',
properties: {
attrs: {
text: {
title: {
type: 'text',
label: 'Title',
index: 1
},
body: {
type: 'textarea',
label: 'Body',
index: 2,
when: { eq: {'????': false} } // what path should be used here?
}
},
toggles: {
toggleBody: {
defaultValue: false,
type: 'text',
label: 'Hide body',
index: 3
},
}
} // attrs
} // properties
} // item
}
}
I have verified through renderFieldContent:
renderFieldContent: function(options, path, value) {
if(path.endsWith('/attrs/text/body')){
console.log(path);
}
} // 1 item in the list outputs: mylist/0/attrs/toggles/toggleBody
That the list items paths follow the pattern `mylist/${i}/attrs/toggles/toggleBody` where ${i} is the item number...
I tried to reference mylist/0/attrs/toggles/toggleBody in the expression (so it would always reference the first item), but this also does not seem to work... Is there a way to reference a list item property's path?
From Rappid v3.2, one can place wildcards within the path.
'mylist/${index}/attrs/toggles/toggleBody'
A wildcard ${index} will be dynamically substituted for the actual index of the item inside which the when clause is being evaluated.
inputs: {
mylist: {
type: 'list',
label: 'List of items',
item: {
type: 'object',
properties: {
attrs: {
text: {
title: {
type: 'text',
label: 'Title',
index: 1
},
body: {
type: 'textarea',
label: 'Body',
index: 2,
when: {
eq: {
'mylist/${index}/attrs/toggles/toggleBody': false
},
// otherwise: { unset: true }
// Uncomment above to clear the body text
// from the model when the body is hidden
}
}
},
toggles: {
toggleBody: {
defaultValue: false,
// Changed to built-in toggle
type: 'toggle',
label: 'Hide body',
index: 3
}
}
}
}
}
}
}
so I am trying to modify the example Cumulative flow chart here so that it has a release dropdown, making it so that it only shows information pertaining to a given release. My problem is that when a new release is selected from the release dropdown, the graph does not reload itself, and so it never actually shows information pertinent to the selected release. I think I have implemented the listeners correctly but I am not sure, so I am wondering if someone could tell me why this is happening and how to fix it. Thanks! My code is below:
<!DOCTYPE html>
<html>
<head>
<title>Historical Summary</title>
<script type="text/javascript" src="/apps/2.0rc3/sdk.js"></script>
<script type="text/javascript">
Rally.onReady(function() {
Ext.define('Rally.example.CFDCalculator', {
extend: 'Rally.data.lookback.calculator.TimeSeriesCalculator',
config: {
stateFieldName: 'ScheduleState',
stateFieldValues: ['Defined', 'In-Progress', 'Completed', 'Accepted']
},
constructor: function(config) {
this.initConfig(config);
this.callParent(arguments);
},
getMetrics: function() {
return _.map(this.getStateFieldValues(), function(stateFieldValue) {
return {
as: stateFieldValue,
groupByField: this.getStateFieldName(),
allowedValues: [stateFieldValue],
f: 'groupByCount',
display: 'area'
};
}, this);
}
});
Ext.define('Rally.example.CFDChart', {
extend: 'Rally.app.App',
requires: [
'Rally.example.CFDCalculator'
],
launch: function() {
this.add({
xtype: 'rallyreleasecombobox',
fieldLabel: 'Filter by Release:',
project: this.getContext().getProject(),
//value: Rally.util.Ref.getRelativeUri(this.getContext().getRelease()),
listeners: {
select: this._onSelect,
ready: this._onLoad,
scope: this
}
});
},
_onLoad: function() {
this.add({
xtype: 'rallychart',
storeType: 'Rally.data.lookback.SnapshotStore',
storeConfig: this._getStoreConfig(),
calculatorType: 'Rally.example.CFDCalculator',
calculatorConfig: {
stateFieldName: 'ScheduleState',
stateFieldValues: ['Defined', 'In-Progress', 'Completed', 'Accepted']
},
chartConfig: this._getChartConfig()
//context: this.getContext();
});
},
_onSelect: function() {
var histChart = this.down('rallychart');
histChart.refresh({
storeConfig: {
filters: [this._getOwnerFilter()]
}
});
},
_getOwnerFilter: function() {
//var userCombo = this.down('rallyusersearchcombobox');
var releaseValue = this.down('rallyreleasecombobox');
return {
property: 'Release',
operator: '=',
value: releaseValue.getValue()
};
},
/**
* Generate the store config to retrieve all snapshots for stories and defects in the current project scope
* within the last 30 days
*/
_getStoreConfig: function() {
return {
find: {
_TypeHierarchy: { '$in' : [ 'HierarchicalRequirement', 'TestSet' ] },
Children: null,
_ProjectHierarchy: this.getContext().getProject().ObjectID,
_ValidFrom: {'$gt': Rally.util.DateTime.toIsoString(Rally.util.DateTime.add(new Date(), 'day', -30)) }
},
fetch: ['ScheduleState'],
hydrate: ['ScheduleState'],
sort: {
_ValidFrom: 1
},
context: this.getContext().getDataContext(),
limit: Infinity
};
},
/**
* Generate a valid Highcharts configuration object to specify the chart
*/
_getChartConfig: function() {
return {
chart: {
zoomType: 'xy'
},
title: {
text: 'Project Cumulative Flow: User Stories & Test Sets'
},
xAxis: {
tickmarkPlacement: 'on',
tickInterval: 1,
title: {
text: 'Date'
}
},
yAxis: [
{
title: {
text: 'Count'
}
}
],
plotOptions: {
series: {
marker: {
enabled: false
}
},
area: {
stacking: 'normal'
}
}
};
}
});
Rally.launchApp('Rally.example.CFDChart', {
name: 'Historical summary: test cases, stories, and defects'
});
});
</script>
<style type="text/css">
</style>
</head>
<body></body>
</html>
Your code errors with "Uncaught TypeError: undefined is not a function" on line
histChart.refresh
I modified example of ProjectCumulativeFlow to filter by Release. Full code is in this github repo.
Instead of extending Rally.app.App, I extended Rally.app.TimeboxScopedApp.
SnapshotStore may filter by Release, but requires ObjectID.
Here is the find:
find: {
_TypeHierarchy: { '$in' : [ 'HierarchicalRequirement', 'Defect' ] },
Release: this.getContext().getTimeboxScope().record.data.ObjectID,
Children: null,
_ProjectHierarchy: this.getContext().getProject().ObjectID
}
To update the app after Release selection check if the chart already exists (if yes, destroy it):
onScopeChange: function() {
if (this.down('#mychart')) {
this.down('#mychart').destroy();
}
this.add({
xtype: 'rallychart',
itemId: 'mychart',
storeType: 'Rally.data.lookback.SnapshotStore',
storeConfig: this._getStoreConfig(),
calculatorType: 'Rally.example.CFDCalculator',
calculatorConfig: {
stateFieldName: 'ScheduleState',
stateFieldValues: ['Defined', 'In-Progress', 'Completed', 'Accepted']
},
chartConfig: this._getChartConfig()
});
},
I'm using GeoExt2 (alpha) + Extjs 4.1 now to implement a map application. The thing is sometimes when I select a feature on the map, two popups are displayed. one at the bottom of the screen which has correct info and one empty in the right place. it doesn't go even I close it. I wonder if this is a bug ?
myLayer.events.on({
featureselected: function(e) {
createPopup(e.feature);
},
featureunselected: function(){
popup.destroy();
}
});
function createPopup(feature) {
popup = Ext.create('GeoExt.Popup', {
id: 'popup',
title: title,
location: feature,
});
popup.on({
close: function() {
if(OpenLayers.Util.indexOf(myLayer.selectedFeatures,
this.feature) > -1) {
selectControl.unselect(this.feature);
}
}
});
PopupTab = Ext.create('Ext.tab.Panel', {
id: 'PopupTabs',
activeTab:2,
items: [
{
title: 'Supervisor',
itemId: 'tab1',
},
{
title: 'student',
itemId: 'tab2',
items: [
{
xtype: 'label',
id: 't',
html: content,
layout: 'fit',
cls:'tabStyle'
}
]
},
],
listeners: {
tabchange: function(panel, tab) {
if (tab.popup !== undefined) { // show window after tab change
tab.popup.show();
}
}
}
});
popup.add(PopupTabs);
popup.show();
}