JSFiddle - React, Tailwind, and code Playground
HTML
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/2.2.1/knockout-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/mustache.js/0.7.2/mustache.min.js"></script>
<div class="container span12">
<form class="form form-horizontal">
<div class="control-group">
<label class="control-label">Headline</label>
<div class="controls">
<input type="text" data-bind="value: headline, valueUpdate: 'afterkeydown'" />
</div>
</div>
<div class="control-group">
<label class="control-label">Body Content</label>
<div class="controls">
<input type="text" data-bind="value: body, valueUpdate: 'afterkeydown'" />
</div>
</div>
</form>
<div id="wrap">
<iframe id="frame"></iframe>
</div>
</div> <!-- /container -->
CSS
#wrap {
width: 410px;
height: 426px;
padding: 0;
overflow: hidden;
border:1px solid #ccc;
box-shadow: 0px 0px 3px #333;
}
#frame {
-ms-zoom: 0.5;
-ms-transform-origin: 0 0;
-moz-transform: scale(0.5);
-moz-transform-origin: 0px 50px;
-o-transform: scale(0.5);
-o-transform-origin: 0px 50px;
-webkit-transform: scale(0.5);
-webkit-transform-origin: 0 0;
}
#frame{
width: 950px;
height: 1000px;
border: 0;
overflow: hidden;
}
JavaScript
var templateStr = '<!DOCTYPE html>\
<html>\
<head>\
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">\
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">\
<style>\
body {\
padding-top: 60px;\
padding-bottom: 40px;\
}\
</style>\
</head>\
<body>\
<div class="container">\
<div class="row">\
<div class="span3 well">\
<img src="http://placekitten.com/50/50" />\
<ul>\
<li>Hello World</li>\
</ul>\
</div>\
<div class="span8">\
<h1>{{headline}}</h1>\
<p>{{body}}</p>\
</div>\
</div>\
</div>\
</body>\
</html>';
var PreviewViewModel = function () {
var self = this;
self.previewFrame = $('#frame');
self.previewTemplate = templateStr;
self.headline = ko.observable('');
self.body = ko.observable('');
self.toJSON = function () {
var model = {};
model.headline = self.headline();
model.body = self.body();
return model;
};
self.populatePreviewFrame = function (content) {
var doc = self.previewFrame[0].contentWindow.document,
$body = $('body', doc);
$body.html(content);
};
self.renderTemplate = function () {
return Mustache.to_html(self.previewTemplate, self.toJSON());
};
self.headline.subscribe(function () {
self.populatePreviewFrame(self.renderTemplate());
});
self.body.subscribe(function () {
self.populatePreviewFrame(self.renderTemplate());
});
self.initialize = function () {
self.populatePreviewFrame(self.renderTemplate());
};
self.initialize();
};
$(function () {
ko.applyBindings(new PreviewViewModel());
});