Webpage jumping after using anchorscroll and http.get - javascript

Here is my index.html
<body ng-cloak>
<div id="main">
<!-- angular templating -->
<div ng-view=""></div>{{scrollTo}}
</div>
I have a top menu where I'm using anchors. Top Menu is generated from json files.
Part of top menu json File :
{
"menu": "About Me",
"hrefs": "#/about",
"show": "true",
"menuitem": [
{"submenu": "Research", "addresstoredirect": "#about?scrollTo=research"},
{"submenu": "Education", "addresstoredirect": "#about?scrollTo=education"},
{"submenu": "Career Awards", "addresstoredirect": "#about?scrollTo=careerawards"},
{"submenu": "Visited Institutes", "addresstoredirect": "#about?scrollTo=visitedinstitutes"},
{"submenu": "CV", "addresstoredirect": "#about?scrollTo=cv"}
]
},
Here is method for anchorscroll :
mainApp.run(function($rootScope, $location, $anchorScroll, $routeParams,$timeout) {
$rootScope.$on('$routeChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
if ($location.hash($routeParams.scrollTo)) {
$timeout(function() {
var hashId = $location.hash($routeParams.scrollTo);
$anchorScroll();
//TODO
},3000);
}});
});
Each view also contains dynamic content downloaded from json files for example here is aboutView controller :
mainApp.controller('aboutController', function ($scope, $http,$routeParams,$localStorage){
if ($localStorage.message === "ENG")
{
$http.get('../app/assets/json/abouttxtEng.json').success(function(data) {
$scope.aboutTexts = data;
})}
And aboutView.html
<h1>About View</h1>
<p>{{ message }}</p>
<br>
<br>
<p>{{aboutTexts[0].aboutString[0]}}
<p>{{aboutTexts[0].aboutString[1]}}
<p>{{aboutTexts[0].aboutString[2]}}
<br>
<br>
<p>{{aboutTexts[1].aboutString2[0]}}
<p>{{aboutTexts[1].aboutString2[1]}}
<p>{{aboutTexts[1].aboutString2[2]}}
<a name="research"></a>
<div id="research">
<br>
<br>
<h3>This is research section of about page</h3>
Research
<p>{{aboutTexts[2].Research[0]}}
<p>{{aboutTexts[2].Research[1]}}
<p>{{aboutTexts[2].Research[2]}}
</div>
<a name="education"></a>
<div id="education">
And last piece of the storry. Part of abouttxtEng.json file :
[{
"aboutString":
[
"aboutText1ENG",
"aboutText2ENG",
"aboutText3ENG"
]
},
{
"aboutString2":
[
"aboutText4ENG",
"aboutText5ENG",
"aboutText6ENG"
]
},
{
"Research" :
[
"ResearchText1ENG",
"ResearchText2ENG",
"ResearchText3ENG",
"ResearchText4ENG"
]
},
{
So the problem is when I remove timeout from $rootScope.$on and click any anchor on topmenu, "jump will be executed site will be positioned correctly, but after a while http.get will return aboutText1ENG etc. and page will go down. When I used timeout ( everything is fine ) but 3 seconds is just my assumption. What if http.get will work slower etc. Maybe there is a way to wait before executing jump after http.get will finish ?
I have second solution for that, just in case. I can put whole content in *.js files and load it in the beginning in index.html, but it is good for small amount of content, for bigger it is not. Can sb can help me out ?
P.S Don't bother about html it's just a tests.

Related

How to click on the thumb and the video appear AngularJS?

Here´s my code
<div class="container">
<!-- THE YOUTUBE PLAYER -->
<div class="vid-container">
<iframe id="vid_frame" ng-src="{{selectedVideo.url}}" frameborder="0" width="560" height="315"></iframe>
</div>
<!-- THE PLAYLIST -->
<div class="vid-list-container">
<div class="vid-list">
<div ng-repeat="video in youTubeVideos">
<div class="vid-item" ng-click="selectedVideo.url = video.url">
<div class="thumb"><img ng-src="//img.youtube.com/vi/{{video.img}}/0.jpg"></div>
<div class="desc">{{video.desc}}</div>
</div>
</div>
</div>
</div>
</div>
</div>
$scope.youTubeVideos = [
{
url: '//youtube.com/embed/eg6kNoJmzkY?autoplay=1&rel=0&showinfo=0&autohide=1',
img: 'eg6kNoJmzkY',
desc: 'Jessica Hernandez & the Deltas - Dead Brains'
},
{
url: '//youtube.com/embed/_Tz7KROhuAw?autoplay=1&rel=0&showinfo=0&autohide=1',
img: '_Tz7KROhuAw',
desc: 'Barbatuques - CD Tum Pá - Sambalelê'
},
];
$scope.selectedVideo = {};
There is an error on Console:
Error: [$interpolate:interr] Can't interpolate: {{selectedVideo.url}}
Error: [$sce:insecurl] Blocked loading resource from url not allowed by $sceDelegate policy. URL: https://youtube.com/embed/eg6kNoJmzkY
I can not solve this error and I also need to leave video # 1 available in vid-container
You resource request is being blocked by the $sceDelegateProvider in AngularJS.
The $sceDelegateProvider allows one to get/set the whitelists and
blacklists used to ensure that the URLs used for sourcing AngularJS
templates and other script-running URLs are safe
Add the URL to the $sceDelegateProvider whitelist and you should be able to grab the video
angular.module('myApp', []).config(function($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist([
'self',
'https://youtube.com/embed/**'
]);
});
How can I change the selected video?
var app = angular.module('myApp', []);
app.controller('videoCntrl', ['$scope', '$http', function ($scope, $http) {
$scope.changeVideo = function (video) {
$scope.selectedVideo = $scope.videos[video];
}
$scope.videos = [{
url: '//youtube.com/embed/eg6kNoJmzkY?autoplay=1&rel=0&showinfo=0&autohide=1',
img: 'eg6kNoJmzkY',
desc: 'Jessica Hernandez & the Deltas - Dead Brains'
},
{
url: '//youtube.com/embed/_Tz7KROhuAw?autoplay=1&rel=0&showinfo=0&autohide=1',
img: '_Tz7KROhuAw',
desc: 'Barbatuques - CD Tum Pá - Sambalelê'
}];
}]);
Add the ng-click attribute to your desired trigger. Something like:
<div ng-click="changeVideo(1)"></div>
Finally, add the ng-controller attribute on the body tag.
<body ng-controller="videoCntrl">

ng-mouseenter and ng-mouseleave not working inside an ng-repeat loop

I have an angular ng-repeat that displays list items inside of an unordered list. Within each list item, I have another unordered list of sub-items. Inside each sub-item <li>, I have a div to display a name and a div to store a value.
I am trying to hook up the ng-mouseenter and ng-mouseleave attributes to the value div, but they aren't firing. Even just trying to execute a console.log statement inside of the directives is not printing anything to the console.
I have no page load errors, everything displays on the page fine so angular is set up correctly, it's just ng-mouseenter and ng-mouseleave are not firing.
What do I have to do in order to get ng-mouseenter and ng-mouseleave to properly fire?
index.html
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular.js"></script>
<script src="js/app.js"></script>
<script src="js/SkillsetController.js"></script>
</head>
<body ng-app="mainApp">
<div id="skillset" ng-controller="SkillsetController">
<h2>{{title}}</h2>
<div class="skillListContainer" id="skillListContainer">
<ul class="skillCategoriesList">
<li class="skillCategory" ng-repeat="category in skillsetCategories">
<h3>{{category.title}}</h3>
<ul class="skillsList">
<li class="skill" ng-repeat="skill in category.skills">
<div class="skillName">
<span>{{skill.name}}</span>
</div>
<div class="skill-value" data-skill-value="{{skill.level}}"
ng-mouseenter="console.log('enter');"
ng-mouseleave="console.log('leave');">
{{skill.level}}
</div>
</li>
</ul>
</li>
</ul>
</div>
</div>
</body>
</html>
app.js
var app = angular.module("mainApp", []);
SkillsetController.js
app.controller("SkillsetController", ["$scope", function ($scope) {
$scope.title = "Skillset";
$scope.skillsetCategories = [
{
"title": "Backend",
"skills": [
{
"name": "Java",
"level": 10
}
]
},
{
"title": "Frontend",
"skills": [
{
"name": "HTML",
"level": 9
}
]
},
{
"title": "Frameworks",
"skills": [
{
"name": "jQuery",
"level": 9
}
]
},
{
"title": "Databases",
"skills": [
{
"name": "MySQL",
"level": 10
}
]
}
];
}]);
ng-mouseenter and ng-mouseleave work just fine in your code, just you can't call console.log in html directly, the functions you are using in your html template must be defined in your controller, try move console.log to your controller should resolve the problem.
index.html
<div class="skill-value" data-skill-value="{{skill.level}}"
ng-mouseenter="mouseEnter()"
ng-mouseleave="mouseLeave()">
{{skill.level}}
</div>
controller:
$scope.mouseEnter = function(){
console.log('enter');
};
$scope.mouseLeave = function(){
console.log('leave');
};
console.log() is not valid directly in the html
thats why you need to create those function to work
just change this add this function to your controller
$scope.mouseEnter = function(){
console.log("enter");
};
$scope.mouseLeave = function(){
console.log("leave");
};
and change this in the html
<div class="skill-value" data-skill-value="{{skill.level}}"
ng-mouseenter="mouseEnter()"
ng-mouseleave="mouseLeave()">
{{skill.level}}
</div>
Here is a example

angularjs application - can i include business logic/backend code in my angular controllers written inside javascript file

I am developing a web application with technologies html,angularjs, java, Spring.
My requirement is to create a search page for my application. Please find the demo here
I need to enter the details and search the information.Please enter Atlanta in From text field and Chicago in To text field and click on SearchLocations button to view the information.
Few questions which i have:
1) Can i write the business logic in my angularjs controllers which are written in javascript file as the sample code shown below:
angular.module('myApp').controller('searchController', ['$scope', function($scope) {
$scope.places = ['', ''];
$scope.searchValue = '';
$scope.submit = function() {
$scope.showGrid = $scope.Passport;
if ($scope.places[0].length > 0 && $scope.places[1].length > 0) {
$scope.searchValue = $scope.places[0] + $scope.places[1];
}
};
2) Can i write backend logic in my controllers. If yes can you please suggest any links so that i can proceed or gain knowledge from their.
The javascript code which i have written, can i say it as a backend code/business logic. Sorry about this kind of questions but i thought this is the great platform to put my questions to clarify..
If someone ask me to write backend code for this kind of search functionality, how would anyone proceed. Any suggestions would be very very helpful.The code which i wrote is as shown in the demo plunker above.Thanks.
js code:
angular.module('myApp', ['ngAnimate', 'ui.bootstrap', 'ngTouch', 'ui.grid', 'ui.grid.selection', 'ui.grid.edit', 'ui.grid.cellNav']);
angular.module('myApp').controller('citiesCtrl', function($scope) {
// $scope. places = undefined;
$scope.items = ["Atlanta", "Chicago", "NewYork"];
$scope.selectAction = function() {
console.log($scope.places1);
};
});
/*Controller for searchLocations button*/
angular.module('myApp').controller('searchController', ['$scope', function($scope) {
$scope.places = ['', ''];
$scope.searchValue = '';
$scope.submit = function() {
$scope.showGrid = $scope.Passport;
if ($scope.places[0].length > 0 && $scope.places[1].length > 0) {
$scope.searchValue = $scope.places[0] + $scope.places[1];
}
};
$scope.users = [{
'name': 'AtlantaChicago',
'show': true,
'details': [{
"Travel Date": "10/10/2014",
commute: "Bus"
}, {
"Travel Date": "10/11/2014",
commute: "flight"
}]
}, {
'name': 'NewYorkChicago',
'show': true,
'details': [{
"Travel Date": "3/15/2016",
commute: "flight"
}, {
"Travel Date": "10/12/2016",
commute: "flight"
}, ]
}];
$scope.gridOptions = {
enableFiltering: true,
columnDefs: [{
name: 'Travel Date',
width: '5%'
}, {
name: 'Departurecommute',
enableFiltering: false,
width: '12%'
}],
rowHeight: 20,
enableHorizontalScrollbar: 2
};
}]);
html code:
<div>
<label>
Show one Grid
<input type="radio" name="Passport" ng-model="Passport" value=1 ng-click="ShowPassport('Y')" />
</label>
<label>Show two Grids
<input type="radio" name="Passport" ng-model="Passport" value=2 ng-click="ShowPassport('N')" />
</label>
</div>
<div class="row">
<div class="form-group" ng-controller="citiesCtrl">
<label>From</label>
<input type="text" ng-model="places[0]" placeholder="Type Departure City" typeahead="item for item in items | filter:$viewValue | limitTo:8">
</div>
<div class="form-group" ng-controller="citiesCtrl">
<label>To</label>
<input type="text" ng-model="places[1]" placeholder="Type Destination City" typeahead="item for item in items | filter:$viewValue | limitTo:8">
</div>
</div>
<input type="button" value="SearchLocations" ng-click="submit()">
<div ng-show="showGrid==='1'||showGrid==='2'">
<div ng-repeat="user in users | filter: {name: searchValue} : true ">
<h3>First Grid</h3>
<div ui-grid="{ data: user.details }" ng-show="user.show" class="myGrid"></div>
</div>
</div>
<div ng-show="showGrid==='2'">
<div ng-repeat="user in users | filter: {name: searchValue} : true ">
<h3>Second Grid</h3>
<div ui-grid="{ data: user.details }" ng-show="user.show" class="myGrid"></div>
</div>
</div>
Angular is MVW framework, the main component is view and model. So Basically its used for segregation of page rendering from Server Code. Now business logic related to client request handling and page rendering could be write in angular controller but the logic which is related to our actual data/database can not be write in angular controller.So you better know what kind of code you have in back-end and decide based on that.

How to properly execute a function inside ng-repeat

SITUATION:
I am making an app in AngularJs that assign permissions.
In order to do this i have three nested ng-repeat.
First loop: display PERMISSION GROUP
Second loop: For each permission group display CATEGORIES.
Inside this loop execute a function that will get all the SUB CATEGORIES for each category
Third loop: display SUB CATEGORIES
ISSUE:
The problem is in the execution of the function inside the second loop.
ATTEMPT 1 - ng-init:
<div class="row" ng-repeat="permission_group in list_permission_groups">
<div class="col-sm-3">
<h3>
{{permission_group.permission_group_name}}
</h3>
</div>
<div class="col-sm-9">
<ul>
<li ng-repeat="category in list_categories">
<span>
{{ category.name }}
</span>
<div class="checkbox">
<label>
<div ng-init="temp_result = get_Sub_Categories(category.category_id)">
<p ng-repeat="sub_category in temp_result">
{{ sub_category.name }}
</p>
</div>
</label>
</div>
</li>
</ul>
</div>
</div>
In the controller:
$scope.get_Sub_Categories = function(category_id) {
$http({
url: base_url + 'main/json_get_list_sub_categories',
data: {
category_id: category_id
},
method: "POST"
}).success(function(data) {
return data;
});
}
Te behavior is quite strange. Porbably due to dirty checking the page is loaded 682 times.
No result is displayed.
ATTEMPT 2 - ng-click: (only for debug)
<div class="row" ng-repeat="permission_group in list_permission_groups">
<div class="col-sm-3">
<h3>
{{permission_group.permission_group_name}}
</h3>
</div>
<div class="col-sm-9">
<ul>
<li ng-repeat="category in list_categories">
<span>
{{ category.name }}
</span>
<div class="checkbox">
<label>
<button ng-click="get_Sub_Categories(category.category_id)">
GET SUB-CATEGORIES
</button>
{{ list_sub_categories }}
</label>
</div>
</li>
</ul>
</div>
</div>
In the controller:
$scope.get_Sub_Categories = function(category_id) {
$http({
url: base_url + 'main/json_get_list_sub_categories',
data: {
category_id: category_id
},
method: "POST"
}).success(function(data) {
$scope.list_sub_categories = data;
});
}
This time the page is loaded only once.
If I press the button the proper sub-categories are displayed BUT of course not only for the corresponding category but FOR ALL, because i am modifying the var in the global scope.
THE AIM:
What I want to obtain is simply displaying all the proper sub-categories for each category.
Without using a button, but simply see all the proper content as soon as the page load.
But i don't understand how can this be done properly in AngularJs.
THE QUESTION:
How can i properly execute a function inside a ng-repeat that return and display different data for each loop?
EDIT - DUMP OF EXAMPLE OF SUB-CATEGORIES FOR ONE CATEGORY:
[{
"sub_category_id": "1",
"name": "SUB_CATEGORY_1",
"category_id_parent": "1",
"status": "VISIBLE"
}, {
"sub_category_id": "2",
"name": "SUB_CATEGORY_2",
"category_id_parent": "1",
"status": "VISIBLE"
}, {
"sub_category_id": "3",
"name": "SUB_CATEGORY_3",
"category_id_parent": "1",
"status": "VISIBLE"
}, {
"sub_category_id": "4",
"name": "SUB_CATEGORY_4",
"category_id_parent": "1",
"status": "VISIBLE"
}]
Calling a function inside ng-repeat is same as normal one. Since you need to display the sub categories at the time of page loading its better to get these data beforehand.
Asynchronously loading sub categories will not fit into this scenario.
Here is a minimal snippet achieving this (JS Fiddle)
<div ng-app="app" ng-controller="ctrl">
<div ng-repeat="category in model.categories"> <span> Category: {{ category.name }} </span>
<p ng-repeat="subCategory in getSubCategories(category.Id)">{{ subCategory.name }}</p>
</div>
</div>
Controller
angular.module("app", [])
.controller('ctrl', ['$scope', function ($scope) {
$scope.model = {
categories: [{
"Id": 1,
name: '1'
}, {
"Id": 2,
name: '2'
}],
subCategories: [{
"parentId": 1,
name: 'a1'
}, {
"parentId": 1,
name: 'a2'
},
{
"parentId": 2,
name: 'a3'
}]
}
$scope.getSubCategories = function(parentId){
var result = [];
for(var i = 0 ; i < $scope.model.subCategories.length ; i++){
if(parentId === $scope.model.subCategories[i].parentId){
result.push($scope.model.subCategories[i]);
}
}
console.log(parentId)
return result;
}}])
The subcategory example did not work for my case and it took my code into an infinte loop for some reason. may be because i was using an accordion.
I achieved this function call inside ng-repeat by using ng-init
<td class="lectureClass" ng-repeat="s in sessions" ng-init='presenters=getPresenters(s.id)'>
{{s.name}}
<div class="presenterClass" ng-repeat="p in presenters">
{{p.name}}
</div>
</td>
The code on the controller side should look like below
$scope.getPresenters = function(id) {
return SessionPresenters.get({id: id});
};
While the API factory is as follows:
angular.module('tryme3App').factory('SessionPresenters', function ($resource, DateUtils) {
return $resource('api/session.Presenters/:id', {}, {
'query': { method: 'GET', isArray: true},
'get': {
method: 'GET', isArray: true
},
'update': { method:'PUT' }
});
});
I think that the good solution here is to use Angular Directive.
You can see an example of directive used in a ng-repeat here : Angular Directive Does Not Evaluate Inside ng-repeat
For more information on directives, you can check the official documentation : https://docs.angularjs.org/guide/directive
I would create a factory for category then move your get_sub_categories function into this new factory.

Angular scope and Kendo UI controls

Suppose I have following html file:
<!DOCTYPE html>
<html>
<head>
<title>LOG</title>
</head>
<body>
<div class="panel panel-success">
<!-- Default panel contents -->
<div class="panel-heading">Log data</div>
<div class="panel-body">
<!-- List group -->
<ul class="list-group">
<li class="list-group-item">Start processing at {{StartProcessing }}</li>
<li class="list-group-item">Finished processing at {{EndProcessing }}</li>
</ul>
<div id="logTvId" kendo-tree-view
k-data-source="treeData">
</div>
</div>
</div>
and following controller code:
Arch.LogController = function ($scope, $resource, $routeParams)
{
var LogResource = $resource('log/:markerId', {}, {
get: {method: "GET", isArray: false}
});
LogResource.get({markerId: $routeParams.markerId}, function (data1)
{
$scope.StartProcessing = new Date(data1.StartProcessing).toLocaleString();
$scope.EndProcessing = new Date(data1.EndProcessing).toLocaleString();
$scope.treeData = new kendo.data.HierarchicalDataSource({ data: [
{ text: "Item 1" },
{ text: "Item 2", items: [
{ text: "SubItem 2.1" },
{ text: "SubItem 2.2" }
] },
{ text: "Item 3" }
]});
});
};
After page load I can see StartProcessing and EndProcessing on page, but I can't see treeview. If I take out code related to $scope.treeData from resource load (say the next instruction after)
then everything works as expeteced. If I add $scope.$apply() to my initial controller code it throws exception...
What I'm doing wrong? Should I deal with promises ($q ??) and wait after resource is loaded?
Thanks in advance.
Ok, actually problem is solved. In resource handler I create kendo treeview by "hand" (via jquery, as usual), so I'm not using kendo-tree-view directive. Simple div with id + jquery.

Categories

Resources