I'm using JSTree and it has shown to be an awesome tool.
Using the Drag and Drop plugin I came across this:
When I drag a file to a folder with valid_children that does not allow files it does not show the red cross, but also does not allow to drop (as valid_children expected behavior). For a better user expecience I need to show the cross when the parent node's valid_children does not contain the node being dragged's type. Here is an example of what I am looking for:
Any ideas?
Found the solution and it differs a little from what I've found in StackOverflow
explicitly define your valid_childrens on "types" configuraton.
add parameters on check_callback to function(operation, node, node_parent, node_position, more)
add to check_callback:
switch (operation) {
case 'move_node':
return ($.inArray(node.type, this.get_rules(more.ref).valid_children) != -1);
default:
return true;
}
Related
The 1.66 (March 2022) release introduces a TreeDragAndDropController API which allows for handling drag & drop events for custom tree views.
However in the docs for the DataTransfer object is says:
Drag and drop controllers that implement {#link TreeDragAndDropController.handleDrag handleDrag} can add additional mime types to the data transfer. These additional mime types will only be included in the handleDrop when the the drag was initiated from an element in the same drag and drop controller.
Does this mean that you cannot drag & drop between custom tree views as they would typically have a custom drag & drop controller per view? Or that you're meant to re-use a drag & drop controller between tree views in order to enable dragging & dropping between views?
I have tried various combinations and been unsuccessful in getting a full drag & drop between two tree views. I do see an error in the console on drop in some situations but that is about it.
It took me a while to figure out how to get drag & drop to work between two different treeviews. For me, the problem was a combination of:
Misunderstanding the purpose / usage of dragMimeTypes.
Misunderstanding the purpose / usage of treeDataTransfer.set().
Using an incorrect naming convention for mime types.
This is probably best described by way of example.
Let's assume we're only going to drag from TreeView_A and we'll only drop onto TreeView_B.
For TreeView_A
dropMimeTypes can be an empty array as we're not expecting to receive any drops.
We don't really need a handleDrop() method, again we're not expecting to receive any drops.
dragMimeTypes needs to include the mime type of the treeview that we're going to drop onto (i.e. TreeView_B). A word of warning here, this MUST be in the format application/vnd.code.tree.<treeidlowercase>. So, for this example it would read something like this:
dragMimeTypes = ['application/vnd.code.tree.treeView_b'];
handleDrag() method needs to set using a mime type of the target treeview (Treeview_B), (remember lowercase!)
public async handleDrag(source: TreeItem[], treeDataTransfer: vscode.DataTransfer, token: vscode.CancellationToken): Promise<void> {
treeDataTransfer.set('application/vnd.code.tree.treeView_b', new vscode.DataTransferItem(source));
}
The lowercase requirement seems more like a suggestion if you read the comments in the underlying code... but no from my experience it seems more like a requirement. Had me stumped for ages!
For TreeView_B
dragMimeTypes can be an empty array as we won't be dragging anything from here.
similarly, we don't really need a handleDrag() method.
dropMimeTypes needs to include the mime type of the treeview that we're going to drop onto (i.e. this treeview, TreeView_B)
dropMimeTypes = ['application/vnd.code.tree.treeView_b'];
the handleDrop() method needs to get the correct mime type (you guessed it, Treeview_B in lowercase). In this method, I just log to console.
public async handleDrop(target: TreeItem | undefined, sources: vscode.DataTransfer): Promise<void> {
const transferItemAppContent = sources.get('application/vnd.code.tree.treeView_b');
if (transferItemAppContent) {
console.log(JSON.stringify(transferItemAppContent));
return;
}
}
I'm still not sure that I've 100% understood how this is supposed to be implemented, but I can tell you that the above method works. Hope it helps.
I need to select multiple ranges simultaneously via the Office.js API like you can do in the MSWord UI by holding down the CTRL key and highlight multiple non-contiguous paragraphs, like the screenshot below:
This attempt doesn't work. Rather than highlighting the first two instances of the word "the" in the document, it's highlighting the first, then highlight the second afterwards:
Word.run(function (context) {
// Set up the search options.
var options = Word.SearchOptions.newObject(context);
options.matchCase = false;
options.ignoreSpace = true;
options.ignorePunct = true;
options.matchWildcards = true;
var searchText = "the";
var searchResults = context.document.body.search(searchText, options);
context.load(searchResults);
return context.sync().then(function () {
searchResults.items[0].select();
searchResults.items[1].select();
});
});
No, none of the APIs support multiple selections. Even the ability for the user to do so, using Ctrl+select is relatively new. The capability was never carried over to the APIs.
The closest the APIs can do is to highlight (or otherwise format) the Range objects of interest. There is such functionality in Word's dialog box which is also available to the COM APIs, but I don't find an equivalent for the JS APIs...
To confirm what Cindy mentioned, Non-continuous selections are not only not supported in Office.js (for Word, we DO support them for Excel though) but also not supported manually on other platforms (i.e. Word Online).
It might be possible.
I ran across an odd result when using bindings and Office.context.document.goToByIdAsync(). Using this function you can navigate to any binding without having to call Word.Run(), which is nice. There is an option called SelectionMode, which by default does not select the binding, but can be set to select the contents of the binding. Weirdly, selecting the content in this way does not deselect the current selection! Which is not the result I wanted, fwiw; to me it is a nuisance that requires me to "deselect" any current selection before I use goToByIdAsync. But it's possible you could use this to select multiple ranges by wrapping them in contentControls and then creating bindings on them, then calling goToByIdAsync (with SelectionMode set to Select) on each binding. I have not tested this.
Edit
Actually, the previous selection is deselected, but it remains highlighted as though it is still selected. This appears to be a display bug.
I'm currently trying to develop an Eclipse Plugin to support code replacement, like what the default content assist in Eclipse do. What I want to implement is something like "insert argument names automatically on method completion with visualized box around the argument" and I can "use the Tab key to navigate between the inserted names" and "while navigating, list of optional variables for current argument can be displayed and be chosen".
In short, it comes to two questions:
How to add the visualized box around the already existed variable or even Java keywords that need replacement? And at the meanwhile I can use Tab key to switch between these boxes.
How to display a list of candidates to select from when I trigger on the box?
By now I only figure out the extension point : org.eclipse.jdt.ui.javaCompletionProposalComputer may be useful, but I have no idea where to start at? Thanks in advance.
Oh, finally I've solved it myself...
For the 'box', it should be the LinkedModeModel, this class should work with LinkedPositionGroup and LinkedPosition to add mutiple boxes. And we should use LinkedModeUI to set it up.
For the content assistant, there's no need to use the extension point. There is a ProposalPosition class which extends LinkedPosition for you to add your proposals for the 'box' in its constructor. And we can simply use the CompletionProposal to construct a ICompletionProposal array as the argument of ProposalPosition's constructor.
What's the correct XPath syntax to check if an option element is currently selected, or just to get the selected option element from a select element, on an open page with which the user, and JavaScript, may have interacted? Is this even possible with XPath, or does it lack the ability to look at DOM properties?
I can't find any documentation on this, and have (speculatively) tried:
//option[#selected=true]
//option[#selected="selected"]
//option[#selected]
but none of these work; they simply don't match any elements.
(In case it matters, I've tried this both using the $x function in the Chrome developer console, and using the find_elements_by_xpath method in Selenium for Python.)
Short answer: it's not possible.
Longer answer: XPath can look at HTML attributes, but it can't look at DOM properties. Selecting an <option> element in a <select> changes the selected property of the <option> to true, and also changes the value property of its parent <select> element, but it doesn't affect the attributes of either, so it is invisible to XPath.
To find <option> elements that have the selected attribute set, which is often how a page author might determine which option is initially selected, you can use //option[#selected]. But this does not find the currently selected <option>; changes that the user makes to the selection are invisible to XPath. There's no guarantee it will even find the initially selected option, since it's possible that the page author didn't put the selected attribute on any elements and either let the browser select the first option by default or had some JavaScript select the initial option via the selected property.
The multiple other answers here claiming that a selector like //option[#selected] can detect selection changes made by the user after the page loads are simply completely wrong.
Of course, if you're able to use CSS selectors instead of XPath selectors, then option:checked will do the job.
The problem could be the " (double quotes).
//select/option[#selected='selected'] - Will match the selected option, i am using this successfully.
//select/option[#selected='selected' and #value='specific value'] - Will only match the selected option if it has a 'specific value', i'm also using this.
If you are still having trouble, it could be an entirely different problem, perhaps there is no option node. I hope this helps.
I think we can use a knowledge from #Mark's answer and account that. Let's just find a node which HAS desired attribute:
tree.xpath('//select/option[#selected]/text()')[0].strip()
I tried "//option[#selected=''] and it has worked for me.
it is able to highlight the selected option within Page objects model.
I would try //option[#selected='true']
i.e. driver.findElements(By.xpath("//option[#selected='true']")).getText();
If I open the extension manager, switch to the tab Import Extensions and select the filter I get the following options:
Display all extensions (empty)
Only display installed extensions (working)
There should also be a Only display updatable extensions selection but this isn't displayed. What is the reason therefore?
I made a TYPO3 update to 4.7.2 and perhaps thats the reason why it isn't correctly displayed?
The repository is up to date.
The filter has been moved from the Import Extensions to the Available Extensions tab.
You do not actually want to import an extension, but update an existing one.
Just suggestion: I had similar issues with button displaying in EM before (4.6.x) (ie. Install ext button) and realised, that the button is available, but sprite image had wrong position which caused that the button was transparent,
Try to use ie FireBug to check it, and eventually fix the CSS (and report the bug)
Edit:
Some doom apparently, I just had identical situation just seconds ago ;) Fortunately found the reason: the ext list is displayed with ExtJS grid, which can contain custom filtering per column. Literally: when you for an example click on the column's dropdown arrow, you can in its filter set some value to narrow the search results.
Ie.: in the main filter field write news and additionally in the Extension Key column set other filter tt_news. (if you want to display only %tt_news% in result list of %news%)
In that case even if you'll clear the main filter, the one set on the column will stay active, so next time when you'll try to search for realurl in main filter, it will return empty list as Extension Key filter is still set to tt_news.
Weeeird, however helped me :)
You can recognize filtered columns as their names are written with cursive, finally you can just check every column and disable any filtering on each.