Skip to content

Instantly share code, notes, and snippets.

@walterdavis
Last active August 29, 2015 14:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save walterdavis/5bc16f569929d76993c9 to your computer and use it in GitHub Desktop.
Save walterdavis/5bc16f569929d76993c9 to your computer and use it in GitHub Desktop.
JSONP and Mustache
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="Content-Language" content="en">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" type="text/css" media="screen">
<title>API Test</title>
</head>
<body>
<main class="container">
<div class="row">
<div class="md-col-12">
<h1>Widgets</h1>
<table class="table table-striped">
<thead>
<tr>
<th>
Name
</th>
<th>
Color
</th>
<th>
Description
</th>
</tr>
</thead>
<tbody id="widgets">
<tr id="widget">
<td>
<a href="widget.html?id={{id}}">{{name}}</a>
</td>
<td>
{{color}}
</td>
<td>
{{description}}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</main>
<script type="text/javascript">
// this is simply creating the template for one widget row
var template = document.querySelector('#widget');
template.parentNode.removeChild(template);
// this function does a brain-dead simple form of mustache templating
function mustache(template,data){
var source = template.innerHTML || template;
return source.replace(/\{\{(\w*)\}\}/g,
function(m, key){
return data.hasOwnProperty(key) ? data[key] : "";
});
}
// this is the callback function that the JSONP feature uses
// it takes a single argument, which will automatically be the JSON returned by the script request
function widgets(data){
// the parent element that is getting filled in
var tbody = document.querySelector('#widgets');
// iterate over the returned data
for (var i = 0; i < data.length; i++) {
var d = data[i];
// make a new instance of the template
var t = template.cloneNode(true);
// fill it in with the row of data
t.innerHTML = mustache(t, d);
// make a legal id for the row
t.id += ('_' + d.id);
// add it to the parent
tbody.appendChild(t);
}
}
// this is the special sauce of JSONP: by creating a script tag and appending
// it to the page body, you get around the Same Origin Policy restrictions
// and automatically register and call your callback method.
var script = document.createElement('script');
script.src = 'http://localhost:3000/widgets.json?callback=widgets';
document.body.appendChild(script);
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="Content-Language" content="en">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" type="text/css" media="screen">
<title>{{name}} | API Test</title>
</head>
<body>
<main class="container">
<div class="row">
<div class="md-col-12" id="widget">
<h1>{{name}}</h1>
<p>Color: {{color}}</p>
<p>{{description}}</p>
<p><a href="/api">Back</a></p>
</div>
</div>
</main>
<script type="text/javascript">
// get the querystring value
var id = window.location.search.split('?id=')[1] || 1;
// same as before, capture the template element
var template = document.querySelector('#widget');
template.parentNode.removeChild(template);
// same mustache
function mustache(template,data){
var source = template.innerHTML || template;
return source.replace(/\{\{(\w*)\}\}/g,
function(m, key){
return data.hasOwnProperty(key) ? data[key] : "";
});
}
// the callback also changes the page title
function widget(data){
template.innerHTML = mustache(template, data);
document.title = mustache(document.title, data);
document.querySelector('.row').appendChild(template);
}
// the JSONP invocation
var script = document.createElement('script');
script.src = 'http://localhost:3000/widgets/' + id + '.json?callback=widget';
document.body.appendChild(script);
</script>
</body>
</html>
class WidgetsController < ApplicationController
def index
@widgets = Widget.all
render json: @widgets, callback: params[:callback]
end
def create
@widget = Widget.new
@widget.update_attributes(widget_params)
render json: @widget, callback: params[:callback]
end
def show
@widget = Widget.find params[:id]
render json: @widget, callback: params[:callback]
end
private
def widget_params
params.require(:widget).permit(:name, :color, :description)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment