elbywan / bosket Goto Github PK
View Code? Open in Web Editor NEWCollection of tree view components for front-end frameworks. :deciduous_tree:
Home Page: https://elbywan.github.io/bosket/
License: MIT License
Collection of tree view components for front-end frameworks. :deciduous_tree:
Home Page: https://elbywan.github.io/bosket/
License: MIT License
Hello!
Thank you for this component!
I'm trying to use it without a local state.
For example:
const regions = this.props.regionsTree.regions; // redux store
const tree = {
category: 'sub_regions', // name of the property containing the children
selection: [],
model: regions, // object for iterate
display: (_) => _.region, // field for show
onSelect: (newSelection, item, ancestors, neighbours) => {
// newSelection -> updated array containing all the selected items
// item -> the newly selected item (excluding the old one in case of multi selection)
// ancestors -> the ancestors of the newly selected item
// neighbours -> the neighbours of the newly selected item
this.selection = newSelection;
},
};
/* Drag'n'drop presets */
const dragndrop = {
// To drag or drop on specific items
// you can use a function : (item) => true/false
draggable: true,
droppable: true,
drag: null, // action to perform on drag
drop: null, // action to perform on drop
over: null, // hook on dragover
enter: null, // hook on dragenter
leave: null, // hook on dragleave
cancel: null, // action to perform on cancellation
guard: null, // prevents dragover and drop
};
<TreeView
{...tree}
dragndrop={dragndrop}
onSelect={tree.onSelect}
/>
Of course, drag'n'drop don't work (need describe action).
Do you have an example of using a TreeView with Redux?
this.pluckPreset.drag(target, event, inputs);
ERROR Error: Unexpected call to method or property access.
this.pluckPreset.drop(target, event, inputs);
ERROR TypeError: Object doesn't support property or method 'indexOf'
When entering a special regular-expression character, the search fails due to an invalid Regexp being created. For example, try entering a plus (+) character into the search field.
Hello @elbywan ,
First your tool is very very awesome thanks for this simple and easy to use.
I need your help for the drag and drop.
I want drag element but only with the same level between the source Item and the destination Item.
I try Many solutions, but I don't arrive drag only the same element with the same level or except when a specific properties in model allowIt , specialy with async element.
Also it's possible to open automatically the children when I drag element over it?
You can see the model here: https://stackblitz.com/edit/react-zasmjr?file=model.js
all elements have a level.
Thanks for your help
Hi again!
I would like to create my own sorting function in Vue 2.0, according to whether it is a folder or a leaf. However, I only get infinite loops:
sort: (a, b) => {
if((a.children && b.children) || (!a.children && !b.children)) {
return a.name.localeCompare(b.name)
} else if (a.children && !b.children) {
return -1
} else {
return 1
}
}
Could you please help me understand how the sort function works?
display: item => <folder-tree-item v-bind:folder="item" v-bind:email-account="this.emailAccount" v-bind:parent-folder-name="item.RawFolderName" ></folder-tree-item>,
I'm curious if its possible to render another component in the display function.
Thanks!
Hi,
I'm trying to display my items according to this template :
<span>
<span style="font-size:80%;color:#3298FF;font-weight:bold;"> item.type </span> item.name
</span>
In that, I have created a display function:
display: item => {
return createElement('span', {
'class': this.itemClass(item.actif)
},
[
createElement('span', this.itemStyle(item.type), item.type),
item.name,
createElement('i', {
'class':{
state: true,
fa: true,
'fa-exclamation-triangle': item.late,
'fa-power-off': item.actif
}
}),
createElement('i', {
'class':{
state: true,
fa: true,
'fa-pause': item.standby
}
})
]
)
}
However, I get the error 'createElement is not defined', how do I implement my own model ?
Hi @elbywan - love this component! It's been very useful.
One issue I have is when the model changes, any opened nodes automatically collapse. Ideally we'd like an option to keep all node's expanded/collapsed state when the model changes.
This may be an option already but I have not found it - we currently use these strategies:
:strategies="{
selection: ['single'],
click: ['select', 'unfold-on-selection'],
fold: ['opener-control']
}"
onDrop event doesn't have a event.dataTransfer.
I'm still using RequireJS with RiotJS. I can see bosket/riot/index.js
contains the core modules, like dragndrop
but I have no access to them, for example to use the dragndrop.selection
preset. Is there a way to access them, or could you export them as part of the pre-built index.js
module?
Hello,
I have a react configuration.
I try to install with a simple create app install and yarn install or npm install, after I put bosket in package.json, but I have the following error:
./~/bosket/react/traits/transitions.js
Module not found: Can't resolve 'react-transition-group/CSSTransitionGroup' in '/Users/j3di/Downloads/react-bosquet/node_modules/bosket/react/traits'
I try add react-transition-group in my package.json but it doesn't work..
my package.json configuration
{
"name": "react-bosquet",
"description": "",
"dependencies": {
"react": "15.6.1",
"react-dom": "15.6.1",
"react-scripts": "1.0.10",
"bosket": "0.2.1",
"react-transition-group":"2.2.0"
},
"version": "0.1.0",
"private": true,
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
I'm unclear why it's recommended to install this package as a development dependency instead of a regular one. My linter is too.
tx.
I might have missed this in the docs, but how can I automatically open all nodes on initial load?
Hi, I'm trying to build a folders system. Nodes with children are my folders and nodes without children are my files. I need to open multiple folder nodes (multiselection ), but with only one file item selected at the same time.
So I tried to made some strategies to acomplish these behaivor:
{
selection: [
'multiple',
(item, selection) => {
// Take only folders
var modifiedSelection = selection.filter((node) => {
return node.children ? true : false;
});
if (!item.children) {
modifiedSelection.push(item);
}
return modifiedSelection;
}
],
click: ['select'],
fold: [
(item) => {
var recurseCheck = node => {
return this.isSelected(node)
|| node['children']
&& node['children'] instanceof Array
&& node['children'].some(recurseCheck);
}
return !recurseCheck(item)
}
]
}
The isSelected method:
isSelected(item) {
var found = this.selection.filter((selectionItem) => {
if (selectionItem.id == item.id && selectionItem.children == item.children) {
return true;
}
return false;
});
return found.length > 0 ? true : false;
}
This works more or less how I expected. However lets say that I'm having these structure
--folder A
----item A1
----item A2
--folder B
----item B1
----item B2
When the folder A is selected I can open/close folder B and select any of the items inside. But when for example item A1 is selected and I pick folder B or any other element inside of B, the folder A is closed because the selection losts any reference to A or any of it's items.
Any idea about how I can mantain the folder A opened?
I am using the display prop to render custom text and display an "edit" button in react. i am passing the object passed to the display function to the onClick handler of the button to be used for editing. is the object passed to the display function the actual object from within the original tree model? i.e. if I update the passed object am i updating the original data? If not, how could I programmatically delete and add a new node with the updated content? or update and render the original data?
mainTreeProps = {
...this.treeProps, display: d => <div><Button onClick={() => {
d.items ? this.props.EditGroup(d) : this.props.EditItem(d);
}}>Edit</Button>{d.name}</div>
};
(i.e. is "d" a copy or a reference to the object in the original model / object)
Hello,
Do you think it possible to separate each module with his own package.
I mean instead have "bosket/react" , the package was "bosket-react" for example with only file for react,
one for vue => "bosket-vue" etc etc...
Because I use unpkg.com for load package like a cdn in my project , and I would like make demo with playground editor like https://stackblitz.com/
Other thing, I see You use typescrpit can you put a file typescript definition file in the root of project ? I would like use the intellisence of typescript. thanks for your answer
I would like to have my tree view search even in items that haven't been asynchronously loaded yet. So it would walk through the whole tree, resolve promises if they are not resolved yet and then search based on the results.
Right now when I search and the tree items haven't been expanded yet, they are not searched because their children weren't resolved yet.
How to add custom html? For example, I want to add a button to edit an item and a button to delete a member. How can i do this?
Hi,
how can i use a custom input field that trigger the search for available nodes?
Hey,
I am currently working on managing a large project with bosket (~500 root entries, 20k total entries). Although children are loaded asynchronically, any action (selecting/opening/closing nodes) on that tree takes several seconds. I suspect some sort of filter/map being applied to the whole tree on every action. Is there a way to avoid these loading times? I would really like to continue working with bosket =)
Hi,
I am just wondering if there is a way to expose/use nodeEvents
in bosket/src/core/dragndrop.js
?
What I am trying to do is to show different animation on drag enter and drag leave in a sortable tree.
Thanks,
Hi.
I have a problem with model.
<template>
<div id="app">
<TreeView :model="model" category="children"></TreeView>
</div>
</template>
<script>
import { TreeView } from "@bosket/vue"
import { string } from "@bosket/tools"
export default {
name: 'test-bosket',
components: {
"TreeView": TreeView
},
data: function() {
return {
selection: [],
category: "children",
model: [{
label: "Animals",
children: [{
label: "Mammals",
children: [
{ label: "Tiger" },
{ label: "Platypus" },
{ label: "Bear" }
]
}, {
label: "Reptiles",
children: [
{ label: "Turtle" },
{ label: "Crocodile" }
]
}]
}]
}
}
}
</script>
<style>
/* CSS */
</style>
When I try to run app? I have error.
[Vue warn]: Error in render: "TypeError: Cannot read property 'indexOf' of undefined"
found in
---> <TreeViewNode>
<WithTransitionTreeViewNode>
<TreeView>
<WithLabelsTreeView>
<WithListenerWithLabelsTreeView>
<WithListenerWithListenerWithLabelsTreeView>
<Passmanager> at src/renderer/App.vue
<Root>
And error stack
TypeError: Cannot read property 'indexOf' of undefined
at Object.contains (/node_modules/@bosket/tools/bundle/tools.umd.min.js:1:3284)
at n.o.isSelected (/node_modules/@bosket/core/bundle/core.umd.min.js:1:11309)
at n.o.liCss (/node_modules/@bosket/core/bundle/core.umd.min.js:1:12388)
at /node_modules/@bosket/vue/bundle/vue.umd.min.js:1:7413
at Array.map (native)
at Proxy.render (/node_modules/@bosket/vue/bundle/vue.umd.min.js:1:7346)
at VueComponent.Vue._render (webpack-internal:///0:4545:22)
at VueComponent.updateComponent (webpack-internal:///0:2789:21)
at Watcher.get (webpack-internal:///0:3143:25)
at new Watcher (webpack-internal:///0:3132:12)
Can you help me solve this problem?
Hello,
Maybe it is possible natively, but i haven't found it how, but how could i selected a node programmatically?
I'am working with VueJS.
Here is my use case:
I have the tree view component on the left part of my app and when i click on a node (Node1) it expands its children (Node1.1, Node1.2, Node1.3,...)
Then on the right part of my app i have the content page component which will sometimes display the list of the children too (Node1.1, Node1.2, Node1.3,...)
What i would like is when in the content page i click on let's say Node1.2 , that in the tree view the node Node1.2 would be selected, and so the expension of its children would be triggered
Thanks for your help.
JM
The demo uses a custom sort function, so I was expecting that without that you'd be able to reorder nodes amongst siblings. However, this doesn't seem to be possible - I can only change the hierarchy/nesting, not simply reorder these items.
Would it be possible to add this (as a flag, perhaps)?
Hi there.
Apparently it was decided that <virtual>
and data-is
should not be used together:
This construct is still being used here, though:
we have in core/logic.js:
_this.hasChildren = function (item) { return item[_this.inputs.get().category] && item[_this.inputs.get().category] instanceof Array; }
it's possible to make one more check for array's length?
_this.hasChildren = function (item) { return item[_this.inputs.get().category] && item[_this.inputs.get().category] instanceof Array && item[_this.inputs.get().category].length; }
Clicking around tree items in the Riot.js demo, items sometimes disappear completely or move to another branch in the tree.
Hi,
Working with vuejs, let's say I have a tree with :
Because my items are so numerous, I'd like to load them asynchronously, while all the subfolders (= tree elements with children) are preloaded.
I tried both parts: loading asynchronously my items and loading only the folders and subfolders, but I can't figure out the proper syntax for mixing both.
Do you have a clue ?
Thank you.
Hey,
first off, great work so far, I really like this component.
I'm not sure if I just don't get the strategies or if this is a bug.
I use the following strategies
strategies = { click: ['select', 'unfold-on-selection'], selection: ['single'], fold: ['no-child-selection', 'not-selected'] };
What kind of expected is that when I click on an unfolded item (expanded?!), that only this item gets collapsed/folded and not the whole tree.
But I also want to be able to use the activated route '.../item/{[id}' to use that id and select an item in the tree. I had a look at this issue Auto expand on load,
but I really had no idea how to use this within my component. So I choose to set the [selection] on my will at loading.
Am I missing something?
Thanks in advance :)
Hey, I think about switching from AngularJS to Vue, but need a plugin to display tree-like hierarchy with drag&drop and easy customization. Seems like bosket is the only solution. So thanks for that! :)
But the customization is what gives me headache. I built a sample app using laravel-mix bundled with Vue. After fixing the webpack/babel setup to be able to use
display: (item, inputs) =>
<strong>{ item.label }</strong>,
in my component, which should also display the tree. But since this is now fixed, I get the ReferenceError.
Full message:
[Vue warn]: Error in render: "ReferenceError: h is not defined"
found in
---> <TreeViewNode>
<WithTransitionTreeViewNode>
<TreeView>
<WithLabelsTreeView>
<WithListenerWithLabelsTreeView>
<WithListenerWithListenerWithLabelsTreeView>
<ExampleComponent> at resources/assets/js/components/ExampleComponent.vue
<Root>
When I switch back to a simple display function (e.g. display: function(item) { return item.label; }
) it works.
Is this a problem with bosket or still an error with my setup?
My added .babelrc (without it html was not allowed in display()
)
{
"presets": [
[ "env", { "modules": false } ]
],
"plugins": [
"transform-vue-jsx",
"transform-object-rest-spread",
"transform-class-properties",
]
}
app.js
import { TreeView } from '@bosket/vue';
import ExampleComponent from './components/ExampleComponent.vue';
require('./bootstrap');
window.Vue = require('vue');
Vue.component('example-component', ExampleComponent);
Vue.component('tree-view', TreeView);
const app = new Vue({
el: '#app'
});
It would be nice to have custom search placeholder, as current default one doesn't look very good with foreign language.
Hello,
I'am using the VueJS version of bosket and I'am struggled with probably a stupid thing, how could i detect that a click on the opener has been made, I knowh there is the onSelect method which is triggered when an item is selected, but i would like to know is if there is a way to have a kind of OnOpener method which would provide the state of the node (fold/unfold) and the item corresponding to it but without selecting the item.
Thanks,
JM
I wonder what is the best way to add a tree node dynamically.
Using Angular, I modified the input variable for the model, but change detection is not happening. Only if I create a copy of the model, the change is recognized in the tree. For this I do the following to make a copy of the model:
this.model = JSON.parse(JSON.stringify(this.model))
However this seems not to be the best way. Does anyone have a better solution? If I could get a hold of the actual TreeViewNode-component, I probably could tell it, to get updated.
Is there a way to make the items that are dragged off the canvas in their original places?
npm start gets this error
> [email protected] bundle-templates C:\Users\J83528\Desktop\tmp\bosket-master
> scripts/bundle-hbs.js
'scripts' is not recognized as an internal or external command,
operable program or batch file.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] bundle-templates: `scripts/bundle-hbs.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] bundle-templates script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\J83528\AppData\Roaming\npm-cache\_logs\2018-07-09T20_18_58_048Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] bundle: `webpack --progress --colors --config config/webpack.config.js -p && npm run bundle-templates`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] bundle script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\J83528\AppData\Roaming\npm-cache\_logs\2018-07-09T20_18_58_099Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] build: `npm run build-js && npm run build-ts && npm run bundle`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\J83528\AppData\Roaming\npm-cache\_logs\2018-07-09T20_18_58_147Z-debug.log
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start: `npm run build && npm run build-docs`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\J83528\AppData\Roaming\npm-cache\_logs\2018-07-09T20_18_58_193Z-debug.log
Hey, it's me again ๐
I'm trying to add a custom children()
function, based on properties. Thus, I decided to use a computed
property, which takes an input array and returns the same array, but with a children()
function. This didn't work, so I stripped it down to the code of one of your examples (one entry with async children), but this didn't work too...Then, I moved if from computed
, back to data()
and everything works fine. Am I missing something or is it not intended to use computed
?
Thanks in advance!
Edit: the error occurs when I click on the opener to show the children.
[Vue warn]: Error in render: "TypeError: model is undefined"
found in
---> <TreeViewNode>
<WithTransitionTreeViewNode>
<TreeViewNode>
<WithTransitionTreeViewNode>
<TreeView>
<WithLabelsTreeView>
<WithListenerWithLabelsTreeView>
<WithListenerWithListenerWithLabelsTreeView>
<TestTree> at resources/assets/js/components/TestTree.vue
<Root>
My Component:
<script>
import { TreeView } from '@bosket/vue';
export default {
components: {
'tree-view': TreeView
},
props: ['arr'],
mounted() {},
methods: {
onSelect(newSelection) {
this.selection = newSelection
}
},
data() {
return {
selection: [],
strategies: {
selection: ["single"],
click: ["select"],
fold: ["opener-control"]
},
category: "children",
display: (item, inputs) => {
return item.label;
}
}
},
computed: {
model() {
return [{
name: "Asynchronous children",
children: () =>
new Promise(resolve =>
setTimeout(() =>
resolve([{ label: "It took exactly one second to fetch me the first time, I am cached afterwards." }]), 1000))
}];
}
}
}
</script>
Is there a way to drag and drop where you can change the order of sibling nodes?
When using search, then it would be good to have the functionality to clear the search when starting a drag.
Version: Vue
Use case:
Users searches for a specific item. Initiates drag and wants to position the draggable element between two specific elements.
Problem: User cannot make the drop since the items aren't visible.
I tried just to clear the input but being Vue, the $data.searchInput
doesn't change and therefore the tree doesn't update.
When you use drag & drop there is no indication where the drop will occur.
Also the entire branch appears selected, although I'm only dragging a single item,
Finally I'm unable to drop an item so that it becomes an descendant of an item.
You might want look at using Dragula https://github.com/bevacqua/dragula instead of what I assume is your own d&d implementation.
Hi @elbywan - would it be possible to add an option to position the opener before the displayTag
component? Here:
https://github.com/elbywan/bosket/blob/master/src/riot/components/TreeViewNode.tag#L25
I've switched to a flexbox-based layout right now, to change the order of elements, but it feels like a hack right now.
Is there a way to expand a node programmatically? It's an important feature especially if you want to open a certain tree path and select a certain sub-node.
Do you have any ideas? I'm using the angular implementation.
Is there a way to currently add styles to leaf nodes as oppose to parent nodes?
I would like to add to features to the search box:
Any idea how to implement these features?
It would be nice if the tree view supported tabbing through items via the key.
When testing the Riot demo, there's a native type="search"
(x) button when the search field has a value. However, clicking on it doesn't reset the tree display, it only empties the field itself. Perhaps a different event (like input
) should be used?
Hi again,
(I'm sorry for having so many questions in a few amount of time ๐ !)
Still using Vue.js, I was wondering how to access the selected list. I would like to store it in my store in vuex, so that when I reload the tree (after I add a child for example), I get the same opened folders.
Thank you @elbywan
Hello,
I am just wondering if you can reorder a node in a tree? Similar to sortable. Right now I believe you can only drag nodes into groups but you can not reorder them.
Thanks,
Maybe it escaped me, but I couldn't see a demo on the website, nor a link in the GitHub readme.
That would be much appreciated!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.