Using a sidebar, I get user input and save it as a script property. Next time the sidebar is loaded, I'd like to check if the saved property exists. If so, display it instead of the text entry box.
I know to use:
google.script.run.withSuccessHandler().myFunction()
Honestly, I have tried so many different things at this point. Any help would be greatly appreciated.
This is what I have tried, I want to load values in the sidebar if they exist. If they do not I want it load a text entry box, that is what it does by default.
Edit - Adding Code
function loadSidebarValues() {
if (dateText != 'ErrorStuff') {
var div = document.getElementById('dateValue');
div.innerHTML = dateText;
var errorDiv = document.getElementById('error');
errorDiv.innerHTML = "";
$('#dateText').val(
PropertiesService.getScriptProperties().getProperty('dateColumn')
);
} else {
var div = document.getElementById('sidebarValues');
div.innerHTML = "";
var errorDiv = document.getElementById('error');
errorDiv.innerHTML = 'There was an error.';
}
var scriptProperties = PropertiesService.getScriptProperties();
scriptProperties.setProperties({
'dateColumn': 'dateText',
});
Logger.log("date: " + userProperties.getProperty('dateColumn'));
}
function onLoad(){
if (PropertiesService.getScriptProperties().getProperty('dateColumn') != null) {
loadSidebarValues();
};
}
You can write server code to retrieve UserProperties value, then run the HTML script to get that value as instructed in File-open dialogs
section in this guide
What they do:
getOAuthToken in Code.gs
Call that function in Picker.html by this code:
function getOAuthToken() {
google.script.run.withSuccessHandler(createPicker)
.withFailureHandler(showError).getOAuthToken();
}
createPicker method from withSuccessHandler take token value from getOAuthToken in first step.
You can use the same pattern for your own case.
Related
I'm trying to retrieve values set in chrome storage. The original value was stored using a different script in the same extension.
The value stored was stored using:
chrome.storage.sync.set({
logoStore: logolink})
Then I am using below to retrieve the storage value and replace the image url. No doubt the entirely incorrect method, syntax and all. :(
chrome.storage.local.get('logoStore', function (result) {
alert(logoStore.result);
});
var logourl = logoStore.result;
// ======= SWAP IMAGES ==========
var images = document.getElementsByTagName ("img");
var x=0;
while(x<images.length)
{
if(images[x].src == "https://www.this-url.com/images/new-brand-2016/common/logo-2016-246x48-v1.gif")
{
images[x].src = 'logourl';
}
x=x+1;
}
I'm very new to js, and have searched extensively on SO and elsewhere for the correct method to use the stored values. Sorry for such a noob question.
On an upnote - I did manage to resolve my last question with help and some further efforts myself :) Thanks.
========= UPDATE =========
I got this part working thanks to your input :)
Working code for this is...
chrome.storage.sync.get(['logoStore'], function(result) {
console.log('Value currently is ' + result.key);
var logourl = result.logoStore;
// ======= SWAP IMAGES ==========
var images = document.getElementsByTagName ("img");
var x=0;
while(x<images.length)
{
if(images[x].src == "https://www.url.com/images/new/common/logo-246x48-v1.gif")
{
images[x].src = logourl;
}
x=x+1;
}
});
Next Step...
Now I have to get two more values from storage and insert them into existing HTML.
I can successfully get the first value to load, but it is breaking my inline style, and the second value is not loading.
Code below.
// ========== ADD HEADER TEXT ==============
chrome.storage.sync.get(['companyStore', 'dataStore'], function(result) {
console.log('Value currently is ' + result.key);
var company = result.companyStore;
var data = result.dataStore;
var el = document.querySelector('table.delivery-address');
// get element content as string
console.log(el.innerHTML)
// prepend to the element's content
el.innerHTML = '</table><div style="margin-right:0px;float:right;text-align:right;margin-top:20px;"><h2 style="font-size: 28px;">Info</h2><br/><p style="font-size:18px;line-height:1.4em;"><b>' + company; + '</b><br/>' + data; + '<b></p></div><br/><br/><table class="delivery-address">' + el.innerHTML;
});
I'm writing a javascript program that gets the input in any of the below forms.
"Here is the result \"google\", and \"yahoo\""
or
"Here is a plain result"
and this is stored in a variable say X. and I want to create an anchor tag when ever I come across an anchor tag. I know that a href will by default create an anchor tag but in my case the result is rendered as a text, here is my code that I've tried so far.
var newLink = document.createElement('a');
newLink.href = 'http://google.com';
newLink.innerHTML = 'My anchor';
if (message) {
var x = message;
console.log(x.includes("href"));
if (!x.includes("href")) {
responsePara.appendChild(document.createTextNode(message));
responsePara.appendChild(document.createElement('br'));
} else {
//responsePara.appendChild(document.createTextNode(message));
responsePara.appendChild(newLink);
responsePara.appendChild(document.createElement('br'));
}
}
the output that I'm expecting is in case 1
<p> Here is the result "google", and "yahoo"</p>
in case 2
<p>Here is a plain result</p>
please let me know on how can I do this.
Note I'm using only js, no jquery
I can't see your problem, it should be really easy to implement this, right?
All you need to parse is the input that is coming to HTML. within another element (in your case p element)
UPDATE
I have updated this question, so you can modify (or create if there is not ref) an existing element with not parsed a element or with plain text.
function createOrUpdateCompositeLink(input, ref) {
if (ref) {
var isLinkText = input.match(/href/g);
var elementChild;
if (isLinkText) {
elementChild = document.createElement('span');
elementChild.innerHTML = input;
} else {
elementChild = document.createTextNode(input);
}
ref.appendChild(elementChild);
return ref;
} else {
var element = document.createElement('p');
element.innerHTML = input;
return element;
}
}
/* USAGE */
var message;
var element;
message = "Here is the result ";
message1 = "google\"";
message2 = " something plain text ";
message3 = ", and \"yahoo\"";
var reference = document.querySelector('.ref');
var el;
createOrUpdateCompositeLink(message, reference);
createOrUpdateCompositeLink(message1, reference);
createOrUpdateCompositeLink(message2, reference);
createOrUpdateCompositeLink(message3, reference);
<div class="ref"></div>
I would suggest you consider using jQuery and what you are trying to do becomes:
jQuery(".response").append(message);
I assume that your responsePara variable is defined from an existing <div> somewhere. In my example, that <div> would have a class named response.
<div class="response"></div>
Once you get a message, it gets added to the response div but that one line jQuery() command.
I'm trying to modify someone's code that displays an alert if values don't match. Here's the code below:
if (finalData.length>0) {
$scope.rowCollection = finalData;
$scope.displayedCollection = [].concat($scope.rowCollection);
}
// $scope.rowCollection = $scope.rowCollection2;
else {
//$scope.rowCollection.push(finalData);
//alert('values are not matching Belinda');
}
$scope.showTable = true;
I'm trying to remove the alert and display 0 results found below a form on the document. Not sure if this even makes sense but would appreciate any help and would be able to answer any questions to get to the right direction.
TIA!
Atlante
you can assign a variable in the html which will be set in the else part
in the html, where you want to display the message:
<span>{{$scope.resultsMsg}}</span>
and in your js
if (finalData.length>0) {
$scope.rowCollection = finalData;
$scope.displayedCollection = [].concat($scope.rowCollection);
}
// $scope.rowCollection = $scope.rowCollection2;
else {
//$scope.rowCollection.push(finalData);
//alert('values are not matching Belinda');
$scope.resultsMsg = "0 results found.";
}
$scope.showTable = true;
2-way variable binding takes care of the rest in angularjs
PLEASE READ QUESTION BEFORE READING CODE!!!
I've added a checkbox element on Dialog definition of the table dialog (it works). Now I want the checkbox to be checked by default when the table being edited has a certain class (which is usually visible on the advanced tab). According to the documentation, I should be able to do something like this in my setup function. I've tried many things and you could hopefully help me. This is my code.
CKEDITOR.on( 'dialogDefinition', function( evt )
{
var dialog = evt.data;
if(dialog.name == 'table' || dialog.name=='tableProperties')
{
// Get dialog definition.
var def = evt.data.definition;
var infoTab = def.getContents( 'info' );
infoTab.add(
{
type: 'checkbox',
id: 'myCheckBox',
label: 'Table Has Property',
setup: function()
{
//Class to look for if I successfully get the input's value
var classValueToLookFor = 'has-property';
// The current CKEditor Dialog Instance
var thisDialog = CKEDITOR.dialog.getCurrent();
// The Element whose value I want to get
var classElement = theDialog.getContentElement('advanced','advCSSClasses');
// Trying to Get Value of this class Element According to documentation
var containedClasses = theDialog.getValueOf('advanced','advCSSClasses');
// Trying to debug the value above
console.log(containedClasses); // This shows nothing
// Trying to debug InitValue which shows something according to prototype
console.log(classElement.getInitValue()); //This also shows nothing
//Checking if Element has the class I'm looking for to mark the checkbox
if(containedClasses.indexOf(classValueToLookFor) != -1)
{
//Check current checkbox since value has been found
this.setValue('checked');
}
}
onClick: function() // You can ignore this function, just put it in case you were wondering how I'm putting the has-property, might help someone else (works well) ;)
{
var checked = this.getValue();
var classValueToSet = 'has-property';
var thisDialog = CKEDITOR.dialog.getCurrent();
var containedClasses = theDialog.getValueOf('advanced','advCSSClasses');
if(checked)
{
if(containedClasses.indexOf(classValueToSet) != -1)
{
//console.log('already contains class: '+classValueToSet);
}
else
{
containedClasses += containedClasses+" "+classValueToSet;
}
}
else
{
if(containedClasses.indexOf(classValueToSet) != -1)
{
containedClasses = containedClasses.replace(classValueToSet,'');
}
else
{
//console.log('already removed class: '+classValueToSet);
}
}
thisDialog.setValueOf('advanced','advCSSClasses',containedClasses);
}
}
}
Here are some debug statements that can be helpful to add into the setup function and understand what is going on, you shouldn't need to go through all I've went through ;)
console.log('in setup function');
console.log(classElement);
console.log(classElement._);
console.log(classElement.getInitValue());
console.log(classElement.getInputElement());
var inputElement = classElement.getInputElement();
var inputElementId = inputElement.getId();
console.log($('#'+inputElementId+'.cke_dialog_ui_input_text'));
console.log(classElement.getInputElement().value);
It would be nice to test your answer before suggesting. Many of the things I've tried should work in theory, but are practically not working.
Alright, so finally after a few days of trial and error, this is what finally worked for me. Maybe it could be helpful to someone. I'm sure there should be a much cleaner way to do this. All the best to everyone.
setup: function()
{
//This current checkbox
var checkbox = this;
//the class I want to find on my table
var var classValueToLookFor = 'has-property';
//Current Dialog instance
var thisDialog = CKEDITOR.dialog.getCurrent();
//This code below gets a <td> element in the table
var startElement = thisDialog.getParentEditor().getSelection().getStartElement();
// This gets me the parent of the <td> element which is my current table instance
var parentTable = $(startElement.$.offsetParent);
//Finally check if the table has the property I'm looking for.
if(parentTable.hasClass(classValueToLookFor))
{
//Mark the checkbox
checkbox.setValue('checked');
}
}
I am trying to write a Google Apps Script for Documents that will insert some text, and then add inserted text to a named ranged. To make sure that the inserted text is saved to a named range, I just want to select the inserted text.
Here's the code:
function insertText() {
var doc = DocumentApp.getActiveDocument();
var docUi = DocumentApp.getUi();
var cursor = doc.getCursor();
if (cursor) {
var insert = cursor.insertText('{insertedtext}');
var rangeBuilder = doc.newRange();
if (insert) {
rangeBuilder.addElement(insert);
} else {
docUi.alert('Cannot insert text here.');
}
} else {
docUi.alert('Cannot find a cursor.');
}
var savedInsert = rangeBuilder.build()
doc.addNamedRange('myInsertedText', savedInsert)
doc.setSelection(doc.getNamedRangeById('myInsertedText').getRange());
}
When I run the script, doc.setSelection(doc.getNamedRangeById('myInsertedText').getRange()); generates the following error:
TypeError: Cannot call method "getRange" of null.
Any idea of what I am doing wrong?
'myInsertedText' is actually the namedRange's name, not the id:
var namedRange = doc.addNamedRange('myInsertedText', savedInsert);
var namedRangeId = namedRange.getId();
doc.setSelection(doc.getNamedRangeById(namedRangeId).getRange());