Populating HTML with JSON data using jQuery - javascript

I am trying to dynamically create a list of applicants in my HTML. I have a list of applicant saved in JSON format that I am reading in. I have an HTML template of the applicant "tile" that I read in, populate and then append to the page for each applicant.
My template:
<div>
<div class="name"></div>
<div class="age"></div>
<div class="gender"></div>
<div class="email"><i class="fa fa-envelope"></i></div>
</div>
My JSON data:
{
"applicants" : [
{
"name" : "John Smith",
"email" : "email#gmail.com",
"gender" : "Male",
"age" : "22"
}
]
}
My jQuery:
$.get("applicants.json", function(json) {
json.applicants.forEach(function(applicant) {
var newApplicant = $(templates).find("#applicant").html();
$(newApplicant).find(".name").append(applicant.name);
$(newApplicant).find(".email").append(applicant.email);
$(newApplicant).find(".gender").append(applicant.gender);
$(newApplicant).find(".age").append(applicant.age);
$(newApplicant).appendTo(".applicant-list");
});
});
After running this code, I am just getting the template back without the JSON information.
I have tried placing a console.log() after appending applicant.name but there is still no change to newApplicant.
Something else I tried was console.log($(newApplicant).find(".name").append(applicant.name).html()); which showed me that the .name is being populated but those changes are not persisting.
Can anyone see what I am doing wrong?
Thanks.

I am not sure if forEach would be a right one. You can use jQuery's $.each function to loop in an array with this being referred as the current iterated object:
$.each(json.applicants, function () {
var newApplicant = $("body").find("#applicant > div").clone();
newApplicant.find(".name").append(this.name);
newApplicant.find(".email").append(this.email);
newApplicant.find(".gender").append(this.gender);
newApplicant.find(".age").append(this.age);
$(newApplicant).appendTo(".applicant-list");
});
Snippet
$(function () {
json = {
"applicants" : [
{
"name" : "Nicholas Robinson",
"email" : "ntrpilot#gmail.com",
"gender" : "Male",
"age" : "22"
}
]
};
$.each(json.applicants, function () {
var newApplicant = $("body").find("#applicant > div").clone();
newApplicant.find(".name").append(this.name);
newApplicant.find(".email").append(this.email);
newApplicant.find(".gender").append(this.gender);
newApplicant.find(".age").append(this.age);
$(newApplicant).appendTo(".applicant-list");
});
});
<script src="https://code.jquery.com/jquery-1.9.1.js"></script>
<div id="applicant">
<div>
<div class="name"></div>
<div class="age"></div>
<div class="gender"></div>
<div class="email"><i class="fa fa-envelope"></i></div>
</div>
</div>
<div class="applicant-list"></div>

In the question you omitted two HTML elements that instead you mention in the jQuery code, so according to the latter, and correct me if I'm wrong, the HTML should look like that
<div class="applicant-list">
<div class="applicant">
<div class="name"></div>
<div class="age"></div>
<div class="gender"></div>
<div class="email"><i class="fa fa-envelope"></i></div>
</div>
</div>
Then, in the jQuery you should either use your $.get() function and then parse or use instead $.getJSON()
$.getJSON("applicants.json", function(json) {
json.applicants.forEach(function(applicant) {
var newApplicant = $('body').find(".applicant").clone();
$(newApplicant).find(".name").append(applicant.name);
$(newApplicant).find(".email").append(applicant.email);
$(newApplicant).find(".gender").append(applicant.gender);
$(newApplicant).find(".age").append(applicant.age);
$(newApplicant).appendTo(".applicant-list");
});
});

Related

How to pass json file name to javascript function on button click?

I have a Javascript file that returns some HTML Content based on the content of a json file. In other words, in my file called "Resources" I have multiple json files and a single HTML File that contains multiple buttons. It can be more clear with an example, here is the HTML file:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div class="cards">
<div class="card">
<img src="first.jpg" class="card_image">
<a href="javascript:showMenu()" class="animated-button"> <!--showMenu() is inside menu-card.js-->
<span></span>
<span></span>
<span></span>
<span></span>
<p>FIRST BUTTON</p>
</a>
</div>
<div class="card">
<img src="second.jpg" class="card_image">
<a href="javascript:showMenu()" class="animated-button"> <!--showMenu() is inside menu-card.js-->
<span></span>
<span></span>
<span></span>
<span></span>
<p>SECOND BUTTON</p>
</a>
</div>
</div>
<script type="text/javascript" src="first.json"></script>
<script type="text/javascript" src="second.json"></script>
<script type="text/javascript" src="menu_card.js"></script>
</body>
</html>
Here is first.json :
products =
`[
{
"name": "Shoes",
"description": "This are some shoes.",
"price": "180"
}
]`;
Here is second.json :
products =
`[
{
"name": "Hoodies",
"description": "This are some hoodies.",
"price": "90"
}
]`;
Finally, here is menu_card.js :
var storedMenu = JSON.parse(products);
//Some other stuff using storedMenu
Anyways, since I have multiple json files for different "categories" for my project and a SINGLE javascript file "menu_card.js" that must output some HTML content based on the json content, the problem is that I already have a lot of json files and they all have the same object name and I don't plan on changing it for every single file ( products = ... ). Is it possible to maybe pass the json file name from the href inside the HTML to the javascript function that will use it for the JSON.parse()?
I think I was clear enough with my issue, if something is unclear or not specified, I can easily edit the post. Thank you in advance!
Well you can change the script import like that
<script type="text/javascript" src="first.json">
fetch('/first.json')
.then(response => response.json())
.then( json => {
window.products = (window.products || []);
json.forEach( p => window.products.push(p) );
});
</script>
But files must be pure JSON
[
{
"name": "Hoodies",
"description": "This are some hoodies.",
"price": "90"
}
]
Rewrite them programmaticaly.
You could also rewrite then like below but it will change all the solution.
{
"name": "Hoodies",
"description": "This are some hoodies.",
"price": "90"
}
And so on... so everything will be available in window.products.
As it can be long to rewrite, you can do it for every file with something like
<script type="text/javascript" src="first.json">
Promise.all([ '/first.json', '/second.json']
.map( file => fetch(file).then( r => r.json() ) )
)
.then( allProducts => allProducts.flat() )
.then( allProducts => window.products = allProducts)
;
});
</script>

Console log not shoping variables I want it to show

I'm working on a project for school, and I'm trying to make some sort of store where you can buy fireworks.
I've managed to load in several items from a JSON file, and now I'm trying to make the shopping cart work. For this shopping cart, I want a function that can add the selected product's variables to a string and paste them in the cart.
For starters, I want to print the pressed data to the console, but it isn't working and I don't know what to do, as I'm getting S.fn.init {} in the console.
As you can see in the image, I would like the product's name and price and add it to the cart eventually.
This is the HTML I'm using for the cards you can see.
function addToCart() {
var productInfo = $(this.dataset);
console.log($(productInfo.name))
};
//toggle function
function toggle() {
$('.keyboardViewSection').toggle();
$('.touchViewSection').toggle();
var x = document.getElementById("toggleBtn");
if (x.innerHTML === "Keyboard View") {
x.innerHTML = "Touch View";
} else {
x.innerHTML = "Keyboard View";
}
}
$(document).ready(function() {
//Touchview productCard output
$(function() {
$.getJSON("assets/products/sample_products.json", function(response) {
$.each(response.data, function(i, el) {
let card = $($('#productCard-template').html());
card.find('#cardName').html(el.name);
card.find('#cardPrice').html('€' + el.price);
card.find('.productItem').attr('data-price', el.price)
.attr('data-article-number', el.article_number)
.attr('data-id', el.id)
.attr('data-name', el.name)
.attr('data-stock', el.stock)
.attr('data-categorie', el.categorie);
$('#touchViewProducts').append(card);
});
});
});
//KeyboardView Datatable output
$('[data-selected]')
$('#data-table').DataTable({
"paging": false,
"ajax": "assets/products/sample_products.json",
"columns": [{
"data": "article_number"
},
{
"data": "name"
},
{
"data": "stock"
},
{
"data": "price",
render: $.fn.dataTable.render.number(',', '.', 2, '€ ')
},
{
"defaultContent": "<button class='addToCart'>Add to Cart</button><button class='addFree'>Add Free</button>"
}
]
});
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col-3 productCard" id="productCard">
<a href="#" class="productItem" onclick="addToCart()">
<div class="card">
<img src="assets/images/Firecracker.jpg" alt="Avatar" style="width: 100%; height: 8vh;">
<div class="container">
<div class="row" style="height: 6vh; max-width: 20ch;">
<p id="cardName"> </p>
</div>
<div class="row" style="height: 50%">
<b><p id="cardPrice"></p></b>
</div>
</div>
</div>
</a>
</div>
There's a few issues:
You need to remove this onclick="addToCart()" and add it here:
.attr('data-categorie', el.categorie).on('click',addToCard);
Then change function addToCart(){ to function addToCart(event){
and finally, instead of using $(this.dataset) try using $(this).data().
You could also use $(event.target).data().
You might also want the test if the <a> tag or <img> tag was the event.target. If it was the image, then you can use $(event.target).parent().data().

Query for sorting a date that is inside another object in firebase

I'm developing a chat in angularjs where I have a chat list view and a chat view.
What I'm trying to do is sorting my chat list to show the most recent chat on top using Firebase and JS, I did my research but all of the questions I found they have the date directly as a child but inside my DB my date is inside a 'lastMessage' key. My dates are the following format.
date: 1528417493034
Any help would be highly appreciated
My structure is the following:
"Users": {
"nCsXbTl8CcXvoviuL5Tt7kiV6Bn1" : {
"contacts" : {
"VN9AFnn4uXgDfoir8DWHnw54zrJ3" : {
"email" : "test#test.com",
"lastMessage" : {
"date" : 1528417493034,
"senderId" : "VN9AFnn4uXgDfoir8DWHnw54zrJ3",
"status" : "success",
"text" : "Yes?",
"type" : "text",
"uid" : "1528417493034VN9AFnn4uXgDfoir8DWHnw54zrJ3"
},
"name" : "test"
},
"cHuR26YaSgbO7ahSVLg1XG5HYer2" : {
"email" : "aaa#aaa.com",
"lastMessage" : {
"date" : 1528417068249,
"senderId" : "cHuR26YaSgbO7ahSVLg1XG5HYer2",
"status" : "success",
"text" : "Trigeeeers?",
"type" : "text",
"uid" : "1528417068249cHuR26YaSgbO7ahSVLg1XG5HYer2"
},
"name" : "aaa"
}
}
}
My chat list view is the following:
<div layout="row" class="main-chat-container" layout-wrap>
<div class="list-container" flex="30">
<div class="chat-header">
<p>Lista de Chats</p>
</div>
<div class="chats-list">
<div class="chats-header">
<p>Usuarios</p>
</div>
<div class="chats" ng-repeat="chat in chats">
<div class="email-container" ng-click="setUserData(chat)" ng-class="styleData.email == chat.email ? 'new-background' : ''">
<a>{{chat.email}}</a> <p ng-show="counter > 1">{{testData.number}}</p>
</div>
</div>
</div>
</div>
<div class-"chat-container" flex="70">
<ui-view></ui-view>
</div>
And the controller is the following
app.controller('chatController', function (currentAuth, $scope, $firebaseArray, $firebaseObject) {
$scope.chats = [];
$scope.getContactsList = function(){
var listRef = firebase.database().ref('Users').child(currentAuth.uid).child('contacts');
var test = firebase.database().ref('Users').child(currentAuth.uid).child('contacts');
var listArray = $firebaseArray(listRef);
var testArray = $firebaseArray(test);
$scope.chats = listArray;
console.log("TEST ARRAY IS ");
console.log(testArray);
}
$scope.getContactsList();
});
To so a users contacts on the timestamp of their last message, you'd do something like this:
var userRef = firebase.database().ref('Users').child(currentAuth.uid)
var contactsQuery = userRef.child('contacts').orderByChild("lastMessage/date");
Note that this will give you the contacts in chronological order, so you will have to reverse the result in your client.
Alternatively some folks keep an inverted value in a separate property in their database, e.g.
"VN9AFnn4uXgDfoir8DWHnw54zrJ3" : {
"email" : "test#test.com",
"lastMessage" : {
"date" : 1528417493034,
"invertedDate" : -1528417493034,
"senderId" : "VN9AFnn4uXgDfoir8DWHnw54zrJ3",
Since this invertedDate value is inverted, ordering on that property would give you the contacts in reverse chronological order, so that you don't have to reverse them in the client.

How to submit ng-repeat data in angularjs

I need to submit the form which comes under the ng-repeat directive.I m getting the proper data in JSON format but when i execute the insert query it prints the last data.
For example: Take a view to my code
In view :
<div class="row" ng-init="get_membershipPlans()">
<div class="col-md-4" ng-repeat="x in plans" >
<div class="table-columns">
<form method="post" ng-submit="insert_data()">
<ul class="price height-price">
<li class="grey" ng-model="planDetails.price = x.price">${{x.price}}/ year</li>
<li ng-repeat="y in x.plansdetails">
{{y.feature_name}}
</li>
{{planDetails | json}}
</ul>
</form>
</div>
</div>
</div>
In angular controller :
$scope.insert_data = function () {
Data.insertData($.param($scope.planDetails)).success(function (data) {
$scope.planDetails = data;
});
};
In services :
this.insertData = function($data) {
return $http.post(site_url + "FunctionalController/inserttData" , $data);
};
In FunctionalController :
public function inserttData() {
$tablename = 'ult_book_camp';
$rs = $this->db->insert($tablename, $_POST);
if ($rs) {
echo json_encode(array('status' => '1','msg' => 'You have booked camps successfully'));
} else {
echo json_encode(array('status' => '0', 'msg' => 'No Result Found'));
}
}
In view,using ng-repeat it display three blocks when i print the data in json format ,get result like this {"plan_id": "1", "price": "10" } {"plan_id": "2", "price": "100" } {"plan_id": "3", "price": "105" } but when i submit a parrticular block related to plan_id =1 it submitted the plan_id = 3 in database which is the id of last element.
Whereas in database i have two fields plan_id and price. And i need to insert data in these field for each individual block.
Please help me to get this.Any help will be appreciated.
Thanks in advance.
Please check error:
Error: can't assign to properties of (new String("\r\n<pre>Array\n(\n [plan_id] => 3\n [price] => 120\n)\n</pre>")): not an object
fn#http://localhost/ultimate/angular-js/bower_components/angular/angular.min.js line 236 > Function:4:371
hh</<#http://localhost/ultimate/angular-js/bower_components/angular/angular.min.js:293:156
$digest#http://localhost/ultimate/angular-js/bower_components/angular/angular.min.js:144:43
$apply#http://localhost/ultimate/angular-js/bower_components/angular/angular.min.js:147:76
l#http://localhost/ultimate/angular-js/bower_components/angular/angular.min.js:98:419
D#http://localhost/ultimate/angular-js/bower_components/angular/angular.min.js:103:105
ug/</w.onload#http://localhost/ultimate/angular-js/bower_components/angular/angular.min.js:104:77

Show different buttons matching array values

So here's my problem, i'm using AngularJS and i'm getting JSON from PHP, and displaying all my data with ng-repeat. I already have done this.
Now I want to check if some data is in "Array1" and if it is, change the correspndent data from the ng-repeat. I know it sounds really weird, but let me put an example with code:
Here's array1 values
{
"23",
"48",
"51"
}
So when i get the data, it's something like this:
{
id : "23",
name: "example"
}
And for every JSON object i'm using ng-repeat to display them all like this:
<div ng-model="data.posts" ng-repeat="post in posts | orderBy:'-' | unique: 'id'">
...
<button>This button will show if "id" matches</button>
<button>This button will show if "id" not matches</button>
</div>
I want to compare if an id of array1 matches an id from the JSON data and if it matches show one button and if not show other.
I'm on this like 2 weeks, and i can't get the problem solved, and i don't see any way to get it.
Thx for reading at least and sorry for my bad english!
Your array1 should be an array and can add a function in controller to check match id.
in controller:
$scope.array1 = ["23","48","51"];
$scope.checkInArray1 = function(id) {
var index = $scope.array1.indexOf(id);
if(index < 0){
return false;
} else {
return true;
}
};
and in your html:
<button ng-if="checkInArray1(post.id)">This button will show if "id" matches</button><br>
<button ng-if="!checkInArray1(post.id)">This button will show if "id" not matches</button>
Making the assumption that {"23","48","51"} should be a array ["23","48","51"]
You could do something like this:
Working Fiddle: http://jsfiddle.net/ravenous52/rgyom4yd/
myApp.controller('MyCtrl', ['$scope',
function($scope) {
$scope.knownIds = ["23", "48", "51"];
$scope.data = {
posts: [{
id: "23",
name: "example23"
}, {
id: "51",
name: "example51"
}, {
id: "99",
name: "example99"
}]
}
}
]);
<section ng-controller="MyCtrl">
<div ng-repeat="post in data.posts">
<button ng-show="knownIds.indexOf(post.id) >-1">This button will show if "id" matches</button>
<button ng-hide="knownIds.indexOf(post.id) >-1">This button will show if "id" not matches</button>
</div>
</section>
https://jsfiddle.net/alair016/4wc44on1/
<div ng-app='myApp' ng-controller="MyCtrl">
<div ng-model="data.posts" ng-repeat="post in data.posts">
<button ng-if="array1.indexOf(post.id) >-1">{{post.name}} id matches</button>
<button ng-if="array1.indexOf(post.id) == -1">{{post.name}} id does not match</button>
</div>
</div>
var myApp = angular.module('myApp',[])
.controller('MyCtrl', ['$scope', function($scope) {
$scope.array1 = ["23","48","51"];
$scope.data = {
posts : [
{
id : "23",
name: "example"
},
{
id: "24",
name:"second example"
}
]
};
}]);

Categories