How to create vis.js timeline without gaps - javascript

I am working with the vis.js timeline (http://visjs.org/docs/timeline/).
I want to achieve that it is not possible to have gaps between the elements.
If someone is removing an element between other elements the and adding a new element to the gap the new element should auto-fit into the gap.
If someone is updating the time (size) of an element by resizing, it should also auto fit to the next element.
I need an validation that all elements in all groups are filled between a given date range.
These are my editable options:
editable: {
add: true, // add new items by double tapping
updateTime: true, // drag items horizontally
updateGroup: false, // drag items from one group to another
remove: true, // delete an item by tapping the delete button top right
overrideItems: false // allow these options to override item.editable
},
It is not allowed to move the elements between the groups.
My first guess is to use the onMove function but I couldn't figure out how to find the previous and next element do adjust the start and end.
Maybe someone else had the same problem and found a solution.

I had a similar scenario in which dragging an element would rearrenge all the others and dragging an element to another group would make it snap just after the last element.
There is no easy option to set to do this. Basically you have to listen to these events and keep track of where are your elements in order to update it.
For example, in your first case what you have to do is:
Listen for onAdd() event
Search through the elements of that group where this new element will be created by looking at the start and end times.
Update this new item to have the start equals to the end of the previous element and have the end equals to the start of the next element.
Here's a simple JS Fiddle to get you started: http://jsfiddle.net/rj35mbvd/
In this fiddle, everytime you try to add an item, it is added between the two elements already present in the timeline.

Here is the good answer guys :
Use in options of stack: false + stackSubgroups: true and simply use the same subgroup by default, the elements will be displayed inline ;)
Check the <script> at the end of this html page http://visjs.org/examples/timeline/groups/subgroups.html
I will share an advanced roadmap I am working on ;)
Best

Related

SlickGrid DataView syncGridSelection does not remove the old selection when the table changes

I have a SlickGrid running with a dataView and I'm using the rowSelectionModel with the option multiSelect=false. When I select something in the grid and then expand my grid by clicking a button to show some hidden rows, the selection is moving correctly, but the old selection still remains on the old row.
This is what I have so far:
var dataView = new Slick.Data.DataView({inlineFilters: false});
var grid = new Slick.Grid(gridDiv, dataView, columns, options);
grid.setSelectionModel(new Slick.RowSelectionModel({selectActiveRow: true}));
grid.setSelectedRows([]); //make sure the selection is empty
dataView.onRowsChanged.subscribe(function (e, args) {
grid.invalidate();
});
dataView.beginUpdate();
dataView.setItems(data);
dataView.setFilter(displayFilter);
dataView.endUpdate();
dataView.syncGridSelection(grid);
grid.render();
Here are some screenshots on the behavior:
Before expanding:
Expected behavior after expanding:
Actual behavior after expanding:
I'm pretty sure I'm close, but i can't quite figure out what I'm doing wrong.
Thank you in advance for taking the time to help me with this :)
EDIT: I might have found something. I'm using syncGridSelection which sets some events, but overwrite them later. The events I overwrite are
dataView.onRowCountChanged()
dataView.onRowsChanged()
grid.onSelectedRowsChanged
might this be the issue here? I need those events to get the collapse/expand functionality to work. The grid.onSelectedRowsChanged is used to pass the selected item to a chart, so it is also required.
EDIT 2:
I was able to reproduce the issue with Example 5, the modified code can be found in this paste
Steps to reproduce:
1. Select item 10
2. Collapse item 7
Having had a look at the code, I think that is actually is working. It's just that your CSS changes have obscured one point.
There are selected row(s) and the active row. These are different things. You have set the CSS for both (in the CSS area in the page itself) to look the same. So it looks like the selection is still there when in fact it's been removed, but that row is now active.
Just delete the two CSS rules and have a look.
For extra points, use:
dataView.syncGridSelection(grid, true);
and the grid will preserve the selections as the selection moves in and out of sight on collapse/expand.

Move between lists open multiple times

I'm trying to create an app that moves elements between two lists. When the element in the joblist gets clicked it has to open multiple times.
So when I click on: Open: 2 x. This elements has to move to the other list but also show up there twice.
I have no idea how to do this and where to start. I got it so far that you can click the element and it moves to the other list. But i don't know how to multiply it by the number.
$scope.toB = function(item) {
$scope.listB.push(item);
$scope.listA.splice($scope.listA.indexOf(item), 1);
};
$scope.toA = function(item) {
$scope.listA.push(item);
$scope.listB.splice($scope.listB.indexOf(item), 1);
};
My version on plunker
Here is an image that displays what I mean.
Based on your description, I made this:
http://plnkr.co/edit/K9SlyYkJLJjLm9QH0MqV?p=preview
so now when an item in the left list is clicked, it'll show up in the right list x times, where x is the item's id attribute. You can replicate the code to also clone items when clicked in the right list.
Was this anywhere near what you needed, or if not, can you explain your problem in a bit more detail?

How do I get the bottom-most element, or, a list of all elements under my cursor?

I'm creating a drag and drop system that includes sortables, and I'm trying to replicate jQuery's insertBefore/insertAfter behavior when hovering over a list of elements. As such, I have an element under my cursor and I want to put a placeholder where it would show up in the list.
I've tried:
document.elementFromPoint - this only gives me the topmost element
document.querySelectorAll(':hover') - this gives me the containing list and the dragged element, but not the intermediate element that I would insert a placeholder before/after
checking event.toElement, .srcElement, etc.
settings pointer-events: none on the dragged element - this just seems to remove it from the document.querySelectorAll ":hover" list
I want to avoid searching through all items in a list to see if my mouse cursor is inside their boundaries if possible, because I suspect it will be a huge performance hit.
Use document.elementFromPoint.
You need a list of displays and a list of elements.
For each element: (1) save the display string to a list, (2) set display to "none", (3) add the element to a list, and (4) check the element at the point again.
Then, go through the element list in reverse order and set the display back to what it was.

ExtJS Using Tab to navigate between two grids

I have a panel that contains two grids, both of which are editable using the cell editing plugin. Within the grids, users can use the tab key to move between editable fields. However, I can not seem to find the right way to get the tab key to allow the user to move from the last editable cell in the first grid to the first editable cell in the second (there are no components between the two grids). The user is just stuck in the last editable field of the first grid.
I tried using FocusManager, but this made keyboard navigation far more complex, rather than less, requiring use of the arrow keys to get into and out of each form element and grid.
I added this code to the parent panel:
var nav = new Ext.util.KeyNav(Ext.getDoc(), {
tab: function(e) {
console.debug('TAB HIT!', arguments);
},
scope: this
});
nav.enable();
just to see what tabs were detected, but it only activated when the tab key was clicked and a form element in the parent panel itself had focus.
I guess there are a few elements I need to learn, how to I pass focus from element to element, and how do I detect the first and last element in a grid? Or is there some way to do this built into ExtJS? Any suggestions or advice would be greatly appreciated.
I would use the new cellkeydown event for grid panels.
Implement a handler for that event which checks the key type, and whether the cell is the last column in the grid, then starts a cell edit in the first column of the corresponding row in the other grid.
You can find out if it was a TAB key from the 7th argument passed by this event.
You can find out if it is the last cell in the grid from the 3rd argument passed by the event.
The rowIndex is the 6th argument - use that so you know which row to start editing in the other grid.
Event handlers can be added to components using the on method by the way.
You can also look up the functions that need to be called to start cell editing in the API here.
If you had more code and maybe a bounty I might be able to get more specific but that's the gist of how I would do it.

Multy-filter page with transitions - Isotope & Quicksand JS problems

(note: edited since I've just realized the question are somehow correlated, at least in my mind!)
I want to create a multi-filter page in which the result will be animated...
I'm trying with 2 different plugin (quicksand and Isotope) and with both solution I'm having problems...
---ISOTOPE--- (original)
With Isotope I need to filter data based on active class, or based on IDs of filters, which I've already stored in JS, does anyone know how can I do that?
I set up a page with 2 different filter like 'color' (red, blue, orange...) and 'type' (square, round...)
I already have a Javascript that assign class active to the 2 filtering lu based on selection, if all color are selected shift the 'active' class to 'all', and more than one sub-filter can be activated. And this also save the list of the id of the active li items in a string for color filter and another string for shape filter
I also already set up the page like the combination filter Isotope demo at this link: http://isotope.metafizzy.co/demos/combination-filters.html and it is working fine but doesn't allow to select more than one sub-filter at the same time.
I saw the demo at this link http://fiddle.jshell.net/desandro/JB45z/ with filtering combination, but it is based on radio button that I'd like to avoid.
I'm not sure if what I'm trying to do is easy or not... is like, how to tell to Isotope to filter based on the sub-filter that have active class or based on the sum of the li with the ID saved in my two string?
Thanks for any help, as you can easily understand I'm not skilled in js at all and english is not my first language!
--- QUICKSAND --- (edited)
I've just realized that I didn't explain why I stored the IDs of the selected items in the js string. And this is also about the different js question.
I was trying to set up the same system with Quicksand instead of Isotope.
But since quicksand need to have a starting li and a destination li to display the animation I set up the js to pass an array to a different temporary php page that use the array to display a destination li.
All until here is working fine but I'm not able to get back the li data in the original page to let Quicksand perform the animation. The last part of my js appear to have problems that I'm not able to fix (too many days trying with no success), the last part of the js is:
$.post( 'destination_li_filtered.php', {
colorString,
shapeString,
$('#ids').attr('val')
},
function(data) { // should contains the resulting data from the request (?)
$('.list').quicksand( $(data).find('li'),
{ adjustHeight: 'auto' },
function() {
callbackCode();
}
);
e.preventDefault();
});
the external page destination-li-filtered is displaying the results but the original page is not able to take back the data...
Obviously I need to set op the page with isotope or quicksand, not both.
but I'm also wondering witch is the best plugin to display 100's of results with about 20 filters (without considering the combinations). And of course, which is the easiest to use!
You should see the radio button and the change in view as separate things.
It's a common misconception that you should store all your state in the DOM (ie. which checkbox is checked). The DOM is a view, you don't keep state in a view.
You should have a state that lives in your JavaScript.
Like:
var state = "all_selected"; // green, red, blue
Then, when you check the radio button, it will set the appropriate state and update the list (show/hide elements based on state).
This allows you to make any control you want, be it a radio button, a checkbox or something completely custom.

Categories