dragAndDrop NOT working on Chrome - angularjs

I am trying to perform a Drag and Drop operation on our Angular application using Protractor Jasmine. I am able to get hold of the source item but as the test runs, the source element gets selected but nothing happens thereafter; the drag and drop operation does not take place. There are no errors shown in the console.
An interesting thing about the destination container is that the items dropped here can be resized as per user wish. Also, there is no clearly marked place/area in the destination container where the dragged item will get dropped! But the container does have an ID; though that has still not helped here.
Here is the code:
let dragAndDrop = require('html-dnd').code;
.
.
.
function dragAndDropListItems(fdIndex: number): void {
let dragElement = element.all(by.repeater('listDefinition in lists')).get(fdIndex); // Select the first repeater corresponding to the first List Item in the list
let dragElementh5 = dragElement.all(by.css('a')).get(0); // Select the first List Item
let printFD = dragElementh5.getText().then((text: string) => {
console.log(text); // Print the innerHTML text from the chosen List Item to the Console
});
let finalDrop = element.all(by.css('[id="dashboardContainerDiv"]')).get(0);
dragElement.click();
browser.actions().dragAndDrop(dragElement, finalDrop).perform();
};
I have tried using coordinate based DragNDrop operation as well but the same in every case.
Other tried options include:
//browser.executeScript(dragAndDrop, dragElement, finalDrop); // Perform the drag and drop operation
//browser.driver.actions().dragAndDrop(dragElement, finalDrop).perform();
//browser.actions().dragAndDrop(dragElement, { x: 400, y: 400 }).perform();
// browser.driver.actions().mouseDown(dragElement).mouseMove(finalDrop).mouseUp(finalDrop).perform();
Kindly suggest a solution to this issue.
#FlorentB. I have attached the Code with your scripts imported.
let JS_DRAG_DROP = require('./drag-drop.js');
function dragAndDropListItems(fdIndex: number): void {
/*
let source = driver.find_element_by_css_selector("#drag")
target = driver.find_element_by_css_selector("#drop")
driver.execute_async_script(JS_DRAG_DROP, source, target)
# drag and drop an element by offset {x:500, y:200}
source = driver.find_element_by_css_selector("#drag")
driver.execute_async_script(JS_DRAG_DROP, source, None, 500, 200)
# drag and drop an element with a delay of 101ms before the drop
source = driver.find_element_by_css_selector("#drag")
target = driver.find_element_by_css_selector("#drop")
driver.execute_async_script(JS_DRAG_DROP, source, target, 0, 0, 101)
*/
let source = element.all(by.repeater('listDefinition in
lists')).get(fdIndex); // Select the first repeater corresponding to the
first List Item in the list
let dragElementh5 = source.all(by.css('a')).get(0); // Select the first List
Item
let printFD = dragElementh5.getText().then((text: string) => {
console.log(text); // Print the innerHTML text from the chosen List Item
to the Console
});
//browser.driver.switchTo().frame('dashboardContainerDiv');
/*
let finalDropClass = element.all(by.css('[class="dashboard mb10"]')).get(0);
let finalDropCon =
finalDropClass.all(by.css('[id="dashboardContainerDiv"]')).get(0);
let finalDrop =
finalDropCon.all(by.css('[id="dashboardContainerUl"]')).get(0);
*/
let target = element.all(by.css('[id="dashboardContainerDiv"]')).get(0);
//dragElement.click();
browser.executeScript(JS_DRAG_DROP, source, target); // Perform the drag and
drop operation
//browser.actions().dragAndDrop(dragElement, finalDrop).perform();
//browser.driver.actions().dragAndDrop(dragElement, finalDrop).perform();
//browser.actions().dragAndDrop(dragElement, { x: 400, y: 400 }).perform();
// browser.driver.actions().mouseDown(dragElement).mouseMove(finalDrop).mouseUp(finalDrop).perform();
};

Try
https://github.com/html-dnd/html-dnd
Installing it and using the typescript example worked for me.

Related

Google App Script: Dynamically add new rows in Google Sheets

I'm working on a sheet to build a list of products to import into Shopify.
For this, I have a pdf of some basic data (that is irrelevant here) out of which I build a string to crawl the product supplier's website and format the data in a way suitable for import in Shopify.
The products have a varying number of images (1 - 8), so I'm trying to build my script in a way that if a product has more than one image, I am trying to add additional rows under it and add every image past the first into a new row.
Here is my code:
function iterateThroughRows() {
// get spreadsheet
const sheet = SpreadsheetApp.getActive().getSheetByName("MySheet");
const data = sheet.getDataRange().getValues();
// Loop over rows
data.forEach( (row, rowIndex) => {
const imageSrcArray = [ /* list of image URLs, fetched from remote server */ ]
imageSrcArray.forEach( (img, arrayIndex) => {
if(arrayIndex == 0) { // for the first array item, just add it to the current row
const imageCell = sheet.getRange(rowIndex + 1, 24)
imageCell.setValue( imageSrcArray[arrayIndex] )
} else { // for each array item past the first one, add a new row and enter the value there
sheet.insertRows(rowIndex)
const imageCell = sheet.getRange(rowIndex + arrayIndex + 1, 24)
imageCell.setValue( imageSrcArray[arrayIndex] )
}
})
// adding some more values to other cells
});
}
As is this doesn't really work.
I worked on this all day yesterday and had a version using insertRowAfter() that did add additional rows, but added them all lumped together (i.e. there would be 15 rows after the first product, but none after any of the others). But since Google App Script doesn't have version control I lost that version.
I think the problem was that the forEach seems to move on to the newly created rows and keeps adding things from there rather than moving on to the initial next row.
So I'm more or less at the end of my wit with this. Any advise on how to properly do this would be highly appreciated.
I can understand your frustration, it is indeed because you care calculating the row based on the sheet in its version before you added new rows to it.
So my proposal would be to do this, as the currentRow allows you to track the current row you are working on. I also updated the insertRowAfter(), as I assume this is what you actually wanted to do.
let currentRow = 1;
data.forEach( (row, rowIndex) => {
const imageSrcArray = [ "img1URL", "img2URL"]
if( !imageSrcArray.length ) return
imageSrcArray.forEach( (img, arrayIndex) => {
if( arrayIndex == 0 ){
sheet.getRange(currentRow, 24).setValue( img )
} else {
sheet.insertRowAfter(currentRow)
sheet.getRange(currentRow+1, 24).setValue( img )
}
// New rows in between were created
currentRow++
})
});

Vlookup at Google Apps Script with for loop [duplicate]

This question already has answers here:
Google Script version of VLookup (More Efficient Method?)
(2 answers)
Closed 2 years ago.
I need your help please. I would like to do a for loop or something else that works like a Formula =Vlookup
I have two Sheets. in Sheet1 (Overview) there are ID's like 1000, 1002, 1003,...,100X in Column A;
Sheet2 is a Form Response Sheet (Response), where you need to enter your ID and an Action with 'Ok' and 'Nok'. The ID I enter appears in Sheet2 Column B and the Action (Ok/Nok) apperas in Sheet2 Column C.
Now I would like to Copy the Ok/Nok to the Row with the same ID in the Overview sheet with a onFormSubmit function.
for Example. Person with ID 1005 makes a form response with the Action 'Ok'. Now should the 'Ok' copied to the Overview sheet in Column B and in the exact row (in this case: row with the ID 1005).
Here is my function. but I don't want to have formulars in the sheet. so I aked for another solution.
function vlookup() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var cell = sheet.getRange(1,5);
cell.setFormula('=ARRAYFORMULA(IFS(ROW(Response!B:B)=1,"Action from
User",Response!B:B="","",TRUE,IFERROR(VLOOKUP(A:A,Response!B:C,2,0),"Waiting for Response")))');
}
Hope someone can help me.
Thank you in advance for your help!
Jonas
Thank you for all these answers. I tryed the code from stackoverflow.com/questions/60255775 – TheMaster and that workes fine!
but it seams very complicated for a programming beginner. exspecially the part with the "Hash".
I also added a second compare and copy to get the data from a Reason if the Nok is used in the Form.
const ss = SpreadsheetApp.getActive();
/**
* #param {GoogleAppsScript.Spreadsheet.Sheet} fromSht -Sheet to import from
* #param {GoogleAppsScript.Spreadsheet.Sheet} toSht -Sheet to import to
* #param {Number} fromCompCol -Column number of fromSht to compare
* #param {Number} toCompCol -Column number of toSht to compare
* #param {Number} fromCol -Column number of fromSht to get result
* #param {Number} toCol -Column number of toSht to get result
*/
function copyToOverview(e,response,
fromSht = ss.getSheetByName('Response'),
toSht = ss.getSheetByName('Overview'),
fromCompCol = 2,
toCompCol = 1,
fromCol = 3,
toCol = 2,
fromColRej = 4,
toColRej = 3
) {
const toShtLr = toSht.getLastRow();
const toCompArr = toSht.getRange(2, toCompCol, toShtLr - 1, 1).getValues();
const fromArr = fromSht.getDataRange().getValues();
fromCompCol--;
fromCol--;
fromColRej--;
/*Create a hash object of fromSheet*/
const obj1 = fromArr.reduce((obj, row) => {
let el = row[fromCompCol];
el in obj ? null : (obj[el] = row[fromCol]);
return obj;
}, {});
/*Create a second hash object of fromSheet to copy the Reason why it is Nok (also from filling out the Form) */
const obj3 = fromArr.reduce((obj2, row) => {
let el1 = row[fromCompCol];
el1 in obj2 ? null : (obj2[el1] = row[fromColRej]);
return obj2;
}, {});
//Paste to column first toSht copy the "ok/nok" second toSht for the Reason why Nok
toSht
.getRange(2, toCol, toShtLr - 1, 1)
.setValues(toCompArr.map(row => (row[0] in obj1 ? [obj1[row[0]]] : [null])));
toSht
.getRange(2, toColRej, toShtLr - 1, 1)
.setValues(toCompArr.map(row => (row[0] in obj3 ? [obj3[row[0]]] : [null])));
}
I also tried the Code from "Michiel the Temp" and it seams, that it also works.
The code from "Mateo Randwolf" looks very simple and I tried it too. Works also very good!
I have modified it a bit and it works like I wish! I think I will use this code.
function onFormSubmit(e) {
// Get the sheet where the form responses are submitted and the one where we want to check the IDs
var formSheet = SpreadsheetApp.getActive().getSheetByName('Response');
var destinationSheet = SpreadsheetApp.getActive().getSheetByName('Overview');
// Get the new incoming data (ID and Ok/Nok) with each form submit by accessing
// the trigger object e which is the submited and new form response row
var submittedId = formSheet.getRange(e.range.getRow(), 2).getValue();
var submittedValue = formSheet.getRange(e.range.getRow(), 3).getValue();
var submittedValueReason = formSheet.getRange(e.range.getRow(), 4).getValue();
// get all the ID values we have in the sheet we want to check them. flat will convert all the returning
// 2D array of values in a 1D array with all the IDs
var idRange = destinationSheet.getRange(1, 1, destinationSheet.getLastRow(),1).getValues().flat();
// iterate over all your IDs
for(i=0;i<idRange.length;i++){
// if one ID is the same as the incoming one from the form response
if(idRange[i] == submittedId){
// set its value to the one submitted by the form
destinationSheet.getRange(i+1, 2).setValue(submittedValue);
}
if(idRange[i] == submittedId){
destinationSheet.getRange(i+1, 3).setValue(submittedValueReason);
destinationSheet.getRange(i+1, 2).getValue() == "Nok" ? destinationSheet.getRange(i+1, 4).setValue("Closed") : destinationSheet.getRange(i+1, 4).setValue("Open");
}
}
}
Thank you all for the Help you are amazing!
So I can do my next step in the Project with updating checkboxes in the Form.
I didn't test this with a trigger but this should work
function vlookup() {
var ssOverview = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Overview");
var ssOverviewLr = ssOverview.getLastRow();
var ssOverviewData = ssOverview.getRange(2, 1, ssOverviewLr, 1).getValues(); //assuming you have a header in the first row
var ssResponse = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Response");
var ssResponseLr = ssResponse.getLastRow();
var newResponse = ssResponse.getRange(ssResponseLr, 2, 1, 2).getValues();
var Ids = ssOverviewData.map(function (r){return r[0];});
for(var i = 0; i < newResponse.length; i++)
{
var row = newResponse[i];
var id = row[0];
var action = row[1];
var index = Ids.indexOf(id);
if(index == -1)
{
SpreadsheetApp.getActiveSpreadsheet().toast("No matches", "Be aware")
}
else
{
ssOverview.getRange(index + 2, 2).setValue(action); //this puts the action in column B
}
}
}
In order to check the IDs every time there is a new form submission and change the data in the ID sheet accordingly you will need to use installable triggers. Specifically you should use a FormSubmit trigger which triggers the function every time there is a form submission. Along with this trigger you will use its event object.
To add an installable trigger, in your Apps Script editor go to Edit -> Current project's triggers and create a new trigger by clicking Add trigger. Make sure that you select On form submit as the event type and that you select the function presented below (so please first copy/paste the function below before creating your trigger).
The following function takes use of this trigger event to compare the incoming data to your Column A of IDs and check for matches and if so it adds the relevant Ok/Nok information. It has self explanatory comments:
function onFormSubmit(e) {
// Get the sheet where the form responses are submitted and the one where we want to check the IDs
var formSheet = SpreadsheetApp.getActive().getSheetByName('Form Responses 1');
var destinationSheet = SpreadsheetApp.getActive().getSheetByName('Check');
// Get the new incoming data (ID and Ok/Nok) with each form submit by accessing
// the trigger object e which is the submited and new form response row
var submittedId = formSheet.getRange(e.range.getRow(), 2).getValue();
var submittedValue = formSheet.getRange(e.range.getRow(), 3).getValue();
// get all the ID values we have in the sheet we want to check them. flat will convert all the returning
// 2D array of values in a 1D array with all the IDs
var idRange = destinationSheet.getRange(1, 1, destinationSheet.getLastRow(),1).getValues().flat();
// iterate over all your IDs
for(i=0;i<idRange.length;i++){
// if one ID is the same as the incoming one from the form response
if(idRange[i] == submittedId){
// set its value to the one submitted by the form
destinationSheet.getRange(i+1, 2).setValue(submittedValue);
}
}
}

How to extract an element of a spreadsheet as a string, not as an array element Google App Script

(Edited the problem description)
What I am trying to do: Using this Spreadsheet to collect the URLs row by row and paste each image in a new slide of a Google Slide named Output Document. I am using a function addImagetoSlide that takes in the imageUrl, the slide number and the name of the document to add images to each element of the slide.
Where I am stuck When I try to use dataRange (the array containing my spreadsheet element, it works well outside the while loop, but inside the while loop, it does not read the element [0][2] saying that "Cannot read Property 2 of line.. I do not understand why it works outside but not inside the while loop
function collateImages(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var targetDocument = SlidesApp.create("Output Document"); // Target file for the collation
var dataRange = sheet.getDataRange(); // Range of the entire database
Logger.log(dataRange.getValues()[0][2]);
Logger.log(dataRange.getValues()[1][2]);
Logger.log(dataRange.getValues()[2][2]);
Logger.log(dataRange.getValues()[3][2]);
var i = 0; // Iterator
while (i< dataRange.getLastRow()){
i = i + 1;
Logger.log(dataRange.getValues()[i][2]);
addImageToSlide(doubtRange.getValues()[i][2],i,targetDocument);
}
}
// Function to get file id from url
function getIdFromUrl(url) { return url.match(/[-\w]{25,}/); }
//Add Image with URl "ImageUrl" on slide number "index on a presentation named "deck"
function addImageToSlide(imageUrl, index,deck) {
var slide = deck.appendSlide(SlidesApp.PredefinedLayout.BLANK);
var imagefile = DriveApp.getFileById(getIdFromUrl(imageUrl));
var imageblob = imagefile.getBlob();
var image = slide.insertImage(imageblob);
}
The problem with the code you have used is that you are trying to access an index that doesn't exist. As you are incrementing the i value on the last loop, when calling the dataRange.getValues()[i][2], this will try to retrieve the element corresponding to the incremented i which falls out of the range, hence the error message you are receiving.
You can:
move the i increment after calling the dataRange.getValues()[i][2];
use a for loop;
Reference
Sheet Class Apps Script - getDataRange().

Swift - Update and store position of a multiple programmatically created buttons

I have a button which creates other buttons based on the class Clip seen below. Those newly created buttons are added to an array and stored in a plist.
class Clip: Encodable, Decodable {
var name: String = ""
var xCoordinate: Int = 100
var yCoordinate: Int = 300
// more parameter will be added later on e.g color, scale etc..
}
Each button can be moved around the view and the new x & y coordinates are stored in a plist.
#objc func handlePan(sender: UIPanGestureRecognizer){
let uIViewSelected = sender.view!
switch sender.state {
case .began, .changed :
moveViewWithPan(view: uIViewSelected, sender: sender)
break
case .ended:
//Finds the position when the button is no longer being dragged
let x = Int(uIViewSelected.center.x)
let y = Int(uIViewSelected.center.y)
//clipArray[0] need to be the corresponding clicked button e.g clipArray[2]
clipArray[0].xCoordinate = x
clipArray[0].yCoordinate = y
saveData()
break
default:
break
}
}
The above works only if I create one button. When more buttons are added, the above lines only change the first clip from the array. I need a way to update the value to the correct button clicked.
How can identify the array position of the click button as I am creating all them programmatically? At the moment I am placing at value 0 of the clipArray.
clipArray[0].xCoordinate = x
clipArray[0].yCoordinate = y
I am not even sure if using a plist is the best way to store the buttons in the first place.
Any help or documentation would be much appreciated.
Thanks
Following from dfd response, I added tags to each button which are created and it solved the issue for now.
let x = Int(uIViewSelected.center.x)
let y = Int(uIViewSelected.center.y)
//clipArray.append(clip)
var tagNo = uIViewSelected.tag
clipArray[tagNo].xCoordinate = x
clipArray[tagNo].yCoordinate = y

How to count number of rows in sencha gridview?

I have a Gridview on my page and I'm using buffered store. Is there a way to get the visible number of row count. Thank you
Here is a sample code that you can try: (I hope you'll get some idea from this)
// The below condition has to be checked for each record
// record: record instance
var me = this; // grid scope
Ext.Array.each(me.columns, function (item) { // iterate through each column in the grid
if (item.hidden || !item.dataIndex) { // you can avoid hidden columns and one's that re not bound to the store
return;
}
var cellVal;
try {
cellVal = Ext.fly( me.view.getCell(record, item)).select('cell selector class').elements[0].innerHTML;
} catch (e) {
// handle if you want
}
if (!Ext.isEmpty(cellVal)) {
// this record has been rendered
}
}, this);
This will get you all the records that are rendered. Since you are using a bufferedRenderer, this will also return the records that are rendered but not in the view, you can check and put an offset for the buffer.
Note: I've a similar logic in working in ExtJs 5 but haven't tested in touch.

Resources