Cannot Set Property of Undefined Member - javascript

Moving along in AngularJS, I get a JavaScript error on the // ERROR line below.
Why do I get Cannot set property 'show' of undefined?
<html ng-app>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js">
</script>
<div ng-controller='DeathrayMenuController'>
<button ng-click='toggleMenu()'>Toggle Menu</button>
<ul ng-show='menuState.show'>
<li ng-click='stun()'>Stun</li>
<li ng-click='disintegrate()'>Disintegrate</li>
<li ng-click='erase()'>Erase from history</li>
</ul>
<div/>
<script>
function DeathrayMenuController($scope) {
$scope.menuState.show = false; // ERROR HERE
$scope.toggleMenu = function() {
$scope.menuState.show = !$scope.menuState.show;
};
}
</script>
</body>
</html>

you never define $scope.menuState. Instead consider:
<html ng-app>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
<div ng-controller='DeathrayMenuController'>
<button ng-click='toggleMenu()'>Toggle Menu</button>
<ul ng-show='menuState_show'>
<li ng-click='stun()'>Stun</li>
<li ng-click='disintegrate()'>Disintegrate</li>
<li ng-click='erase()'>Erase from history</li>
</ul>
<div/>
<script>
function DeathrayMenuController($scope) {
$scope.menuState_show = false;
$scope.toggleMenu = function() {
$scope.menuState_show = !$scope.menuState_show;
};
}
</script>
</body>
</html>

Just working through the same book and came across this issue. Thought I'd add that the following works as well:
<html ng-app>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js">
</script>
<div ng-controller='DeathrayMenuController'>
<button ng-click='toggleMenu()'>Toggle Menu</button>
<ul ng-show='menuState.show'>
<li ng-click='stun()'>Stun</li>
<li ng-click='disintegrate()'>Disintegrate</li>
<li ng-click='erase()'>Erase from history</li>
</ul>
<div/>
<script>
function DeathrayMenuController($scope) {
$scope.menuState = {show: false}; // ERROR HERE
$scope.toggleMenu = function() {
$scope.menuState.show = !$scope.menuState.show;
};
}
</script>
</body>
</html>

The Errata shows the correction: http://oreilly.com/catalog/errata.csp?isbn=0636920028055
$scope.menuState.show = false; will give an undefined error
Added $scope.menuState = {} before to fix the issue i.e.
function DeathrayMenuController($scope) {
$scope.menuState = {}
$scope.menuState.show = false;
...

Related

How do I template nav bar across multimple websites using a class?

Please check the code below to see why the nav bar won't show up on the index file even after linking it through a class. Thank you in advance for your help!
Here is my templates.js
class MyMenu extends HTMLElement {
connectedCallback() {
this.innerHTML * `
<header>
<nav>
<ul>
<li class="logo">Damian Roiz</li>
<li class="items">Home</li>
<li class="items">About</li>
<li class="items">Services</li>
<li class="items">Blog</li>
<li class="items">Contact</li>
<li class="btn"><i class="fas fa-bars"></i></li>
</ul>
</nav>
<script>
$(document).ready(function(){
$('.btn').click(function(){
$('.items').toggleClass('show');
$('ul li').toggleClass('hide');
});
});
</script>
</header>
`
}
}
customElements.define('my-menu', MyMenu)
Here is my index.html
<head>
<script type='text/javascript' src=js/templates.js></script>
</head>
<body>
<my-menu></my-menu>
</body>

Navigation bar JavaScript

I am writing a code to open and close navigation bar with the button
my code is as follows
#DIV1{
display:block;}
<div id="DIV1">
<ul class="topnav">
<li>About</li>
<li>Contact</li>
<li>News</li>
<li>Home</li>
</ul>
</div>
<button onClick="abc()">HIDE</button>
<script>
function abc()
{
var togg = document.getElementById('DIV1')
if (togg.style.display == "block")
{
togg.style.display="none";
}
else if (togg.style.display == "none")
{
togg.style.display="block";
}
}
</script>
It wont work what should I do or what am I doing wrong? There are other CSS properties for navigation bar which I have skipped.
It doesn't work because you have to set its display with javascript or with inline style to get something by yourDiv.style.display. In your case, when you click on your button, the display is not set and then you can't enter nor in your if neither in your else if statement. So try this:
var togg = document.getElementById('DIV1');
togg.style.display="block"; /* => I set a display value */
function abc(){
if (togg.style.display == "block")
{
togg.style.display="none";
}
else if (togg.style.display == "none")
{
togg.style.display="block";
}
}
#DIV1 {
display:block;
}
/*you can remove this rule. You are changing the display via javascript */
<div id="DIV1">
<ul class="topnav">
<li>About</li>
<li>Contact</li>
<li>News</li>
<li>Home</li>
</ul>
</div>
<button onClick="abc()">HIDE</button>
Another way: you could simply create a class to "hide" your div and then toggle it using classList and toggle:
function abc(){
var togg = document.getElementById('DIV1')
togg.classList.toggle("myClass");
}
.myClass {
display:none;
}
<div id="DIV1">
<ul class="topnav">
<li>About</li>
<li>Contact</li>
<li>News</li>
<li>Home</li>
</ul>
</div>
<button onClick="abc()">HIDE</button>
here is the correct code:
<style> #DIV1{
display:block;}
</style>
<div id="DIV1">
<ul class="topnav">
<li>About</li>
<li>Contact</li>
<li>News</li>
<li>Home</li>
</ul>
</div>
<button onClick="abc()">HIDE</button>
<script>
function abc()
{
var togg = document.getElementById('DIV1');
if (togg.style.display == "block")
{
togg.style.display="none";
}
else
{
togg.style.display="block";
}
}
</script>
if i understood your question try this one:
<!DOCTYPE html>
<html lang="en">
<head>
<style>
#div1{
display:block;}
</style>
<script>
function abc()
{
var togg = document.getElementById("div1")
if (togg.style.display === "none")// 3 ===
{
togg.style.display="block";
}
else {
togg.style.display="none";
}
}
</script>
</head>
<body>
<div id="div1">
<ul class="topnav">
<li>About</li>
<li>Contact</li>
<li>News</li>
<li>Home</li>
</ul>
</div>
<button onclick="abc()">HIDE</button>
</body>
</html>

How do I call a function after user clicks in ng-click?

I'm running an optimizely test in this page:
https://www.thelotter.com/pt/bilhetes-loteria/africa-sul-powerball/?player=0
This is the current javascript for the test:
/* Don't touch this code */
function waitForDelayedContent(selector, experiment, timeout, keepAlive) {
var intervalTime = 50;
var timeout = timeout || 3000;
var keepAlive = keepAlive || false;
var maxAttempts = timeout / intervalTime;
var attempts = 0;
var elementsCount = 0;
var interval = setInterval(function() {
if ($(selector).length > elementsCount) {
if (!keepAlive) {
clearInterval(interval);
}
experiment();
elementsCount = $(selector).length;
} else if (attempts > maxAttempts) {
clearInterval(interval);
}
attempts ++;
}, intervalTime);
}
/* --------------------------------------------- */
waitForDelayedContent(".jackpot", function(){
$("#ctl00_tdMainRightSite").css({"display":"none", "visibility":""});
$("#divMainLeftSite").addClass("Clean_content_left_wide");
$("#tdMainLeftSite").addClass("Clean_TdMainLeftSite");
$(".play-request-options").css({"display":"none", "visibility":""});
$(".play-request-options").attr("style", "display: none !important;");
$(".play-request-summary").addClass("Clean_play-request-summary");
$(".btn-lucky-numbers").css({"display":"none", "visibility":""});
$(".bonus-box").addClass("Clean_bonus-box");
$(".ticket-line-holder").attr("style", "width: 153px !important;");
$(".cell-value").attr("style", "height: 20px !important; width:22px !important; font-size:14px; padding-top: 3px; margin-right:1px;");
$(".SkipThisFixedPosition").css({"display":"none", "visibility":""});
$(".nav-tabs-simple").css({"display":"none", "visibility":""});
$(".wrapper").addClass("Clean_ticket-lines-container");
$(".long_regular_separator").addClass("Clean_long_regular_separator");
$(".nav-tab > .syndication").css({"display":"none", "visibility":""});
$(".nav-tab > .bundle").css({"display":"none", "visibility":""});
$(".nav-tab > .personal").css({"display":"none", "visibility":""});
$(".play-view-regular").addClass("Clean_play-view-regular");
$(".ticket-line-content").addClass("Clean_ticket-line-content");
$(".watermark").addClass("Clean_watermark");
$(".lottery-card").addClass("Clean_lottery-card");
$(".jackpot").addClass("Clean_jackpot");
$(".btn-size-large").addClass("Clean_btn-size-large");
$(".btn-size-large > .btn-content > .btn-text").addClass("Clean_btn-text");
$(".nav-buttons-group > .btn-color-blue").addClass("Clean_btn-color-blue");
$(".nav-buttons-group > .btn-color-blue > .btn-content").addClass("Clean_btn-color-blue_content");
$(".play-type-selection-wrapper").addClass("Clean_play-type-selection-wrapper");
});
But instead of the waitForDelayedContent function, I need the test to run with a function that will make the test run after the user clicks in any of the li tags below (part of the HTML already):
<div id="App-PlayRequest" data-ng-controller="PlayRequest.PlayRequestController" class="ng-scope">
<ul class="play-type-containers">
<li class="play-type-container" ng-click="setGameType(0)">...</li>
<li class="play-type-container" ng-click="setGameType(3)">...</li>
<li class="play-type-container" ng-click="setGameType(4)">...</li>
</ul>
</div>
How do I call a function after the user clicks in any of the ng-click?
I think it might be a simple code, but I'm not a developer and couldn't make the code in the answers work.
Thank you so much!
try bellow code snippet: IT will work if you want to work with angular js.
angular.module('app',[])
.controller('TodoListController', function ($scope) {
$scope.setGameType = setGameType;
function setGameType(index) {
console.log(index);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app'>
<div ng-controller="TodoListController as todoList">
<ul class="play-type-containers">
<li class="play-type-container" ng-click="setGameType(0);">a...</li>
<li class="play-type-container" ng-click="setGameType(3);">b...</li>
<li class="play-type-container" ng-click="setGameType(4);">c...</li>
</ul>
</div>
</div>
update
Also if you want to use only javscript:
try these:-
function setGameType(index) {
console.log(index);
}
<ul class="play-type-containers">
<li class="play-type-container" onclick="setGameType(0);">a...</li>
<li class="play-type-container" onclick="setGameType(3);">b...</li>
<li class="play-type-container" onclick="setGameType(4);">c...</li>
</ul>
Please try this.
<!DOCTYPE html>
<html>
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js">
</script>
<body ng-app="myApp">
<div ng-controller="myCtrl">
<button ng-click="setGameType(1)">OK</button>
<ul class="play-type-containers">
<li class="play-type-container" ng-click="setGameType(0)">One</li>
<li class="play-type-container" ng-click="setGameType(1)">Two</li>
<li class="play-type-container" ng-click="setGameType(2)">Three</li>
</ul>
</div>
<script>
angular.module('myApp', [])
.controller('myCtrl', ['$scope', function($scope) {
$scope.count = 0;
$scope.setGameType = function(val) {
alert("Do something here with id "+val);
};
}]);
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js">
</script>
<body ng-app="myApp">
<div ng-controller="myCtrl">
<button ng-click="setGameType(1)">OK</button>
<ul class="play-type-containers">
<li class="play-type-container" ng-click="setGameType(0)">One</li>
<li class="play-type-container" ng-click="setGameType(1)">Two</li>
<li class="play-type-container" ng-click="setGameType(2)">Three</li>
</ul>
</div>
//This script code according to john pappa's guideline.
<script>
(function() {
angular.module('myApp')
.controller('myCtrl', myCtrl);
function myCtrl(
$scope
) {
$scope.setGameType = setGameType;
function setGameType(val){
console.log('Selected game type value',val);
//do stuff which you want when user click.
}
})();
</script>
</body>
</html>

Function Syntax, Passing Variables

I am trying to make a simple function but doing something wrong. Clicking the href causes a page jump and the function fails. Fiddle: http://jsfiddle.net/XkzUK/5/
HTML:
<nav>
<ul id="site-nav">
<li class="nav1">Recent</li>
<li class="nav2">Highlights</li>
<li class="nav3">Animals</li>
<li class="nav4">Cars</li>
</ul>
</nav>
<div id="content-listing">
<div id="recent">
<ul class="top-level">
</ul>
</div>
<!--end recent-->
<div id="highlights">
<ul class="top-level">
</ul>
</div>
<!--end highlights-->
<div id="animals">
<ul class="top-level">
</ul>
</div>
<!--end animals-->
<div id="cars">
<ul class="top-level">
</ul>
</div>
<!--end cars-->
</div>
<!--end content-listing-->
JS:
var test1;
var test2;
var test3;
var test4;
function switcher(divToShow, thisVar, otherVar, ajaxContent) {
$("#site-nav li a").parents().removeClass("nav-active");
$(this).addClass("nav-active");
if(otherVar) {
otherVar.detach();
}
if(typeof thisVar === 'undefined') {
thisVar = $(divToShow + "ul.top-level").load('/echo/html/', {
html: ajaxContent
}, function () {
alert("I'm new");
});
} else {
thisVar.appendTo("#content-listing");
alert("I'm old");
}
}
//Recent
$("#site-nav .nav1").on("click", function (event) {
switcher("#recent", "test1", "test2", "<li>1</li> <li>2</li> <li>3</li>");
event.preventDefault();
});
//Highlights
$("#site-nav .nav2").on("click", function (event) {
switcher("#recent", "test2", "test1", "<li>A</li> <li>B</li> <li>C</li>");
event.preventDefault();
});​​
http://jsfiddle.net/XkzUK/5/
You have error with
otherVar.detach()
because, otherVar is just a string, so .detach() will not work, .detach() accepts jQuery object.
So correct format should be
$(otherVar).detach();
You're passing strings as all of those parameters.
Therefore, calling methods like detach() or appendTo() throws an error, since those methods don't exist on strings.
You need to pass jQuery objects.

How can I break out of an each() in jQuery?

I have the following HTML + JS. I want the toggleButton to only toggle the first io-section-header. Eventually I will have multiple toggleButton's that will toggle a unique ul.
How can I achieve this?
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
<div><span>Section 1</span></div>
<div class="io-section-header">
<ul>
<li class="advanced">Accounts</li>
<li class="advanced">People</li>
<li class="advanced">companies</li>
<li class="basic">She</li>
</ul>
<div><span>Section 2</span></div>
<div class="io-section-header">
<ul>
<li class="advanced">Accounts</li>
<li class="advanced">People</li>
<li class="advanced">companies</li>
<li class="basic">P</li>
</ul>
</div>
</div>
<div class="toggleButton">Collapse</div>
<script>
jQuery(function ($) {
$('.toggleButton').click(function () {
var currentText = $(this).text();
if(currentText === "Collapse")
$(this).text("Expand");
else
$(this).text("Collapse");
/*$('.io-section-header').each(function() {
$("li").siblings(".advanced").toggle('fast',function(){});
});*/
$('.io-section-header li').siblings(".advanced").toggle('fast');
});
});
</script>
</body>
</html>
From the .each() documentation:
We can break the $.each() loop at a particular iteration by making the callback function return false. Returning non-false is the same as a continue statement in a for loop; it will skip immediately to the next iteration.
This will toggle the first advanced class in each io-section-header class
$('ul li.advanced:first', '.io-section-header').toggle('fast',function(){});
This will toggle the first advanced class in the first io-section-header class
$('ul li.advanced:first', '.io-section-header:first').toggle('fast',function(){});
return false is all you need; why aren't you using first()?

Categories