In the following code why does the jquery template not render? I thought that the template was build in? thank you
<script id="friendsTemplate" type="text/html">
<ul>
{{each(index,friend) friends}}
<li>${ friend.name }</li>
{{/each}}
</ul>
</script>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="Scripts/knockout-2.2.1.js"></script>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>details</h1>
<p>first name: <input data-bind="value: firstName" /></p>
<p>last name: <input data-bind="value: lastName" /></p>
<p>full name: <span data-bind ="text: fullName"></span></p>
<h2>friends</h2>
<div data-bind="template: 'friendsTemplate'"></div>
<script id="friendsTemplate" type="text/html">
<ul>
{{each(index,friend) friends}}
<li>${ friend.name }</li>
{{/each}}
</ul>
</script>
</div>
</form>
</body>
</html>
<script type ="text/javascript">
function friend(name) {
return {
name: ko.observable(name)
};
}
var viewModel ={
firstName: ko.observable("bert"),
lastName: ko.observable("smith"),
friends:ko.observableArray([new friend('steve'),new friend('annie')])
};
viewModel.fullName = ko.dependentObservable(function () {
return this.firstName() + " " + this.lastName();
},viewModel);
ko.applyBindings(viewModel);
</script>
The jQuery.tmpl support is built in however you need to reference jQuery and the jQuery.tmpl to make it work as stated in the documentation under: Note 6: Using jQuery.tmpl, an external string-based template engine:
By default, Knockout comes with support for jquery.tmpl. To use it,
you need to reference the following libraries, in this order:
<!-- First jQuery --> <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<!-- Then jQuery.tmpl --> <script src="jquery.tmpl.js"></script>
<!-- Then Knockout --> <script src="knockout-x.y.z.js"></script>
If you reference all the dependencies your code should work fine: Demo JSFiddle
You need to pass a data object to your template.
data-bind="template: { name: 'friendsTemplate', data: $data }"
Look at http://knockoutjs.com/documentation/template-binding.html for details.
Is there a reason why you are using a jQuery Template? The following is more in alignment with "typical" Knockout usage. Also you should only use external templates if there is reuse. This code could easily be inlined.
<script id="friendsTemplate" type="text/html">
<ul data-bind="friends">
<li data-bind="text: name"></li>
</ul>
</script>
Related
Hy everybody, first question here.
I'm learning angularjs and right now i'm stuck on "Controller and Scope" chapter.
I'm trying to search trough an array of objects and show items that match my query; unfortunately my screen stays blank.
Here's my code:
<!DOCTYPE html>
<html ng-app="">
<head>
<title>Search and print with Scope</title>
</head>
<body>
<div ng-controller="Controller">
<input type="search" ng-model="q" placeholder="CPU" />
<ul>
<li ng-repeat="proc in cpu | filter:q">
{{proc.house}} - {{proc.model}}
</li>
</ul>
</div>
<script src="angular.min.js"></script>
<script>
function Controller($scope)
$scope.cpu = [
{ house: 'Intel', model: 'I7' },
{ house: 'AMD', model: 'Ryzen' },
{ house: 'Qualcomm', modello: 'Snapdragon' }
];
</script>
</body>
</html>
What's wrong?
EDIT for EDIT:Just for those who might look at this question, my error was to call ng-app twice, once in the html tag and once in body tag.
EDIT: I'm here again; I modified the code using the given answers, but I still got a search box and a blank screen. I doubt is code related since I also tried to simply copy and paste it in a new file but i got the same result. What could be?
Code is down here:
<!DOCTYPE html>
<html ng-app="">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script>
var app = angular.module('demoApp', [])
app.controller('SimpleController', function($scope) {
$scope.cpu = [{
house: 'Intel',
model: 'I7'
},
{
house: 'AMD',
model: 'Ryzen'
},
{
house: 'Qualcomm',
model: 'Snapdragon'
}
];
});
</script>
<title>Search and print with Scope</title>
</head>
<body ng-app="demoApp">
<div ng-controller="SimpleController">
<input type="search" ng-model="q" placeholder="CPU" />
<ul>
<li>hi</li>
<li ng-repeat="proc in cpu">
{{proc.house}} - {{proc.model}}
</li>
<li>hi again</li>
</ul>
</div>
</body>
</html>
You need to have a angular module and ng-app mentioned as below
DEMO
var app = angular.module('myApp',[])
app.controller('Controller',function($scope){
$scope.cpu = [
{ house: 'Intel', model: 'I7' },
{ house: 'AMD', model: 'Ryzen' },
{ house: 'Qualcomm', modello: 'Snapdragon' }
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html ng-app="myApp">
<head>
<title>Search and print with Scope</title>
</head>
<body>
<div ng-controller="Controller">
<input type="search" ng-model="q" placeholder="CPU" />
<ul>
<li ng-repeat="proc in cpu | filter:q">
{{proc.house}} - {{proc.model}}
</li>
</ul>
</div>
</body>
</html>
First of all you are trying to get the scope data before declaring it, you need to load the script before using ng-repeat, so move the script before the div definition.
Also you are not correctly defining the Controller, it should be defined within an app module, then bind the ng-app and the Controller in your HTML.
<!DOCTYPE html>
<html ng-app="">
<head>
<title>Search and print with Scope</title>
<script src="angular.min.js"></script>
<script>
var app = angular.module('angularApp',[])
app.controller('Controller',function($scope){
$scope.cpu = [
{ house: 'Intel', model: 'I7' },
{ house: 'AMD', model: 'Ryzen' },
{ house: 'Qualcomm', modello: 'Snapdragon' }
];
});
</script>
</head>
<body ng-app="angularApp">
<div ng-controller="Controller">
<input type="search" ng-model="q" placeholder="CPU" />
<ul>
<li ng-repeat="proc in cpu | filter:q">
{{proc.house}} - {{proc.model}}
</li>
</ul>
</div>
</body>
</html>
This is a very beginner level question as I just started to look at knockout js by downloading js,referring it in my web app.
My simple aspx code. based on first tutorial on knockout js site learning page.
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="KnockoutDemo.aspx.cs" Inherits="knockoutjs.KnockoutDemo" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="javascripts/knockout-3.2.0.js" type="text/javascript"></script>
</head>
<body>
<form id="form1" runat="server">
<script type="text/javascript">
function AppViewModel() {
debugger;
this.firstName = "XYZ";
this.lastName = "UU";
}
function callKnockOut() {
debugger;
ko.applyBindings(new AppViewModel());
}
</script>
<div>
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>
<button id="click" onclick="callKnockOut();"></button>
</div>
</form>
</body>
</html>
ideally the values should take effect after I click button.the code runs through successfully.labels won't show anything!
Knockout is client side javascript library, and you are submitting your form to server so instead of that don't run this at server run it to client i.e. dont write runat="server" for form tag. Then this will absolutely work.
function AppViewModel() {
debugger;
this.firstName = "XYZ";
this.lastName = "UU";
}
function callKnockOut() {
debugger;
ko.applyBindings(new AppViewModel());
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<form id="form1" action="#">
<div>
<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>
<button id="click" onclick="callKnockOut();">submit</button>
</div>
</form>
I have a template for a checkbox row -- I set a value when I render the template, but the MVVM checked binding throws an exception. I'm confused as to why this doesn't work as the generated code is pretty much an example given by kendo itself (http://demos.telerik.com/kendo-ui/mvvm/elements)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://cdn.kendostatic.com/2014.2.716/js/kendo.all.min.js"></script>
<script id="fTemplate" type="text/html">
<div>
<input type="checkbox" value="#=data#" data-bind="checked: selectedF"/>
<div style="display: inline-block; margin-left: 5px;">#=data#</div>
</div>
</script>
<script>
var viewModel = window.kendo.observable({
fSource: ["1","2","3"],
selectedF: [],
selectedFText: function(){
return viewModel.get('selectedF').join(',');
}
});
$(document).ready(function() {
window.kendo.bind($('body'), viewModel);
});
</script>
</head>
<body>
<ul data-bind="source: fSource" data-template="fTemplate"></ul>
<br/>
Selected: <div data-bind="text: selectedFText"></div>
</body>
</html>
Live example here: http://dojo.telerik.com/EMIp
The problem is because you try to access a property of a viewModel that your template doesn't know.
Here is an example that is working. I'm pretty sure it will give you enough to help you.
<script id="fTemplate" type="text/html">
<div>
<input type="checkbox" value="#=data.value#" data-bind="checked: isSelected"/>
<div style="display: inline-block; margin-left: 5px;">#=data.value#</div>
</div>
</script>
<script>
var viewModel = window.kendo.observable({
fSource: [
{
value:"1",
isSelected: false
},
{
value:"2",
isSelected: false
},
{
value:"3",
isSelected: false
}],
selectedF: [],
selectedFText: function(){
}
});
$(document).ready(function() {
window.kendo.bind($('body'), viewModel);
});
</script>
Html:
<body>
<ul data-bind="source: fSource" data-template="fTemplate"></ul>
<br/>
Selected: <div data-bind="text: fSource[0].isSelected"></div>
</body>
your fiddle:
http://dojo.telerik.com/EMIp/5
I am having issue with the Partials/Sub Template generation in the Handlebars.js.
I have used the registerPartials Method properly, but still it is giving some sort of issue in rendering. If I remove the partial template it would render the content properly.
Below is the code that I am using:
<!DOCTYPE html>
<html>
<head>
<title>Handlebars.js example</title>
</head>
<body>
<div id="placeholder">This will get replaced by handlebars.js</div>
<script type="text/javascript" src="handlebars.js"></script>
<script id="myTemplate" type="x-handlebars-template">
{{#each allShoes}}
<li>
<span> {{name}} - </span> price: {{price}}
{{> description}}
</li>
{{/each}}
</script>
<script id="shoe-description" type="x-handlebars-template">
<ul>
<li>{{color}}</li>
<li>{{size}}</li>
</ul>
</script>
<script type="text/javascript">
var source = document.getElementById("myTemplate").innerHTML;
var template = Handlebars.compile(source);
// Register the Partial
//Handlebars.registerPartial("description", $("#shoe-description").html());
var shoesData = {
allShoes:[
{name:"Nike", price:199.00,color:"black", size:10},
{name:"Loafers", price:59.00, color:"blue", size:9},
{name:"Wing Tip", price:259.00, color:"brown", size:11}
]
};
Handlebars.registerPartial("description", $("#shoe-description").html());
document.getElementById("placeholder").innerHTML = template(shoesData);
</script>
</body>
</html>
Is there any issue with the registerPartial?
Any help is appreciated.
Thanks,
Ankit Tanna
I'd guess that your rendering issues are a side effect of asking the browser to render invalid HTML. Your HTML ends up with, more or less, this structure:
<div>
<li>
<ul>...</ul>
</li>
...
</div>
But an <li> must have a <ul>, <ol>, or <menu> as its parent. I quote the specification:
Permitted parent elements
ul, ol, menu
So having a <div> as the parent of an <li> is invalid and the browser may rewrite your not-quite-HTML to make it valid HTML. That correction could be making a mess of your inner lists. Fix your HTML and try again:
<script id="myTemplate" type="x-handlebars-template">
<ul>
{{#each allShoes}}
...
{{/each}}
</ul>
</script>
Demo: http://jsfiddle.net/ambiguous/R23Ak/
I tried to look at documentation but it seems i am missing something. I am trying to inject html which is bound to a json. It works fine if the html is declared but when i inject it despite calling the $compile it is not working. Here is the code
<!DOCTYPE html>
<html ng-app>
<head>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"> </script>
<script src="todo.js"></script>
<script>
function TodoCtrl($scope)
{
$scope.todos = [{text:'LearnAngularJS'}, {text:'Unlearn Angular'},];
}
$(document).ready(function()
{
$('#div1').html(
$compile('<div ng-controller="TodoCtrl"><ul><li ng-repeat="todo in todos" compile="text">{{todo.text}}<li><ul><div>')(scope));
});
</script>
</head>
<body>
<div ng-controller="TodoCtrl">
<ul>
<li ng-repeat="todo in todos">
{{todo.text}}
<li>
<ul>
</div>
<div id="div1">
<div>
</body>
</html>
http://plnkr.co/edit/NQQBgQKBWEqKHxGwnI0h?p=preview
As Ajay pointed out, you'll have to associate one of your scope with template.