Handlebars.js and google spreadsheet show/hide content - javascript

I am trying to get my content brought into handlebars from my google spreadsheets to be in tags that I can show/hide. When you click on the link it shows one panel of content and hides another panel of content. I have the handlebars bringing the content in from the two google spreadsheets but when I add try to do the hide/show panels it does not work. I had the hide/show panels showing up at one time but with no content from the handlebars in it.
here is my fiddle: http://jsfiddle.net/justawebbie/AcW97/17/
Here is the javascript section:
function toggle_visibility(id) {
var e = document.getElementById(id);
if(e.style.display == 'block')
e.style.display = 'none';
else
e.style.display = 'block';
}
// Define spreadsheet URL.
var mySpreadsheet = 'https://docs.google.com/spreadsheet/ccc?key=0AjlSK7_zXoNHdEoyWDYxb3hnZi1xWkl1TVQ0eERBQ2c#gid=0';
var mySpreadsheet2='https://docs.google.com/spreadsheet/ccc?key=0AjlSK7_zXoNHdEpYUEg0VTJ0Rlpzb2RUOVZfLU5oX0E#gid=0'
// Compile the Handlebars template for HR leaders.
var HRTemplate = Handlebars.compile($('#hr-template').html());
var HRTemplate3 = Handlebars.compile($('#hr-template3').html());
// Load top five HR leaders.
$('#hr').sheetrock({
url: mySpreadsheet,
sql: "select A,B,C,N,M,O where B contains 'yes' order by A desc",
headersOff: true,
headers: 2,
rowHandler: HRTemplate
});
$('#hr3').sheetrock({
url: mySpreadsheet2,
sql: "select A,C,D,E order by A desc",
headersOff: true,
headers: 2,
rowHandler: HRTemplate3
});
Here the HTML section:
<ul>
<li>Certificates</li>
<li>Minors</li>
</ul>
<div id="sec1" style="background-color:pink;">
<div id="hr" class="table">
<script id="hr-template" type="text/x-handlebars-template">
<div id='table-row'>
<div id='first-cell'><a href='{{cells.N}}' class='left-link'>{{cells.A}}</a></div>
<div id='second-cell'><a href='{{cells.O}}' class='right-link'>{{cells.M}}</a></div>
</script>
</div>
</div>
<div id="sec2" style="background-color:#eee;">
<div id="hr3" class="table">
<script id="hr-template3" type="text/x-handlebars-template">
<div id='table-row'>
<div id='first-cell'><a href='{{cells.D}}' class='left-link'>{{cells.A}}</a></div>
<div id='second-cell'><a href='{{cells.E}}' class='right-link'>{{cells.C}}</a></div>
</div>
</script>
</div>
</div>

Fiddler appears to be having issues loading the libraries, but it works fine when I build out the page locally. Try this zip file and see if you still have any questions.
http://cris.lc/qtpzm

Related

Random Quote Machine - Cant tweet quote

I have to tweet a quote that I randomly generated using APIs, but my code isn't working. Here is my code, I added comments trying to make it look clearer. I am a novice in coding so it probably has a terrible sintax.
I manage to get my quote by clicking on the "Get another quote" button, but when i want to tweet my quote, clicking on the "Tweet quote" button it wont work and i get the "Uncaught ReferenceError: data is not defined
at pen.js:10" error.
I dont know what i am doing wrong.
(This is a task for FreeCodeCamp). Thanks to everyone who will answer!
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet" type="text/css">
<h2 class="title">Random Quote Generator</h2>
<h4 class="subtitle">A project for the FreeCodeCamp challenge</h4>
<div class="container-box">
<div class="container-quote">
<p class="quote" id ="quote"></p>
<div class="container-author" id="author">
<p></p>
</div> <!--closing div for container author-->
<div class="row">
<div class="col-md-6">
<button id="tweetQuote" href="https://twitter.com/intent/tweet?text=data.quoteText">Tweet this quote!</button>
</div>
<div class="col-md-6">
<button id="newQuote">Get another quote</button>
</div>
</div> <!--row-->
</div> <!--closing div for container quote-->
</div> <!--closing div for container-->
And now the javascript
//setting html elements to variables
var $newQuote = $('#newQuote');
var $quote = $('#quote');
var $tweetQuote = $('#tweetQuote');
//execute function by clicking on button
$newQuote.click(getQuote);
$tweetQuote.click(tweetIt);
var text = data.quoteText;
var author = data.quoteAuthor;
//when getQuote is called call the APIs and get the quote by executing
getQuoteFromAPI
function getQuote() {
$quote.empty();
getQuoteFromAPI();
};
function getQuoteFromAPI() {
var url='https://api.forismatic.com/api/1.0/?
method=getQuote&format=jsonp&lang=en&jsonp=?';
//when the APIs are completely called execute the parseQuote function
$.getJSON(url).done(parseQuote);
//log the datas on the console and transform them into real html elements
function parseQuote (response) {
console.log(response);
document.getElementById('quote').innerHTML = response.quoteText;
document.getElementById('author').innerHTML = response.quoteAuthor;
};
};
function tweetIt() {
var url='https://api.forismatic.com/api/1.0/?
method=getQuote&format=jsonp&lang=en&jsonp=?';
$('#tweetQuote').attr('href', 'https://twitter.com/intent/tweet?text=' + text + '-' + author);
};

Styling a json list

how do i style my json list to material cards?
My json/javascript:
$(document).ready(function(){
var url="getjson.php";
$.getJSON(url,function(data){
console.log(data);
$.each(data.bananas, function(i,post){
var banana =
"<div>"
+"<h3>"+post.name+"</h3>"
+"<h5>"+post.type+"</h5>"
+"</div>";
$(banana).appendTo("#banana-data");
});
now im trying to display it as a nicelt style list of cards but im struggling:
<div class="row">
<div class="col-md-4">
<div id="banana-data" class="box box-widget widget-user">
<div class="widget-user-header bg-aqua-active">
<h3 class="widget-user-username"></h3>
<h5 class="widget-user-desc"></h5>
</div>
</div>
</div>
</div>
But my content appears outside the style of my
I tried using list as follows:
<ol id="banana-data">
<div class="row">
<div class="col-md-4">
<div class="box box-widget widget-user">
<div class="widget-user-header bg-aqua-active">
<h3 class="widget-user-username"></h3>
<h5 class="widget-user-desc"></h5>
</div>
</div>
</div>
</div>
</ol>
var banana =
"<ol>"
+"<h3>"+post.cname+"</h3>"
+"<h5>"+post.sub_type+"</h5>"
+"</ol>";
$(banana).appendTo("#banana-data");
});
The content displayed inside my style,but the entire list of items in the json file was sitting on the same card,and not separating to create multiple styled cards.
this is my php file that converted the data in the msqli table to json:
<?php
require_once 'dbconfig.php';
$posts = array();
$query = "SELECT * FROM bananas";
$stmt = $db_con->prepare($query);
$stmt->execute();
while($row=$stmt->fetch(PDO::FETCH_ASSOC)) {
$posts['bananas'][] = $row;
}
echo json_encode($posts);
?>
I think you have not append it.You have to use after() method like this..
$("#banana-data").after(banana);
So change your script:
$(document).ready(function(){
var url="getjson.php";
$.getJSON(url,function(data){
console.log(data);
banana = "";
$.each(data.bananas, function(i,post){
banana +=
"<div>"
+"<h3>"+post.name+"</h3>"
+"<h5>"+post.type+"</h5>"
+"</div>";
});
$("#banana-data").after(banana);
Very Good Question:
There are multiple libraries you can use for parsing and styling json:
Handlebars is a library that allows you to parse your json with ease and include each json object in your html
The other one is Moustache.But my solution for you is handlebars.
First turn your json into an actual jsonfile as follows...
$json_data = json_encode($posts);
file_put_contents('ldt.json', $json_data);
Add those two lines in your php instead of your echo.ldt is the filename,you can call it whatever you want.
Nextstep:parse the json file using handlebars..
var yourRequest = new XMLHttpRequest();
yourRequest.open('GET', 'ldt.json');
Then in handlebars on create a function and..instruct handlebars to generate html(myhtml) of parsed json and assign it to an id called:eg mycontainer:
var rawTemplate = document.getElementById("thisTemplate").innerHTML;
var myContainer = document.getElementById("my-container");
my.innerHTML = ourGeneratedHTML;
Then in your html:
<div id="my-container"></div>
<script id="thisTemplate" type="text/x-handlebars-template">
//And here call your objects:Example
{{#each bananas}}
<div class="col-md-4">
<div class="box box-widget widget-user">
<div class="widget-user-header bg-black" style="background: url('{{img}}'>) center center;">
<h3 class="widget-user-username"><b>{{name}}</b></h3>
<h5 class="widget-user-desc">({{type}})</h5>
Just make sure your css actually creates your so called cards etc..and your card list will populate your page exactly as you have styled it with all the objects youve parsed.
Ive simply added small snippets of code.For more information,check out:
Handlebars
Theres nothing wrong with just using ajax and create your own elements,but if you want to kill two birds with one stone,use libraries.
There are also alot of tuts on youtube you can watch.I hope this helps

Google Custom Search - don't want trunated title

I am trying to do a simple Google Search where I just get back the titles linked to the pages. I have bought the business search and I have everything working (see code below) - I just want to get the full title of the page, not the truncated title. Can anyone help me?
In my head I have:
<script src="https://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
// Load the Search API
google.load('search', '1');
// Set a callback to load the Custom Search Element when you page loads
google.setOnLoadCallback(
function(){
var customSearchControl = new google.search.CustomSearchControl('011927268382499158334:cuvurabmo-o');
// Use "mysite_" as a unique ID to override the default rendering.
google.search.Csedr.addOverride("mysite_");
// Draw the Custom Search Control in the div named "CSE"
customSearchControl.draw('cse');
},
true);
</script>
In the body I have:
<div style="display:none">
<!-- Return the unescaped result URL.-->
<div id="mysite_webResult" >
<div class="gs-webResult gs-result"
data-vars="{longUrl:function() {
var i = unescapedUrl.indexOf(visibleUrl);
return i < 1 ? visibleUrl : unescapedUrl.substring(i);}}">
<!-- Build the result data structure.-->
<table width="50%" cellpadding="0" cellspacing="0" >
<tr>
<td valign="top">
<!-- Append results within the table cell.-->
<div class="gs-title">
<a class="gs-title" style="color:#990000;font-family:'Times New Roman',serif;font-size:8.0pt;font-decoration:underline;" data-attr="{href:unescapedUrl,target:target}"
data-body="html(title)"></a>
</div>
<!-- Render results.-->
<div data-if="Vars.richSnippet && Vars.richSnippet.action" class="gs-actions"
data-body="render('action',richSnippet,{url:unescapedUrl,target:target})"></div>
</td>
</tr>
</table>
</div>
</div>
<!-- Div container for the searcher.-->
<div id="cse"></div>

TinyMCE not being added to element on AJAX call

I'm having some issues applying TinyMCE onto the textarea element.
I have a page with a list of passengers. When you click a passsenger, AJAX is called and it displays info for the passenger, one field which happens to be a textarea element. My problem is that the first passenger (any passenger) you click on loads TinyMCE, but from here on out, it's just a normal textarea with no TinyMCE applied. I don't know what's happening. Here is the following code I have:
j$ = jQuery.noConflict();
j$(document).ready(function(e) {
tinyMCE.init({
mode : "textareas",
theme : "advanced",
theme_advanced_buttons1 : "bold, italic, underline, | ,bullist, numlist, | ,outdent, indent, | ,link, unlink, |, code",
relative_urls : false,
remove_script_host : false,
});
j$('.names strong').click(function(e) {
//Find passenger ID
var customer_ID = j$(this).closest('.passenger_Container').find("input[name='customer_ID']").val();
//Find placement of returned data
var insert_Data = j$(this).closest('.passenger_Container').find('.package');
j$.ajax({
type: "POST",
url: "/include/passenger_Detail.php",
data: { customer_ID_Data : customer_ID },
success: function(data) {
//get returned data and add into appropriate place
insert_Data.html(data);
var oldEditor = tinyMCE.get('notes');
if (oldEditor != undefined) {
tinymce.remove(oldEditor);
}
tinyMCE.execCommand('mceAddControl', false, 'notes');
//re-initialise WYSIWYG editor. Notes is the ID to re-initialize
/*tinymce.execCommand('mceRemoveControl',true,'notes');
tinymce.execCommand('mceAddControl',true,'notes');*/
}
});
});
});
<!-- content is displayed using PHP while loop -->
<div class="passenger_Container bottom-buffer">
<div class="names row">
<div class="col-xs-1 text-center">
<!-- Display checkbox -->
</div>
<div class="col-xs-4 col-sm-3">
<strong><?php echo $row['f_Name'].' '.$row['l_Name']; ?></strong> </div>
<div class="col-xs-3 hidden-xs">
<!-- display child names -->
</div>
<div class="col-xs-3">
<!-- Display order status -->
</div>
<div class="col-xs-1 col-sm-2">
<!-- Display form -->
</div>
</div>
<div class="package custom-well well-sm top-buffer">
<!-- passenger detail goes here. You will find the code in includes/passenger_Detail.php -->
</div>
</div>
<!-- end PHP while loop -->
I have left the examples I have tried to get TinyMCE to work. I have a sneaky suspicion bad coding practice is the culprit. Each of the textareas have an ID of #notes which I think is the cause. But looking at documentation I don't think tinyMCE lets you use classes to target textareas. Unless I have to loop through all textareas. I'm just spitballing here.
Please inform me if more info is required. Thanks again.
I ended up solving the issue but using a unique ID for each of the textarea elements. So instead of each textarea having the ID "notes", it is now "notes_unique customer_ID".
Following is my answer:
j$.ajax({
type: "POST",
url: "/include/passenger_Detail.php",
data: { customer_ID_Data : customer_ID },
success: function(data) {
//console.log("Returned data: "+data);
//get returned data and add into appropriate place
insert_Data.html(data);
notes = insert_Data.find('textarea').attr('id');
var oldEditor = tinyMCE.get('notes_'+customer_ID);
if (oldEditor != undefined) {
tinymce.remove(oldEditor);
}
tinyMCE.execCommand('mceAddControl', false, 'notes_'+customer_ID);
}
});

Why isn't this XSS attack functioning?

Background
I'm building up a website that lists organisations in my local area. The site is powered by an API and stores it's data in an instance of MongoDB.
I'm fetching JSON from the API and dynamically building the content in Javascript.
Now to test against XSS attacks I deliberately added some code to inject a Javascript alert into my page.
But it's not working? Which obviously I'm happy about but I'm more confused as to why not.
The JSON
{
"_created": "Tue, 11 Mar 2014 19:27:30 GMT",
"_etag": "fd8102613204000414cceff538771453b984a2c6",
"_id": "531f63a246e29300025291ba",
"_updated": "Tue, 11 Mar 2014 19:27:30 GMT",
"description": "<script>alert('hello');</script>",
"tags": [
"Antiques"
],
"title": "HTML Injection",
"url": "www.link.com"
}
the injected code
<script>alert('hello');</script>
The code to retrieve the JSON and render it
function S_GET(id) {
var a = new RegExp(id+'=([^&#=]*)');
return decodeURIComponent(a.exec(window.location.search)[1]);
}
// retrieves languages and adds them to a list
var organisationId = S_GET('organisationId');
var url = 'http://damp-island-8192.herokuapp.com/organisations/' + organisationId;
var dataRequest = new XMLHttpRequest();
dataRequest.open('GET',url, false);
dataRequest.onreadystatechange = processJSON;
dataRequest.send();
function processJSON() {
if ( dataRequest.readyState == 4 && dataRequest.status == 200 ) {
showJSON(dataRequest.responseText);
}
}
function showJSON(input) {
//dom elements
var list = document.createElement('ul');
list.setAttribute('id', 'organisation-details-list');
var organisation = JSON.parse(input);
// list organisation details
// title
var title = document.createElement('li');
title.setAttribute('class', 'organisation-title');
title.innerHTML = organisation.title;
list.appendChild(title);
// description
var desc = document.createElement('li');
desc.setAttribute('class', 'organisation-desc');
desc.innerHTML = organisation.description;
list.appendChild(desc);
// link
var link = document.createElement('li');
link.setAttribute('class', 'organisation-link');
var a = document.createElement('a');
a.setAttribute('href', organisation.url);
a.innerHTML = organisation.url;
link.appendChild(a);
list.appendChild(link);
document.getElementsByClassName('organisation')[0].appendChild(list);
};
The HTML
<!DOCTYPE html>
<head>
<title>Moving To Leicester</title>
<link rel="stylesheet" type="text/css" href="css/styles.css">
</head>
<body>
<div class="container">
<div class="header">
<ul class="nav nav-pills dropdown-menu-right">
<li class="active">Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
<div class="row padding-top-5">
<div class="col-md-2">
<!--Sidebar content-->
</div>
<div class="col-md-10">
<!--Body content-->
<div class="organisation"></div>
</div>
</div>
</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/organisation-details-page.js"></script>
</body>
</html>
Question
Why doesn't the page trigger an alert when I'm viewing it?
To my knowledge inserting executable Javascript via AJAX is somewhat limited.
You cannot just get code via AJAX, put it in a LI's innerHTML an have it executed.
This is what you do:
var organisation=JSON.parse(input);
var title=document.createElement('li');
title.setAttribute('class','organisation-title');
title.innerHTML=organisation.title;
list.appendChild(title);
However, one work-around could be if you change your injection into this:
<iframe src='/' width='1' height='1' onload='window.alert("boo");'></iframe>
I think that would inject itself.

Categories

Resources