I am complete beginner in AngularJS. Now I want to create the chains of dialogs using ui.bootstrap $uibModal service. I want to receive the data to the dialogs from the .txt file. That means, I won't know initially the quantity of dialogs in the chain, it will depend on the .txt data. For now I tried to do that with the loop, but it`s dumb and then I won't be able to have such functional as "previous", "next", ok and cancel. Is there any wise solution to do that? Thank you in advance for the answer.
var app = angular.module('myApp', ['ui.bootstrap']);
angular.module('myApp').config(['$uibModalProvider', function($uibModalProvider) {
$uibModalProvider.options.windowClass = 'show';
$uibModalProvider.options.backdropClass = 'show';
}]);
app.factory('modalDialog', function($uibModal) {
var arr_items = [];
var showModalDialog =function(items) {
return $uibModal.open({
templateUrl: 'test.html', //just the dialog body for the info
animation: true,
size: 'sm',
ariaLabelledBy: 'modal-title',
ariaDescribedBy: 'modal-body',
controller: 'dialogCtrl',
controllerAs: "$ctrl",
resolve: { items: function () { console.log("items before travelling" + JSON.stringify(items));
return items; } }
});
}
return {showModalDialog: showModalDialog};
});
app.controller('TestCtrl', function($scope, $http, modalDialog){
$scope.cancelled = false;
$scope.test = function(){
$http.get('test.txt')
.then(function(response) {
$scope.items=response.data;
for (var i=0; i<$scope.items.length; i++) {
console.log($scope.cancelled);
if ($scope.cancelled) return ;
var showModalDialog = function() {
console.log("here");
modalDialog.items = $scope.items[i];
modalDialog.showModalDialog($scope.items[i]);
};
showModalDialog();
};
});
};
});
app.controller('dialogCtrl', function ($scope, $uibModalInstance, items) {
var $ctrl =this;
console.log("here are my items" + items.request + " " + JSON.stringify(items));
$scope.items = items;
$ctrl.ok = function () {
$uibModalInstance.close($scope.items);
};
$ctrl.cancel = function () {
console.log("cancel");
$scope.cancelled = true;
return $uibModalInstance .dismiss('cancel');
};
});
<!doctype html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.js"></script>
<script src="ui-bootstrap-tpls-2.5.0.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="TestCtrl">
<button class="btn btn-primary" ng-click="test()">Test</button>
</div>
<script type="text/ng-template" id="test.html">
<div><div class="modal-header">
<h1 class="modal-title">Test Modal</h1>
</div>
<div class="modal-body">
Test Data:
<div>{{items}}</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="$ctrl.ok()">OK</button>
<button class="btn btn-primary" type="button" ng-click="$ctrl.cancel()">Cancel</button>
</div>
</div>
</script>
<script src="script.js"></script>
</body>
</html>
Here is my test.txt file:
[{
"request": "new user",
"dialogs": [
["input", "checkbox"],
["input", "radiobutton"],
["input", "input"]
]
},
{
"request": "new project",
"dialogs": [
["input", "input"],
["radiobutton", "radiobutton"],
["input", "input"]
]
},
{
"request": "delete project",
"dialogs": [
["checkbox", "checkbox"],
["input", "radiobutton"],
["input", "input"]
]
}
]
Here you go ! Check this plunkr.
The main logic for loop resides in
function initiateModal(itemList,index){
modalDialog.showModalDialog(itemList[index]).result
.then(function(resp){
if(resp === 'cancel'){ // if user cancel the process in between
$scope.userSeletion.length = 0;
return ;
}else if(itemList.length === (index+1)){ // for pushing the last modal data into array
$scope.userSeletion.push(resp);
return ;
}else{
$scope.userSeletion.push(resp);
index++;
initiateModal (itemList,index);
}
})
}
which waits for the promise of earlier modal to open the next one.
For now, I am passing userInput as a data, which i can fill depending on the user form input
Related
Here i am displaying tabs from array using angularjs and bootstrap.
What i want is when i click on particular tab it should display content of that tab only.
i.e(When i click on dynamic-2 i want to display content of dynamic 2 and hide the content of dynamic-1 and dynamic-3 tab)
Right now i am getting content of all tabs on clicking.
js file
var items=[
{
Name:"tab1",
id:1,
content:"FirstTab",
title:"Dynamic-1",
templateUrl:"first.html"
},
{
Name:"tab2",
id:2,
content:"SecondTab",
title:"Dynamic-2",
templateUrl:"second.html"
},
{
Name:"tab3",
id:3,
content:"ThirdTab",
title:"Dynamic-3",
templateUrl:"third.html"
}
];
}]);
html file
<ul class="nav nav-tabs">
<li ng-repeat="l in list" >
<a href="#firsttab" ng-click="tab = 1" data-toggle="tab" >
{{l.title}} </a>
<div class="tab-content" >
<div id="firsttab" ng-click="tab = 1" ng-
show="tab===1">
Id: {{l.id}} <br>
Name: {{l.Name}} <br>
Content: {{l.content}} <br>
TemplateFile: <div ng-include="l.templateUrl"></div>
</div>
</ul>
</div>
</li>
model.js(Just change the code of this file with the code I have written below. It will give you desired result)
We have to provide delay to broadcast to make it work.
define(['jquery','ocLazyLoad','cssinjector'], function() {
var app=angular.module('App', ['angular.css.injector','oc.lazyLoad']);
app.controller('mycontroller', ['$scope','$ocLazyLoad','cssInjector','$rootScope','$timeout',
function($scope,$ocLazyLoad,cssInjector,$rootScope,$timeout) {
alert("modal-loaded");
$ocLazyLoad.load("http://localhost:8080/tabs/js/modal1.js")
.then(function(){
alert("modal1 loaded");
$scope.view="http://localhost:8080/tabs/view.html";
cssInjector.add("http://localhost:8080/tabs/style.css");
});
// ARRAY
var items=[
{
Name:"tab1",
id:1
},
{
Name:"tab2",
id:2
},
{
Name:"tab3",
id:3
}
];
$timeout(function(){
$rootScope.$broadcast('itmObj', items);
},0);
}]);
angular.element(function() {
angular.bootstrap(document, ['App']);
});
});
If you broadcast like this in parent controller
$scope.$broadcast('itmObj',{ itemsArray: items});
Then you can use the on-catch in child controller like
and you eill have the items array in args.itemsArray
$scope.$on('itmObj', function (event, args) {
var x = args.itemsArray; // args.itemsArray is your items from parentcontroller
});
Trying to add a promise on lazyloading the modalController and modal view will look like this
Modal.js
define(['jquery','ocLazyLoad','cssinjector'], function() {
var app=angular.module('App', ['angular.css.injector','oc.lazyLoad']);
app.controller('mycontroller', ['$scope','$ocLazyLoad','cssInjector',
function($scope,$ocLazyLoad,cssInjector) {
alert("modal-loaded");
// ARRAY
var items=[{
Name:"tab1",
id:1
},{
Name:"tab2",
id:2
},{
Name:"tab3",
id:3
}];
var lazyLoadModal1 = function(){
var deferred = $q.defer();
$ocLazyLoad.load("http://localhost:8080/tabs/js/modal1.js")
.then(function(){
alert("modal1 loaded");
$scope.view="http://localhost:8080/tabs/view.html";
cssInjector.add("http://localhost:8080/tabs/style.css");
deferred.resolve();
},function(){
deferred.reject();
});
return deferred.promise;
};
var init = (function(){
lazyLoadModal1().then(function(){
$scope.$broadcast('itmObj', {item:items});
});
})();
}]);
View.html
<div ng-controller="modalcontroller">
<div ng-repeat="vm in itemsArray">
<p>{{vm.Name}}</p>
<p>{{vm.id}}</p>
</div>
</div>
Modal1.js
angular.module('App', ['angular.css.injector','oc.lazyLoad'])
.controller("modalcontroller", ['$scope','$ocLazyLoad','cssInjector',
function($scope,$ocLazyLoad,cssInjector){
alert("In modal Controller");
$scope.$on("broadcast-started", function (event, data){
$scope.itemsArray=data.item;
console.log($scope.itemsArray);
});
}]);
I have such array of objects:
var cars = [
{
"carMake":"Audi",
"models":[
"A4",
"A6",
"R8"
]
},
{
"carMake":"BMW",
"models":[
"3er",
"X3",
"i8",
"7er"
]
},
{
"carMake":"Toyota",
"models":[
"Corolla",
"Auris",
"Yaris",
"Gt86",
"Rav4"
]
}
];
And I have tried below AngularJS code for searching:
$scope.searching = '';
$scope.producers = [];
$scope.models = [];
$scope.searchCar = function() {
$scope.producers = $filter('filter')(cars, function(value) {
return value.carMake === $scope.searching;
});
$scope.models = $filter('filter')(cars, function(value) {
return angular.forEach(value.models, function(model) {
return model === $scope.searching;
});
});
};
Inside HTML I have:
<label>What do you want to find?
<input type="text" ng-model="searching" ng-change="searchCar()" placeholder="Search...">
</label>
<ul>
<li ng-repeat="producer in producers">{{producer}}</li>
</ul>
<ul>
<li ng-repeat="model in models">{{model}}</li>
</ul>
My code doesn't work as I expected - it only outputs whole cars Array element. For example, when I type "Audi" i got whole "Audi object", although I want separately results for car producers and/or car models that match pattern inside <input>.
I want searching to work like, when I type "Au" then I will see "Audi" in first list and "Auris" in the second. So searching should work as well for cars.carMake as for cars.models[] and present result in both lists (first/left for car producers and second/right for car models).
I'd suggest you to store the items in separated arrays, then use the filter in view:
(function() {
angular
.module("app", [])
.controller('MainCtrl', MainCtrl);
MainCtrl.$inject = ['$scope'];
function MainCtrl($scope) {
$scope.sensitiveCompare = sensitiveCompare;
var cars = [
{
"carMake":"Audi",
"models":[
"A4",
"A6",
"R8"
]
},
{
"carMake":"BMW",
"models":[
"3er",
"X3",
"i8",
"7er"
]
},
{
"carMake":"Toyota",
"models":[
"Corolla",
"Auris",
"Yaris",
"Gt86",
"Rav4"
]
}
];
$scope.producers = cars.map(function(car) {
return car.carMake;
});
$scope.models = [];
cars.forEach(function(car) {
$scope.models = $scope.models.concat(car.models);
});
function sensitiveCompare(input, search) {
return ('' + input).indexOf('' + search) > -1;
}
}
})();
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
</head>
<body ng-controller="MainCtrl">
<label>What do you want to find?
<input type="text" ng-model="searching" ng-change="searchCar()" placeholder="Search...">
</label>
<ul>
<li ng-repeat="producer in producers | filter: searching: sensitiveCompare" ng-bind="producer"></li>
</ul>
<ul>
<li ng-repeat="model in models | filter: searching: sensitiveCompare" ng-bind="model"></li>
</ul>
</body>
</html>
EDIT:
If you really want to create your custom function for this, check this:
(function() {
angular
.module("app", [])
.controller('MainCtrl', MainCtrl);
MainCtrl.$inject = ['$scope', '$filter'];
function MainCtrl($scope, $filter) {
$scope.searchCar = searchCar;
var cars = [
{
"carMake":"Audi",
"models":[
"A4",
"A6",
"R8"
]
},
{
"carMake":"BMW",
"models":[
"3er",
"X3",
"i8",
"7er"
]
},
{
"carMake":"Toyota",
"models":[
"Corolla",
"Auris",
"Yaris",
"Gt86",
"Rav4"
]
}
];
$scope.producers = [];
$scope.models = [];
function searchCar() {
$scope.producers = $filter('filter')(cars, function(car) {
return car.carMake.indexOf($scope.searching) !== -1;
});
$filter('filter')(cars, function(car) {
$scope.models = car.models.filter(function(model) {
return model.indexOf($scope.searching) !== -1;
})
});
}
}
})();
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body ng-controller="MainCtrl">
<label>What do you want to find?
<input type="text" ng-model="searching" ng-change="searchCar()" placeholder="Search...">
</label>
<ul>
<li ng-repeat="producer in producers" ng-bind="producer.carMake"></li>
</ul>
<ul>
<li ng-repeat="model in models" ng-bind="model"></li>
</ul>
</body>
</html>
I'm building out a modal that takes 10 lines of input and when clicked to close randomizes them and "should" display out side the modal. Through other research I have found that I must use a service to make everything work right. However this service is not properly changing over my var for changing over true/false for my ng-hide.
Some code below
Main HTML
<body ng-controller="ModalDemoCtrl">
<my-modal-content></my-modal-content>
<button class="btn btn-small"
ng click="open(lg,'ModalInstanceCtrl')">Add</button>
<ul ng-controller="MainCtrl" >
<button class="btn" ng-click="test()">Test</button>
<li ng-hide="toggle" ng-repeat="random in randomTeams">{{random.team}}</li>
</ul>
<script src="js/vendor/angular.js"></script>
<script src="js/vendor/angular-animate.js"></script>
<script src="js/vendor/angular-ui.js"></script>
<script src="app.js"></script>
<script src="js/Modal.js"></script>
<script src="js/setTeams.js"></script>
<script src="js/randomizeTeamservice.js"></script>
</body>
My-modal-content
<div class="modal-header">
<h3 class="modal-title">Set Team Names</h3>
</div>
<div class="modal-body" ng-controller="MainCtrl">
<div class="input-append" ng-repeat="team in teams | limitTo: 10">
<input class="form-control" type="text" ng-model="team.team"
placeholder="Team {{$index + 1}}" value="{{$index}}">
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="ok();
add(this)">OK</button>
<button class="btn btn-warning" type="button" ng-
click="cancel()">Cancel</button>
</div>
</div>
Modal Controller
app.controller('ModalDemoCtrl', function ($scope, $uibModal) {
$scope.animationsEnabled = true;
$scope.open = function (size,controller) {
$uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller: controller ,
size: size,
});
};
});
// Please note that $uibModalInstance represents a modal window (instance)
dependency.
// It is not the same as the $uibModal service used above.
app.controller('ModalInstanceCtrl', function ($scope, $uibModalInstance, randomService) {
$scope.toggle = randomService.showTeams();
$scope.ok = function () {
$uibModalInstance.close({
}
);
$scope.toggle = false;
console.log($scope.toggle);
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
});
Finally the Service
app.factory("randomService", function(){
var teams = [{},{},{},{},{},{},{},{},{},{}];
var randomTeams = teams.slice(0);
var showTeams = true;
return{
randomTeams: function(){
return randomTeams;
},
teams: function(){
return teams;
},
showTeams: function(){
return showTeams;
}
}
});
So why won't the ng-hide work?
Problem solved. Moved some things around but here it is.
Moved the randomize function to the controller and added a getter so a function will retrieve the toggle (true/false) value.
app.controller('MainCtrl', function($scope, randomService) {
$scope.teams = randomService.teams();
$scope.randomTeams = randomService.randomTeams();
$scope.toggle = function(){
return randomService.getTeams();
}
$scope.add = function(team, show) {
for( var i = 0; i < 10; i++){
$scope.teams.splice(i, 1, team.teams[i]);
}
randomService.shuffle($scope.randomTeams);
$scope.toggle();
};
});
In the service factory in addition to adding the shuffle function and a getter function. I added a line of code that will change the showTeams from true to false.
app.factory("randomService", function(){
var teams = [{},{},{},{},{},{},{},{},{},{}];
var randomTeams = teams.slice(0);
var showTeams = true;
return{
randomTeams: function(){
return randomTeams;
},
teams: function(){
return teams;
},
shuffle: function shuffle(array) {
showTeams = false;
var currentIndex = array.length, temporaryValue, randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
},
getTeams: function(){
return showTeams;
},
}
});
lastly ng-hide="toggle: changed to ng-hide="toggle()"
I'm looking for a way to take the hard coded "Character" data in my Angular app and load it from a separate json file.
I have a controller for the ($http) thats worked in other apps, I'm just not sure how to strip, pull and access these character names and properties from a JSON file. Any help would be appreciated.
<body>
<div class="container">
<div ng-app="polarisApp">
<h1>The Other Guys</h1>
<h3>Custom Events in Nested Controllers</h3>
<div ng-controller="Characters">
<div class="lList"> <span ng-repeat="name in names" ng-click="changeName()">{{name}}</span>
</div>
<div class="cInfo">
<div ng-controller="Character">
<label>Name:</label>{{currentName}}
<br>
<label>Job:</label>{{currentInfo.job}}
<br>
<label>Weapon:</label>{{currentInfo.weapon}}
<br> <span ng-click="deleteChar()">Delete</span>
</div>
</div>
</div>
</div>
<script src="http://code.angularjs.org/1.3.0/angular.min.js"></script>
<script src="angular.js"></script>
<script>
angular.module('polarisApp', [])
.controller('Characters', function ($scope) {
$scope.names = ['Alan', 'Terry', 'Gene', 'Sheila', 'Danson', 'Highsmith', 'Bob'];
$scope.currentName = $scope.names[0];
$scope.changeName = function () {
$scope.currentName = this.name;
$scope.$broadcast('CharacterChanged', this.name);
};
$scope.$on('CharacterDeleted', function (event, removeName) {
var i = $scope.names.indexOf(removeName);
$scope.names.splice(i, 1);
$scope.currentName = $scope.names[0];
$scope.$broadcast('CharacterChanged', $scope.currentName);
});
})
.controller('Character', function ($scope) {
$scope.info = {
'Alan': {
weapon: 'Calculator',
job: 'Police Officer'
},
'Terry': {
weapon: 'Gun',
job: 'Police Officer'
},
'Gene': {
weapon: 'None',
job: 'Police Captain'
},
'Sheila': {
weapon: 'None',
job: 'M D'
},
'Danson': {
weapon: 'Gun',
job: 'Police Detective'
},
'Highsmith': {
weapon: 'Gun',
job: 'Police Detective'
},
'Bob': {
weapon: 'None',
job: 'Police Accountant'
}
};
$scope.currentInfo = $scope.info['Alan'];
$scope.$on('CharacterChanged', function (event, newCharacter) {
$scope.currentInfo = $scope.info[newCharacter];
});
$scope.deleteChar = function () {
delete $scope.info[$scope.currentName];
$scope.$emit('CharacterDeleted', $scope.currentName);
};
});
</script>
</body>
This is the ($http) controller I wrote.
angular.module('polarisApp')
.controller('MainCtrl', function ($scope, $http) {
$http.get('character.json')
.success(function(data) {
$scope.characterStatus = data.caracterStatus;
});
You can try this
var info = null;
$http.get('character.json').success(function(data) {
info = data;
});
The response from the $http.get request will be the object contained in content.json file. If you need to access Alan's job, you can use info.Alan.job and so on.
I got it working with this controller:
App.controller('CharacterCtrl', function($scope, $http) {
$http.get('characters.json')
.then(function(res){
$scope.characters = res.data;
}); });
Thank you very much for your feedback. I haven't seen that variable you used in any similar controllers. I think I should look into it--Might be missing out on a better way to $http. Thanks.
So I'm using Handsontable to render a grid. (Yes, I am NOT using the ngHandsontable. I started out with that but ran into problems and so I went with just rendering a Handsontable from an angularjs directive.)
I want one column to hold an anchor tag.
I want the anchor tag to have the angularjs ng-click directive.
Everything renders correctly but the ng-click is not called.
Here is my example.
var APP = angular.module('APP', ['controllers']);
angular.module('controllers',[])
.controller('testController', function ($scope) {
$scope.doNgClick = function() {
alert('ng-click');
// console.log('ng-click');
};
$scope.simple = [
{
test: "<a href='javascript:void(0);' ng-click='doNgClick()'>Test</a>"
// test: "<a ng-click='doNgClick()'>Test</a>"
}
];
});
APP.directive('htable',function($compile) {
var directive = {};
directive.restrict = 'A';
directive.scope = {
data : '='
};
directive.link = function(scope,element,attrs) {
var container = $(element);
// var safeHtmlRenderer = function (instance, td, row, col, prop, value, cellProperties) {
// var escaped = Handsontable.helper.stringify(value);
// td.innerHTML = escaped;
// return td;
// };
var settings = {
data: scope.data,
readOnly: true,
colHeaders: ['Link'],
columns: [
{
data: "test",
renderer: "html",
// renderer: safeHtmlRenderer,
readyOnly: true
}
]
};
var hot = new Handsontable( container[0], settings );
hot.render();
// console.log(element.html());
// $compile(element.contents())(scope);
};//--end of link function
return directive;
});
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="//handsontable.com/dist/handsontable.full.css">
</head>
<body>
<div ng-app="APP">
<div ng-controller="testController">
<div htable data="simple"></div>
</div
</div>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.24/angular.min.js"></script>
<script src="//handsontable.com/dist/handsontable.full.js"></script>
</body>
</html>
After much reading and digging here is my own answer.
//-- With help from the following:
//--
//-- http://stackoverflow.com/questions/18364208/dynamic-binding-of-ng-click
//-- http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-3-isolate-scope-and-function-parameters
//--
var APP = angular.module('APP', ['controllers']);
angular.module('controllers',[])
.controller('testController', function ($scope) {
$scope.click = function(msg) {
console.log('ctrl_doNgClick: ng-click: msg: '+msg);
};
$scope.simple = [
{
test: "<a href='javascript:void(0);' ng-click='dir_ctrl_click(\"blah1,blah1\")'>Test 1</a>"
},
{
test: "<a href='javascript:void(0);' ng-click='doClick(\"blah2,blah2\")'>Test 2</a>"
},
{
test: "<a href='javascript:void(0);' ng-click='doClick(\"blah3,blah3\")'>Test 3</a>"
}
];
});
APP.directive('htable',function($compile) {
var directive = {};
directive.restrict = 'A';
directive.scope = {
data : '=',
click : '&'
};
directive.controller = function($scope) {
$scope.dir_ctrl_click = function( msg ) {
console.log('controller: dir_ctrl_click: click via the directive controller method');
$scope.click()(msg);
};
};
directive.link = function(scope,element,attrs) {
var container = $(element);
scope.doClick = function(msg) {
console.log('link: doClick: click via the directive link method');
scope.click()(msg);
};
var linkHtmlRenderer = function (instance, td, row, col, prop, value, cellProperties) {
//-- here is the magic that works
//-- the method, in ng-click, must either be defined here in the link method or in the controller method (the example data contains both)
var el = angular.element(td);
el.html($compile(value)(scope));
return el;
};
var settings = {
data: scope.data,
readOnly: true,
colHeaders: ['Link'],
columns: [
{
data : "test",
renderer : linkHtmlRenderer,
readyOnly : true
}
]
};
var hot = new Handsontable( container[0], settings );
// hot.render();
};//--end of link function
return directive;
});
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="http://handsontable.com/dist/handsontable.full.css">
</head>
<body>
<div ng-app="APP">
<div ng-controller="testController">
<div htable data="simple" click="click"></div>
</div
</div>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.24/angular.min.js"></script>
<script src="http://handsontable.com/dist/handsontable.full.js"></script>
</body>
</html>