Hiding Rows using Google Apps Script - javascript

I'm looking to create almost a drop-down feature in Google Sheets. I was hoping to have arrows set that could potentially collapse rows when clicked.
It would be amazing if I could get it so each main "title" row has an arrow, that would cause the rows to either hide/unhide.
Since only the titles would be written in column A, I was thinking it might be possibly for a script to recognize the blank cells in between two filled ones?
So far I only have this, which is basically useless:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
// Hides the first three rows
sheet.hideRows(1, 3);
In a perfect world, the spreadsheet would look something like this, with the functionality to collapse the rows with the click of the arrow.
https://docs.google.com/spreadsheets/d/1-oGawFoPXjdHvadxXsSFxuZWWdOxN9ZgbvS10jelWZY/edit?usp=sharing
Not sure if this is possible, but if there is any hope/ideas I'd love to hear them.

function onEdit(e) {
const sh=e.range.getSheet();
const shts=['Sheet13'];
if(shts.indexOf(sh.getName())!=-1 && e.range.columnStart==1 && e.value=="TRUE") {
e.range.setValue("FALSE");
sh.hideRows(Number(e.range.rowStart));
e.source.toast('Row ' + e.range.rowStart + ' has been hidden.');
}
}
Animation:

Instead, have you considered using the group row facility? You can just group and ungroup the rows to show/hide them.
Just select all the rows that you want to group,
right click select Group rows.
I have added the same in the spreadsheet that you have shared.

Related

How to temporarily change color of active cell using Apps Script

So this is an interesting one...in most simple terms - I have a script that jumps me to a specific cell (based on matches in both the column and row - script below for context):
function Jump(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("In-Office"); // change to sheet containing dates
var r = s.getRange("ah1").getValue(); //change A1 to cell containing =match formula
var row = s.getRange("ai1").getValue();
s.setActiveSelection(s.getRange( r + row ));
}
I have this running from a custom menu, where the user can jump to the cell that contains today's date.
I can use conditional formatting to highlight that cell, but there's been an idea I've wanted to execute in other projects and it feels now would be the time to try it out.
Basically, when the cell jumps, I want the COLOR to change for 10 seconds, then reset itself.
I've tried doing this with macros, but the color change is instant, so you never see it.
I tried implementing a "wait period" similar to how you would while showing a TOAST alert, but wasn't able to figure it out.
My other thought is.. setting up a conditional formatting rule through the script, delaying it for 10 seconds, then deleting it. Seems like a lot to just color the activated cell for a specific amount of seconds.
Anyone ever try something like this before? Essentially, I want to flash a different color for the active cell - I think it could be applicable to many other projects as well.
Here's one way to handle that:
const targetCell = 'B12'; // I'm being lazy here, but hoping you get the idea
const range = s.setActiveSelection(targetCell);
const bgColor = range.getBackground();
range.setBackground('red');
SpreadsheetApp.flush();
Utilities.sleep(10000);
range.setBackground(bgColor);
SpreadsheetApp.flush();

Color cell according to condition

I have a table in which I have to set background color when the cell in header and cell in row appear as pair in a certain list in data source.
For example:
column : "AUD, USD"
row : "BRL, CZK"
in the cell of column AUD and row is BRL I check if exists in the list in datasource "AUD-BRL" and if so I need to color in a green
Now, I thought to do it in this way:
columns and rows will be in lists.
I go over both lists and then color in those indexes the cell.
So that I will have one function for whole table and not have to call from each cell to function (There are 1200 cells overall).
How can that be done?
The answer from Fede MG is correct.
If I understand your question correctly, you want to add a highlighting rule to all cells in the table detail row. Unfortunately I think it is a bit cumbersome to achieve this in BIRT.
I assume that your table has e.g. bindings like COL_VALUE_1, ..., COL_VALUE_9 for the cell values and COL_TITLE_1, ..., COL_TITLE_9 for the column headers.
Furthermore I assume a bit of experience with using Javascript in BIRT.
The way I do this like this:
For each detail cell I create a onCreate event script with code like this:
highlightDetailCell(this, row, 1);
... where 1 is the column number. E.g. this is the code for the first column, for the second column i replace the 1 with 2 and so on. One can quickly do this with copy&paste.
Next I implement the logic in a function inside the onInitialize script of the report like this:
function highlightDetailCell(item, row, colnum) {
var colTitle = row["COL_TITLE_" + colnum];
var colValue = row["COL_VALUE_" + colnum];
var highlight = use_your_logic_to_decide(colTitle, colValue);
if (highlight) {
item.get_Style().backgroundColor = "yellow";
}
}
This is the basic idea. If you want to add the script to many cells, it might be a lot of work to do this by hand. In fact it is possible to attach the call to the highlightDetailCell function with a script (of course, this is BIRT :-). You should read the documentation and just tinker with the Design Engine API (DE API for short).
But be warned that writing and debugging such a script may be even more work than doing the donkey work of adding and editing a one-liner to 1200 cells!
What I once did was basically this (in the onFactory event of the report item):
// This code is a simplified version that modifies just the first cell,
// However it should point you into the right direction.
// Some preparation
importPackage(Packages.org.eclipse.birt.report.model.api);
var myconfig = reportContext.getReportRunnable().getReportEngine().getConfig();
var de = DataEngine.newDataEngine( myconfig, null );
var elementFactory = reportContext.getDesignHandle().getElementFactory();
// Find the item you want to modify (in my case, a "Grid Item").
// Note that for tables, the structure is probably a bit different.
// E.G. tables have header, detail and footer rows,
// while grids just have rows.
var containerGrid = reportContext.getDesignHandle().findElement("Layout MATRIX");
// Get the first row
var row0 = containerGrid.getRows().get(0);
// Do something with the first cell (:
var cell = row0.getCells().get(0).getContent();
cell.setStringProperty("paddingTop", "1pt");
cell.setStringProperty("paddingLeft", "1pt");
cell.setStringProperty("paddingRight", "1pt");
cell.setStringProperty("paddingBottom", "1pt");
cell.setStringProperty("borderBottomColor", "#000000");
cell.setStringProperty("borderBottomStyle", "solid");
cell.setStringProperty("borderBottomWidth", "thin");
cell.setStringProperty("borderTopColor", "#000000");
cell.setStringProperty("borderTopStyle", "solid");
cell.setStringProperty("borderTopWidth", "thin");
cell.setStringProperty("borderLeftColor", "#000000");
cell.setStringProperty("borderLeftStyle", "solid");
cell.setStringProperty("borderLeftWidth", "thin");
cell.setStringProperty("borderRightColor", "#000000");
cell.setStringProperty("borderRightStyle", "solid");
cell.setStringProperty("borderRightWidth", "thin");
// When you're finished:
de.shutdown( );
Things are more complicated if you have to handle merged cells.
You could even add content to the cell (I created a whole matrix dynamically this way).
The script does not exactly what you want (add the script to each cell), but I leave this as an exercise...
It is also helpful to save the dynamically modified report design for opening in the designer, to see the outcome:
reportContext.getDesignHandle().saveAs("c:/temp/modified_report.rptdesign");
HTH
Go to the cell you want to format (applies also to elements like rows or columns), on the "Property Editor" go to "Highlights" and click "Add...". You'll get a dialog where you can enter a condition for the highlight and what styling to apply on the element if the condition is true.
Screenshot here

Google Sheets: Replace cell contents with another cell contents when "Clicked"?

Google Sheets: Replace cell contents with another cell contents when "Clicked" ?
I'm trying to create an easy way to reveal more data from a row when any cell is clicked from the row it lives in. Currently, I have a nice =VLOOKUP("*") ... function that allows me to type in a COMPANY name into a "search bar" cell, and then VLOOKUP will display cell contents depending on which COMPANY it is.
You can see it in action here:
Google Sheets Demo
How To Use:
Green Cells: Type in the "Search Bar" cell for a company name...
Orange Cells: If "COMPANY" is found, it displays the companies cell contents to the left.
What I want to do:
Click on a cell in any row
Have that cell realize what row it's in and navigate to the COMPANY column.
Copy the cells contents from the COMPANY column and replace the current contents of the "search bar" cell
VLOOKUP will then handle the rest.
Possible?
Is this possible with Google Sheet functions alone? Or is this something that should be handled with a script? How would I got about it?
There is currently no way to create an onClick function. The closest thing we have is an onEdit() function. I can think of two ways to make this sort of work.
1) This onEdit version works only if you don't mind locking your script down. You could write an IF statement to create a way to stop this from running temporarily while you edit it.
2) You could setup a second sheet and have the values imported from there or backed up there, and then just run this on the first one at all times.
function onEdit(e) {
//This sets up the worksheet variables
var worksheet = SpreadsheetApp.getActive();
var sheet = worksheet.getActiveSheet();
//This saves the original value e
var origValue = e.oldValue
//This figures out where you clicked, and gets the K+rowyouclicked value.
var selection = sheet.getActiveCell().getA1Notation();
var splitselection = selection.match(/([A-Za-z]+)([0-9]+)/);
var CompName = sheet.getRange("K" + splitselection[2]).getValue();
//set the value on the search bar and return the original value to where you changed.
sheet.getRange("C3").setValue(CompName);
sheet.getActiveCell().setValue(origValue)
}

Manipulating a Form's data in Google Sheets

I'm using Google Drive/Sheets to host my personal film ratings list, and I thought it'd be a lot easier than this.
I've set up a form which asks about the film and what rating I give it (out of 4 categories), and then it puts this into a sheet. The data is inputting fine, but I want the sheet to automatically find out the average of my 4 individual ratings, and then add an overall rating to that row of data.
What I can work out...
What I would like...
I'm assuming it requires some kind of trigger from the form submission which then performs some javascript and inputs a new piece of data in the appropriate column and row, but I just want work it out. Any help appreciated.
Navigate in top menu to Tools->Script editor in Summary spreadsheet
Place this code inside
function setAvarage() {
var summaryCloumn = 10 //row J
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
sheet.getRange(lastRow, summaryCloumn).setFormula("SUM(E"+lastRow+":H"+lastRow+")/4");
};
Now setup the trigger in very same script editor Materials->Triggers (first option - unfortunately I do not have docs in english so name can be slightly different..)
Choose add trigger
"setAvarage", "From table", "on change"
just tested and worked...

JS/JQUERY: Moving numbered table rows up and down without losing user input

I have created a table in HTML, consisting of table rows in a tbody tag.
I've used a javascript code snippet from mredkj.com to be able to add rows and delete them, too. The rows are sorted and their rank is in the first TD (cell) in every TR (row).
Now I would like the add the functionality of being able to manually 'resort' the tablerows.
The problems are:
my javascript/jquery knowledge is
very limited
the ranks of tablerows
do not get updated(when you delete a row, the
rowranks get updated by the
'reorderRows function, but calling this function from within my jQuery does not seem to
sort out the problem)
the user's input in textarea's gets erased as soon as up or down button is clicked.
For example: user adds a TR, that gets added at the bottom of the current list of tablerows, fills in the textarea and desides that the row (s)he filled should be ranked first, so she clicks the up arrow a couple of times, until it's on top.
The rank of the row is now #1 and the input is still in the textarea's.
My questions are:
Does anyone know how I can make the
rows update their ranking when the
user moves the row?
How do I maintain the user's input?
Any help is very much appreciated and if you have any other suggestions, please share them.
Code here: http://jsbin.com/eyefu5/edit - for some reason, the moving up and down doesn't work in js bin, it does however when I run it in my browser.
I updated your code to do what I think you were trying to do: http://jsbin.com/eyefu5/9/
My primary changes were to the following swap logic:
function swap(a, b){
b.before(a);
reorderRows(document.getElementById(TABLE_NAME), 0);
}
function getParent(cell){ return $(cell).parent('tr'); }
$('#diagnosetabel').on('click', '.upArrow', function(){
var parent = getParent(this);
var prev = parent.prev('tr');
if(prev.length == 1){ swap(parent, prev); }
});
$('#diagnosetabel').on('click', '.downArrow', function(){
var parent = getParent(this);
var next = parent.next('tr');
if(next.length == 1){ swap(next, parent); }
});
The biggest difference is that I switched the swap code to using jQuery's before method, which should take care of just about everything for you. I also added a call to the reorderRows method which you were already using. At the moment it starts at the beginning and reorders all the numbers after the swap, but you could narrow this down as needed because you know the only two rows which were modified.
Hope that helps!

Categories