ng-Include: evaluator function never called - javascript

HTML:
<section ng-controller="NavigationController as navCtrl">
<ul>
<li ng-click="navCtrl.setNav(1)" ng-class="{ 'myApp_nav_items_selected': navCtrl.isNavPage(1) , 'myApp_nav_items': !navCtrl.isNavPage(1) }"><a ng-class="{ 'myApp_nav_selected_a': navCtrl.isNavPage(1) , 'myApp_nav_a': !navCtrl.isNavPage(1) }" href="#">Option 1</a></li>
<li ng-click="navCtrl.setNav(2)" ng-class="{ 'myApp_nav_items_selected': navCtrl.isNavPage(2) , 'myApp_nav_items': !navCtrl.isNavPage(2) }"><a ng-class="{ 'myApp_nav_selected_a': navCtrl.isNavPage(2) , 'myApp_nav_a': !navCtrl.isNavPage(2) }" href="#">Option 2</a></li>
<li ng-click="navCtrl.setNav(3)" ng-class="{ 'myApp_nav_items_selected': navCtrl.isNavPage(3) , 'myApp_nav_items': !navCtrl.isNavPage(3) }"><a ng-class="{ 'myApp_nav_selected_a': navCtrl.isNavPage(3) , 'myApp_nav_a': !navCtrl.isNavPage(3) }" href="#">Option 3</a></li>
</ul>
<div class="myAppta_page">
<div ng-include="navCtrl.getPage()"></div>
</div>
</section>
JS
tripdataApp.controller('NavigationController', function ($scope) {
this.$scope = $scope;
this.$scope.navPage =1;
this.setNav = function(theNavPage) { <--- WORKS OK
console.log("set nav " + theNavPage);
this.$scope.navPage = theNavPage;
console.log("nav IS set to " + this.$scope.navPage);
};
this.isNavPage = function(checkNavPage) { <---- WORKS OK
return this.$scope.navPage === checkNavPage;
};
this.getPage = function() { <---- NEVER CALLED
console.log("-=-=-=-=- nav IS set to " + this.$scope.navPage);
switch (this.$scope.navPage)
{
case 1:
console.log("dashboard");
return "#/pages/dashboard.php";
break;
default:
console.log("ddefault");
return "#/pages/unimplemented.php";
break;
}
}
});
What am I doing wrong?

As per I can see in the docs, there is no reference saying that you can evaluate a controller method within an ng-include directive. Other than that, it does say that you can use a constant but you have to add single quotes wrapping up the content of the ng-include.
For more info https://docs.angularjs.org/api/ng/directive/ngInclude
I think a different approach is the solution for this issue.

Related

How to click using query selector

I am having a list of navigation items that on load click the first element from the list
<li class="nav-item" v-for="(checkoutplan, index) in checkoutplans" :key="checkoutplan.id">
<a class="nav-link" :class="{ 'active show' : index === 0 }" href="#settings" data-toggle="tab" #click="editModal(checkoutplan)">Checkout Plan {{index +1}}</a>
</li>
What i am trying
document.querySelector("li[class='nav-item']").click()
nor
document.querySelector("li.nav-item:first-child").click()
It is not working
created() {
axios.get("api/checkoutplan")
.then(({ data }) => {this.checkoutplans = data;document.querySelector("a.nav-link:first-child").click();});
}
First add refs to your HTML (at a tag) as
<li class="nav-item" v-for="(checkoutplan, index) in checkoutplans" :key="checkoutplan.id">
<a :id="'nav' + index" :ref="'nav' + index" class="nav-link" :class="{ 'active show' : index === 0 }" href="#settings" data-toggle="tab" #click="editModal(checkoutplan)">Checkout Plan {{index +1}}</a>
</li>
Now in vuejs
$(this.$refs.nav0).click(function(){
//nav0 is beacuse you want first element & first element index is 0
});
as your comment , I tried like below in mounted method (not created) .Beware nextTick is required when vue element is modify by data
new Vue({
el: "#app",
data: {
checkoutplans : []
},
methods: {
editModal : function(param) {
console.log(param);
}
},
mounted: function() {
this.checkoutplans = [{id:1},{id:2}];
this.$nextTick(() => {
this.$el.querySelector("li.nav-item:first-child a").click();
});
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<ul>
<li class="nav-item" v-for="(checkoutplan, index) in checkoutplans" :key="checkoutplan.id">
<a class="nav-link" :class="{ 'active show' : index === 0 }" href="#settings" data-toggle="tab" #click="editModal(checkoutplan)">Checkout Plan {{index +1}}</a>
</li>
</ul>
</div>
Your code seem to click first li after api called ! So the method you will call is editModal({firstItem}) . How about calling the method directly without clicking like
axios.get("api/checkoutplan")
.then(({ data }) => {this.checkoutplans = data;this.editModal(this.checkoutplans[0]) // direct call });
Created method is not ready state for document element so you can't call document element in that method
var button = document.querySelector("input[type=button]");
button.addEventListener("click", function() {
alert("button was clicked");
})
document.querySelector('.nav-link');
please try this code.
You binded click event in href a.nav-link tag. not in so try
document.querySelector("a.nav-link:first-child").click()

Hide or Display an Item with Angular or Jquery?

i am using mvc. I have model and i take data from model to view with this code:
<ul>
<li id="geri"><<</li>
#foreach (var item in Model.Skills)
{
<li id="#String.Format("{0}{1}", "skill", item.SkillId)">
#item.SkillName
</li>
}
<li id="ileri" style="margin-right: 0;">>></li>
</ul>
After first 4 items, they should be hidden (display:none). I searched angular and find ng-show attribute but cannot find how to use. Now my website looks like:
It should be one line and when i pressed next button, first item will hide and 5th item will show.
I hope i can explain myself, thanks
In Angular, try to use limitTo and offset filters.
Here's the Jsfiddle link.
AngularJS sample codes:
HTML:
<div ng-app="myApp">
<ul ng-controller="YourCtrl">
<li ng-click="previousSkills()"><<</li>
<li ng-repeat="skill in skills | offset: currentPage * 4 | limitTo: 4">
{{skill.SkillName}}
</li>
<li ng-click="nextSkills()">>></li>
</ul>
</div>
AngularJS Controller:
'use strict';
var app = angular.module('myApp', []);
app.controller('YourCtrl', ['$scope', function ($scope) {
$scope.currentPage = 0;
$scope.skills = [
{SkillName:'C#'},
{SkillName:'MVC'},
{SkillName:'Web Forms'},
{SkillName:'Web API'},
{SkillName:'SignalR'},
{SkillName:'EF'},
{SkillName:'Linq'},
{SkillName:'Github'},
{SkillName:'Html'},
{SkillName:'CSS'},
{SkillName:'SQL'},
{SkillName:'Angular'},
{SkillName:'Azure'}
];
$scope.previousSkills = function() {
$scope.currentPage = $scope.currentPage - 1;
};
$scope.nextSkills = function() {
$scope.currentPage = $scope.currentPage + 1;
};
}]);
app.filter('offset', function() {
return function(input, start) {
start = parseInt(start, 10);
return input.slice(start);
};
});
Hope it helps.
In Angular your HTML should be something like this to display only the first 4 items <li>, where items is your $scope.items:
<ul>
<li id="geri"><<</li>
<li ng-repeat="(key, item) in items" ng-show="key <= 3">{{item.SkillName}}</li>
<li id="ileri" style="margin-right: 0;">>></li>
</ul>
JSFiddle here

Ternary not working properly for function call in angular expressions

I have to call a function on $last in ng-repeat, if I use,
div(ng-repeat="note in notes")
li: {{note}}
{{$last ? 'true' : 'false' }}
It prints false only on last li element, but for the same if I call a function instead of 'true', like below
div(ng-repeat="note in notes")
li: {{note}}
{{$last ? update() : 'false' }}
the function is called for each loop.
For your information, I had tried "&&" kind of solution given in this link
{{$last && update() || '' }}
also, but not working.
You are not doing anything obvious wrong so maybe error is somewhere else in your code. See the following:
app.controller('MyCtrl', function ($scope) {
$scope.notes = ['Note 1','Note 2'];
$scope.update = function () {
return 'i haz updated!1';
};
});
<div ng-controller="MyCtrl">
<ul ng-repeat="note in notes">
<li>
{{note}} - isLast:{{$last ? 'true' : 'false'}} - {{$last ? update() : '???'}}
</li>
</ul>
</div>
Plunker http://plnkr.co/edit/DwCpcC
Please check the demo
<ul>
<li data-ng-repeat="note in notes">
{{ note }}
{{ $last ? update():''}}
</li>
</ul>

Changing Element Colour on Hover AngularJS

So, I'm just getting started with angularjs and I'm already confused. I want to change the colour of a list element that corresponds to a hex code colour that is in an array. I've tried some stuff but I just can't get it.
Here's my code so far:
HTML
<div id="mainContentWrap" ng-app="newApp">
<div id="personContainer" ng-controller="personController">
<ul id="personList">
<li class="bigBox no_s" ng-style="personColour" ng-repeat="i in persons" ng-hover="changeColor()">< href="#/{{i.person_id}}">{{i.person_name}}</a></li>
</ul>
Javascript:
var app=angular.module('newApp',[]);
app.controller('personController',function($scope,$rootScope){
$rootScope.persons=[
{person_id:'0',person_name:'Jim',colour:"cc0000"},
{person_id:'4',person_name:'Bob',colour:"f57900"},
{person_id:'2',person_name:'James',colour:"4e9a06"},
{person_id:'9',person_name:'Paul',colour:"3465a4"},
{person_id:'3',person_name:'Simon',colour:"77507b"}
];
$scope.changeColor(){
$scope.personColour=$scope.persons.color// not sure what to do here???
}
});
There is no ng-hover directive. You'll want to use ng-mouseenter and ng-mouseleave.
Also, keep in mind that the syntax for ng-style is an object corresponding the CSS key-value pairs.
<li ng-repeat="i in persons" ng-style="personColour" ng-mouseenter="changeColor(i)"></li>
$scope.changeColor = function(person) {
$scope.personColour = {color: '#'+person.colour};
};
If you'd like for the color to change back to what it was before you hovered, you can create two functions, or pass a parameter to $scope.changeColour:
<li ng-repeat="i in persons" ng-style="personColour" ng-mouseenter="changeColor(i,true)" ng-mouseleave="changeColor(i,false)"></li>
$scope.changeColor = function(person, bool) {
if(bool === true) {
$scope.personColour = {color: '#'+person.colour};
} else if (bool === false) {
$scope.personColour = {color: 'white'}; //or, whatever the original color is
}
};
To take it a step further
You could create a directive for each person.
<person ng-repeat="i in persons"></person>
// your module, then...
.directive('person', [function() {
return {
restrict: 'E',
replace: true,
template: '<li class="bigBox no_s">{{i.person_name}}</li>',
link: function(scope, elm, attrs) {
elm
.on('mouseenter',function() {
elm.css('color','#'+i.colour);
})
.on('mouseleave',function() {
elm.css('color','white');
});
}
};
}]);
If you want to hack stay in the view:
<div ng-repeat="n in [1, 2, 3]" ng-style="{ 'background': (isHover ? '#ccc' : 'transparent') }" ng-mouseenter="isHover = true;" ng-mouseleave="isHover = false;">
<span>{{ n }}</span>
</div>
in the code bellow i add easy code to understand how to active style with condition. I hope that help you
<li ng-style="( (isOver == 'true') && (linkToActive == 'm1') ) ? { 'background-color': '#00bdcb' } : {'background-color': '#ededed'}"
ng-mouseenter="vm.changeColorMenu('m1','true')" ng-mouseleave="vm.changeColorMenu('m1','false')">
</li>
<li ng-style="( (isOver == 'true') && (linkToActive == 'm2') ) ? { 'background-color': '#00bdcb' } : {'background-color': '#ededed'}"
ng-mouseenter="vm.changeColorMenu('m2','true')" ng-mouseleave="vm.changeColorMenu('m2','false')">
</li>
</ul>
Javascript Code
function changeColorMenu(indexMenu,bool)
{
$scope.isOver = bool;
$scope.linkToActive = indexMenu;
}
If you check an example here you will see that ng-style directive waits for css style, not just value, so in your case it'll be:
$scope.person.colourStyle={'background-color':$scope.persons.color}
and in html it'll be:
<li class="bigBox no_s" ng-style="i.colourStyle" ng-repeat="i in persons" ng-hover="changeColor()">< href="#/{{i.person_id}}">{{i.person_name}}</a></li>
edit:
And You also need to set colour value to full hex for example: '#cc0000'.
In Angular, there is not ng-hover directive, so you should use ng-mouseenter & ng-mouseleave to simulate it.
<ul id="personList">
<li class="bigBox no_s" ng-style="personColour"
ng-repeat="i in persons" ng-mouseenter="changeColor($index)"
ng-mouseleave="recoverColor($index)">
{{i.person_name}}
</li>
</ul>
And you should use $index to get your element in persons Array
$scope.changeColor = function() {
$scope.personColour = { 'color': '#' + $scope.persons[$index].color };
// or 'background-color' whatever you what
}
$scope.recoverColor = function() {
$scope.personColour = {};
}
See Plunker Demo Here
Use ng-style to conditionally apply CSS styles - I've chosen to name this style 'personStyle'. Next, bind the ng-mouseover event to set the personStyle background-color to the person's colour attribute. Finally, bind the ng-mouseleave event to reset the personStyle when the mouse leaves the element. The changeColor() function is not needed for this solution to work.
<div id="personContainer" ng-controller="personController">
<ul id="personList">
<li class="bigBox no_s" ng-repeat="i in persons" ng-style="personStyle">
<a href="#/{{i.person_id}}" ng-mouseleave="personStyle={}"
ng-mouseover="personStyle={ 'background-color':'#' + i.colour}">
{{i.person_name}}</a>
</li>
</ul>
</div>

AngularJS: how to split functionality into many controllers

I have a single controller in my application http://jsfiddle.net/HKF9h/:
<div ng-controller="MyCtrl">
All Items:
<ul>
<li ng-repeat="item in items">{{item }} -
like it
</li>
</ul>
Items you liked:
<ul>
<li ng-repeat="item in likedItems">{{item }}
</li>
</ul>
</div>
<script type="text/javascript">
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.items= ['foo', 'bar', 'z'];
$scope.likedItems = [];
$scope.like = function (item) {
if($scope.likedItems.indexOf(item) === -1) {
$scope.likedItems.push(item);
}
}
</script>
}
I would like move all 'favoriting' functionality into sep controller that can be reused later. Here's what i did, but repeater is not showing likedItems anymore. What did I do wrong? http://jsfiddle.net/MR8wz/
<div ng-controller="MyCtrl">
All Items:
<ul>
<li ng-repeat="item in items">{{item }} -
<a href=""
ng-controller="FavoriteCtrl"
ng-click="like(item)">like it</a>
</li>
</ul>
Items you liked:
<ul ng-controller="FavoriteCtrl">
<li ng-repeat="item in likedItems">{{item }} //this one does not trigger
</li>
</ul>
</div>
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.items= ['foo', 'bar', 'z'];
}
function FavoriteCtrl($scope) {
$scope.likedItems = [];
$scope.like = function (item) {
console.log('you liked', item); //this one is displayed
if($scope.likedItems.indexOf(item) === -1) {
$scope.likedItems.push(item);
}
}
}
You shouldn't really be relying on controller inheritance for sharing data. It's a bad case of close coupling.
In Angular, if you want to share data, you're advised to use services/factories because:
They're easily injectable anywhere you need them
They're easily mockable
They're easily testable
FIDDLE
var myApp = angular.module('myApp',[]);
myApp.factory('Favorite', function(){
var likedItems = [];
function like(item) {
console.log('you liked', item); //this one is displayed
if(likedItems.indexOf(item) === -1) {
likedItems.push(item);
}
}
function getLikedItems(){
return likedItems;
};
return {
like: like,
getLikedItems: getLikedItems
};
});
function MyCtrl($scope, Favorite) {
$scope.favorite = Favorite;
$scope.items = ['foo', 'bar', 'z'];
}
function FavoriteCtrl($scope, Favorite) {
$scope.likedItems = Favorite.getLikedItems();
}
<div ng-controller="MyCtrl">
All Items:
<ul>
<li ng-repeat="item in items">{{item }} -
<a href=""
ng-controller="FavoriteCtrl"
ng-click="favorite.like(item)">like it</a>
</li>
</ul>
Items you liked:
<ul ng-controller="FavoriteCtrl">
<li ng-repeat="item in likedItems">{{item }}
</li>
</ul>
</div>
You use ng-controller directive two times
like it
and
<ul ng-controller="FavoriteCtrl">
It creates two different scope this is the reason it doesn't work. So if you move
$scope.likedItems = []; in parent controller MyCtrl then it works. Updated
fiddle

Categories

Resources