Jstree show context menu conditionally - conditional-statements

This code below shows my attempt to show a jstree context menu only at level 1.
The menu shows at level one and selection of the menu items shows an alert.
The menu does not show at level 2 which is fine and what I want.
But, after selecting a level 2 node, then selecting a level 1 node the menu appears as it should, but selection of the menu items does nothing.
Any help appreciated.
fiddle: https://jsfiddle.net/NervousElk/4p5hqg0r/17/ fiddle
document.getElementById("gobtn").addEventListener("click", buildtree);
function buildtree()
{
$('#ttstafftree').jstree(
{
plugins: ["wholerow", "json_data", "ui", "themes", "sort", "state", "contextmenu"],
'core' :
{
"check_callback": true,
'data' :
[
{ "id" : "ajson1", "parent" : "#", "text" : "Root 1" },
{ "id" : "ajson1-1", "parent" : "ajson1", "text" : "a" },
{ "id" : "ajson2", "parent" : "#", "text" : "Root 2" },
{ "id" : "ajson2-1", "parent" : "ajson2", "text" : "b" },
]
},
"contextmenu":
{
"items":
{
opt1:
{
label: "opt 1",
action: function(data)
{
alert('opt 1')
}
},
opt2:
{
label: "opt 2",
action: function(data)
{
alert('opt 2')
}
}
}
},
})
.on('show_contextmenu.jstree', function(e, reference, element)
{
if ( reference.node.parents.length != 1)
{
$('.vakata-context').remove();
}
});
}

You're removing the vakata-context element to hide the context menu for leaf nodes. Although I'm not too certain of this, to me it seems that this breaks the event handlers set on the context menu so they don't work anymore. Looking at the source code for the context menu, jsTree internally uses $.vakata.context.hide() to hide the tree. You could use that in your event handler for the show_contextmenu.jstree event.
.on('show_contextmenu.jstree', function (e, reference, element) {
if (reference.node.parents.length != 1) {
$.vakata.context.hide();
//$('.vakata-context').css('display',"none");
}
});

Related

Objects in React Native

I have a piece of text and every time you click on it the text changes to the next item in the object. I also need the name of the one saying the text so I used a multidimensional array like this:
let texts = {
0:{
"name" : "Bob",
"text" : "Hello, this is a text",
},
1:{
"name" : "Peter",
"text" : "Hey there.",
},
};
This is my state:
this.state = {
textNumber: 0,
};
And this is the function I call onPress:
nextScene = () => {
if(this.state.textNumber >= Object.keys(texts).length-1){
}
else{
this.setState({textNumber: this.state.textNumber+1})
}
};
It works perfectly just the way I want it. But my question is: is this the way it should be done in React Native? Or is there a better way?
You probably want an array of objects:
let texts = [
{
"name" : "Bob",
"text" : "Hello, this is a text",
},
{
"name" : "Peter",
"text" : "Hey there.",
},
];
Then you can do:
if(this.state.textNumber < this.state.texts.length-1) {
this.setState({textNumber: this.state.textNumber+1});
}
If you want a loop, you can also do the following:
this.setState({textNumber: this.state.textNumber+1 % this.state.texts.length});
About your question, there is no difference between doing this in React Native or not. This is merely JS.
It is fine to keep this in the state (both React or RN). If you want more fancy solution you can write a HOC to manage the state of your component (see for example recompose).
const DATA = [
{
'title': 'Test Series (12,13)',price:"1000",
},
];

How DataTables determine columns type

I have a dynamic table enhanced by jQuery DataTables, which display a custom object similar to this example.
JSON:
{
"data": [
{
"name": "Tiger Nixon",
"position": "System Architect",
"salary": "$320,800",
"start_date": {
"display": "SomeString",
"timestamp": 1303686000
},
"office": "Edinburgh",
"extn": "5421"
},
// ... skipped ...
]}
JavaScript:
$(document).ready(function() {
$('#example').DataTable( {
ajax: "data/orthogonal.txt",
columns: [
{ data: "name" },
{ data: "position" },
{ data: "office" },
{ data: "extn" },
{ data: {
_: "start_date.display",
sort: "start_date.timestamp"
} },
{ data: "salary" }
]
} );
} );
The difference is that I dynamically build the columns configuration, because the columns can be in any order, and others columns can be added or removed from the list. For this example (my case is very similar) the problem is that for some reason the timestamp property is ordered as a String instead of being ordered as a number.
I discovered that after setting the column "type" as "number" the ordering works perfectly. I'm presuming that DataTables is auto detecting the column as "String" for some reason (maybe because the display element is a string).
How does DataTables set the type of the columns, when is not explicitly declared?
Edit 1
I made a sample code to show the problem
http://jsfiddle.net/Teles/agrLjd2n/16/
jQuery DataTables has built-in mechanism for type detection. There are multiple predefined functions for various types with fallback to string data type.
It's also possible to use third-party plug-ins or write your own.
There are multiple ways to specify data type, below are just the few.
SOLUTION 1
Use type option.
$(document).ready(function() {
$('#example').DataTable( {
ajax: "data/orthogonal.txt",
columns: [
{ data: "name" },
{ data: "position" },
{ data: "office" },
{ data: "extn" },
{ data: "start_date.display", type: "date" },
{ data: "salary" }
]
} );
} );
SOLUTION 2
Use returned JSON data for type detection, see columns.data for more information.
$(document).ready(function() {
$('#example').DataTable( {
ajax: "data/orthogonal.txt",
columns: [
{ data: "name" },
{ data: "position" },
{ data: "office" },
{ data: "extn" },
{ data: {
_: "start_date.display",
sort: "start_date.timestamp",
type: "start_date.timestamp",
} },
{ data: "salary" }
]
} );
} );
DataTables always check the "type" property of the column "data" to auto detect the type of the column, if no "type" property is specified it will check the default value "_".
So if you want DataTables to auto detect the type of the column checking the type of your "sort" property you should set the "type" property of data to be equals to your "sort" value
Here is a sample code with different approchs to achieve what I was tryng to do. Thanks #Gyrocode.com and #davidkonrad.
var Cell = function(display, value) {
this.display = display;
this.value = value;
}
$(document).ready(function() {
var cells = [
new Cell("120 (10%)", 120),
new Cell("60 (5%)", 60),
new Cell("30 (2.5%)", 30)
];
$('#example').DataTable( {
data: cells,
columns: [
{
title : "Column NOT OK",
data: {
_: "display",
sort: "value"
}
}, {
type : "num",
title : "Column Ok setting column type",
data: {
_: "display",
sort: "value"
}
}, {
title : "Column Ok changing default value",
data: {
_: "value",
display: "display",
filter: "display"
}
}, {
title : "Column Ok setting data type",
data: {
_: "display",
sort: "value",
type: "value"
}
}, {
type : "num",
title : "Column Not OK",
data: "display"
}
]
} );
} );

Paging and grouping in dynamic grid

I am using dynamic grid using this plugin.
I want to make paging in it,
I tried like,
Ext.define('....', {
extend: 'Ext.data.Store',
pageSize: 10,
proxy: {
type: 'rest',
url: me.url,
reader: {
type: 'dynamicReader',
totalProperty: 'totalCount'
}
}
});
me.bbar = Ext.create('Ext.PagingToolbar', {
store: me.store,
displayInfo: true,
displayMsg: 'Displaying topics {0} - {1} of {2}',
emptyMsg: "No topics to display"
});
In DynamicGrid.js totalProperty is not working. Am I setting the property properly there?
Then I am also trying to make grouping in the same plugin.
I have a combobox with some fields and want to select grouping field from it dynamically. When I select a field in combo box, it sends that data to grid's groupField property.
I have that combo box value selected in controller like,
var groupData = Ext.ComponentQuery.query('#groupid')[0].getValue();
I am sending it to grid like,
Ext.define('Group', {
singleton: true,
param: groupData
});
I am getting that for grid property (in DynamicGrid.js) like,
groupField: [Group.param]
But this automatically selects first field for groupField property before even selecting anything in combo box and makes grouping, selecting other fields in combo box also doesn't work, it always has first field for grouping.
What is going wrong? Please help.
I did grouping successfully by adding the following code in listener,
me.store.group(Group.param);
Still having issues with totalProperty, can someone help me to make it work?
I think I am making a mistake, now actual JSON response is,
[{
"userId": 123,
"name": "Ed Spencer",
"email": "ed#sencha.com"
}]
So the code for getting data and manipulating works fine like,
readRecords: function(data) {
if (data.length > 0) {
var item = data[0];
var fields = new Array();
var columns = new Array();
var p;
for (p in item) {
if (p && p != undefined) {
fields.push({name: p, type: 'floatOrString'});
columns.push({text: p, dataIndex: p});
}
}
data.metaData = { fields: fields, columns: columns };
}
return this.callParent([data]);
}
But for sending other metaData properties, from the docs I should probably have the following JSON response,
{
"count": 1,
"ok": true,
"msg": "Users found",
"users": [{
"userId": 123,
"name": "Ed Spencer",
"email": "ed#sencha.com"
}],
"metaData": {
"root": "users",
"idProperty": 'userId',
"totalProperty": 'count',
"successProperty": 'ok',
"messageProperty": 'msg'
}
}
So how do I point root in the readReords function so that it knows data is in root?
Thereby I will have other metaData properties also passed.
Please help!

Kendo Hierarchical Datasource for treeview, filter to checked nodes

I am using the Kendo Hierarchical Datasource for a Kendo UI Treeview.
On a click event, I want to leave only the checked roms in the datasource.
I tried
$('#treeview')
.getKendoTreeView()
.dataSource
.filter({
field: "checked",
operator: "eq",
value: true });
But to no avail.
Do I have the correct field?
Also, for bonus points, how do I remove the filter?
checked is the correct field if you have defined it as so in the template :
$("#treeview").kendoTreeView({
checkboxes: { template: "<input type='checkbox' name='checkedNodes' #= item.isChecked ? 'checked' : '' # value='#= item.id #' />" },
dataSource: [{
id: 1, text: "My Documents", expanded: true, spriteCssClass: "rootfolder", items: [
{ id: 2, text: "about.html", expanded: true, isChecked: false, spriteCssClass: "folder" },
{ id: 3, text: "index.html", expanded: true, isChecked: true, spriteCssClass: "folder" }
]
}]
});
in my case, it is named isChecked (see item.isChecked in my code).
But, in order to filter correctly, be careful : filter only acts on the current level (see for example this question).
And for your bonus question, to remove the filter, simply apply the following code :
$('#treeview')
.data("kendoTreeView")
.dataSource
.filter({ });
(same as before on all levels on your hierarchy!).
Edit
Here is some fiddle in order to play with the filter : http://jsfiddle.net/scaillerie/RHh67/ .

node.updateInfo is not a function while appending node in extjs

I am trying to load data into an extjs 4 TreeStore but while appending node, I am getting node.updateInfo is not a function error.
My model classes are as follows :
Dimension.js
Ext.define('ilp.model.Dimension', {
extend : 'Ext.data.Model',
require : [
'ilp.model.DimensionLevel'
],
fields : [
'actualName',
'displayName'
],
hasMany : {model : 'ilp.model.DimensionLevel', name : 'dimensionLevels'}
});
DimensionLevel.js
Ext.define('ilp.model.DimensionLevel', {
extend : 'Ext.data.Model',
fields : [
{name : 'name', type : 'string'},
{name : 'totalTrainees', type : 'int'}
]
});
and tree store code is as follows :
Ext.define('ilp.store.DimensionTree', {
extend : 'Ext.data.TreeStore',
requires : [
'ilp.model.Dimension',
'ilp.model.DimensionLevel'
],
model : 'ilp.model.Dimension',
root: {
name: 'Dimensions'
},
proxy: {
type: 'ajax',
url: 'http://localhost:8080/pentaho/content/cda/doQuery',
reader: {
type: 'pentahoReader',
root: 'resultset'
},
extraParams: {
path: 'RINXDashboards%2FCDAs%2FILP_Employee_Qeries.cda',
dataAccessId:'Get_All_Levels_From_All_Dimensions',
userid : 'joe',
password : 'password'
}
},
listeners: {
append : function(parentNode, newNode, index, options) {
if(newNode.get('text') != 'Root') {
console.log('newNode text value = ' + newNode.get('text'));
newNode.set('checked', null);
newNode.set('expandable', true);
if(Ext.ClassManager.getName(newNode) == "ilp.model.Dimension") {
newNode.set('expanded', true);
newNode.set('text', newNode.get('displayName'));
if(newNode.dimensionLevels().getCount() > 0) {
newNode.dimensionLevels().each(function(level) {
newNode.appendChild(level);
});
} else {
newNode.set('leaf', true);
}
}else if(Ext.ClassManager.getName(newNode) == "ilp.model.DimensionLevel") {
newNode.set('leaf', true);
newNode.set('text', newNode.get('name'));
}
}
}
}
});
I am getting above error on following line :
newNode.dimensionLevels().each(function(level) {
while debugging I have found that updateInfo() method of newNode is undefined.
Can anyone please tell me why this error is coming? I am totally clueless now !!!
May this is caused by the bug EXTJSIV-6051
see Sencha Forum for further infos
I think your problem comes from :
root: {
name: 'Dimensions'
},
root attribute must be of type: Ext.data.Model/Ext.data.NodeInterface/Object. So try to replace 'root' attribute by this:
root: {
text: "Dimensions",
leaf: false
}
Check Sencha doc for more information: http://docs.sencha.com/ext-js/4-1/#!/api/Ext.tree.Panel-cfg-root