I want to show one json to list in my page with AngularJS.But that Json have sub object i try something but not working. I can showing text and id but it's not working lat and lon in posibiton name tag.I don't know how to show that data in my list
var app = angular.module("VarnaApp",[]);
app.service("varnaService",function($http, $q)
{
var deferred = $q.defer();
$http.get('api/station.json').then(function(data)
{
deferred.resolve(data);
});
this.getStations = function ()
{
return deferred.promise;
}
})
.controller ("varnaCtrl",function($scope,varnaService)
{
var promise = varnaService.getStations();
promise.then(function(data)
{
$scope.stations = data.data;
});
})
<!doctype html>
<html lang="en">
<head>
<title>AccioCode AngularJS Tutorial</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-COMPATIBLE" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, user-scalable=no">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="js/app.js"></script>
</head>
<body>
<div class="mainContainer" data-ng-app="VarnaApp">
<h1>Varna Stations</h1>
<div data-ng-controller="varnaCtrl">
<table class="table table-striped">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>loc</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="station in stations">
<td>{{station.id}}</td>
<td>{{station.text}}</td>
<td>{{station.loc}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
My Json Is
[
{
"id": 2063,
"text": "test",
"position": {
"lat": 43.357048,
"lon": 27.9815636
}
},
{
"id": 2563,
"text": "test2",
"position": {
"lat": 43.3570175,
"lon": 27.9816666
}
},
{
"id": 2538,
"text": "test3",
"position": {
"lat": 43.3092232,
"lon": 27.97827
}
}
]
I don't quite understand what station.loc should be. If you want to display lat and lon just do it like that:
<tbody>
<tr data-ng-repeat="station in stations">
<td>{{station.id}}</td>
<td>{{station.text}}</td>
<td>{{station.position.lat}}</td>
<td>{{station.position.lon}}</td>
</tr>
</tbody>
The JSON you have is a JSON string. You have to parse it to a JavaScript object first:
.controller ("varnaCtrl",function($scope,varnaService)
{
var promise = varnaService.getStations();
promise.then(function(data)
{
$scope.stations = JSON.parse(data.data);
});
})
Related
How to feed template to HTML from Javascript? Sounds confusing? I'll try my best to explain after put all the codes in here...
I have index.html here:
<!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>Inject Template</title>
</head>
<body>
<div id="app">
<div v-html="injectHTML" v-if="injecting"></div>
<div id="chart">
<ol>
<li id="card-wrapper">
<div id="card">
<employee-card :info="emp.chart[1]"></employee-card>
</div>
</li>
</ol>
</div>
</div>
<!-- Vue.js Component: Employee Card Template -->
<script type="text/x-template" id="employee-card-template">
<div class="employee-wrapper" v-if="info" :id="info.id">
<a class="node" :href="'#'+info.id">
<div class="empinfo">
<p class="name">{{info.name}}</p>
<p class="office">{{info.office}}</p>
<p class="title">{{info.title}}</p>
</div>
</a>
</div>
</script>
<script src="lib/vue/dist/vue.js"></script>
<script src="js/app.js"></script>
</body>
</html>
and here is app.js
const app = new Vue({
el: "#app",
data: {
emp: [], //collect employee information from JSON
injectHTML: '',
injecting: false,
key: 0
},
watch: {
key: function () {
app.$forceUpdate();
app.injecting = true;
}
},
created: function () {
this.loadEmpJson();
setTimeout(() => { this.inject(); }, 500);
},
methods: {
loadEmpJson: function () {
const xhr_oho = new XMLHttpRequest();
xhr_oho.open('GET', 'data/employee.json', true);
xhr_oho.responseType = 'text';
xhr_oho.send();
xhr_oho.onreadystatechange = function () {
console.log(`xhr_oho.readyState: ${xhr_oho.readyState}`)
console.log(`xhr_oho.status: ${xhr_oho.status}`)
console.log(`xhr_oho.statusText: ${xhr_oho.statusText}`)
}
xhr_oho.onload = function () {
app.emp = JSON.parse(xhr_oho.responseText);
}
},
inject: function () {
this.injectHTML =
`<div id="chart">
<ol>
<li id="card-wrapper">
<div id="card">
<employee-card :info="emp.chart[0]"></employee-card>
</div>
</li>
</ol>
</div>`
setTimeout(() => { this.key++; }, 500);
}
}
});
Vue.component('employee-card', {
template: '#employee-card-template',
props: {
info: { type: Object, default: () => ({}) }
}
})
lastly, the excerpt employee.json
{
"description": "ABC Company Organizational Chart",
"chart": [
{
"name": "Jimmy Moore",
"office": "Front Office",
"title": "CEO/Owner"
},
{
"name": "Betty Kahoolawe",
"office": "Front Office",
"title": "President"
},
{
"name": "David Merrill",
"office": "Front Office",
"title": "Vice President",
"assistants": [
{
"name": "Amanda Cochran",
"office": "Front Office",
"title": "Executive Assistant"
},
{
"name": "Savannah Clewiston",
"office": "Front Office",
"title": "Budget Officer"
}
]
}
]
}
I would like to be able to feed multi marker template (employee-card) dynamically from app.js. Reason for this, I will have a recursive collecting data from JSON file and elaborate the employee-wrapper template depending on data from JSON. Grouping by the employees such as office, division, component, and branch. Also grouping by the employees under each supervisor where it can be expand and collapse those employees under the supervisor.
But the point I need to be able to feed the from app.js
You can see the output:
1.
1. Betty Kahoolawe
Front Office
President
which should be:
1. Jimmy Moore
Front Office
CEO/Owner
2. Betty Kahoolawe
Front Office
President
Your help is greatly appreciated! Thank you.
Given the following code:
http://jsfiddle.net/KN9xx/1102/
Suppose I received an ajax call with the following data I pass to a scope variable:
$scope.people_model = {
"people":[
{
"id":"1",
"name":"Jon"
},
{
"id":"2",
"name":"Adam"
}
]
};
How would I work with the select box to iterate over the 'people' via ng-options?
<select
ng-options="p.name for name in people_model"
ng-model="people_model">
</select>
Change your select as ,
<select ng-model="currentSelected" ng-options="selection.id as selection.name for selection in people_model.people"></select>
You need to access the array people inside the object people_model
DEMO
var app = angular.module('myapp', []);
app.controller("FirstCtrl", ["$scope",
function($scope) {
$scope.currentSelected = "1";
$scope.people_model = {
"people": [{
"id": "1",
"name": "Jon"
}, {
"id": "2",
"name": "Adam"
}]
};
}
]);
<!DOCTYPE html>
<html ng-app="myapp">
<head>
<title>To Do List</title>
<link href="skeleton.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>
<script src="MainViewController.js"></script>
</head>
<body ng-controller="FirstCtrl">
<select ng-model="currentSelected" ng-options="selection.id as selection.name for selection in people_model.people"></select>
</body>
</html>
I have been trying to solve this and have been looking everywhere. Apologies in advance if this sounds stupid or there is a duplicate question somewhere that I have missed.
I am trying to create dynamic email content and send the email via php mail. I want to use angularJS to compile the html content and using $http.post method send to a submit.php to send email.
I can manually enter in the html content in php and no problem but having a compiled dynamic html is the issue.
I am really not too sure how to tackle this, so any help would be much appreciated.
Thanks,
My angular controller:
$scope.url = 'submit.php';
$scope.formsubmit = function(isValid) {
if (isValid) {
$http.post($scope.url, {"name": $scope.name, "email": $scope.email, "message": $scope.message }).
success(function(data, status) {
console.log(data);
$scope.status = status;
$scope.data = data;
$scope.result = data;
})
}
}
submit.php
$post_date = file_get_contents("php://input");
$data = json_decode($post_date);
$to = $data->email;
$from = "John#example.com";
$name = $data->name;
$subject = "Email from AngularJS";
$htmlContent = $data->message;
I have added my code below :
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Dynamic Email AngularJS</title>
</head>
<body ng-app="myApp" ng-cloak>
<div ng-controller="formCtrl">
<pre ng-model="result">
{{result}}
</pre>
<form name="userForm">
<input type="text" class="form-control" ng-model="$parent.name" placeholder="Name Lastname" required>
<input type="text" class="form-control" ng-model="$parent.email" placeholder="me#email.com" required>
<div ng-view></div>
<button ng-click="add()">New Item</button>
<button type="submit" class="btn" ng-click="formsubmit(userForm.$valid)" ng-disabled="userForm.$invalid">Submit </button>
</form>
</div>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<script src="//code.angularjs.org/1.4.3/angular-route.min.js"></script>
<script src="app.js"></script>
</body>
</html>
app.js:
myApp.controller("formCtrl", ['$scope', '$http','$templateRequest','$compile', function($scope, $http, $templateRequest, $compile) {
$scope.lists = [
{
"year":"year I",
"semesters":[
{
"label": "Semester I",
"max": "4",
"courses": [
{"name": "Introductory Accounting I", "type": "populated"},
{"name": "Principles of Economics I", "type": "populated"},
]
},
{
"label": "Semester II",
"max": "4",
"courses": [
{"name": "Accounting Method II", "type": "populated"},
]
}
]
},
{
"year":"year II",
"semesters":[
{
"label": "Semester I",
"max": "4",
"courses": [
{"name": "Introductory Accounting I", "type": "levelII"},
{"name": "Business Finance I", "type": "levelII"}
]
},
{
"label": "Semester II",
"max": "4",
"courses": [
{"name": "Accounting Method II", "type": "levelII"},
{"name": "Management Accounting II", "type": "levelII"},
]
}
]
}
]
$scope.add = function () {
$scope.lists.push(
{
"year":"year III",
"semesters":[
{
"label": "Semester I",
"max": "4",
"courses": [
{"name": "Introductory Accounting I", "type": "levelII"},
{"name": "Business Finance I", "type": "levelII"}
]
},
{
"label": "Semester II",
"max": "4",
"courses": [
{"name": "Accounting Method II", "type": "levelII"},
{"name": "Management Accounting II", "type": "levelII"},
]
}
]
});
}
$scope.url = 'submit.php';
$scope.formsubmit = function(isValid) {
if (isValid) {
$templateRequest('email.html').then(function(html) {
$scope.contentHtml = $compile(html);
});
$http.post($scope.url, {"name": $scope.name, "email": $scope.email, "message": $scope.contentHtml }).
success(function(data, status) {
console.log(data);
$scope.status = status;
$scope.data = data;
$scope.result = data;
})
}else{
alert('Form is not valid');
}
}
}]);
submit.php:
<?php
$post_date = file_get_contents("php://input");
$data = json_decode($post_date);
$to = $data->email;
$from = "Sam#example.com";
$name = $data->name;
$subject = "Dynamic Email";
$htmlContent = $data->message;
// Set content-type header for sending HTML email
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
// Additional headers
$headers .= 'From: '.$from . "\r\n";
if(mail($to,$subject,$htmlContent,$headers)) {
echo "Mail Sent. Thank you " . $name . ", we will contact you shortly.";
} else {
echo 'Sorry there was an error sending your message. Please try again later.';
}
echo "Name : ".$data->name."\n";
echo "Email : ".$data->email."\n";
echo "Hero : ".$data->hero."\n";
echo "Message": $htmlContent;
?>
email.html
<table ng-repeat="list in lists">
<tr>
<td>
<h1>{{list.year}}</h1>
</td>
</tr>
<tr>
<td ng-repeat="semester in list.semesters">
<table>
<tr>
<td>
<h3>{{semester.label}}</h3>
<ul>
<li ng-repeat="course in semester.courses">{{course.name}}</li>
</ul>
</td>
</tr>
</table>
</td>
</tr>
</table>
I had to do the very same thing. But my setup is somewhat different. My Backend is a Firebase.com database. Loaded into my frontend via angularFire, the library for loading stuff into an angular project. I have a mail template in the front-end. In fact, i plan to let users choose their e-mail template from several provided ones. I just fill in the fields, a but like a mail-merge in MS-Office.
On the serverside, i'm using php-mailer (google it!)
In big lines, this is what's happening:
- Create vars like mailTo (all the emails where i have to send mail to) and bind them to the $scope (yeah i know i shouldn't do that but stay with me)
- other stuf from the database records that should be in the mail, i bind to the $scope again.
- and then i do this:
$templateRequest("templates/mail-packs/mail-1.html")
.then(function(emailtemplate) {
var base = angular.element('<div></div>');
base.html(emailtemplate);
$compile(base)($scope);
$timeout(function(){
mail = base.html()
console.log(mail);
constructMail(mail)
}, 300)
})
the base variabel was needed beceause you are not compling to the DOM. You have to trick angular there and start with a blank DOM.
The function constructMail() is a function just doing that, prepping the data to send to the php-mailer.
I have successfully implemented this architecture in my one project. I have created separate service to get email template. I passed URL and $scope object to getTemplate() method and this method will return compiled email template to me.
templateService.js
angular.module('myApp').factory("TemplateService", ['$resource', '$q', '$rootScope', '$templateRequest', '$compile', '$timeout', function ($resource, $q, $rootScope, $templateRequest, $compile, $timeout) {
class TemplateService {
constructor() {
}
/**
* Get the template from url and then compile it with data.
* #param url
* #param $scope
* #returns {*|Promise<T>}
*/
static getTemplate(url, $scope) {
return $templateRequest(url)
.then(function(response){
let template = angular.element('<div></div>');
template.html(response);
//3. Pass the data to email template, in data will be merged in it
$compile(template)($scope);
return $timeout(function(){
return template.html();
}, 300);
})
.catch(function(err){
return $templateRequest('views/templates/404.html');
});
}
}
return TemplateService;
}]);
contact_email.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="https://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Email</title>
</head>
<body leftmargin="0" marginwidth="0" topmargin="0" marginheight="0" offset="0">
<table align="center" border="0" cellpadding="0" cellspacing="0" height="100%" width="100%" id="bodyTable" style="background: #f2f2f2;padding:40px 10px;">
<tr>
<td align="center" valign="top" id="bodyCell">
<table border="0" cellpadding="0" cellspacing="0" id="templateContainer" style="background: white;text-align: center;border: 1px solid grey;padding: 20px;box-shadow: 0 0 5px 2px grey;margin:0 auto;">
<tr>
<td align="center" valign="top">
<table border="0" cellpadding="0" cellspacing="0" width="100%" id="templateBody">
<tr>
<td valign="top" class="bodyContent">
Hello {{ contactEmailCtrl.contact.firstName }}
<p compile="contactEmailCtrl.message">
</p>
<p>
</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
Usage in controller
contact.controller.js
angular.module('myApp').controller('ContactController', ['$scope', 'Global', 'TemplateService', $scope, Global, TemplateService]) {
let vm = this;
vm.sendEmail = function(params) {
//1. Prepare email template, Pass data to email template and compile it
$scope.contactEmailCtrl = {
user: Global.user,
message: $scope.emailCommunication.message || null,
};
TemplateService.getTemplate('views/templates/emails/contact_email.html', $scope).then(function(emailBody) {
console.log('--> | emailBody ', emailBody);
//Todo: Send email
let emailParams = {
tos: 'example#example.com',
subject: 'subject goes here',
emailBody: emailBody
}
// EmailService.sentEmail(emailParams); // Either send by PHP or Nodejs Or Ruby whatever
}).catch(function(err) {
console.log(' err ', err);
});
};
}
This is whole implementation. Hope this will help who wants to maintain clean architecture and separate email html and inject on the fly to send email.
I am using an ng-repeat directive with filter like so:
<div ng-repeat="person in data">
</div
i.e Showing {{data.length}} Persons. (I am expect to pass the length value to controller)
But i need to pass the filtered length value to controller because i do same logic based on the filtered length value.
1.Method 1
ng-repeat="item in filtered = (data | filter:filterExpr)"
Would create the filtered list.
filtered.length will show the filtered length.
2.Method 2
Use $watch for detecting the filtered length.
$scope.length = $scope.data.length;
$scope.$watch("search", function(query) {
$scope.length = $filter("filter")($scope.data, query).length;
});
Example
var app = angular.module('angularjs-starter', [])
app.controller('MainCtrl', function($scope, $filter) {
$scope.data = [{
"name": "Martin",
"age": 21
}, {
"name": "Peter",
"age": 26
}, {
"name": "Arun",
"age": 25
}, {
"name": "Maxwell",
"age": 22
}];
$scope.counted = $scope.data.length;
$scope.$watch("search", function(query) {
$scope.filteredData = $filter("filter")($scope.data, query);
});
});
<html ng-app="angularjs-starter">
<head lang="en">
<meta charset="utf-8">
<title>Demo</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
<link rel="stylesheet" href="style.css">
<script>
document.write('<base href="' + document.location + '" />');
</script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<input ng-model="search" type="text">
<br>Showing {{data.length}} Persons;
<br>Filtered {{filteredData.length}}
<ul>
<li ng-repeat="person in filteredData">
{{person.name}}
</li>
</ul>
</body>
<script>
</script>
</html>
I'm able to iterate through a simple json loop, but actually the API i'm working with returns a response with multiple headers and I tried different methods to access the results objects but still not working, the response looks like this:
"meta": {
"name": "openaq-api",
"license": "CC BY 4.0",
"website": "https://docs.openaq.org/",
"page": 1,
"limit": 100,
"found": 1544
},
"results": [
{
"city": "Buenos Aires",
"country": "AR",
"locations": 4,
"count": 8064
},
{
"city": "Gemeinde Wien, MA22 Umweltschutz",
"country": "AT",
"locations": 21,
"count": 136958
},
What I'm trying to do is to access results then iterate with cities infos, my runnable attempts:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8">
<title>Open AQ API</title></head>
<body>
<div id="data"></div>
<script src="https://code.jquery.com/jquery-3.2.1.js"
integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE="
crossorigin="anonymous"></script>
<script type="text/javascript">
var url = "https://api.openaq.org/v1/cities";
$.getJSON(url, function (data) {
var json = data
$.each($.parseJSON(json), function() {
alert(results.this.city);
});
});
</script>
</body>
</html>
Attempt 2 :
// data[i]
$.each(data, function(i, item){
$('#data').append(
$('<h1>').text(item.results.city),
$('<div>').text(item.results.country),
$('<h6>').text(data[i].results.count),
);
});
This works just fine, try this instead for your jQuery.
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8">
<title>Open AQ API</title></head>
<body>
<div id="data"></div>
<script src="https://code.jquery.com/jquery-3.2.1.js"
integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE="
crossorigin="anonymous"></script>
<script type="text/javascript">
var url = "https://api.openaq.org/v1/cities";
$.getJSON(url, function (data) {
$.each(data.results, function(i, result) {
console.log(result.city);
});
});
</script>
</body>
</html>
Kindly update below logic, data will give full response, SO you have to take results from data like $.parseJSON(json).results and then run for each loop as shown below.
$.each(json.results, function(index,value) {// json is same as data as per your code
alert(value.city);
});