I have an HTML page and multiple URLs as follows
var app = angular.module('app', []);
app.controller('index', ($scope,$http) => {
$http.get('/get_js').then((res) => {
$scope.cat = res.data;
}, () => {
alert('database error');
});
});
/get_js
/get_node
/get_ng
......
I expect if I query different url, such as $http.get('/get_js') or $http.get('/get_node') or $http.get('/get_ng') it will render different content on the same HTML.
For example, I have several links. If I click on 'a'link, HTML will render some content via '/get_js'. If I click on 'b'link, HTML will render some content via '/get_ng' and so on. Each time, I will click one link.
Could anyone tell me how can I do that?
Thank you very much!
PS: I am using an express server to host the content.
Then you can take a function and make appropriate api call in that function when a link is clicked by sending the parameter.
Steps:
Write a funciton which calls each api dynamically depending on the
parameter.
Send the api url as a parameter from the respective anchot tag to
that function.
Make the api call in that function and show the response in html
Here is how the function may look, I commented your API call.
$scope.linkClicked = function(link)
{
// $http.get('/get_js').then((res) => {
// $scope.data = res.data;
// }, () => {
// alert('database error');
// });
$scope.data = link + ' clicked';
}
Code:
var app = angular.module('myApp', []);
app.controller('index', function($scope) {
$scope.linkClicked = function(link)
{
// $http.get('/get_js').then((res) => {
// $scope.data = res.data;
// }, () => {
// alert('database error');
// });
$scope.data = link + ' clicked';
}
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="index">
<a ng-click="linkClicked('get_js')"> Link1 </a>
<a ng-click="linkClicked('get_node')"> Link2 </a>
<a ng-click="linkClicked('get_ng')"> Link3 </a>
<p ng-if="data"> {{data}} </p>
</div>
</body>
</html>
Please run the above snippet
Here is a working DEMO
Related
Without page refresh, I am calling an ajax request that goes to the controller and brings a Thymeleaf fragment,
On button click, I request the controller using ajax to get the fragment. Every Time I click on the button same fragment gets called but with a different <p> tag innerHTML.
<div id="express" th:fragment="Display">
<p id="app">Include details about your goals</p>
</div>
For the first time, js works very well, split into an array and add span tag but the issue with the new content which is dynamically replaced.
The issue is on the javascript side when the new fragments with different innerHTML inside of the <p> tag come the Javascript did not work. I need to refresh the page to re-run the js which I don't want to refresh.
here is the js
let comp = document.getElementById("app").innerHTML;
let struct = comp.split(" ");
document.getElementById("app").innerHTML = struct.reduce((acc, word, index) => {
return `${acc} <span class="word">${word}</span>`;
}, "");
const handleClick = () => {
axios.post(url)
.then(response => {
console.log(response.data);
$("#express").replaceWith($recievedHTML);
})
.catch(error => {
console.log(error);
});
}
Let's say you have your HTML page, which has your JS file or you have added your JS inside <script> tag directly. Something like ...
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<script src="/path/lib/jquery/3.5.1/jquery.min-dc5e7f18c8d36ac1d3d4753a87c98d0a.js" type="text/javascript"></script>
<script src="/path/js/your_file.min-cf4fcae72d4468307341eac1012bb6d8.js" type="text/javascript"></script>
</head>
<body>
<div id="express" th:fragment="Display">
<p id="app">Include details about your goals</p>
</div>
</body>
</html>
Javascript for this page may look like ...
$(function() {
function my_load_function() {
// do your loading procedures here
// for example I just copied your inline code...
let comp = document.getElementById("app").innerHTML;
let struct = comp.split(" ");
document.getElementById("app").innerHTML = struct.reduce((acc, word, index) => {
return `${acc} <span class="word">${word}</span>`;
}, "");
}
function my_do_something_else_function() {
// dosomething else over here
}
const handleClick = () => {
axios.post(url)
.then(response => {
console.log(response.data);
// what is '$recievedHTML'? should it be response.data?;
// ayway, you said replacement works;
$("#express").replaceWith($recievedHTML);
// after this call any function again
my_load_function();
my_do_something_else_function();
})
.catch(error => {
console.log(error);
});
};
// call your loading function first time
my_load_function();
});
I have put my additional explanation in the comments of JS code. Please note, I just write it directly in SO and didn't even try to run, so there are maybe some typos.
The fruit is just so I can make sure it works. Then I will make it work with mlab
Here is what I have in my html page I want it to show in.
<body ng-controller="PackingController as vm">
<h2>List of fruits</h2>
<li ng-repeat="fruit in vm.fruits">{{fruit}}</li>
</body>
In my packingcomponents.js page I have it like this.
class PackingController {
constructor($http) {
this.pack = "are you here";
this.packing = $http({
method: "GET",
url: "/api/camp"
//handels success
}).then(function mySuccess(response) {
console.log(response.data);
return response.data;
//handels errors
}, function myError(response) {
return response.statusText;
});
this.packinglist = this.packing;
console.log(this.packing);
}
}
Then last page I have is my angular_app.js page.
app.controller("PackingController", PackingController)
this.hello = "world";
this.fruits = ["apples", "oranges", "berries"];
Right now I am trying to just get it to work then make it show my packing list on the page.
If you are using AngularJs Modify these part of codes:
1-Use this template for Your controllers
(function() {
"use strict";
angular.module("app")
.controller("PackingController", PackingController);
/* #ngInject */
function PackingController(factory) {
var vm = this;
//-------------------------------variables
vm.fruits = [];
//-------------------------------functions
main();
function main() {
// call factory and get controller's data
}
}
})();
2-Modify your html codes
<div ng-controller="PackingController as vm">
<h2>List of fruits</h2>
<ul>
<li ng-repeat="fruit in vm.fruits">{{fruit}}</li>
</ul>
</div>
cartController in AngularJS:
angular.module('demo', [])
.controller('Hello', function($scope, $http) {
$scope.refreshCart = function() {
$http.get('http://localhost:8080/rest/cart')
.success(function(response) {
$scope.items = response.data;
});
};
$scope.removeFromCart = function(productId) {
$http.delete('/delete/' + productId)
.success(function (data) {
$scope.refreshCart();
});
};
$scope.addToCart = function(productId) {
$http.put('/add/'+ productId)
.then(function(response) {
$scope.refreshCart();
});
};
});
First HTML file (here everything works):
<a href = "#" type="button" class="btn btn-info" th:attr="
ng-click='addToCart(' + ${product.id} + ')'" data-toggle="modal" data-target="#myModal">
Add to cart</a>
Second HTML file:
<html lang="en" xmlns:th="http://www.thymeleaf.org" ng-app="demo">
<script src="http://localhost:8080/cartController.js"></script>
<body ng-controller="Hello">
(...)
<tbody ng-repeat="item in items.cartItemList">
<div class="row">
<h4 class="nomargin">{{item.product.name}}</h4>
<p>{{item.product.description}}</p>
</div>
<td data-th="Price">{{item.price}} PLN</td>
<td data-th="Quantity">{{item.quantity}}</td>
</tbody>
(...)
So what i need to do is:
1) Hit the button in first HTML file, and load JSON to $scope.items (it works).
2) Show the second HTML file, load JSON from $scope.items, and view this JSON to user.
But when I get the second HTML file and try to show data, the $scope.items is empty. Can you help pleae ?
Do you get console errors in your browser? Maybe you have to define items on the controller as empty array like in the example below ...
.controller('Hello', function($scope, $http) {
//define empty array
$scope.items = [];
$scope.refreshCart = function() {
$http.get('http://localhost:8080/rest/cart')
.success(function(response) {
$scope.items = response.data;
});
};
//...
}
I would suggest you to use broadcast and emit. Pass data between the controllers using these. You should use $broadcast if you want to pass data from parent controller to child controller. And emit if the other way around.
I have a page on a website based on AngularJS on which content gets loaded via ajax into a div. My problem is that the Angular directives in the loaded content and the controller seem to get ignored. How can I make the controller working?
HMTL:
Load Content
<div id="myForm-con">
</div>
<script src="js/angular.min.js"></script>
<script src="js/app.js"></script>
<script type="text/javascript">
$('#loadContent').on('click', function() {
$.post("load-my-form.php", function(data, result) {
$('#myForm-con').html(data);
});
});
</script>
app.js
(function() {
var app = angular.module('app', []);
app.controller('validationCtrl', ['$scope',
function ($scope) {
$scope.submitForm = function () {
$scope.submitted = true;
if ($scope.myForm.$valid) {
alert('form is valid');
}
}
}
]);
})();
HTML ajax loaded form
<div ng-controller="validationCtrl">
<form id="my-form" name="myForm" ng-submit="submitForm()" novalidate>
...
</form>
</div>
I'd probably try something like this:
HTML
Load Content
Angular
$scope.loadContent() = $http.post("load-my-form.php", data).then(function (result) {
$('#myForm-con').html(result);
});
Or alternatively
Angular
$scope.formResults = '';
$scope.loadContent() = $http.post("load-my-form.php", data).then(function (result) {
$scope.formResults = result;
});
HTML
<div id="myForm-con">{{formResults}}</div>
In order for this to work you have to do 2 things:
1 - use angular http and .then for the callback -
$http.post('/someUrl', data, config).then(successCallback, errorCallback);
2- use angular data-binding to link your data to a view, for example - 2-ways data-binding.
Still wrapping my head around AngularJS. I have a pretty basic page which has two controllers. One has text input to take tags (for searching). The other calls http.get(), using the tags to get the images... it does a bit of ordering and then they're displayed. Following some info on the page below, I came up w/ something.
Can one controller call another?
Caveat: It requires onClick() to execute. Generally I want it to load up on page load with zero tags... and after a click with the tags. I've seen a few suggestions in other threads here, but I'm not quite sure how to pull them off in this case. imagesController runs on load, but of course doesn't get past the 'handleBroadcast' bit.
var myModule = angular.module('myModule', []);
myModule.run(function($rootScope) {
$rootScope.$on('handleEmit', function(event, args) {
$rootScope.$broadcast('handleBroadcast', args);
});
});
function tagsController($scope) {
$scope.handleClick = function(msg) {
$scope.tags = msg;
$scope.$emit( 'handleEmit', { tags: msg });
};
}
function imagesController($scope,$http) {
$scope.$on('handleBroadcast', function(event, args) {
$scope.tags = args.tags;
var site = "http://www.example.com";
var page = "/images.php";
if ( args.tags ) {
page += "?tags=" + $scope.tags;
}
$http.get(site+page).success( function(response) {
// SNIP
$scope.data = response;
});
});
}
The HTML is quite trivial. Slightly simplified, but it should suffice.
<form name="myForm" ng-controller="tagsController">
<div class="left_column">
<input class="textbox_styled" name="input" data-ng-model="tags"><br>
<button ng-click="handleClick(tags);">Search</button><br>
</div>
</form>
<div class="centered" data-ng-controller="imagesController">
<span class="" data-ng-repeat="x in data">
{{x}}
</span>
</div>
Not sure I fully understood, but if you want to show it with no tags on load, simply emit the event when the controller loads:
function tagsController($scope) {
$scope.handleClick = function(msg) {
$scope.tags = msg;
$scope.$emit( 'handleEmit', { tags: msg });
};
$scope.$emit( 'handleEmit', { tags: "" }); // or $scope.handleClick("");
}