Read Json and update template from mustache - javascript

I have a Index.html file, where I am using container class.
I have another html file with which contains mustache variables.
Here is the code which I am using,
Lets say this is a.html.
<script id="filtersOptions" type="text/html">
<ul class="checkboxCommonContent">
{{#data}}
<li>
<div>
<input type="checkbox" id="checkbox-1-1" class="regular-checkbox"><label for="checkbox-1-1"></label><span class="lblText">{{brand_name}}</span>
</div>
</li>
{{/data}}
</ul>
I have a json file, where the brand information something like this,
{
"brands":[
{
"brand_name":"Adidas",
"available_products":30
}
]
}
Through Javascript I am featching the Json data and trying to udapete the mustache tempalte but getting error.
Featchng information from js
loadFileForFilters: function(){
$.getJSON('js/json/brand.json', {}, function(data, textStatus, jqXHr) {
console.log(data);
var f = $("#filtersOptions").html();
$.get('files/sort_and_filter_lb.html', function(template, textStatus, jqXhr) {
var template = Mustache.render(f, {data: data});
//$(".container").html(template);
});
});
}
container - Is in side index.html.
The sort_and_filter_lb.html file have following code
<script id="filtersOptions" type="text/html"><ul class="checkboxCommonContent"> {{#data}} <li> <div> <input type="checkbox" id="checkbox-1-1" class="regular-checkbox"><label for="checkbox-1-1"></label><span class="lblText">{{brand_name}}</span> </div> </li> {{/data}} </ul> </script>
Can some one please guide me. Why I am not getting the data in the main template.

Edit,
Browsed some documentations MUSTACHE MANUAL , and demonstrations A Simple Mustache Demo , along with re-reading Question , for introduction into Mustache.js .
At first glance , appear that json object at brand.json does not have data property to correspond to {{#data}} ; see http://mustache.github.io/mustache.5.html#Sections at template and hash of {{#repo}}.
Not certain about necessity of second ajax call, i.e., $.get() ? Existing #filtersOptions (f) html could be modified , to reduce ajax call to first , $.getJSON() ?
Above portions not directly addressed here , though ajax pieces re-arranged to process their respective return values within .then() callback .
Changed <script> element at sort_and_filter_lb.html file to <div> , for jsfiddle to process .
Note, Not previously tried Mustache.js
Try
v2
html
<script id="filtersOptions" type="text/html">
<ul class="checkboxCommonContent"> {{#data}}
<li> <div> <input type="checkbox"
id="checkbox-1-1"
class="regular-checkbox" /> <label
for="checkbox-1-1"> </label><span class="lblText">{{brand_name}}</span> </div>
</li> {{/data}}
</ul>
</script>
<div class="process">
<button>Process Template</button>
</div>
<div id="container"></div>
js
$(function () {
$(".process button").on("click", function () {
var f = $('#filtersOptions').html();
var _data = {
"brands": {
"data": [{
"brand_name": "Adidas"
}, {
"available_products": 30
}]
}
};
var file = String('<div id=filtersOptions type=text/html>'
+'<ul class=checkboxCommonContent> {{#data}} <li>'
+'<div>'
+'<input type=checkbox id=checkbox-1-1 class=regular-checkbox>'
+'<label for=checkbox-1-1></label>'
+'<span class=lblText>{{brand_name}}</span>'
+'</div> </li> {{/data}} </ul> </div>');
var request1 = $.post("/echo/json/", {
json: JSON.stringify(_data)
}, function (data, textStatus, jqxhr) {
return data.brands;
});
var request2 = $.post("/echo/html/", {
html: file
}, function (data, textStatus, jqxhr) {
return data
});
$.when(request1, request2)
.then(function (a, b) {
console.log(a[0], b[0]);
var html = Mustache.render(b[0] /* or , `f` */, a[0].brands);
$('#container').html(html);
})
});
});
jsfiddle http://jsfiddle.net/guest271314/uhf73/

Your code appears a little messed up but close. If you want to render a template using an external file and external data, try something like this:
$.getJSON('js/json/brand.json', {}, function(data) {
// on success, request template
$.get('files/sort_and_filter_lb.html', function(template_string) {
// when we have both template and data, render it
var output = Mustache.render(template_string, {data: data});
$(".container").html(output);
});
});

Related

How can I add Automatic intellisense to a Textbox using Jquery

I want to add automatic Intellisense (Auto Complete--Filtering Search Result) to a textbox, corresponding to the words that I'm typing in that textbox and the Intellisense is fetched from a database table. How can I achieve this? Can anyone help?
Here is my jQuery code:
$(document).ready(function() {
$('#city').autocomplete({
source:'send.php'
});
});
send.php file given below:
$link=mysqli_connect("localhost","hari","123","hari");
$searchTerm = $_GET['query']; //get search term
$query = $db->query("SELECT fname FROM user WHERE fname LIKE
'%".$searchTerm."%' ORDER BY fname ASC"); //get matched data from user table
while ($row = $query->fetch_assoc()) {
$data[] = $row['fname'];
}
echo json_encode($data);//return json data
Corresponding HTML Code is given below:
<div class="content col-sm-12">
<form>
<h1>Hello!!!</h1>
<input type="text" id="city" name="city" size="20" class="city"
placeholder="Please Enter City or ZIP code"><br><br>
</form>
</div>
You have to include the following scripts in your html page
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
And add the following css in head of your html
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
The mistake you made is the parameter passing with the name term and trying to read with the name query in your php file. In your send.php file change the line
$searchTerm = $_GET['query'];
into
$searchTerm = $_GET['term'];
Try this:
$(document).ready(function() {
$('#city').autocomplete({
source: function( request, response ) {
$.ajax( {
url: "send.php",
dataType: "jsonp",
data: {
query: request.term
},
success: function( data ) {
response( data );
}
} );
},
});
});
I have a recommendation for you, use angular 1 for this, you can simply write that code without additional UI libraries and with much much better performance and issue-free solution.
Add the following parent div to your input element:
Change your input to this:
<input type="text" id="city" name="city" size="20" class="city" ng-model="query" ng-change="fetch()" placeholder="Please Enter City or ZIP code">
Add the following code right under your <input>:
<ul>
<li ng-repeat="text in suggestions">{{ text }}</li>
</ul>
As a basic set up, you need this in your <head> section:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
Finally you will create a new file like in assets directory like "suggestions.js" in your assets directory or somewhere and add this file right before you your </body> tag like this in your template:
<script src="assets/suggestions.js"></script>
The file will have the following lines:
var app = angular.module('myApp', []);
app.controller('suggestionsCtrl', function($scope, $http) {
$scope.suggestions = [];
$scope.query = '';
$scope.fetch = function() {
$http({method: 'POST', url: 'send.php', params: { query: $scope.query } }).
then(function(response) {
$scope.status = response.status;
$scope.suggestions = response.data;
}, function(response) {
/* SOMETHING WENT WRONG WTIH THE CALL DO SOMETHING HERE */
});
};
});
There is very simple set-up/tutorial for Angular 1 here:
https://www.w3schools.com/angular/default.asp
This is not a direct answer but believe me a more efficient answer. Angular 1 and the newer versions save a lot of time and brings performance.
And btw, autocomplete() is not a native jQuery function. Also I do not mention that you need jQuery also for Angular, but I assume it's already added in your template.

Unable to grab complete Handlebars template from Javascript

I am using Handlebars and AJAX to re-render template on every AJAX response. However, nothing is happening, neither template is rendered nor any error message is shown by browser. On little debugging, I found out that javascript is not grabbing complete hbs template.
Here is my Handlebars template:
<!--Template-->
<script id="careers-template" type="text/x-handlebars-template">
<ul>
{{#each careers_list}}
<li class="mt-list-item">
<div class="list-icon-container">
<button data-toggle="tooltip"
title="Add to Favorites"><i
class="fav-btn ion ion-ios-heart-outline font-red-intense"></i>
</button>
</div>
<div class="list-item-content">
<h3 class="uppercase">
{{this}}
</h3>
</div>
</li>
{{/each}}
</ul>
</script>
Here is console output of source:
<ul> </ul>
Here is my AJAX call:
$.ajax({
url: '/dashboard/careers/get_careers_list',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({category: category})
}).done(function (data) {
var container = $("#career-detail-list");
var source = $("#careers-template").html();
var template = Handlebars.compile(source);
var list = template({careers_list: data});
console.log(source);
container.html(list);
});
The AJAX return an array of strings.
Can anyone please help why javascript is not grabbing complete hbs template??
The problem is careers_list is empty.
Check if its this.careers_list instead of just careers_list
Also send the key in quotes
var list = template({'careers_list':data})

Knockout did not render template with my data

Stuck with javascipt's knockout library.
So, I want to implement simple forum. I have javascript file with two ajax requests, for topics and for posts. And I have html template.
function dealModel() {
var self = this;
self.board = ko.observableArray([]);
var res = [];
$.getJSON("http://someaddress/threads", function(data) {
$.each(data, function(i, thread) {
var js = jQuery.parseJSON(thread);
js.posts = ko.observableArray([]);
var postres = []
$.getJSON("http://someadress/posts/" + js.id, function(postdata) {
$.each(postdata, function(idx, post){
var jspost = jQuery.parseJSON(post);
postres.push(jspost);
})
})
js.posts(postres);
res.push(js);
})
self.board(res);
})
}
$(document).ready(function(){
ko.applyBindings(new dealModel());
});
var testdata = [{text : "text 1"} , {text : "text2"}]
This is my js code. It perfectly works with topics, but when I put my posts, my observable array "posts" already empty.
For test I created test array "testdata" (below), and pass in my observable array. And, javascript work perfectly.
Here is my template
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"></script>
<script type="text/javascript" src="ajaxknockout.js"></script>
</head>
<body>
<div class='board'>
<div class='threads' data-bind="foreach: board">
<p data-bind="text: title"></p>
<div class= "posts" data-bind="foreach: $data.posts">
<p data-bind="text: text"> </p>
</div>
</div>
</div>
</body>>
</html>
So, I think something bad with my posts JSON.
Here it is.
["{\"createTime\": \"Monday, 04. January 2016 05:53PM\",\"thread_id\": \"2\",\"text\": \"post 1\",\"id\": \"4\"}", "{\"createTime\": \"Monday, 04. January 2016 05:53PM\",\"thread_id\": \"2\",\"text\": \"post 2\",\"id\": \"5\"}", "{\"createTime\": \"Monday, 04. January 2016 05:53PM\",\"thread_id\": \"2\",\"text\": \"post 3\",\"id\": \"6\"}"]
SO, I have a question. Whats wrong with my code? Why knockout understand my testdata, but completly reject production data?
That's because this part of your first json request:
js.posts(postres);
executes ahead of callback from your second json request where you are pulling posts. You have to change that so the posts array is populated before doing js.posts(postres);, e.g like so:
$.getJSON("http://someadress/posts/" + js.id, function(postdata) {
$.each(postdata, function(idx, post){
var jspost = jQuery.parseJSON(post);
postres.push(jspost);
})
js.posts(postres);
})

Ajax executes half of the success function after third call

I call ajax to draw a table from the mysql datas and put textareas below that table to be able to write a documentation for each fields.
Here's my problem. After I type the table name to the search field and click the button, I get the whole page as I wished. After I search for the same table name, I get the same page again, but after I check the same table the third time, I only get two tables being drew. The same issue occurs if I check 'test' table once, then 'test2' twice.
UPDATE: After the second ajax call (so if you type something and click to check meanwhile an other one is in the browser) the jQuery plugin only load the mysqlTable template and doesn't the textareas. Despite this textareas still appear, but if you call the third time any table then the issue occurs, the success function stops executing half-way and I only see two tables without textareas.
What I noticed is that the third time it calls ajax, it only executes until that part where I left the comment /* *** this is the point where ... That's the reason why textareas and other does not appear.
It supposed to be like this.
But it looks like this after the third call.
I disable the search input while loading, in order to avoid multiple ajax call, but something happens here.
JS ajax call
function templatesHandling(){
clear();
$('#textareaHolder').html('');
$.ajax({
url: "ajax/table.php?function=get_table_data&table="+tableName,
dataType: "json", // it'll convert json to objects
type : "GET",
beforeSend : function(){ $('#ajax-loader-gif').show(); $('#search').attr({'disabled':'disabled','placeholder':'Loading...'});},
complete : function(){ $('#ajax-loader-gif').hide(); $('#search').removeAttr('disabled').prop('placeholder','Type the table name..'); },
error: function(er){ $("#check").after("<span id='error'>Error</span>"); },
success: function(data){
// add the current table name to the first object in order to be able to print out with {{tableName}}
if (!data[0].TableName){
data[0].TableName = tableName;
}
// call the 'table' template and send the data to work with
$("#tableHolder").loadFromTemplate({
template : "mysqlTable",
data : data
});
/* *** this is the point where sometimes the ajax call stops executing *** */
// call the 'textareas' template and send the data to work with
$("#textareaHolder").loadFromTemplate({
template : "textareas",
data : data
});
/* *** parseWiki *** */
$('#parseWikiHolder').show(); // show the last textarea
for (key in data[1]){
res_head[++j] = '!scope="col"| '+ key + '\n'; //
}
for(var i=1;i<data.length;i++){
for(key in data[i]){
res_body[++j] = '|'+data[i][key]+'\n';
}; // -for in | parse <tbody>
res_body[++j] = '|-\n';
}; // -for | parse <tbody>
} // -success
});
};
I use jQuery HandlebarsJS to load Handlebars templates from separated files.
Do you have any thought about this issue? Why does it happen?
(let me know if more code needed)
UPDATE
I inserted the full JS code of mine to JSFiddle, click here!
textareas (template)
{{#each this}}
{{#if TableName}}
<label for='{{TableName}}'>Description of <em class="tableName">{{TableName}}</em> table</label>
<textarea id='{{TableName}}'></textarea>
{{/if}}
{{#if Field}}
<label for='{{Field}}'>Description of <em class="tableName">{{Field}}</em> field</label>
<textarea id='{{Field}}'></textarea>
{{/if}}
{{/each}}
mysqlTable (template)
<table>
<thead>
<tr>
{{#each this}}
{{#if TableName}}
<th class="structure_thead" colspan="6">Structure of {{TableName}} table</th>
{{/if}}
{{/each}}
</tr>
<tr>
<th>Field</th>
<th>Type</th>
<th>Null</th>
<th>Key</th>
<th>Default</th>
<th>Extra</th>
</tr>
</thead>
<tbody>
{{#each this}}
{{#if Field}}
<tr>
<td><span class="ui-icon ui-icon-link"></span>{{Field}}</td>
<td>{{Type}}</td>
<td>{{Null}}</td>
<td>{{Key}}</td>
<td>{{Default}}</td>
<td>{{Extra}}</td>
</tr>
{{/if}}
{{/each}}
</tbody>
</table>
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Doksi</title>
<link rel="stylesheet" type="text/css" href="css/styles.css">
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
<link href='http://fonts.googleapis.com/css?family=Vollkorn' rel='stylesheet' type='text/css'>
</head>
<body>
<div class="container">
<div class="searchHolder">
<input id="search" type="text" placeholder="Type the table name.."/>
<input id="check" type="button" value="Check" />
<img id="ajax-loader-gif" src="img/ajax-loader.gif" />
</div>
<div id="tableHolder"></div>
<div id="textareaHolder"></div>
<div id="parseWikiHolder">
<input type="text" disabled="disabled" value="Ready to copy?"/>
<input id="copy" type="button" value="Hell, yeah!" />
<textarea id="parseWiki"></textarea>
</div>
</div>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.3.0/handlebars.min.js" type="text/javascript" charset="utf-8"></script>
<script src="js/jquery.loadFromTemplate.js"></script>
<script src="js/ajax.js"></script>
</body>
</html>
Get the table name - JSON file I receive
[
{
table: "teszt"
},
{
table: "teszt2"
}
]
Get the table's data - JSON file I receive
[
{
eredmeny: "siker"
},
{
Field: "id",
Type: "int(11)",
Null: "NO",
Key: "PRI",
Default: null,
Extra: "auto_increment"
},
{
Field: "name",
Type: "varchar(64)",
Null: "NO",
Key: "",
Default: null,
Extra: ""
},
{
Field: "type",
Type: "enum('y','n')",
Null: "NO",
Key: "",
Default: "n",
Extra: ""
},
{
Field: "date",
Type: "datetime",
Null: "NO",
Key: "",
Default: null,
Extra: ""
}
]
UPDATE 2
I commented out that jQuery plugin and tried a simple ajax call, but the same issue occurs. If I run this code, just the table will appear. If I change the code as textareas are in the first place, then only they will appear. Why does the code stops executing without any error? Are the two ajax call kick each other out?
The new ajax calls
(function getTemplateAjax(path) {
var source;
var template;
$.ajax({
url: path, //ex. js/templates/mytemplate.handlebars
cache: true,
success: function(data) {
source = data;
template = Handlebars.compile(source);
$('#tableHolder').html(template(o));
}
});
})('templates/mysqlTable.html')
(function getTemplateAjax2(path) {
var source;
var template;
$.ajax({
url: path, //ex. js/templates/mytemplate.handlebars
cache: true,
success: function(data) {
source = data;
template = Handlebars.compile(source);
$('#textareaHolder').html(template(o));
}
});
})('templates/textareas.html')
I found a (half)solution
As I copied that new code block to below UPDATE2, after I changed that again and found the (half)solution.
...
success: function(o){
// add the current table name to the first object in order to be able to print out with {{tableName}}
if (!o[0].TableName){
o[0].TableName = tableName;
};
// call the 'mysqlTable' template and send the data to work with
(function getTemplateAjax(objectum, path, element){
var source, template;
$.ajax({
url: path,
cache: true,
success: function(data) {
source = data;
template = Handlebars.compile(source);
element.html(template(objectum));
}
});
})(o, 'templates/mysqlTable.html', $('#tableHolder'));
// call the 'textareas' template and send the data to work with
(function getTemplateAjax(objectum, path, element){
var source, template;
$.ajax({
url: path,
cache: true,
success: function(data) {
source = data;
template = Handlebars.compile(source);
element.html(template(objectum));
}
});
})(o, 'templates/textareas.html', $('#textareaHolder'));
...
It's quite ugly and with more template files it won't the best practice, so I'll look for a better solution. At least it works now.
So the bug was probably inside the plugin. I am going to write my own jQuery plugin for this task.
I think the problem is with the async mode for the ajax call for that reason I just commited a new changes you can take a look into the examples:
https://github.com/CKGrafico/jQuery_HandlebarsJS/commit/41eb4c7c39f9c1ef8bbd1015b594d0a33bb585ac maybe this could fix your problem.

Template not working with JSON / Mustache.js

I am currently running into trouble with Mustache.js templates. Everything seems to be correct, and the template loads as HTML on the page. But it doesn't have access to the JSON data and I'm not quite sure why. Can anyone help out? Thanks in advance.
The Javascript that I am using is below.
query.find({
success: function(results){
var template = $("#newCurrItem").html();
var newContents = Mustache.to_html(template, results);
$("#curr-list").append(newContents);
},
error: function(error){
console.log("error");
}
});
This image shows the JSON format:
http://i.imgur.com/JrYrORk.png?1
And, here is the template:
<script id="newCurrItem" type="text/html">
{{#results}}
<!-- Template for new curriculum -->
<li id="curr-list-item">
<div id="curr-item">
<input type="checkbox" class="item-delete">
<label id="item-content" class="item-content">{{curr}}</label>
</div>
</li>
{{/results}}
</script>
Try structuring your JSON data more like this:
{ "results" : [
{
"curr": "curr_dbc",
"createdAt" : ...,
"updatedAt":...
}
]};

Categories