Better MV-ish Framework
From simple user interfaces to complex single-page applications using faster, server-side rendered and easy to learn framework
Learn more DownloadFrom simple user interfaces to complex single-page applications using faster, server-side rendered and easy to learn framework
Learn more DownloadWrite code queries in your HTML. No need to learn a new syntax
Keep your model and view always in sync by using observables
Use built-in utility library for advanced & faster data manipulations
jsblocks is fast but we will not stop here. We have ideas how to make it even faster.
Download all performance test cases from here.
<!DOCTYPE html>
<html>
<head>
<script src="http://jsblocks.com/jsblocks/blocks.js"></script>
<script>
blocks.query({
firstName: blocks.observable('John'),
lastName: blocks.observable('Doe')
});
</script>
</head>
<body>
First Name: <input data-query="val(firstName)">
Last Name: <input data-query="val(lastName)">
<h2>Hello {{firstName}} {{lastName}}!</h2>
</body>
</html>
This example shows how easy it is to implement CSS3 Transitions.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<script src="http://jsblocks.com/jsblocks/blocks.js"></script>
<script src="script.js"></script>
</head>
<body>
<input data-query="val(filterVal)" placeholder="Search for a block name">
<div class="result-box" data-query="each(items.view)">
<div class="tile" data-query="css('top', Math.floor($index() / 4) * 91).css('left', ($index() % 4) * 91)">
<span class="fa fa-{{icon}}"></span>
<h4>{{title}}</h4>
</div>
</div>
</body>
</html>
var items = [
{ icon: 'cubes', title: 'blocks' },
{ icon: 'exchange', title: 'bindings' },
{ icon: 'line-chart', title: 'speed' },
{ icon: 'database', title: 'data' },
{ icon: 'wrench', title: 'debugging' },
{ icon: 'server', title: 'architecture' },
{ icon: 'cube', title: 'modular'},
{ icon: 'cogs', title: 'extensible' },
{ icon: 'crosshairs', title: 'consistent' },
{ icon: 'lightbulb-o', title: 'innovative' },
{ icon: 'terminal', title: 'clean' },
{ icon: 'plug', title: 'feature rich' }
];
var filterVal = blocks.observable();
blocks.query({
filter: filterVal,
items: blocks.observable(items).extend('filter', function (value) {
return !filterVal() || value.title.indexOf(filterVal().toLowerCase()) != -1;
})
});
/* CSS Transitions */
/* The built-in classes shown below allow for easy CSS transitions */
.tile.b-hide-end {
opacity: 0;
}
.tile.b-show {
opacity: 0;
}
.tile.b-show-end {
opacity: 1;
}
/* Other styles */
input { font-size: 16px; padding: 12px 16px; margin-bottom: 40px;
width: 326px; background: #ddf4e8; border: 1px solid #54b07e;}
.result-box { position: relative; text-align: center; }
.tile { position: absolute; width: 86px; background-color: #3ebee3;
height: 86px; color: #fff; transition: 1s linear all; }
.tile .fa { margin-top: 20px; font-size: 24px; }
.tile h4 { font-size: 14px; margin: 15px 0; }
This example is built using the MVC architecture that jsblocks offers. This powerful module lets you build complex applications. However, if you don't need this functionality you could always remove it to reduce file size.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="http://jsblocks.com/jsblocks/blocks.js"></script>
<script src="script.js"></script>
</head>
<body>
<div id="products" data-query="view(Products)">
<input data-query="val(newProduct.name).keydown(keydown)" placeholder="Add new value and press enter">
<div data-query="each(products)">
<div class="result-wrap">
<span data-query="visible(!editing())" class="value-holder">
{{name}}
</span>
<span data-query="visible(editing)" class="value-holder">
<input data-query="val(name)">
</span>
<span class="buttons-holder">
<span data-query="click(toggleEdit)">
{{editing() ? 'Update' : 'Edit'}}
</span>
<span data-query="click(remove)" class="btn-delete">Delete</span>
</span>
</div>
</div>
</div>
</body>
</html>
var App = blocks.Application();
var Product = App.Model({
name: App.Property(),
editing: blocks.observable(false),
toggleEdit: function () {
this.editing(!this.editing());
},
remove: function () {
this.destroy(true);
}
});
var Products = App.Collection(Product);
App.View('Products', {
newProduct: Product(),
products: Products([{ name: 'HTML' }, { name: 'CSS' }, { name: 'JavaScript' }]),
keydown: function (e) {
if (e.which == 13) {
this.products.add(this.newProduct);
this.newProduct.reset();
}
}
});
#products > input {
font-size: 16px;
padding: 12px 16px;
width: 326px;
background: #ddf4e8;
border: 1px solid #54b07e;
}
.result-wrap {
margin-top: 10px;
border: 1px solid #dcdcdc;
background: #fbfbfb;
width: 360px;
}
.result-wrap .buttons-holder {
display: table-cell;
}
.buttons-holder > span {
cursor: pointer;
margin-left: 10px;
color: #2d8dc4;
}
.buttons-holder .btn-delete {
color: #e65f5f;
}
.result-wrap .value-holder {
display: table-cell;
border-right: 1px solid #dcdcdc;
width: 220px;
padding: 10px;
}