Google Apps Script - Move Cursor onclick - javascript

I would like to implement a Table of Contents in the sidebar of a Google Docs document which will take you to the appropriate sections when clicked. I am generating the HTML for the sidebar element by element, and I see that there is a moveCursor(position) function in Document class, but I can't see how to actually call it using onclick. Not the full code but shows the problem:
function generateHtml() {
var html = HtmlService.createHtmlOutput('<html><body>');
var document = DocumentApp.getActiveDocument();
var body = document.getBody();
//Iterate each document element
var totalElements = body.getNumChildren();
for(var i = 0; i < totalElements; ++i) {
var element = body.getChild(i);
if(element.getType() == DocumentApp.ElementType.PARAGRAPH) {
var text = paragraph.getText();
if(text.trim()) { //Not blank paragraph
var position = document.newPosition(element, 0);
/**Would like to have <a onclick=document.moveCursor(position)> here**/
//Show first 20 chars as preview in table of contents
html.append('Detected paragraph ')
.append(text.substring(0, 20))
.append('<br />');
}
}
}
html.append('</body></html>');
return html;
}
How can I accomplish this in Apps Script? The code can be completely restructured as needed.

This line:
/**Would like to have <a onclick=document.moveCursor(position)> here**/
Change to:
<div onmouseup="myClientFunction()">Text Here</div>
Add a <script> tag to your HTML:
<script>
var valueToSend = code to get value;
window.myClientFunction = function() {
google.script.run
.myGsFunctionToMoveCursor(valueToSend);
};
</script>
Then you need a myGsFunctionToMoveCursor() function in a script file (.gs extension)
function myGsFunctionToMoveCursor(valueReceived) {
//To Do - Write code to move cursor in Google Doc
. . . Code to move cursor
};

Related

Javascript pulling content from commented html

Bit of a JS newbie, I have a tracking script that reads the meta data of the page and places the right scripts on that page using this:
var element = document.querySelector('meta[name="tracking-title"]');
var content = element && element.getAttribute("content");
console.log(content)
This obviously posts the correct tag to console so I can make sure it's working .. and it does in a test situation. However, on the actual website the meta data i'm targeting is produced on the page by a Java application and beyond my control, the problem is it is in a commented out area. This script cannot read within a commented out area. ie
<!-- your tracking meta is here
<meta name="tracking-title" content="this-is-the-first-page">
Tracking finished -->
Any ideas appreciated.
You can use this code:
var html = document.querySelector('html');
var content;
function traverse(node) {
if (node.nodeType == 8) { // comment
var text = node.textContent.replace(/<!--|-->/g, '');
var frag = document.createDocumentFragment();
var div = document.createElement('div');
frag.appendChild(div);
div.innerHTML = text;
var element = div.querySelector('meta[name="tracking-title"]');
if (element) {
content = element.getAttribute("content");
}
}
var children = node.childNodes;
if (children.length) {
for (var i = 0; i < children.length; i++) {
traverse(children[i]);
}
}
}
traverse(html);
One way is to use a NodeIterator and get comment nodes. Quick example below. You will still need to parse the returned value for the data you want but I am sure you can extend this here to do what you want.
Fiddle: http://jsfiddle.net/AtheistP3ace/gfu791c5/
var commentedOutHTml = [];
var iterator = document.createNodeIterator(document.body, NodeFilter.SHOW_COMMENT, NodeFilter.FILTER_ACCEPT, false);
var currentNode;
while (currentNode = iterator.nextNode()) {
commentedOutHTml.push(currentNode.nodeValue);
}
alert(commentedOutHTml.toString());
You can try this. This will require you to use jQuery however.
$(function() {
$("*").contents().filter(function(){
return this.nodeType == 8;
}).each(function(i, e){
alert(e.nodeValue);
});
});

How to dynamically create list of <a> tags using js

I am creating html page which needs to create a list of links dynamically on a click of button. I know how to create this list when number of links to be created is known before like this:
//For 4 tags:
var mydiv = document.getElementById("myDiv");
var aTag = document.createElement('a');
aTag.innerHTML = "link1 text";
aTag.setAttribute('onclick',"func()");
mydiv.appendChild(aTag);
var bTag = document.createElement('b');
bTag.innerHTML = "link2 text";
bTag.setAttribute('onclick',"func()");
mydiv.appendChild(bTag);
var cTag = document.createElement('c');
cTag.innerHTML = "link3 text";
cTag.setAttribute('onclick',"func()");
mydiv.appendChild(cTag);
var dTag = document.createElement('d');
dTag.setAttribute('onclick',"func()");
dTag.innerHTML = "link4 text";
mydiv.appendChild(dTag);
But the problem is that the count will be known at run time and also on function call i need to identify the id of link that invoked function.. Can anybody help?
I don't know weather you receive or not the HTML to be shown in the anchor, but anyway, this should do the work:
function createAnchor(id, somethingElse) {
var anchor = document.createElement('a');
anchor.innerHTML = "link" + id + " text";
anchor.setAttribute("onclick", "func()");
return anchor;
}
Then you call the function like this:
function main(num_anchors) {
var mydiv = document.getElementById("myDiv");
for (var i = 0; i < num_anchors; i += 1) {
mydiv.appendChild(createAnchor(i));
}
}
Of course this code can be improved, but this is just for show how can this be possible.
Yes it is possible to do this at runtime .
JQuery provides very useful dom manipulation . So you can traverse the dom , filter what you need ..
you can find a lot of useful functions here .
http://api.jquery.com/category/traversing/
It would look something like this.
$( document ).ready(function() {
$( "a" ).each(function( index ) {
// enter code here..
}
});
document.ready gets invoked once the DOM has loaded.

How can I link to an anchor tag that doesn't exist until the Javascript has created it?

I have a page that has a set of <div> elements, and each one has an anchor tag associated with it. It looks something like this:
<a name="anchor-0"></a>
<div id="div0">Some stuff</div>
<a name="anchor-1"></a>
<div id="div1">More stuff</div>
<a name="anchor-2"></a>
<div id="div2">Yet more stuff</div>
The problem is that this set of <div> and <a> tags are generated by Javascript, and so they don't exist until after the page has been created. When I create a link like this:
http://www.mywebsite.com/mypage.html#anchor-2
... it loads the page but does not jump to the anchor-2 position, which is only created some time after the browser has had time to execute the Javascript that generated it.
How can I get the browser to move to the selected anchor tag position once the Javascript has generated them?
Here is essentially what the Javascript that is generating the HTML looks like:
function init() {
gapi.client.setApiKey('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
gapi.client.load('blogger', 'v2', function() {
var request = gapi.client.blogger.posts.list({
'blogId': 'xxxxxxxxxxxxxxxxxxxxxxxx',
'fields': 'items(content,title)'
});
request.execute(function(response) {
var main = document.getElementById("main");
var anchor = 0;
for (var i = 0; i < response.items.length; i++)
{
var Div = document.createElement("div")
$(Div).append(response.items[i].title);
$(main).append(Div);
anchor = document.createElement("a");
anchor.name = "anchor-" + anchor;
anchor = anchor +1;
}
});
});
}
after creation of element, you could do:
location.hash = "#anchor-2";
or using scrollIntoView
element = document.getElementById('your_element-id');
element.scrollIntoView();
get the hash value from url, by doing something like::
var hashVal = window.location.hash.substr(1);
//then jump to that hash
location.hash = "#" + hashVal;

Google news box within div

I'm trying to place a google news search within a div on my site. I'm currently using the script google provides, but am a novice at Ajax/JavaScript. I am able to display the most recent stories from google news, but don't know how to have it display within a div let alone manipulate the style with CSS. Below is the code I'm using. Any help would be greatly appreciated!
<script type="text/javascript">
google.load('search', '1');
var newsSearch;
function searchComplete() {
// Check that we got results
document.getElementById('averagecontainer').innerHTML = '';
if (newsSearch.results && newsSearch.results.length > 0) {
for (var i = 0; i < newsSearch.results.length; i++) {
// Create HTML elements for search results
var p = document.createElement('p');
var a = document.createElement('a');
a.href = newsSearch.results[i].url;
a.innerHTML = newsSearch.results[i].title;
// Append search results to the HTML nodes
p.appendChild(a);
document.body.appendChild(p);
}
}
}
function onLoad() {
// Create a News Search instance.
newsSearch = new google.search.NewsSearch();
// Set searchComplete as the callback function when a search is
// complete. The newsSearch object will have results in it.
newsSearch.setSearchCompleteCallback(this, searchComplete, null);
// Specify search quer(ies)
newsSearch.execute('Barack Obama');
// Include the required Google branding
google.search.Search.getBranding('branding');
}
// Set a callback to call your code when the page loads
google.setOnLoadCallback(onLoad);
</script>
If I understand correctly, this is what you need:
Create the <div> and give it an ID:
<div id="your-div">HERE BE NEWS</div>
Then modify the searchComplete funcion like this:
function searchComplete() {
var container = document.getElementById('your-div');
container.innerHTML = '';
if (newsSearch.results && newsSearch.results.length > 0) {
for (var i = 0; i < newsSearch.results.length; i++) {
// Create HTML elements for search results
var p = document.createElement('p');
var a = document.createElement('a');
a.href = newsSearch.results[i].url;
a.innerHTML = newsSearch.results[i].title;
// Append search results to the HTML nodes
p.appendChild(a);
container.appendChild(p);
}
}
}
As for style manipulation, you can match the elements by the given ID in css. For example like this:
#your-div a {
font-weight: bold;
}
EDIT:
To show you that this is working, I have created a jsfiddle: http://jsfiddle.net/enjkG/
There is not a lot of things you can mess up here. I think you may have a syntactic error and did not check the console for errors.

JS - print only <div> from another file

Now I'm using onClick="window.print(); return false;"...
But I need to print a div content form another file.
Example:
I have the file buttons.html, but in this file is my print button with window.print().
I need when this button is pressed to print only div content (e.g. div id=...), but from the file index.html.
I hope you understand me.
*Please give more detailed code, I'm new.
Thanks!
function printDivs()
{
var divs = document.getElementsByTagName("div");
var text = "";
for( var i=0; i<divs.length; i++ )
{
var div = divs[i];
if (typeof(div.nodeName) !== "undefined")
{
text = text + div.innerHTML + "<br /><br />";
}
}
document.body.innerHTML = text;
window.print();
}
That should work, as long if its executed on the same page. Is this what you mean or do you mean something else?
You can call this script by using: Print for example.
That's unusual, but certainly possible:
// buttons.html, Using jQuery
$('button').click(function() {
$.get('index.html', function(h) {
$('body').html($('div#content', h).html());
window.print();
}, "html");
});

Categories

Resources