First of all, Im new at ExtJS. I wanted your help to let me know the best way to obtain a tree menu with n recursive items in it.
In example:
FOLDER
..FOLDER
....ITEM
....FOLDER
......ITEM
......ITEM
....FOLDER
...
Im following the best practises proposed by Sencha. I was able to do a tree menu with one level, but when trying to do it for n levels, it fails (in fact, the app works but shows infinite nodes of 1st level). Clearly the issue is the model definition of my menu item, see:
Ext.define('Dashboard.model.MenuItem',{
extend: 'Dashboard.model.AbstractMenuElement',
fields:
[
{name: 'content', type: 'string'},
{name: 'skeletonFlag', type: 'string'},
{name: 'fatherId', type: 'int'}
],
associations:
[
{type: 'hasMany', model: 'Dashboard.model.MenuItem', name: 'children', mapping: 'items'}
]
});
So this model recursively creates infinite nodes. But... do you know how should i model my menu item in order to achieve the recursive menu?
Thanks!
To display a tree-like structure in Ext JS, I think your best bet is to use Ext.model.TreeModel, Ext.model.TreeStore in conjunction with Ext.tree.Panel.
Here is an simple example to match the structure you mentioned in the question:
Ext.create('Ext.tree.Panel', {
store: Ext.create('Ext.data.TreeStore', {
root: {
text: 'Root Folder',
expanded: true,
children: [
{text: 'Folder 1', children: [
{text: 'Item 1', leaf: true}
]},
{text: 'Folder 2', expanded: true, children: [
{text: 'Item 2', leaf: true},
{text: 'Item 3', leaf: true}
]},
{text: 'Folder 3', children: []}
]
}
}),
renderTo: Ext.getBody()
});
You can view this example on Plunker.
Related
I have a structure, like this
[{
title: "Section 1",
items: [{
title: 'Dashboard',
icon: 'tachometer-alt',
route: '/dashboard',
opened: false
},
{
title: 'Appointments',
icon: 'calendar-alt',
route: '/appointments',
opened: true
},
{
title: 'Orders',
icon: 'box',
route: '/orders',
opened: false,
children: [{
title: 'Orders submenu 1',
route: '/orders/sub1',
opened: false,
children: [{
title: 'Orders submenu 1 subsubmenu 1',
route: '/orders/sub1/sub1sub1'
}]
}]
}
]
}]
These are basically sections with menu items and every menu item could contain submenus, submenus have subsubmenus, etc.
I have a toggle function, which is getting a property array. I want to negate the variable that is "marked" by this array, so when I am getting an [0, 'items', 2, 'children', 0, 'opened'] array, the expected behaviour would be that the "Orders submenu 1" has its "opened" property set to "true".
The property indexer array is alterable too, so I can tweak that a little bit, if needed.
With Ramda, i can easly get the current value with R.path([0, 'items', 1, 'opened'], menu) but how can I set it to "true"?
Jsfiddle for example: https://jsfiddle.net/hurtonypeter/1tm4wcuo/
You can make use of lenses in Ramda to achieve this.
const togglePath = (path, obj) => R.over(R.lensPath(path), R.not, obj)
togglePath([0, 'items', 1, 'opened'], menu)
In my Electron App, I can created a Menu template at an external local file and called it menuTemplate.js
The menu works find but I want to be able to open a local file from it, for example about.html
I've tried 'window.open('url here')' but it doesn't understand window ...
Here is the template:
module.exports = [
{
label: 'Electron',
submenu: [
{label: 'Item 1'},
{label: 'Item 2'}
]
},
{
label: 'Actions',
submenu: [
{label: 'Action 1'},
{label: 'Action 2'},
{label: 'Action 3'},
{role: 'toggledevtools'},
{label: 'ClickMe', click () { window.open('url here'); } }
]
}
]
I've tried shell.openExternal and it works but I cannot get an app window to open from here.
How can I do this?
While it is a good idea to separate a template like this into a separate file, you cannot access the scope of the original file there. To solve this problem you have to bring your window from your mainfile (assumed to be called main.js) into your menuTemplate.js.
You could do this for example by creating a method that builds the template on execution. It could look something like this:
menuTemplate.js
module.exports = function(window){
return [
{
label: 'Electron',
submenu: [
{label: 'Item 1'},
{label: 'Item 2'}
]
},
{
label: 'Actions',
submenu: [
{label: 'Action 1'},
{label: 'Action 2'},
{label: 'Action 3'},
{role: 'toggledevtools'},
{label: 'ClickMe', click () { window.open('url here'); } }
]
}
]
}
Now when loading the template in main.js you do not do something like
const template = require('menuTemplate')
but something like
const template = require('menuTemplate')(window),
with "window" being the name of your window variable.
This is what worked for me:
label: 'General',
submenu: [
{label: 'Unidades',
click () { mainWindow.loadURL(url.format({
pathname: path.join(__dirname, './app/fixed_footer.html'),
protocol: 'file:',
slashes: true
})); }
I have got a nested structure which looks like this example:
let structure = [{
section: '1',
title: 'First lvl title',
children: [{
section: '1.1',
title: 'Second lvl title',
children: []
}, {
section: '1.2',
title: 'Second lvl title',
children: [{
section: '1.2.1',
title: 'Third lvl title',
children: []
}, {
section: '1.2.2',
title: 'Third lvl title',
children: []
}]
}, {
section: '1.3',
title: 'Second lvl title',
children: []
}]
}, {
section: '2',
title: 'First lvl title',
children: [{
section: '2.1',
title: 'Second lvl title',
children: []
}, {
section: '2.2',
title: 'Second lvl title',
children: []
}]
}, ...other objects]
As you can see, structure is similar to the table of contents - I have got objects which represents units and each unit has own section number, title and array with subsections.
Data characteristic is that I never know how many sections and how many nested subsections I have. I need to assume that I can get something around 2 000 objects (maybe more) with different configuration. Also, I cannot predict maximum nested level and it can be different for specific sections.
I am trying to find the most optimized way to represent this structure as HTML page. I am thinking about using ng-repeat but I don't know if it is a good idea since I don't know how many deep levels I will have. Also, after generating my HTML page, I can remove one section (for example section 1) and I need to recalculate section numbers for each other section and subsection (section 2 is now section 1, subsection 2.1 is now subsection 1.1, and so on). What is the best way to handle this operation on such a big amount of data?
You'll want a recursive template, wherein it won't matter what the structure is nor how many levels deep the data go. You can use a recursive custom directive or recursive ngInclude:
<script type="text/ng-template" id="categoryTree">
{{ category.title }}
<ul ng-if="category.categories">
<li ng-repeat="category in category.categories" ng-include="'categoryTree'">
</li>
</ul>
</script>
http://benfoster.io/blog/angularjs-recursive-templates
I am using the javascript library JsTree the current version to build a tree-kind structure in a web application. I would like to know how best to select a particular node within the tree once the tree is loaded.
Try using the ready.jstree event, than the jstree.select_node() method.
The ready event will occur when the tree is loaded, than you can select the node you want.
Set the state property "selected=true" for the particular node to be selected on tree load.
$('#jstree_test').jstree({
core: {
data: [
{
id: 'parent1',
parent: '#',
text: 'p1',
'state' : {
'opened' : true,
'selected' : true
}
},
{
id: 'child1',
parent: 'parent1',
text: 'c1'
},
{
id: 'child2',
parent: 'parent1',
text: 'c2'
},
{
id: 'child3',
parent: 'parent1',
text: 'c3'
}
]
}
});
JS Bin Demo Link
I want to 2 forms, & I want to use card layout, so that when the user submits form1, he is taken to form2. But, when I try to MyApp.container.setActiveItem(2) (using console), it does not move to form2(card2).
Ext.define('MyApp.view.Forms', {
extend: 'Ext.Container',
xtype: 'formsPage',
id: 'formsForm',
config: {
title: 'Patient Registration',
iconCls: 'user',
layout:{
type: 'card'
},
items: [
{
xtype: 'fieldset',
title: 'Patient Registration1',
items: [
{
xtype: 'textfield',
label: 'Names',
name: 'name'
},
{
xtype: 'textfield',
label: 'City',
name: 'city'
}
]
},
{
xtype: 'fieldset',
title: 'Patient Registration1',
items: [
{
xtype: 'textfield',
label: 'Phone',
name: 'phone'
},
{
xtype: 'textfield',
label: 'Country',
name: 'conutry'
}
]
}
],
constructor:function(config) {
this.initConfig(config);
return this;
}
}
});
MyApp.container = Ext.create('MyApp.view.Forms', {});
Please note that array items in Sencha Touch 2 are indexed from 0, so if you want to activate second one, it should be something like this:
MyApp.container.setActiveItem(1)
Edited: I've figured it out. You should add another config to your view: fullscreen:true and it should work well :)
Is your form xtype of 'formsPage' custom, I can't seem to find it in the doco? If it's not, that might be contributing to the issue.
The doco also suggests that you don't create the card layout directly, but instead use carousel or tab panel. Maybe use a carousel as your base component, then make each card a separate form? This would make your intentions clear that each card/form is to be independent.
Hope that helps
do the following:
extend the carousel
extend: 'Ext.Carousel',
change the config section to:
config: {
title: 'Patient Registration',
iconCls: 'user',
cls: 'card'
----
guess that should fix it