Suppress enter - expand group in ag-grid - ag-grid

In Ag-grid you can navigate with the keyboard. When you use grouping you can press enter to expand the current node.
Is there a way to stop this when the node is a leaf?
GroupCellRenderer.prototype.onKeyDown = function (event) {
var enterKeyPressed = isKeyPressed(event, KeyCode.ENTER);
if (!enterKeyPressed || this.params.suppressEnterExpand) {
return;
}
var cellEditable = this.params.column && this.params.column.isCellEditable(this.params.node);
if (cellEditable) {
return;
}
this.onExpandOrContract();
};
This is the code that checks if the node should be expanded.
So I would need suppressEnterExpand to be a function so I can give it some context on the current node.
Or it should not try to call the expand when it's on a leaf.

Related

VSCode extension - how to alter file's text

I have an extension that grabs the open file's text and alters it. Once the text is altered, how do I put it back into the file that is displayed in VSCode?
// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {
// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
console.log('Congratulations, your extension "myExtension" is now active!');
console.log(process.versions);
// The command has been defined in the package.json file
// Now provide the implementation of the command with registerCommand
// The commandId parameter must match the command field in package.json
let disposable = vscode.commands.registerCommand('extension.myExtension', () => {
// The code you place here will be executed every time your command is executed
let activeEditor = vscode.window.activeTextEditor;
if (!activeEditor) {
return;
}
let text = activeEditor.document.getText();
getAsyncApi(text).then((textToInsertIntoDoc) => {
let finaldoc = insertTextIntoDoc(text, textToInsertIntoDoc);
// not what I want - just used to see new text
vscode.window.showInformationMessage(textToInsertIntoDoc);
});
});
context.subscriptions.push(disposable);
}
The API you can use here is TextEditor.edit, whose definition is
edit(callback: (editBuilder: TextEditorEdit) => void, options?: { undoStopBefore: boolean; undoStopAfter: boolean; }): Thenable<boolean>;
It asks for a callback as the first parameter and in the callback, you can make edits to the document by visiting editBuilder.
I put a sample extension in https://github.com/Microsoft/vscode-extension-samples/tree/master/document-editing-sample which reverses the content in current selection, which is basically a simple use TextEditor.edit.
This is a revision of the main function in Rebornix's extension sample (included with the set of Microsoft extension samples) that handles the selection issues you raised. It reverses the content of the selection(s) (leaving the selections) or if a selection is empty it will reverse the word under the cursor at that selection without leaving anything selected. It often makes sense to leave a selection, but you can add code to remove selection.
let disposable = vscode.commands.registerCommand('extension.reverseWord', function () {
// Get the active text editor
const editor = vscode.window.activeTextEditor;
if (editor) {
const document = editor.document;
editor.edit(editBuilder => {
editor.selections.forEach(sel => {
const range = sel.isEmpty ? document.getWordRangeAtPosition(sel.start) || sel : sel;
let word = document.getText(range);
let reversed = word.split('').reverse().join('');
editBuilder.replace(range, reversed);
})
}) // apply the (accumulated) replacement(s) (if multiple cursors/selections)
}
});
Admittedly, while I could remove a single selection by setting .selection to a new empty selection that doesn't seem to work with .selections[i]. But you can make multiple changes without having selections in the first place.
What you don't want to do is make a selection through code just to alter text through code. Users make selections, you don't (unless the end purpose of the function is to make a selection).
I came to this question looking for a way to apply a textEdit[] array (which is normally returned by a provideDocumentRangeFormattingEdits callback function). If you build changes in the array you can apply them to your document in your own function:
const { activeTextEditor } = vscode.window;
if (activeTextEditor) {
const { document } = activeTextEditor;
if (document) {
/*
build your textEdits similarly to the above with insert, delete, replace
but not within an editBuilder arrow function
const textEdits: vscode.TextEdit[] = [];
textEdits.push(vscode.TextEdit.replace(...));
textEdits.push(vscode.TextEdit.insert(...));
*/
const workEdits = new vscode.WorkspaceEdit();
workEdits.set(document.uri, textEdits); // give the edits
vscode.workspace.applyEdit(workEdits); // apply the edits
}
}
So that's another way to apply edits to a document. Even though I got the editBuilder sample to work correctly without selecting text, I have had problems with selections in other cases. WorkspaceEdit doesn't select the changes.
Here is the code snippet that will solve your issue :
activeEditor.edit((selectedText) => {
selectedText.replace(activeEditor.selection, newText);
})
Due to the issues I commented about in the above answer, I ended up writing a quick function that does multi-cursor friendly insert, and if the selection was empty, then it does not leave the inserted text selected afterwards (i.e. it has the same intuitive behavior as if you had pressed CTRL + V, or typed text on the keyboard, etc.)
Invoking it is simple:
// x is the cursor index, it can be safely ignored if you don't need it.
InsertText(x => 'Hello World');
Implementation:
function InsertText(getText: (i:number) => string, i: number = 0, wasEmpty: boolean = false) {
let activeEditor = vscode.window.activeTextEditor;
if (!activeEditor) { return; }
let sels = activeEditor.selections;
if (i > 0 && wasEmpty)
{
sels[i - 1] = new vscode.Selection(sels[i - 1].end, sels[i - 1].end);
activeEditor.selections = sels; // required or the selection updates will be ignored! 😱
}
if (i < 0 || i >= sels.length) { return; }
let isEmpty = sels[i].isEmpty;
activeEditor.edit(edit => edit.replace(sels[i], getText(i))).then(x => {
InsertText(getText, i + 1, isEmpty);
});
}
let strContent = "hello world";
const edit = new vscode.WorkspaceEdit();
edit.insert(YOUR_URI, new vscode.Position(0, 0), strContent);
let success = await vscode.workspace.applyEdit(edit);

How to remove ContentEdit.Static element in ContentTools

I created a new tool in ContentTools that adds a static table (I don't want you to edit).
But being a static element doesn't maintain focus and I can not remove it when I click remove button.
I can do so that the table is not editable but can be removed if you click on it?
That's how I created the element:
new ContentEdit.Static('div', {'data-ce-moveable': true}, '<table><thead><tr><th>Foo head</th></tr></thead><tbody><tr><td>Foo body</td></tr></tbody></table>')
Thank you!
Static elements can't be interacted with for the most part (other elements can be dragged around them but that's about it). ContentEdit/Tools does allow you to restrict the some behaviour for elements but not being able to modify the content of a text element isn't one right now (though I think this might be a worthy addition).
However whilst there's no set way to do this at the moment here's an approach you can use that should provide the behaviour you describe (do let me know how you get on):
ContentEdit.Root.get().bind('mount', function(element) {
// We only care about `TableCell` elements
if (element.type() != 'TableCell') {
return;
}
// We only want to make the element read-only if the parent table has
// the `data-read-only` attribute.
var table = element.closest(function(node) {
return node.type() == 'Table';
});
if (table.attr('data-read-only') !== undefined) {
// Disable text editing for the table cell
element.tableCellText()._onKeyDown = function(ev) {
ev.preventDefault();
}
}
// Disable dragging of the table rows
var tableRow = element.closest(function(node) {
return node.type() == 'TableRow';
});
tableRow.can('drag', false);
tableRow.can('drop', false);
});

Event.stop within .each (prototype)

I am struggling with function that should check form fields before submitting.
I have some select (dropdown fields) and a text field. None of them should be empty for submit.
The script http://jsfiddle.net/6KY5J/2/ to reproduce.
I check dropdown fields within .each and additional text field. Here is the function:
function checkFields(e) {
$$('.dropdown').each(function (element) {
if (element.selectedIndex === 0) {
alert('Fill all dropdown fields!');
Event.stop(e);
throw $break;
return;
}
});
if ($('sometext').value == '') {
alert('Fill the input!');
Event.stop(e);
return;
}
alert('OK!');
}
But I am not able to prevent further execution of the script if one of dropdown is empty. Event.stop(e) seems to to work for the input field only in the second part.
Desired behaviour:
Check dropdowns, if one is empty, stop execution, do not make any
further checks.
Check text input field only if dropdowns are not empty.
Submit only if everything if filled.
The issue is in step 1. My script does not stop here, alerts, but does not stop. Any idea? Thank you!
function checkFields(e) {
var dropdownsokay = true;
$$('.dropdown').each(function (element) {
if (dropdownsokay && element.selectedIndex === 0) {
alert('Fill all dropdown fields!');
Event.stop(e);
dropdownsokay = false;
}
});
if(dropdownsokay) { //only check textfield if all the dropdowns are okay
if ($('sometext').value == '') {
alert('Fill the input!');
Event.stop(e);
return;
}
alert('OK!');
}
}

Why aren't these two functions toggling on click event?

I'm trying to toggle two functions. When user clicks the pause button, the input fields are disabled, the label is text is changed to grey and the button changes to a different image. I thought I could use .toggle(), but I can't get the two functions to work either -- only the first one function runs (pauseEmailChannel();), not both on toggle click. I found the even/odd clicks detection script here on SO, but that is not "toggling" these two functions on the click event. My code may be ugly code, but I'm still learning and wanted to show how I am thinking -- right or wrong. At any rate, can someone give me a solution to how to do this? I didn't think it would be too difficult but I'm stuck. Thanks.
HTML
jQuery
$(".btn_pause").click(function(){
var count = 0;
count++;
//even odd click detect
var isEven = function(num) {
return (num % 2 === 0) ? true : false;
};
// on odd clicks do this
if (isEven(count) === false) {
pauseEmailChannel();
}
// on even clicks do this
else if (isEven(count) === true) {
restoreEmailChannel();
}
});
// when user clicks pause button - gray out/disable
function pauseEmailChannel(){
$("#channel-email").css("color", "#b1b1b1");
$("#notify-via-email").attr("disabled", true);
$("#pause-email").removeClass("btn_pause").addClass("btn_disable-pause");
}
// when user clicks cancel button - restore default
function restoreEmailChannel(){
$("#channel-email").css("color", "#000000");
$("#notify-email").attr("disabled", false);
$("#pause-email").removeClass("disable-pause").addClass("btn_pause");
$("input[value='email']").removeClass("btn_disable-remove").addClass("btn_remove");
}
try this code. It should work fine, except that I could make a mistake when it is even and when odd, but that should be easy to fix.
$(".btn_pause").click(function(){
var oddClick = $(this).data("oddClick");
$(this).data("oddClick", !oddClick);
if(oddClick) {
pauseEmailChannel();
}
else {
restoreEmailChannel();
}
});
The count variable is initialized and set to 0 every time .btn_pause is clicked. You need to move the variable to a higher scope.
For example,
$(".btn_pause").each(function(){
var count = 0;
$(this).click(function(){
count++;
...
});
});
In this way count is initialized only once and it is accessible in the click event handler.
As an alternative way you can also use:
$(".btn_pause").each(function(){
var count = 0;
$(this).click(function(){
[restoreEmailChannel, pauseEmailChannel][count = 1 - count]();
});
});
If the previous construct was too abstract, a more verbose one will look like this:
$(".btn_pause").each(function(){
/* Current element in the array to be executed */
var count = 0;
/* An array with references to Functions */
var fn = [pauseEmailChannel, restoreEmailChannel];
$(this).click(function(){
/* Get Function from the array and execute it */
fn[count]();
/* Calculate next array element to be executed.
* Notice this expression will make "count" loop between the values 0 and 1.
*/
count = 1 - count;
});
});

Add ondblClick and click event to Codemirror

I would like to add onDblClick event to codemirror 2. I found that onCursorActivity does not deliverer the event so there is no way for me from this method to filter the events.
How can I implement onDbClick event on Codemirror ?
Thanks in advance.
You can call on method on object returned by CodeMirror:
var cm = CodeMirror.fromTextArea(document.querySelector('textarea'));
cm.on('dblclick', function() {
alert('You double click the editor');
});
You can find the list of all available events in documentation.
Register a handler on the element returned by the getWrapperElement() method. Unless you want to not just detect double-clicks, but also prevent the default (select word under mouse cursor) from occurring... in that case I guess some modification of the core code is needed.
http://jsfiddle.net/yusafkhaliq/NZF53/1/
Since codemirror renders inside the element specified you can add an ondblclick event to the element, like below the highlighter renders without line numbers once double clicked that specific elements will display line numbers
var codeelems = document.getElementsByClassName("code");
for (i = 0; i < codeelems.length; i++) {
(function ($this) {
var value = $this.innerHTML;
$this.innerHTML = "";
var editor = CodeMirror($this, {
value: value,
mode: "text/javascript",
lineNumbers: false
});
$this.ondblclick = function () {
editor.setOption("lineNumbers", true);
}
})(codeelems[i]);
}