I have a Vaadin Table with some Filters and sorts. Is it possible to get the ID of the row over and under the current selected row?
Object currentRow = table.getValue(); //current selected row
Object nextRow = table.nextItemId(currentRow);
Object previousRow = table.prevItemId(currentRow);
Related
This is the simplified version of my data. I want to place a button at the bottom of the grey area, so that upon clicking, a new row is inserted above the bottom. the new row must have the formula as the rows before it.
my real formulas are very complicated so I cant use arrayFormula to fulfill the data in new rows.
this a link to my spreadsheet.
You can refer to this sample code that uses a custom menu to insert new row with formula based on the previous row.
Code:
function onOpen() {
var ui = SpreadsheetApp.getUi();
// Or DocumentApp or FormApp.
ui.createMenu('Custom Menu')
.addItem('Insert New Row', 'insertRow')
.addToUi();
}
function insertRow() {
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
var lastCol = sheet.getLastColumn();
//Exit function if current active sheet is not Sheet1
if(sheet.getName() != "Sheet1"){
return;
}
//insert new row
sheet.insertRowAfter(lastRow);
sheet.getRange(lastRow,2,1,3).copyTo(sheet.getRange(lastRow+1,2));
}
What it does?
Get the last row and the last column that has content in the active sheet using getLastRow() and getLastColumn()
Insert a new row after the last row that has content using insertRowAfter(afterPosition)
Get the range of the last row that has content using getRange(row, column, numRows, numColumns)
Where:
row = your last row that has content
column = column index where you want to start (in the sample sheet it is in column B/ index 2)
numRows = should be 1 (we only want to copy the current last row that has content)
numCols = how many columns to select. In the sample sheet there are 3 columns (column B-D)
Use copyTo(destination) to copy both values and formatting of the range selected in step 3 and paste it in the newly added row. Destination range should be the top-left cell. Since we want to copy it to the new row.I used getRange(last row +1, 2)
Output:
Note:
If you want to use button placed below the grey row, just use insertRow when you assign a script in your button
Please make sure that the last row with content is the row that has formula.
If you want to use the function on a specified list of sheets, you can add this in the sample code. This will exit the function if the current active sheet name is not included in the valid sheets listed
var validSheets = ["Sheet1", "Sheet2"];
if(!validSheets.includes(sheet.getName())){
return;
}
Remove the last comment ... then click on the new menu : this script will add a new line in the active sheet
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('>> Action <<')
.addItem('Copy last row (formulas only)', 'copyLastRow')
.addToUi();
}
function copyLastRow() {
var sh=SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
var rng=sh.getRange(sh.getLastRow(),1,1,sh.getLastColumn())
rng.copyTo(sh.getRange(sh.getLastRow()+1,1,1,sh.getLastColumn()), SpreadsheetApp.CopyPasteType.PASTE_FORMULA, false)
}
How can I get the selected row index in a grid?
Something like
int selectedRowIndex = grid.getSelectedRowIndex();
I already have the following if it can help
Set<Record> selectedRow = (Set<Record>)((SelectionModel) grid.getSelectionModel()).getSelectedItems();
Thank you
I have a list of 100 employees and 50 dropdowns. I want to select some of the employees in the dropdowns but I want to prevent the user from choosing the same employee more than once.
I want to deduct the chosen employees from the possible dropdown answers. How can I manage to do so?
I tried to filter out the selected employees but it shows an ugly warning sign for those who were selected
you can view my spreadsheet here:
https://docs.google.com/spreadsheets/d/1bzMPC3-SDOjsgZVXHQgmfBnkiTEsa1Pei7p_DybIebY/edit?usp=sharing
You can use the Simple Trigger onEdit(e) to automatically do the job:
The onEdit(e) trigger runs automatically when a user changes the value
of any cell in a spreadsheet [...]
It's not exactly the same as you had before, because the selected values will still be displayed on the list. They just will be removed if they are repeated.
The only change you should do is to remove the current Data Validation from Column D and set a new one with values from Column A.
function onEdit(event){
if (event.range.getColumn() == 4){ //Run only if the edited cell is from column D
var sheet = SpreadsheetApp.getActiveSheet();
var selection = sheet.getRange("D2:D22").getValues();
var editedRow = event.range.getRow(); //Gets the edited row
for (var i = 0; i < selection.length; i++){
//If some value from D is equal to the edited value but in a different Row (so it ignores the inputted value)
if ((i + 2) != editedRow && selection[i][0] == event.value){
sheet.getRange(event.range.getA1Notation()).setValue(""); //Change the new value to empty
}
}
}
}
The function will run every time you select an item in the column D.
Result:
References:
Range
Sheet
setValue
The rows in my sheet have a fill color in column A of that particular row. I want to be able to use a macro or maybe for loop to search for these rows with the color identifier, copy and paste them below, return to the row where I was and continue the search until the I've hit the bottom of the original list.
Update -
Basically I want to start with a sheet like this.
Google Sheet before macro
and have the end result look like this
Google sheet post macro
If I understand you correctly, you want to loop through each row in your sheet and copy/paste the ones which have a certain background color in column A after the last row. If that's the case, then you could use something along the following lines using Google Apps Script (you would have to create a script bound to your spreadsheet):
function appendRows() {
var sheet = SpreadsheetApp.getActiveSheet();
var color = "#582323"; // Please change accordingly
var firstRow = 1;
var numRows = sheet.getLastRow() - firstRow + 1;
var column = 1;
var numCols = sheet.getLastColumn() - column + 1;
var range = sheet.getRange(firstRow, column, numRows); // Get column A
var backgrounds = range.getBackgrounds(); // Get backgrounds of each cell in column A
for (var i = 0; i < backgrounds.length; i++) { // Iterate through each cell in column A
if (backgrounds[i][0] == color) { // Check background color
var rowToCopy = sheet.getRange(i + 1, column, 1, numCols); // Row to be copied
var lastRow = sheet.getLastRow(); // Row index to copy to
rowToCopy.copyTo(sheet.getRange(lastRow + 1, column, 1, numCols)); // Copy row to the bottom
}
}
}
Notes:
Please change the background color you want to look for.
Check inline comments for more information on what the script is doing, line by line.
Reference:
getBackgrounds
getRange
copyTo
I hope this is of any help.
I created a multiselectable table in vaadin, but I can't select only a cell in this table when I click it selects all row.
Is there any way of selecting only a cell of a row ?
The title of the question doesn't reflect the actual question inside
Is there any way of selecting only a cell of a row ?
No. The whole point of a Vaadin table is to reflect rows of data in a tabular form. Setting a table to selectable keeps track of the itemIds of the selected rows with the table
You might be able to simulate selecting cells by using a ColumnGenerator in the table, and adding a listener to the generated component. Removing the listener may be tricky, however.
Alternatively, you may wish to simply generate components in a GridLayout and keep track of the selected cells yourself.
Ultimately, the approach here really depends upon exacly what you are trying to achieve.
It depends on what you're trying to accomplish. (Your question title and your question details are addressing two different questions.) If you're wondering whether or not you can target a specific cell and add a click listener to it, then yes, of course you can:
//initial layout setup
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
//Create a table and add a style to allow setting the row height in theme.
final Table table = new Table();
table.addStyleName("components-inside");
//Define the names and data types of columns.
//The "default value" parameter is meaningless here.
table.addContainerProperty("Sum", Label.class, null);
table.addContainerProperty("Is Transferred", CheckBox.class, null);
table.addContainerProperty("Comments", TextField.class, null);
table.addContainerProperty("Details", Button.class, null);
//Add a few items in the table.
for (int i=0; i<100; i++) {
// Create the fields for the current table row
Label sumField = new Label(String.format(
"Sum is <b>$%04.2f</b><br/><i>(VAT incl.)</i>",
new Object[] {new Double(Math.random()*1000)}),
Label.CONTENT_XHTML);
CheckBox transferredField = new CheckBox("is transferred");
//Multiline text field. This required modifying the
//height of the table row.
TextField commentsField = new TextField();
//commentsField.setRows(3);
//The Table item identifier for the row.
Integer itemId = new Integer(i);
//Create a button and handle its click. A Button does not
//know the item it is contained in, so we have to store the
//item ID as user-defined data.
Button detailsField = new Button("show details");
detailsField.setData(itemId);
detailsField.addListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
// Get the item identifier from the user-defined data.
Integer iid = (Integer)event.getButton().getData();
Notification.show("Link " +
iid.intValue() + " clicked.");
}
});
detailsField.addStyleName("link");
//Create the table row.
table.addItem(new Object[] {sumField, transferredField,
commentsField, detailsField},
itemId);
}
//Show just three rows because they are so high.
table.setPageLength(3);
layout.addComponent(table);
It might be beneficial to examine the documentation.