How to update title of the SPA in angularjs? - javascript

To be noted:
The site that I am talking here is SPA and using angularjs.
Say I have music site. Now there are n number of albums.
Hindi
English
Bhajans
My requirement is if user clicks on Hindi Albums, the title of the page should be set to Hindi, if he clicks on English title should be updated to English and so on.
Plus,how do I change the og tags as well as every albums has social share buttons so I need to update the og tags as well.
If you say that I can set the title while configuring routes,that doesn't works in my scenario.
Scenario
.when('/albums',
{
templateUrl: 'Angular-Templates/albums.html',
controller: 'albumsCtrl',
caseInsensitiveMatch: true,
title: 'Albums'
})
Now albumsCtrl in turns calls db function and fetches the list of availbles albums. Now user will click on any of the fetched albums and title should be updated to the name of the album,
FYI:-
I am NOT using angular.ui, but core angular.

You could define controller at the level.
<html ng-app="app" ng-controller="titleCtrl">
<head>
<title>{{ Page.title() }}</title>
...
<a ng-click="page">
You create controller:
angular.controller('$scope',
function($scope) {
var title = 'default';
$scope.page = function(data) {
title = data;
}
});
Inject Page and Call 'Page.setTitle()' from controllers.

In order to update the title of the browser in JavaScript, you should utilize the document.title property.
Example:
in controller
$scope.setTitleHindi = function() {
document.title = "Hindi";
}
and in your template
<span ng-click="setTitleHindi">Click Me!</span>

Related

Python Flask Web App Navigation Without Page Refresh

I Want to develop a flask navigation bar like Google Contacts.
I Want to Render a particular HTML page inside the red box (as in the picture) when I click each of the navigation buttons (the green box as in picture) without refreshing the page.
I have already tried using
{% extends "layout.html" %}
As #Klaus D. mentioned in the comments section, what you want to achieve can be done using Javascript only. Maybe your question were
How can I send a request to my server-side (to get or fetch some information) and receive back a response on the client-side without having to refresh the page unlike the POST method usually does?
I will try to address the aforementioned question because that's probably your case.
A potential solution
Use Ajax for this. Build a function that sends a payload with certain information to the server and once you receive back the response you use that data to dynamically modify the part of the web-page you desire to modify.
Let's first build the right context for the problem. Let's assume you want to filter some projects by their category and you let the user decide. That's the idea of AJAX, the user can send and retrieve data from a server asynchronously.
HTML (div to be modified)
<div class="row" id="construction-projects"></div>
Javascript (Client-side)
$.post('/search_pill', {
category: category, // <---- This is the info payload you send to the server.
}).done(function(data){ // <!--- This is a callback that is being called after the server finished with the request.
// Here you dynamically change parts of your content, in this case we modify the construction-projects container.
$('#construction-projects').html(data.result.map(item => `
<div class="col-md-4">
<div class="card card-plain card-blog">
<div class="card-body">
<h6 class="card-category text-info">${category}</h6>
<h4 class="card-title">
${item.title_intro.substring(0, 40)}...
</h4>
<p class="card-description">
${item.description_intro.substring(0, 80)}... <br>
Read More
</p>
</div>
</div>
</div>
`))
}).fail(function(){
console.log('error') // <!---- This is the callback being called if there are Internal Server problems.
});
}
Build a function that will fetch the current page via ajax, but not the whole page, just the div in question from the server. The data will then (again via jQuery) be put inside the same div in question and replace old content with new one.
Flask (Server-side)
''' Ajax path for filtering between project Categories. '''
#bp.route('/search_pill', methods=['POST'])
def search_pill():
category = request.form['category']
current_page = int(request.form['current_page'])
## Search in your database and send back the serialized object.
return jsonify(result = [p.serialize() for p in project_list])
Thank you #CaffeinatedCod3r,#Klaus D and #newbie99 for your answers.
I Figured it out. instead of using Flask we can use Angular JS Routing for navigation.
Here is the example that i referred:
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular-route.js"></script>
<head>
<base href="/">
</head>
<body ng-app="myApp">
<p>Main</p>
Banana
Tomato
<p>Click on the links to change the content.</p>
<p>Use the "otherwise" method to define what to display when none of the links are clicked.</p>
<div ng-view></div>
<script>
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider, $locationProvider) {
$routeProvider
.when("/banana", {
template : "<h1>Banana</h1><p>Bananas contain around 75% water.</p>"
})
.when("/tomato", {
template : "<h1>Tomato</h1><p>Tomatoes contain around 95% water.</p>"
})
.otherwise({
template : "<h1>Nothing</h1><p>Nothing has been selected</p>"
});
$locationProvider.html5Mode(true);
});
</script>
</body>
</html>
By Using $locationProvider.html5Mode(true) i was able to remove the # from the URL.

how to set default view using angular-route-segment (not in index.html) angular js

In my MEAN application for nested views I am using angular-route-segment. Everything works fine with the nested views except for the initial default screen.
my first page (index.html) contains header & footer with buttons connect & disconnect. This theme is common in all the pages.
once I click connect, it should load all list of todos (this is where I get problem).
Here is my controller config code
app.config(function ($routeSegmentProvider) {
$routeSegmentProvider.
when('/todos', 's1').
when('/todo/:id', 's2').
when('/task/:id', 's2.task').
segment('s1',{
templateUrl: "public/views/todos.html"
}).
segment('s2',{
templateUrl : "public/views/todo.html"
}).
within().
segment('home',{
default:true,
templateUrl : "public/views/default.html"
}).
segment('task', {
templateUrl: "public/views/task.html",
dependencies: ['id']
})
})
index.html
<html ng-app="Todo">
<body ng-controller="ConnectioCtrl">
<button class="btn btn-primary" ng-click="connect()">Connect</button>
<button class="btn btn-danger" ng-click="disconnect()">Disonnect</button>
<div ng-if="connected" ng-controller="ToDoListCtrl">
Todo List
<div app-view-segment="0"></div>
</div>
</body>
</html>
This perfectly works fine for me. but the problem here is I am forced to give Todo List which is a hyperlink. I don't want this hyperlink to be present in my screen. All that I need is, when ever I click on connect it executes a function which checks all the conditions and returns connected = true, and then by default it should go to list of todos rather than giving a hyperlink Todo list to click on.
please let me know if I need to provide any additional info to bring clarity on this query.
thanks in advance!!

Layout with form in angular Js

I am a beginner in angular Js and need some help / pointers. I want to create an application (SPA). Every page of an application has a header bar and in that header bar, I have a form (like search bar) where a user can add data and search. But I am not being able to approach.
How should my approach be so that this header is present in any page of my app and I must be able to search in any page. How can this be done without code repetition? I mean I dont want to create a directive and call it in every page. I want to know if there is a proper way to do it?
The app should be like Quora where the input field for question is present in any page.
Request you to not downvote it as I am naive in Angular and need some good help.
Thank you in advance.
Search for ui-router and define some states for your application, basically you have a main states which hold header and footer, and sub states that are children of your main state.
your markup would be like this:
<header></header>
<ui-view></ui-view>
<footer></footer>
and the header can contain the search form, and all sub states are loaded in mains <ui-view>
Have you checked out ui-router?
You could define a layout/root state whose template defines multiple named ui-views. The layout/root state could load the persisting elements (ex. the search input field) into one view, and child states could load the unique page content into another view.
ex. layout.html
<div class="layout">
<div class="search" ui-view="search"></div>
<div class="content" ui-view="content"></div>
</div>
ex. state configuration (in a module's config() function)
$stateProvider.state('root', {
url: '',
views: {
'main': {
templateUrl: 'layout.html'
},
'search#root': {
template: '<input type="text" ng-model="search.input" />',
controller: ['$scope', function($scope){
$scope.search = {
input: ''
};
}]
}
}
});
$stateProvider.state('root.page1', {
views: {
'content#root': {
template: '<p>This is the first page.</p>',
}
}
})
.state('root.page2', {
views: {
'content#root': {
template: '<p>This is the second page.</p>'
}
}
});
With that config, you would need to have in your main index.html:
<div ui-view="main"></div>
Plunker Demo

How can I read URL parameters in AngularJS?

I'm trying to make a blog using AngularJS. The home page queries a third party service of mine that returns an array of all my articles/posts. I am displaying shortened versions of these posts on the home page, and want to have "read more" under each post that passes that post's ID through a URL parameter to another HTML page:
index.html:
<div ng-controller="blogCtrl" id="blog">
<div class="post" ng-repeat="post in posts">
<div class="header">
<h1>{{ post.fields.title }}</h1>
<p class="date">{{ post.sys.createdAt | date}}</p>
</div>
<p>{{ post.fields.body | cut:true:1600:' ...'}}</p>
read more
</div>
</div>
What do I need to do in post.html so that I can read the value of id in the URL parameter? Do I need to create a new angularJS app in post.html?
edit:
I've changed the read more link to <a href="post/{{post.sys.id}}"> and i am trying to set up the following route:
app.config(function($routeProvider){
$routeProvider
.when('/post/:postid',{
templateUrl: '/post.html',
controller: 'postCtrl'
})
});
However, clicking the "read more" link doesn't load up post.html, but instead a page that says File not found: /post/2B1K9K2DHqsYaGYcms2YeW. The route doesn't seem to be getting properly set up, since post.html isn't getting loaded.
This isn't all that hard to do, but you need to have routing set up on your app. You can create this functionality in your existing app, or separate it into a new one, it's up to you. Here are the relevant things you'll need to include in your code:
In your app include ngRoute as a dependency:
var myApp = angular.module('myApp', ['ngRoute']);
Also include routing config for your app:
myApp.config(function($routeProvider){
$routeProvider
.when('/someroute', {
templateUrl: 'someFolder/withSomeFile.html'
}
.when('/someroutewithparamters/:aftercolonisparameter', {
templateUrl: 'someFolder/post.html'
}
});
You can include a default route as well, but it's not necessary if you'd rather not. Be sure to include angular-route.js in your index.html for this to work.
Now in your controller you can simply do something like:
myApp.controller('postCtrl', function($routeParams, $scope, postFactory){
$scope.post = postFactory.functionToLoadPost($routeParams.aftercolonisparameter);
});
Obviously this will be different for your implementation based on how everything is set up, and you'll probably want to pick better names for your elements than I did, but those are the things you'll need in place to make this work. It's actually pretty straightforward.

How to get AngularJS to respond to navigation

I am designing a site which has a fixed data set (17 records - each representing a 'book' for sale) and allows navigation between several pages that display details about each of the books. The problem I am having is that when the hyperlink goes to a different view, everything works fine, but if it is hyperlink is to a different book of the same view, it fails to run the controller script. How do I force this to be done.
I have made a minimal executable example:
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.min.js"></script>
<script>
var fooApp = angular.module('fooApp', []);
fooApp.controller('fooCtrl', function ($scope) {
$scope.books = ["Book1", "Book2", "Book3", "Book4", "Book5"]
$scope.selectedBook = "Book1";
var curPath = window.location.toString();
var hashPos = curPath.indexOf("#/");
if (hashPos>0) {
$scope.selectedBook = curPath.substring(hashPos+2);
}
});
</script>
</head>
<body ng-app="fooApp" ng-controller="fooCtrl">
Selected Book: {{selectedBook}}
<ul>
<li ng-repeat="book in books">Visit A {{book}}
</li>
</ul>
<ul>
<li ng-repeat="book in books">Visit B {{book}}
</li>
</ul>
</body></html>
Save the above to two different files: PageA.htm and also as PageB.htm. The selected book is passed as a parameter after the hash mark. You will see the behavior as this: When on PageA you can click on a link to PageB and the book is selected appropriately. But if you click on a link to PageA the URL changes in the address bar, but the controller function does not apparently run. Similarly, on PageB, links to PageA will select a book, but links that stay on PageB do not.
I like the fact that the page is NOT re-read from the server ... it comes out of cache, but I would like to somehow trigger the the controller function again so that the new passed parameter can be read and the correct data displayed. What am I doing wrong?
Update One
Some have suggested to add target="_self" to the hyperlink tag. This works in the simplified minimal example above. Unfortunately, it does not work on fully elaborated site. I don't know why. You can check the full site and the problem is that the "Featured-Book" does not display if you are showing the details of any other book.
Ok. It seems you need to use the $location service and $locationChangeSuccess event in order to keep track url changes. These are part of the Angular core API.
fooApp.controller('fooCtrl', function ($scope, $rootScope, $location) {
$scope.books = ["Book1", "Book2", "Book3", "Book4", "Book5"]
$scope.selectedBook = "Book1";
$rootScope.$on('$locationChangeSuccess', function (event, location) {
$scope.selectedBook = $location.path().substring(1);
});
});
It seems that you are trying to implement a route system.
Have you looked into Angular's ngRoute? check out this example.
ngRoute is great because you can access route data via its $route service or simply via $routeParams.

Categories

Resources