Mustache not rendering JSON data - javascript

So, I have just started with Mustache JS. I have this simple html file
<!DOCTYPE html>
<html lang="en">
<head>
<title>JavaScript Mustache template</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.3.0/mustache.min.js"></script>
</head>
<body>
<script id="mp_template" type="text/template">
<p>Country: {{ name }}</p>
<p>Capital: {{ capital }}</p>
<p>Flag: <img src={{{ flag }}} ></p>
</script>
<div id="mypanel"></div>
<button id="btn">Load</button>
<script>
$(function () {
$("#btn").on('click', function () {
$.getJSON('https://restcountries.eu/rest/v2/name/aruba?fullText=true', function (data) {
var template = $("#mp_template").html();
var text = Mustache.render(template, data);
console.log(data);
$("#mypanel").html(text);
});
});
});
</script>
Its getting some data back via the .getJSON call and then trying to render that data on button click. No data is rendering. Can someone please advise what am I doing wrong ?
Please see this URL to see the structure of returned data https://restcountries.eu/rest/v2/name/aruba?fullText=true

That API returns a JSON array, not an object, that's why it isn't working.
If you only want the first item, you can do:
var template = $("#mp_template").html();
var text = Mustache.render(template, data[0]);
console.log(data);
$("#mypanel").html(text);
Or you can iterate through all the countries, by passing the array in an object property: { countries: data } and use {{#countries}} in your template
$(function () {
$("#btn").on('click', function () {
$.getJSON('https://restcountries.eu/rest/v2/name/aruba?fullText=true', function (data) {
var template = $("#mp_template").html();
var text = Mustache.render(template, { countries: data });
$("#mypanel").html(text);
});
});
});
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.3.0/mustache.min.js"></script>
</head>
<body>
<script id="mp_template" type="text/template">
{{#countries}}
<p>Country: {{ name }}</p>
<p>Capital: {{ capital }}</p>
<p>Flag: <img src={{{ flag }}} style="width: 50px"></p>
{{/countries}}
</script>
<div id="mypanel"></div>
<button id="btn">Load</button>
</body>

Related

How do I get the id present in the link using jQuery?

I am calling data from a movie API using jquery and it has an endpoint where I can call a particular show with an id. The home page displays the movies and clicking them should call another endpoint of the API. Below is my code:
$(function (){
let $movies = $('#showList')
$.ajax({
method:'GET',
url:'http://api.tvmaze.com/shows',
success: function(movies){
$('#show').hide()
$('#showList').removeAttr('hidden');
$.each(movies, function(i,movie){
$movies.append('<li class="list"><a id="ss" href="'+ movie._links.self.href+'">'+ movie.name +'</a></li>')
})
}
})
})
$('body').on('click','.list a',function(event){
event.preventDefault();
$('#showList').hide();
$('#show').empty()
let currentId = event.target.id;
console.log(currentId)
$.ajax({
method:'GET',
url:'http://api.tvmaze.com/shows/'+currentId,
success: function(movies){
$('#show').append('<h1>'+ movies.name +'</h1>')
}
})
$('#show').show();
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TV Shows</title>
</head>
<body>
<h1>TV Shows</h1>
<div id="show" hidden></div>
<ul id="showList" hidden></ul>
<form id="searchForm">
<input type="text" id="search_term">
<label for="text">Search</label>
<button>Submit</button>
</form>
<a id="homelink" href="/" hidden>Back to All Shows</a>
<footer>Swayam Shah, 10471353</footer>
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
crossorigin="anonymous"></script>
<script src="/public/js/index.js"></script>
</body>
</html>
How do I get this id when I click on the movies link? The console.log shows empty.
you haven't mentioned id attribute in your anchor tag.
$movies.append('<li class="list">'+ movie.name +'</li>')
Had to replace URL with only currentID
Using "this" works for me.
$("a").click(function() {
console.log($(this).attr("id"));
});

The rest Api returns data but it is not showing up on the page

I am trying to fetch data from the rest api that I made. The api returns data but the angular fails to load it. I could see the data being passed from the network tab in developer tools.
HTML code:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<link href="Content/bootstrap.css" rel="stylesheet" />
<script src="Scripts/angular.js"></script>
<script src="Scripts/angular-resource.js"></script>
</head>
<body ng-app="productsApp">
<div ng-controller="productsController">
<table>
<tr ng-repeat="p in products">
<td>{{p.productName}}</td>
<td>{{p.productCode}}</td>
<td>{{p.releaseDate | date}}</td>
<td>{{p.price | currency}}</td>
</tr>
</table>
</div>
<script src="Scripts/App.js"></script>
<script src="Scripts/http.js"></script>
<script src="Scripts/service.js"></script>
</body>
</html>
Service.js
(function () {
angular.module("productService", ["ngResource"]).
factory("product", function ($resource) {
return $resource('http://localhost:55755/api/products/:id');
});
}());
App.js
var app = angular.module("productsApp", ["productService"]);
app.controller("productsController", function ($scope, product) {
$scope.products = product.query();
});
While query() returns a promise you can do it like this. Just inject a callback function which is executed in the promised part automatically.
product.query(function (products) {
$scope.products = products;
});
>> fiddle demo

Substring helper in handlebars

Can i write a helper in Handlebars that can tell if a string is a substring of another string?
I wrote the following code, but it doesn't seem to be working
This is the helper:
'if_sub': function(a, b, opts) {
if (a.includes(b))
return opts.fn(this);
else
return opts.inverse(this);
}
And this is the implementation:
{{#if_sub colvalues "success"}}
<td class="log-success"> {{colvalues}} </td>
{{/if_sub}}
just little mistake . if (a.includes(b)) should be if (b.includes(a))
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>How to render html with Handlebars.js</title>
<script src="https://cdn.jsdelivr.net/handlebarsjs/4.0.3/handlebars.min.js"></script>
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script id="simple-template" type="text/x-handlebars-template">
{{#if_sub colvalues "success"}}
<td class="log-success"> {{colvalues}} </td>
{{/if_sub}}
</script>
<script type="text/javascript">
Handlebars.registerHelper("if_sub",function(a, b, opts) {
if (b.includes(a)){
return opts.fn(this);
}
else{
return opts.inverse(this);
}
});
//wait for page to load
$(document).ready(function(){
var raw_template = $('#simple-template').html();
var template = Handlebars.compile(raw_template);
var data = {colvalues:"suc"}; //change value and see.
var html = template(data);
$('#main').append(html);
});
</script>
</head>
<body>
<!-- Insertion point for handlebars template -->
<div id="main" style="margin-left:100px">
</div>
</body>
</html>

How to get the autocomplete in angular js?

I have a object which contains name and id.I just want to do the autocomplete based on name.I have tried the code as shown below
//Js file
var app=angular.module("myapp",[]);
app.controller("controller",['$scope',function($scope){
$scope.persons=[
{
Name:"Bhavani",
Id:67
},
{
Name:"Mamata",
Id:66
},
{
Name:"Prasanna",
Id:65
},
{
Name:"Ramya",
Id:64
},
{
Name:"Navya",
Id:63
}
];
$scope.complete=function(){
$("#autocomp").autocomplete({
source: $scope.persons.Id
});
};
}]);
//Html file
<!DOCTYPE html>
<html ng-app="myapp">
<head>
<meta charset="UTF-8">
<title>Auto Complete based on name</title>
<script src="angularfiles/angular.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"></script>
<script src="Jsfiles/autocomp.js"></script>
</head>
<body ng-controller="controller">
<div ng-repeat="p in persons">{{p.Name}}
</div>
<div class="ui-widget">
<input type="text" id="autocomp" ng-keyup="complete()">
</div>
</body>
</html>
The above code may have some errors .Its not getting output which i want to have .Can anyone help me out to solve this problem.
Try like this,
HTML:
<div ng-app = "myapp">
<div ng-controller="controller">
<div class="ui-widget">
<input type="text" id="autocomp" auto-complete>
</div>
</div>
</div>
Js:
var app = angular.module("myapp",[]);
app.controller("controller",function($scope){
$scope.availableTags = [
{
Name:"Bhavani",
Id:67
},
{
Name:"Mamata",
Id:66
},
{
Name:"Prasanna",
Id:65
},
{
Name:"Ramya",
Id:64
},
{
Name:"Navya",
Id:63
}
];
}).directive("autoComplete",function(){
return function(scope,element,attrs){
var names =$.map(scope.availableTags,function(value){ return value.Name;
});
element.autocomplete({
source: names
});
};
});
Working jsbin
This is how you should use any jQuery API's in an AngularJS project (i believe). Anytime you are doing DOM Manipulation or jQuery things, it should be placed inside the link: function() {} via directive.
Probably the main problem with your code was that the source: $scope.persons.Id is just a number. The source needs to be an array of Strings (at least as per the documentation). So I seperated all the names from your persons array and placed them in a new array peopleNames
<!doctype html>
<html lang="en" ng-app="myapp">
<head>
<meta charset="utf-8">
<title>jQuery UI Autocomplete - Default functionality</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script src="vendors/angular.min.js"></script>
</head>
<body ng-controller="controller">
<div ng-repeat="p in persons">{{p.Name}}
</div>
<div class="ui-widget">
<input type="text" id="tags" autocomplete-directive>
</div>
<script>
var app = angular.module("myapp",[]);
app.controller("controller",['$scope',function($scope){
$scope.persons=[
{
Name:"Bhavani",
Id:67
},
{
Name:"Mamata",
Id:66
},
{
Name:"Prasanna",
Id:65
},
{
Name:"Ramya",
Id:64
},
{
Name:"Navya",
Id:63
}
];
// array of only strings autocomplete
$scope.peopleNames = [];
for(var i = 0, j = $scope.persons.length; i < j; i++) {
$scope.peopleNames.push($scope.persons[i].Name);
}
}]);
app.directive('autocompleteDirective', [function($scope) {
return {
link: function(scope, element, attrs) {
element.autocomplete({
source: scope.peopleNames
});
}
};
}]);
</script>
</body>
</html>
Thank For every one for suggesting me answer.I have also done in another way .It may help to others.
//html file
<!DOCTYPE html>
<html ng-app="myapp">
<head>
<title>Auto Complete based on name</title>
<script src="angularfiles/angular.js"></script>
<script src="angularfiles/angular-animate.js"></script>
<script src="angularfiles/ui-bootstrap-tpls-0.13.4.js"></script>
<script src="angularfiles/bootstrap-theme.css"></script>
<script src="Jsfiles/autocomp.js"></script>
</head>
<body ng-controller="controller">
<div ng-repeat="p in persons">{{p}}</div>
<div class="ui-widget">
<input type="text" ng-model="selected" typeahead="p.Name for p in persons | filter:$viewValue">
</div>
</body>
</html>
//js file
var app = angular.module("myapp",['ui.bootstrap']);
app.controller("controller",['$scope',function($scope){
$scope.persons=[
{
Name:"Bhavani",
Id:67
},
{
Name:"Mamata",
Id:66
},
{
Name:"Prasanna",
Id:65
},
{
Name:"Ramya",
Id:64
},
{
Name:"Navya",
Id:63
}
];
}]);

Add CSS to a div using a function in knockoutJS

I am trying to implement CSS binding in knockoutJS.
I want to print all the names in the names array, One after another.
The catch is that there is another array which has some special names.
All the special names should get "good" CSS class. And the rest, "bad" css class.
Here is something that i have tried:
HTML
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery.min.js"></script>
<link href="http://getbootstrap.com/dist/css/bootstrap.css" rel="stylesheet" type="text/css" />
<script src="http://getbootstrap.com/dist/js/bootstrap.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-min.js"></script>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div data-bind="foreach : items">
<div data-bind="text: $data, css: checkName($data)" ></div>
</div>
</body>
</html>
JAVASCRIPT
var dataModel = function(){
self.items = ko.observableArray(["don","bom","harry","sharry","ron"]);
self.names = ["ron","harry"];
self.checkName = ko.observable(function(name){
if( $.inArray(name,self.names) ){
return "good";
}
else{
return "bad";
}
});
};
ko.applyBindings(new dataModel());
FIDDLE - http://jsbin.com/difaluwo/2/edit
Now its not woking. In console its giving me "Script error. (line 0)"
Thanks !
The out of the box CSS binding is a little tricky. You specify class name and then the condition when it will be applied.
JSBIN
<div data-bind="foreach : items">
<div data-bind="text: $data, css: { good: isGoodName($data), bad: !isGoodName($data) }" ></div>
</div>
And your view model:
var dataModel = function(){
self.items = ko.observableArray(["don","bom","harry","sharry","ron"]);
self.names = ["ron","harry"];
self.isGoodName = function (name) {
return $.inArray(name, self.names) !== -1;
};
};
ko.applyBindings(new dataModel());

Categories

Resources