i'm implementing this tenor API into my Site....the thing is that with this function I retrieve a single value single gif...How do I foreach() all of them?
How would need to be the html structure and the javascript loop
JAVASCRIPT/ JSON
function grab_data(anon_id)
{
// set the apikey and limit
var apikey = "*************";
var lmt = 8;
.....
// callback for trending top 10 GIFs
function tenorCallback_trending(responsetext)
{
// parse the json response
var response_objects = JSON.parse(responsetext);
top_10_gifs = response_objects["results"];
// load the GIFs -- for our example we will load the first GIFs preview size (nanogif) and share size (tinygif)
document.getElementById("preview_gif").src = top_10_gifs[1]["media"][0]["nanogif"]["url"];
document.getElementById("share_gif").src = top_10_gifs[6]["media"][0]["tinygif"]["url"];
return;
}
I would have this top_10_gifs variable loaded of content...how do I foreach it?
HTML
<h2 class="title">GIF loaded - preview image</h2>
<div class="container">
<img id="preview_gif" src="" alt="" style="">
</div>
<h2 class="title">GIF loaded - share image</h2>
<div class="container">
<img id="share_gif" src="" alt="" style="">
</div>
Depends on what exactly you're trying to do (which you haven't explained), but something like
response_objects.results.forEach((gifObj, i) => {
if (i >= 8) return;
// do something with each gifObj
document.querySelector('.container')
.appendChild(document.createElement('img'))
.src = gifObj.media[0].tinygif.url;
});
to iterate over all of them.
recently I have been trying to grab HTML form input data, add a prefix, then write that back into a <div> For example:
HTML:
<h1>Please enter Details</h1><hr>
GUID (Generator):<div id="guidInput" style="display:inline;">
<!-- Changed to an onkeyup="" method. Works the same but with less code. -->
<input onkeyup="gen()" id="guidText" style="height: 16px;"></input>
</div>
ID:<div id="idInput" style="display:inline;">
<!-- Changed to an onkeyup="" method. Works the same but with less code. -->
<input type="number" type="number" onkeyup="gen()" id="idText" style="height: 16px;"></input>
</div>
<div id="command" class="command"></div>
JS:
$(document).ready(function(){
var command = ""; /*Here for future developement*/
command += ""; /*Here for future developement*/
document.getElementById('command').innerHTML = command;
});
function gen() {
var id = $('#idText').val();
var guid = $('#guidText').val();
var command = ""; /*Here for future developement*/
var tags = [];
tags.push("GUID "+guid);
tags.push("ID "+id);
command += tags.join("<br>");
command += ""; /*Here for future developement*/
document.getElementById('command').innerHTML = command;
}
This does what I want it to: https://imgur.com/a/QrwD7 But I want the user to download the output as a file. To do this I implemented FileSaver.js, and added this code to my files:
HTML (placed above the <div id="command" class="command"></div>):
<button onclick="saver()">Save</button>
JS:
function saver() {
var text = document.getElementById("command").innerHTML;
var newText = text.replace(/(<([^>]+)>)/ig,"");
var filename = ("File")
var blob = new Blob([text], {type: "text/plain;charset=utf-8"});
saveAs(blob, filename+".txt");
}
That grabs the content of the <div> containing the output, and triggers a download of File.txt. The contents of this file look like this (from imgur.com link above.):
GUID qwertyuiop<br>ID 12345
This is where I'm having my problem. I NEED the file to look like this:
GUID qwertyuiop
ID 12345
With a line break after every part. the <br> is for displaying it on the site, but I need some way to make sure it's on a separate line in the downloaded file, and having no HTML tags in the file.
var newText = text.replace(`<br>`, `\n`).replace(/(<([^>]+)>)/ig,"");
or
function gen(delimiter) {
// ... //
command += tags.join(delimiter);
return command;
}
function saver() {
// ... //
var newText = gen(`\n`);
// ... //
}
Your code is violating SRP: Single Responsibility Principle.
You are trying to do two things at the same time.
Prefixing and formatting in HTML are two different concerns and they should be separated.
After that, the answer will become obvious.
This is the code I am currently working with: I need to display a starting image (preferably green) and then, every time the button is clicked, the image needs to change to trafficlight and then to the other image which it didn't start as. e.g it needs to go from green to orange then red then back to orange etc.
<!DOCTYPE html/>
<html>
<script type="text/javascript">
var trafficlight = [];
trafficlight [0] = " http://4vector.com/i/free-vector-traffic-light-green- clip-art_117820_Traffic_Light_Green_clip_art_medium.png ";
trafficlight [1] = "http://www.clker.com/cliparts/8/1/7/4/11949849782053089133traffic_light_yellow_ dan_01.svg.med.png ";
trafficlight [2] = "http://www.clker.com/cliparts/1/f/a/2/11949849771043985234traffic_light_red_dan_ge_01.svg.med.png ";
var num = 0;
function changepic()
{
if (num>=trafficlight.length-1){
num=0;
}
num=num+1;
document.trafficlight.src=trafficlight[num];
}
</script>
</head>
<body>
<center>
<img src ="http://4vector.com/i/free-vector-traffic-light-green-clip- art_117820_Traffic_Light_Green_clip_art_medium.png" name="trafficlightpic" width="400" height="400" />
<p>click here</p>
</center>
</body>
</html>
As noted by Jonas W - you are trying to referecnce the image but using the wrong reference. You can either do it via an id or using the name as you have. Note that if you are using the name then you need to reference it with a [0] after it as I have in the post - this is because getting the element by name will return an array like object - so you need to specify that its the first item in that. Also your image src for the orange light is broken. The folowing works and allows swapping of the src (with the exception that the yellow light image does not display).
var trafficlight = ["http://4vector.com/i/free-vector-traffic-light-green-clip-art_117820_Traffic_Light_Green_clip_art_medium.png","http://www.clker.com/cliparts/8/1/7/4/11949849782053089133traffic_light_yellow_dan_01.svg.med.png","http://www.clker.com/cliparts/1/f/a/2/11949849771043985234traffic_light_red_dan_ge_01.svg.med.png"];
function changepic()
{
var imageSrc=document.getElementsByName('trafficlightpic')[0].src;
var num =trafficlight.indexOf(imageSrc);
if (num >= trafficlight.length-1){num=-1;}
num+=1;
document.getElementsByName('trafficlightpic')[0].src=trafficlight[num];
}
<center>
<img src ="http://4vector.com/i/free-vector-traffic-light-green-clip- art_117820_Traffic_Light_Green_clip_art_medium.png" name="trafficlightpic" width="400" height="400" />
<p onclick="changepic();">click here</p>
</center>
document.trafficlight doesn't exist. You need:
document.getElementById("trafficlightpic").src=trafficlight[num];
instead. And you should change name="" to id="" in the img element. That should work.
There are several similar questions, so I hope this is a unique problem. None of the proposed solutions on those similar questions have solved my issue. Humble apologies from this beginner if I messed up somehow.
I have an empty div on my page with I am loading using javascript with strings from an array. Currently, I have a script running on a button which reloads the entire page. I would like for that button to just reload the div with items from my javascript array.
Here is my code:
<html>
<head>
<link rel="stylesheet" href="obliqueStyle.css">
<style></style>
</head>
<link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<body>
<div id="wrapper">
<div id="strategyBox"></div>
<div id="button">
<a class="againbutton" onclick="buttonReload()">Again</a>
<script>
var buttonReload = function() {
document.getElementById("strategyBox").innerHTML = '<p id="strategyText">' + randomStrategy + '</p>';
}
</script>
</div>
</div>
<script src="os.js"></script>
</body>
Here is a snippet of my array and the JS (coming from the os.js file referenced in index.html) I am using to load the div initially/on refresh:
var obliqueStrategy = ["Abandon normal instruments",
"Accept advice",
"Accretion",
"A line has two sides"];
var randomStrategy = obliqueStrategy[Math.floor(Math.random() * obliqueStrategy.length)];
document.getElementById("strategyBox").innerHTML = '<p id="strategyText">' + randomStrategy + '</p>';
I've tried calling the same javascript as a function in script in the html like this:
<div id="button">
<a class="againbutton" onclick="buttonReload()">Again</a>
<script>
var buttonReload = function() {
document.getElementById("strategyBox").innerHTML = '<p id="strategyText">' + randomStrategy + '</p>';
}
</script>
</div>
I've tried using the jQuery AJAX load function like this:
<script>
$(function() {
$("#againbutton").on("click", function() {
$("#strategyBox").load("index.html")
return false;
})
})
</script>
I've played around with variations of the above and tried a couple other things that I'm forgetting exactly how and what I did, so I can't include them. I've really hit a wall on this even though it seems profoundly simple.
Thanks in advance for any help.
Here's one method: http://jsfiddle.net/kxqcws07/
HTML
<div id="wrapper">
<div id="strategyBox"><p id="strategyText"></p></div>
<div>
<input type="button" class="againbutton" value="Again">
</div>
</div>
Javascript
//wrapping your logic in a namespace helps reduce the chances of naming collisions of functions and variables between different imported js files
var localNameSpace = function() {
//private array containing our strings to randomly select
var obliqueStrategy = [
"Abandon normal instruments"
, "Accept advice"
, "Accretion"
, "A line has two sides"
];
var api = {
//bindButtonAction binds the generateRandomStrategy function to the click event of the againbutton
bindButtonAction: function() {
$('#wrapper .againbutton').click(api.generateRandomStrategy);
}
, generateRandomStrategy: function() {
//get the position of one of the string randomly
//Math.random() returns a float value < 1 so multiplying it by 100 gets us a range of (0.* - 99.*)
//then we Math.floor() that to get rid of the float value and keep just the integer part
//finally we modulus it with the length of the string array
//if you are unfamiliar with modulus, what it does is gives you the remainder of a division. for instance 10 / 3 gives you 3 with a remainder of 1, so 10 % 3 would be just 1.
//what this does for us is keeps the random offset of our within the bounds of the array length (0 to length -1)
var randomOffset = Math.floor(Math.random() * 100) % obliqueStrategy.length;
//finally once we have the offset, we set the html to the string at the position in the array
$('#wrapper #strategyBox #strategyText').html( obliqueStrategy[randomOffset] );
}
};
return api;
}();
$(document).ready(function() {
//here we call the bind action so the button will work, but we also explicitly call the generateRandomStrategy function so the page will preload with a random string at the start
localNameSpace.bindButtonAction();
localNameSpace.generateRandomStrategy();
});
I'm developing an electronic invoicing system, and one of our features is generating PDFs of the invoices, and mailing them. We have multiple templates for invoices, and will create more later, so we decided to use HTML templates, generate HTML document, and then convert it to PDF. But we're facing a problem with wkhtmltopdf, that as far as I know (I've been Googleing for days to find the solution) we cannot simply both use HTML as header/footer, and show page numbers in them.
In a bug report (or such) ( http://code.google.com/p/wkhtmltopdf/issues/detail?id=140 ) I read that with JavaScript it is achievable this combo. But no other information on how to do it can be found on this page, or elsewhere.
It is, of course not so important to force using JavaScript, if with wkhtmltopdf some CSS magic could work, it would be just as awesome, as any other hackish solutions.
Thanks!
Actually it's much simpler than with the code snippet. You can add the following argument on the command line: --footer-center [page]/[topage].
Like richard mentioned, further variables are in the Footers and Headers section of the documentation.
Among a few other parameters, the page number and total page number are passed to the footer HTML as query params, as outlined in the official docs:
... the [page number] arguments are sent to the header/footer html documents in GET fashion.
Source: http://wkhtmltopdf.org/usage/wkhtmltopdf.txt
So the solution is to retrieve these parameters using a bit of JS and rendering them into the HTML template. Here is a complete working example of a footer HTML:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script>
function substitutePdfVariables() {
function getParameterByName(name) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}
function substitute(name) {
var value = getParameterByName(name);
var elements = document.getElementsByClassName(name);
for (var i = 0; elements && i < elements.length; i++) {
elements[i].textContent = value;
}
}
['frompage', 'topage', 'page', 'webpage', 'section', 'subsection', 'subsubsection']
.forEach(function(param) {
substitute(param);
});
}
</script>
</head>
<body onload="substitutePdfVariables()">
<p>Page <span class="page"></span> of <span class="topage"></span></p>
</body>
</html>
substitutePdfVariables() is called in body onload. We then get each supported variable from the query string and replace the content in all elements with a matching class name.
To show the page number and total pages you can use this javascript snippet in your footer or header code:
var pdfInfo = {};
var x = document.location.search.substring(1).split('&');
for (var i in x) { var z = x[i].split('=',2); pdfInfo[z[0]] = unescape(z[1]); }
function getPdfInfo() {
var page = pdfInfo.page || 1;
var pageCount = pdfInfo.topage || 1;
document.getElementById('pdfkit_page_current').textContent = page;
document.getElementById('pdfkit_page_count').textContent = pageCount;
}
And call getPdfInfo with page onload
Of course pdfkit_page_current and pdfkit_page_count will be the two elements that show the numbers.
Snippet taken from here
From the wkhtmltopdf documentation (http://madalgo.au.dk/~jakobt/wkhtmltoxdoc/wkhtmltopdf-0.9.9-doc.html) under the heading "Footers and Headers" there is a code snippet to achieve page numbering:
<html><head><script>
function subst() {
var vars={};
var x=document.location.search.substring(1).split('&');
for(var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);}
var x=['frompage','topage','page','webpage','section','subsection','subsubsection'];
for(var i in x) {
var y = document.getElementsByClassName(x[i]);
for(var j=0; j<y.length; ++j) y[j].textContent = vars[x[i]];
}
}
</script></head><body style="border:0; margin: 0;" onload="subst()">
<table style="border-bottom: 1px solid black; width: 100%">
<tr>
<td class="section"></td>
<td style="text-align:right">
Page <span class="page"></span> of <span class="topage"></span>
</td>
</tr>
</table>
</body></html>
There are also more available variables which can be substituted other than page numbers for use in Headers/Footers.
Safe approach, even if you are using XHTML (for example, with thymeleaf). The only difference with other's solution is the use of // tags.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<script>
/*<![CDATA[*/
function subst() {
var vars = {};
var query_strings_from_url = document.location.search.substring(1).split('&');
for (var query_string in query_strings_from_url) {
if (query_strings_from_url.hasOwnProperty(query_string)) {
var temp_var = query_strings_from_url[query_string].split('=', 2);
vars[temp_var[0]] = decodeURI(temp_var[1]);
}
}
var css_selector_classes = ['page', 'topage'];
for (var css_class in css_selector_classes) {
if (css_selector_classes.hasOwnProperty(css_class)) {
var element = document.getElementsByClassName(css_selector_classes[css_class]);
for (var j = 0; j < element.length; ++j) {
element[j].textContent = vars[css_selector_classes[css_class]];
}
}
}
}
/*]]>*/
</script>
</head>
<body onload="subst()">
<div class="page-counter">Page <span class="page"></span> of <span class="topage"></span></div>
</body>
Last note: if using thymeleaf, replace <script> with <script th:inline="javascript">.
My example shows how to hide some text on a particular page, for this case it shows the text from page 2 onwards
<span id='pageNumber'>{#pageNum}</span>
<span id='pageNumber2' style="float:right; font-size: 10pt; font-family: 'Myriad ProM', MyriadPro;"><strong>${siniestro.numeroReclamo}</strong></span>
<script>
var elem = document.getElementById('pageNumber');
document.getElementById("pageNumber").style.display = "none";
if (parseInt(elem.innerHTML) <= 1) {
elem.style.display = 'none';
document.getElementById("pageNumber2").style.display = "none";
}
</script>
Right From the wkhtmltopdf Docs
Updated for 0.12.6.
Footers And Headers:
Headers and footers can be added to the
document by the --header-* and --footer* arguments respectively. In
header and footer text string supplied to e.g. --header-left, the
following variables will be substituted.
[page] Replaced by the number of the pages currently being printed
[frompage] Replaced by the number of the first page to be printed
[topage] Replaced by the number of the last page to be printed
[webpage] Replaced by the URL of the page being printed
[section] Replaced by the name of the current section
[subsection] Replaced by the name of the current subsection
[date] Replaced by the current date in system local format
[isodate] Replaced by the current date in ISO 8601 extended format
[time] Replaced by the current time in system local format
[title] Replaced by the title of the of the current page object
[doctitle] Replaced by the title of the output document
[sitepage] Replaced by the number of the page in the current site being converted
[sitepages] Replaced by the number of pages in the current site being converted
As an example specifying --header-right "Page [page] of [topage]", will result in the text "Page x of y" where x is the
number of the current page and y is the number of the last page, to
appear in the upper left corner in the document.
Headers and footers can also be supplied with HTML documents. As an
example one could specify --header-html header.html, and use the
following content in header.html:
<!DOCTYPE html>
<html>
<head><script>
function subst() {
var vars = {};
var query_strings_from_url = document.location.search.substring(1).split('&');
for (var query_string in query_strings_from_url) {
if (query_strings_from_url.hasOwnProperty(query_string)) {
var temp_var = query_strings_from_url[query_string].split('=', 2);
vars[temp_var[0]] = decodeURI(temp_var[1]);
}
}
var css_selector_classes = ['page', 'frompage', 'topage', 'webpage', 'section', 'subsection', 'date', 'isodate', 'time', 'title', 'doctitle', 'sitepage', 'sitepages'];
for (var css_class in css_selector_classes) {
if (css_selector_classes.hasOwnProperty(css_class)) {
var element = document.getElementsByClassName(css_selector_classes[css_class]);
for (var j = 0; j < element.length; ++j) {
element[j].textContent = vars[css_selector_classes[css_class]];
}
}
}
}
</script></head>
<body style="border:0; margin: 0;" onload="subst()">
<table style="border-bottom: 1px solid black; width: 100%">
<tr>
<td class="section"></td>
<td style="text-align:right">
Page <span class="page"></span> of <span class="topage"></span>
</td>
</tr>
</table>
</body>
</html>
ProTip
If you are not using certain information like the webpage, section, subsection, subsubsection, then you should remove them. We are generating fairly large PDFs and were running into a segmentation fault at ~1,000 pages.
After a thorough investigation, it came down to removing those unused variables. No we can generate 7,000+ page PDFs without seeing the Segmentation Fault.
I have not understood the command line en finally I find the solution to put this information directly in the controller without any JS en command line.
In my controller when I call the format.pdf I just put the line footer:
format.pdf do
render :pdf => "show",
page_size: 'A4',
layouts: "pdf.html",
encoding: "UTF-8",
footer: {
right: "[page]/[topage]",
center: "Qmaker",
},
margin: { top:15,
bottom: 15,
left: 10,
right: 10}
end
The way it SHOULD be done (that is, if wkhtmltopdf supported it) would be using proper CSS Paged Media: http://www.w3.org/TR/css3-gcpm/
I'm looking into what it will take now.