I am trying to test a sorting function for a table. The table enables sorting on a primaray and secondary value. The secondary sorting value is set by holding down the shift key.
Code for setting the sort order:
private sortClick(event: any, column: DataGridColumn): void {
if (!column.sortable) {
return;
}
if (event.shiftKey) { // When the shift key is pressed, secondary sorting is being set.
if (column.headerText === this.primarySorting.headerText) {
return;
}
this.secondarySortingColumn.setSortingProperty(column.headerText, column.name);
} else {
this.primarySorting.setSortingProperty(column.headerText, column.name);
this.secondarySortingColumn.clear();
}
this.sortData(this);
}
Now I'm writing the unit testst for the function.
The primary sorting is done using the following:
let firstColumn: NodeListOf<HTMLElement> = <NodeListOf<HTMLElement>>compiled.querySelectorAll("#header0");
firstColumn.item(0).click();
How can I call the .click() function with shift key pressed in the unit test
You can use the dispaatchEvent method to invoke the click event and supply other event information as follows:
var event = new MouseEvent('click', {
'view': window,
'bubbles': true,
'shiftKey': true
});
let firstColumn: NodeListOf<HTMLElement> = <NodeListOf<HTMLElement>>compiled.querySelectorAll("#header0");
firstColumn.item(0).dispatchEvent(event);
Note the shiftKey member is set to true in the mouseEventInit dictionary parameter to the MouseEvent constructor which allows us to specify that the shiftKey is pressed.
Related
I am trying to add a template doc into an existing google doc.The template is being added, but next time when i am trying to add the template again the template is appending at the bottom of the existing google doc but i want to insert the template at the top.
You can do this by getting the Body of one document and appending its child Elements to the current document.
function addtemplate() {
var thisDoc = DocumentApp.getActiveDocument();
var thisBody = thisDoc.getBody();
var templateDoc = DocumentApp.openById(''); //Pass in id of doc to be used as a template.
var templateBody = templateDoc.getBody();
for(var i=0; i<templateBody.getNumChildren();i++){ //run through the elements of the template doc's Body.
switch (templateBody.getChild(i).getType()) { //Deal with the various types of Elements we will encounter and append.
case DocumentApp.ElementType.PARAGRAPH:
thisBody.appendParagraph(templateBody.getChild(i).copy());
break;
case DocumentApp.ElementType.LIST_ITEM:
thisBody.appendListItem(templateBody.getChild(i).copy());
break;
case DocumentApp.ElementType.TABLE:
thisBody.appendTable(templateBody.getChild(i).copy());
break;
}
}
return thisDoc;
}
It sounds like your goal is to choose the position of the document where the content is added?
One option is to add the template at your current cursor location.
In the example below I have two functions. The first function creates a menu in Google Docs when I open the document (usually a few seconds delay).
The second function attempts to identify the position of my cursor. If it's successful it will insert the date at my cursor position.
Since I've created a menu item I don't have to go to the script editor to trigger this function.
function onOpen() {
// Add a menu item in Google Docs.
DocumentApp.getUi().createMenu('Insert Menu')
.addItem('Insert Current Date', 'insertCurrentDate')
.addToUi();
}
function insertCurrentDate() {
var cursor = DocumentApp.getActiveDocument().getCursor();
if (cursor) {
// Attempt to insert text at the cursor position. If insertion returns null,
// then the cursor's containing element doesn't allow text insertions.
var date = Utilities.formatDate(new Date(), "GMT", "yyyy-MM-dd");
var element = cursor.insertText(date);
if (element) {
element.setBold(true);
} else {
DocumentApp.getUi().alert('Document does not allow inserted text at this location.');
}
} else {
DocumentApp.getUi().alert('Cannot find a cursor in the document.');
}
}
It's also possible that you want to clear the previous template before pasting the new one in? You can do that with the clear() function and then run the rest of your code.
body.clear()
I have got one listview in qml now known as listview1. For each element in listview1, it contains another listview used to show some of its variables. Now I want to make it possible for all such sub-listviews able to add items to them. And also adding item to one of them will not affect all the other listviews in other elements of listview1.
What is the best way to solve such problem? Thanks
Adapted from https://stackoverflow.com/a/55604525/1493608 (same thing but with a GridView instead of a ListView) :
Give each sub-ListView a UUID.
Connect each sub-ListView to a listview1 signal that you will use to broadcast to sub-ListView delegates what you will want to do.
In this signal, put your UUID.
In sub-ListView receivers, put a filter on the UUID and do what you want to do only if it is the right one.
ListView {
id: listview1
signal broadcaster(string uuid, var other_args)
delegate: ListView {
// Provided like this or as a role from the corresponding list element
property string uuid: ""
signal sendToOtherLV(string uuid, var other_args)
function lv_receiver(broadcasted_uuid, other_args) {
if (this.uuid === broadcasted_uuid) {
// Do what you have to do with other_args.
}
}
Component.onCompleted: {
/*
* Custom way to generate the UUID and store it so
* the other ListViews will be able to retrieve it.
*/
this.uuid = generateAndStoreUUID()
// Connecting the sub-ListView to your "sub-ListView LAN".
this.sendToOtherLV.connect(listview1.broadcaster)
listview1.broadcaster.connect(this.lv_receiver)
}
Component.onDestruction: {
// Disconnecting the sub-ListView from your "sub-ListView LAN".
this.sendToOtherLV.disconnect(listview1.broadcaster)
listview1.broadcaster.disconnect(this.lv_receiver)
}
// Here is an example of what you might have to do
function foo() {
// ...
var otherlv_receiver_uuid
var signal_args
// Retreive the UUID of the ListView that you want to send something to.
// Set the other arguments you want to send through the signal.
this.sendToOtherLV(otherlv_receiver_uuid, signal_args)
// ...
}
// Other sub-ListView-related stuff
}
// Other listview1-related stuff
}
On ionChange I am checking some condition, if condtion is set to false I want to restore the toggle buttons previous position. Here is the relevant code
changeStatus(item) {
if(this.mqttservice.response) {
//doing smthg
}
else {
item.status =!item.status;
//bring back the toggle to previous position
}
}
<ion-toggle [(ngModel)]="item.status" (ionChange)="changeStatus(item);" checked="false">
The issue is since I am changing the state changeStatus() is called indefinitely. How do I prevent this and restore toggle button previous position on else condition?
The [()] syntax means you are getting updates and posting updates when the variable changes. Since you are using (ionChange) you can use the [] syntax instead, which means it only gets updates (but won't post them)
<ion-toggle [ngModel]="item.status" (ionChange)="changeStatus($event, item);">
Since the toggle button changes its state, in order for it to "change back" you need to toggle the value back and forth. You can solve this by setting the value and then if it fails, trigger a change "in the future" by adding a setTimeout.
public changeStatus(event: boolean, item: Item) {
item.status = event;
if (allGood) {
// do something
}
else {
// revert to old value
setTimeout(() => { item.status = !event; });
}
}
I have a scene, and this fully functional button called btnRemove,
Button btnRemove = new Button("Remove");
btnRemove.setMinWidth(85);
btnRemove.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
if(mediaTable.getSelectionModel().isEmpty()){
txtNotification.setText("Please select an item from the list");
}
else{
medium.remove(mediaTable.getSelectionModel().getSelectedItem());
}
}
});
and now I want to make it so that when the DELETE-key is pressed, the btnRemove button is triggered and removes the item in focus/the selected element.
Here's the code:
scene.setOnKeyReleased(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
System.out.println(event.getCode());
if("DELETE".equals(event.getCode())) {
System.out.println("ATTEMPT ----");
btnRemove.fire();
}
}
});
When I run it, the console outputs DELETE whenever I press DELETE, but it doesn't output "ATTEMPT ----" after that.
I don't see any reason why it shouldn't trigger
What gives??
You are trying to compare a KeyCode to a String. Change the condition to -
if (KeyCode.DELETE == event.getCode()) { ... }
What you are seeing in the first println is the KeyCode's toString, which apparently returns it's name.
I couldn't find a way to pass arguments when using Ember's Custom Events which I found here.
I prefer avoiding solutions which target "parent" views specifically, such as this one since we lose the "bubbling".
My Usage is as following
plugins.js
Em.Object.reopen({
triggerEvent: function (eventName) {
this.$().trigger(eventName, this);
}
});
MyView.js
click: function () {
this.triggerEvent('stepClicked');
}
The code in Ember (0.96+) shows that passing an additional params is considered a manager, which isn't passed on
rootElement.delegate('.ember-view', event + '.ember', function(evt, triggeringManager) {
...
if (manager && manager !== triggeringManager) {
result = self._dispatchEvent(manager, evt, eventName, view);
} else if (view) {
result = self._bubbleEvent(view,evt,eventName);
}
Super thanks in advance,
Oren Rubin
You can pass an event object which will tell you what element is being clicked on:
click: function(event){
// will be called when when an instance's
// rendered element is clicked
console.log("element clicked: " + this.get('elementId') );
return false; // return true if you want the click event to bubble up to parent view (default it true)
}
I think an even better way would be to use {{action}} in your template. Take a look at this answer for an example.