One of the problems with the first version was that I couldn't figure out how to update a global variable because in Google Apps Script every time you run a script global variables get initialized to their original states. After some thought I decided to store them client side because I can access the global object on the client whenever I press the save buttons and pass it to the server side. So in this version I am able to store all of the original attributes for all of the cells in all of the tables in a document.
This version utilizes a templated html approach.
Code.gs
function onOpen() {
DocumentApp.getUi().createMenu('Table Menu')
.addItem('Find Table Cells', 'displaySideBar')
.addToUi();
}
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}
function setCellTextStyleBold(cObj) {
var doc=DocumentApp.getActiveDocument();
var body=doc.getBody();
body.getChild(cObj.child).asTable().getRow(cObj.row).getCell(cObj.cell).editAsText().setAttributes(Bold1);
return cObj;
}
function findingTableCells1() {//this is a new version it gets loaded with the JQuery readyState functon
var attObj={};
var d=DocumentApp.getActiveDocument();
var body=d.getBody();
var numChildren=body.getNumChildren();
var html='<table>';
for(var i=0;i<numChildren;i++) {
var child=body.getChild(i);
if(child.getType()==DocumentApp.ElementType.TABLE) {
html+=Utilities.formatString('<span class="childhdr">Child[<a href="#" title="Child Index">%s</a>]:</span><br />',i);
var numRows=child.asTable().getNumRows();
for(var ri=0;ri<numRows;ri++) {
var numCells=child.asTable().getRow(ri).getNumCells();
for(var ci=0;ci<numCells;ci++) {
var cellText=child.asTable().getRow(ri).getCell(ci).editAsText().getText();
attObj['att-' + i + '-' + ri + '-' + ci]=child.asTable().getRow(ri).getCell(ci).editAsText().getAttributes();//collecting all of the attributes here
html+=Utilities.formatString('<span class="tblcell">R:[<a href="#" title="Row Index">%s</a>] C:[<a href="#" title="Cell Index">%s</a>]:<input type="text" value="%s" id="%s-%s-%s" size="10" title="Editable Cell Text"/>',ri,ci,cellText,i,ri,ci);
html+=Utilities.formatString('<input type="button" value="Save" onClick="saveCellText({child:%s,row:%s,cell:%s});" title="Saves Text in original style."/>', i,ri,ci);
html+=Utilities.formatString('<input type="button" value="Bold" onClick="setCellTextStyleBold({child:%s,row:%s,cell:%s});" title="Bolds & Enlarges Text"/></span><br />', i,ri,ci);
}
}
}
}
html+='</table';
return {html:html,attributes:attObj};//returning html and all of the attributes
}
function displaySideBar() {//this launches the new version
var ui=HtmlService.createTemplateFromFile('index').evaluate().setTitle('Finding Table Cells');
DocumentApp.getUi().showSidebar(ui);
}
function saveCellText1(cObj) {//this is the new version
var doc=DocumentApp.getActiveDocument();
var body=doc.getBody();
var key='att-' + cObj.child + '-' + cObj.row + '-' + cObj.cell;
if(!cObj.hasOwnProperty('att')) {
cObj['att']=body.getChild(cObj.child).asTable().getRow(cObj.row).getCell(cObj.cell).editAsText().getAttributes();
}
body.getChild(cObj.child).asTable().getRow(cObj.row).getCell(cObj.cell).editAsText().setText(cObj.text).setAttributes(cObj.att);
return cObj;
}
script1.html
<script>
$(function(){
google.script.run
.withSuccessHandler(function(rObj){
attObj=rObj.attributes;//passing all of the attributes to the clientside global object attObj
$('#main').html(rObj.html);
})
.findingTableCells1();
});
var attObj={};
function saveCellText(cObj) {
var key='att-' + cObj.child + '-' + cObj.row + '-' + cObj.cell;
if(attObj.hasOwnProperty(key)) {
cObj['att']=attObj[key];
}
var id='#' + cObj.child + '-' + cObj.row + '-' + cObj.cell;
$(id).css('background-color','#ffffff');
var txt=$(id).val();
cObj['text']=txt;
google.script.run
.withSuccessHandler(function(cObj) {
var key='att-' + cObj.child + '-' + cObj.row + '-' + cObj.cell;
if(cObj.hasOwnProperty('att') && !attObj.hasOwnProperty(key)) {
attObj[key]=cObj.att;
}
var id1='#' + cObj.child + '-' + cObj.row + '-' + cObj.cell;
$(id1).css('background-color','#ffff00');
})
.saveCellText1(cObj);
}
function setCellTextStyleBold(cObj) {
var id='#' + cObj.child + '-' + cObj.row + '-' + cObj.cell;
$(id).css('background-color','#ffffff');
var txt=$(id).val();
cObj['text']=txt;
google.script.run
.withSuccessHandler(function(cObj) {
var id1='#' + cObj.child + '-' + cObj.row + '-' + cObj.cell;
$(id1).css('background-color','#ffff00');
})
.setCellTextStyleBold(cObj);
}
console.log('My Code');
</script>
res1.html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
css1.html
<style>
body{font-size:14px;font-family:calibri;}
td,th{border:1px solid black;}
.tblcell input[type="text"]{background-color:#ffff00;margin:2px 1px;}
.tblcell input{margin:1px;}
.tblcell a{text-decoration:none;}
.childhdr{background-color:#00ffff;}
.childhdr a{text-decoration:none;}
</style>
index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<?!= include('res1') ?>
<?!= include('css1') ?>
</head>
<body>
<div id="main"></div>
<?!= include('script1') ?>
</body>
</html>