Comment makes ng-options work, why? - javascript

So, I was working through a bug concerning the ngOptions directive within an ngInclude. I came across sample code showing the directive working, copy-pasted it in, and saw that both my (non-functioning) old ngOptions was now functioning. I'm curious as to how that worked.
I no longer have access to the old code, but it looked something like this:
HTML:
<div ng-controller="Widget" ng-class="{{widget.properties.styleClass}}" ng-init="optionsShow = false" class="irrelevant" "style = "height:100%;" >
<div>
<!-- ... -->
<!-- my options button-->
<span class="icon" ng-click="showOptions(); adjustHeight()">
options
</span>
</div>
<!-- Options div shows only when button is clicked -->
<!-- Canvas Options -->
<div class="options command-options" ng-show="optionsShow" style="height:50%;">
<!-- ... -->
<span ng-click="addCommand()">Add New Command +</span>
<div class="row">
<div class="col-xs-3">
<label>Command to edit:<br/>
<select ng-model="selected" ng-change="verifySelected()" ng-options="object as object.index for object in widget.objects"></select>
<!-- The select here wouldn't show any options no matter what I did -->
</label>
</div>
</div>
</div>
<!-- ... -->
JS, within the controller:
//...
$scope.widget.objects = [];
//...
$scope.addObject = function(){
$scope.widget.objects.push({index:$scope.widget.objects.length + 1, type:$scope.objectTypes[0]});
}
$scope.addObject();
$scope.verifySelected = function(){
console.log("irrelevant")
}
The working HTML now looks like this:
<div ng-controller="Widget" ng-class="{{widget.properties.styleClass}}" ng-init="optionsShow = false" class="irrelevant" "style = "height:100%;" >
<div>
<!-- ... -->
<!-- The following comments help make thing work in the options div. Don't ask why, I don't know. Just don't remove them
<b>Total Things:</b> {{totalThings}}
<p ng-repeat="oneThing in things">
<input value="{{oneThing.text}}" type="checkbox" ng-model="oneThing.checked" />
{{oneThing.text}}
</p>
<ul class="unstyled">
<li ng-repeat="oneThing in things">
<span>{{oneThing.text}}</span>
</li></ul>-->
<!-- my options button, everything below this point unchanged-->
<span class="icon" ng-click="showOptions(); adjustHeight()">
options
</span>
</div>
<!-- Options div shows only when button is clicked -->
<!-- Canvas Options -->
<div class="options command-options" ng-show="optionsShow" style="height:50%;">
<!-- ... -->
<span ng-click="addCommand()">Add New Command +</span>
<div class="row">
<div class="col-xs-3">
<label>Command to edit:<br/>
<select ng-model="selected" ng-change="verifySelected()" ng-options="object as object.index for object in widget.objects"></select>
<!-- The select here wouldn't show any options no matter what I did -->
</label>
</div>
</div>
</div>
<!-- ... -->
The working JS controller now also has these lines:
$scope.totalThings = 5;
//...
$scope.things = [{text: 'This is needed in order to make things work... for some reason.'}];
What happened to make it work?

ngOptions works as expected with your old code, I have made a plunker with your old code widget plunker$scope.widget = {}; and $scope.objectTypes = ["something"]; are added to make your code working.

Related

$scope variable not updating in view

I have the following snippet of code,
<div ng-controller="GraphCtrl" ng-if="errorTracerouteResultsLength!=0">
<h5>Erroneous Traceroute Paths
<small>Sub-heading</small>
</h5>
<a href="#" ng-repeat="(key, val) in errorTracerouteResults" ng-click="loadTraceroutePath(val.metadata);">
S: {{val.source.ip}}
D: {{val.destination.ip}}
</a>
</div>
It works fine, loadTraceroutePath belongs to another controller,(lets call it X) but somehow ng-click works and console.log gets printed out with the correct metadata value.
However, in controller X, I have,
$scope.loadIndividualTraceroutePath = function (metadataKey) {
$scope.noOfResults = 1;
}
In the html, I have {{noOfResults}} all over the place. Some of it are able to display 1 while some can't. I have already attached the ng-controller directives and point to controller X, but {{noOfResults}} does not display.
How can I make {{noOfResults}} display in any section of the HTML?
Edit: I have added the HTML.
<div class="row">
<div class="col-lg-9">
<div class="panel panel-default">
<div class="panel-heading">
<i class="fa fa-bar-chart-o fa-fw"></i> Visualisation
<div class="pull-right">
Layout
</div>
</div>
<!-- /.panel-heading -->
<div class="panel-body">
<div class="container" ng-controller="X">
<!--This does not work-->
{{noOfResults}}
</div>
<div>
<div ng-controller="IndividualTraceroutePathGraphCtrl" id="individual_traceroute_path_graph"></div>
</div>
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
The ng click in the first part of this question is way below.
You have a extra ; at the end, also you are not using the object what you are passing as a parameter to the function, hence Change
From:
<a href="#" ng-repeat="(key, val) in errorTracerouteResults" ng-click="loadTraceroutePath(val.metadata);">
To:
<a href="#" ng-repeat="(key, val) in errorTracerouteResults" ng-click="loadTraceroutePath(val)">
Then,
$scope.loadIndividualTraceroutePath = function (metadataKey) {
$scope.noOfResults = 1;
}
EDIT
You don't need to mention so many controllers in the view, have one controller where the function is defined and remove the rest, here, Update like this,
<div class="container" >
<!--This does not work-->
{{noOfResults}}
</div>
<div>
<div id="individual_traceroute_path_graph"></div>
</div>
</div>

JQuery .on("click"... works intermitently

I have a piece of code:
$("body").on("click", ".reply-button", function(){
alert("test");
});
That is suppose to alert me when I click on an element that is generated on the fly (it is not part of the DOM when this code is executed).
Sometimes it works just as it's suppose to. I click the button and a little alert pops up. However, other times it stop working. Nothing I bind to it will work. If I bind to the container div (also generated on the fly), it does work, but not if I change the handler to incorporate button.
I am asking for what could be the possible reasons for this error? I do not know how to go about debugging this. My first guess was that it was something due to stopImmediatePropagation or stopPropagation but I couldn't find that being used in the same area.
Does anyone have any idea on how I should go about debugging this?
EDIT:
How is the DOM being generated?
I get the HTML from a template that's hidden.
var html = $("#template").html();
Then I append the template to a div container
$("#container").append(html);
EDIT2:
Here is the template being pulled:
<div id="tweets-container" class="feed-wrapper">
</div>
<div id="tweet-template" style="display:none;">
<!-- Tweet 1 -->
<div class="tweet animated" data-scannedTweetId="s_id">
<!-- User -->
<div class="tweet-user">
<!-- User picture -->
<img class="tweet-user-picture" src="s_twt_owner_profile_img_url" />
<!-- User info -->
<div class="tweet-user-info">
<!-- User name -->
<div class="tweet-user-info-name">
s_twt_owner_name (#s_twt_owner_sn)
</div>
<!-- User biography -->
<div class="tweet-user-info-biography">
s_twt_owner_desc
</div>
</div>
</div>
<!-- User statistics (following, followers, and tweets) -->
<span class="tweet-statistics animated">
<div class="following">
<div class="statistic-count">s_twt_owner_num_following</div>
<div class="statistic-label">following</div>
</div>
<div class="followers">
<div class="statistic-count">s_twt_owner_num_follower</div>
<div class="statistic-label">followers</div>
</div>
<div class="tweets">
<div class="statistic-count">s_twt_owner_num_twt</div>
<div class="statistic-label">tweets</div>
</div>
</span>
<!-- Tweet bars/graph -->
<div class="side-information animated">
<div class="bar-wrapper">
<!-- Actual bars -->
<div class="bars">
<div class="bar big-bar bar-green" style="height: tqes_heightpx; background: tqes_color;" data-toggle="tooltip" data-placement="top" title="tq_engage_score"></div>
<div class="bar bar-yellow" style="height: tqrs_heightpx; background: tqrs_color;" data-toggle="tooltip" data-placement="top" title="tq_relevancy_score"></div>
<div class="bar bar-light-green" style="height: sks_heightpx; background: sks_color;" data-toggle="tooltip" data-placement="top" title="s_klout_score"></div>
<div class="bar bar-green" style="height: sls_heightpx; background: sls_color;" data-toggle="tooltip" data-placement="top" title="s_legitimacy_score"></div>
<div class="bar bar-gray" style="height: tqgs_heightpx; background: tqgs_color;" data-toggle="tooltip" data-placement="top" title="tq_geography_score"></div>
</div>
<!-- Labels that correspond with each bar -->
<div class="bar-labels">
<div class="bar-label big-bar-label" data-toggle="tooltip" data-placement="bottom" title="Score">tq_engage_score</div>
<div class="bar-label-icon" style="font-size: 12px; color: #000;" data-toggle="tooltip" data-placement="bottom" title="Relevancy">
<i class="fa fa-bullseye"></i>
</div>
<div class="bar-label-icon" data-toggle="tooltip" data-placement="bottom" title="Influence">
<i class="fa fa-users"></i>
</div>
<div class="bar-label-icon" data-toggle="tooltip" data-placement="bottom" title="Legitimacy">
<i class="fa fa-check-circle"></i>
</div>
<div class="bar-label-icon" data-toggle="tooltip" data-placement="bottom" title="Geography">
<i class="fa fa-map-marker"></i>
</div>
</div>
</div>
<!-- Notes below the bars/graph -->
<div class="explanations">
<!-- Note below the bars/graph -->
<div class="explanation">
<div class="explanation-check"><i class="fa fa-first-comment"> </i>
<div class="explanation-text">
comment_one
</div>
</div>
</div>
<!-- Note below the bars/graph -->
<div class="explanation">
<div class="explanation-check"><i class="fa fa-second-comment"> </i>
<div class="explanation-text">
comment_two
</div>
</div>
</div>
</div>
</div>
<!-- Tweet score -->
<div class="score-wrapper">
<div class="score animated">tq_engage_score</div>
</div>
<!-- Tweet content -->
<div class="tweet-content">
s_twt_text
</div>
<!-- Time since tweet was posted -->
<div class="tweet-time-elapsed">
s_twt_time
</div>
<!-- Area below tweet with reply textarea and buttons -->
<div class="tweet-reply-section animated">
<!-- Reply textarea -->
<textarea class="tweet-reply animated">#s_twt_owner_sn </textarea>
<!-- Buttons -->
<div class="buttons animated">
<!-- Small buttons on top of reply button -->
<div class="top-buttons">
<span class="character-count">
</span>
</div>
<!-- Reply button -->
<div class="reply-button">
Reply <i class="fa fa-reply"></i>
</div>
</div>
</div>
</div>
</div>
JavaScript:
/**
* Add a tweet to the feed.
*/
function _addTweetToFeed(tweet, keywords) {
/** Get the tweet template */
var tweetHtml = $('#tweet-template').html();
// add score heights and colors properties to the tweet
tweet = _setScoreBars(tweet);
/** Linkify elements of the tweet */
tweet.s_twt_text = twitterify(tweet.s_twt_text); // the tweet
tweet.s_twt_owner_desc = twitterify(tweet.s_twt_owner_desc);
// fix search terms to be highlighted
tweet.s_twt_text = _highlightSearchTerms(tweet.s_twt_text, keywords); // the tweet
tweet.s_twt_owner_desc = _highlightSearchTerms(tweet.s_twt_owner_desc, keywords);
// change from twitter links to readable links
tweet = _fixTweetLinks(tweet);
/** Make numbers readable */
tweet.s_twt_owner_num_following = abbrNum(tweet.s_twt_owner_num_following, 1);
tweet.s_twt_owner_num_follower = abbrNum(tweet.s_twt_owner_num_follower, 1);
tweet.s_twt_owner_num_twt = abbrNum(tweet.s_twt_owner_num_twt, 1);
/** Loop through the properties of tweet object and populate tweetHtml with them */
for (var prop in tweet) {
if (tweet.hasOwnProperty(prop)) {
tweetHtml = _replaceAll(tweetHtml, prop, tweet[prop]);
}
// add comments
tweetHtml = _addComments(tweet, tweetHtml);
/** If both location and url are not present, remove the comma */
if (!(tweet.s_twt_owner_loc && tweet.s_twt_owner_url)) {
$('#url_comma').html('');
}
}
$('#tweets-container').append(tweetHtml);
}
"Sometimes it works just as it's suppose to" this line alone suggests that you run your code prior to DOM creation. sometimes your browser creates the dom fast enough and the handler is being attached to the body, and sometimes your javascript runs first and it isnt being attached. wrap your code in this:
$(function(){
$("body").on("click", ".reply-button", function(){
alert("test");
});
});
Does anyone have any idea on how I should go about debugging this?
Sometimes it's best to pull out a tiny portion of code, and see if it works in isolation. For example: http://jsfiddle.net/6v7z9fak/
js:
$("body").on("click", ".reply-button", function(){
alert("test");
});
html:
<button type="button" class="reply-button">Reply</button>
As you'll see, it works fine. So you can be confident that the error is not in that bit of code alone. It is either another part of the code, or how the parts are interacting together, or something else. Now slowly add more code, test, and see where it breaks.

AngularJS toggling header works only if changed in directive

I have the following markup:
<div class="schedule">
<!-- Header info -->
<div class="row">
<!-- Schedule title -->
<div class="title" ng-click="toggleHeader()">
<span ng-hide="isScheduleVisible">{{ schedule.name }} (Open to View)</span>
<input ng-model="schedule.name" class="schedule-name" ng-show="isScheduleVisible"/>
</div>
<!-- Action menu items go here -->
<div class="actions" ng-show="isScheduleVisible"></div>
</div>
<!-- Schedule Info -->
<div class="row" ng-show="isScheduleVisible">
<!-- This is the time on the left of the table -->
<div id="times"></div>
<!-- Conditions for the Schedule -->
<div id="conditions"></div>
<!-- Shifts of the Schedule -->
<div class="shifts"></div>
</div>
</div>
I want to toggle the content by clicking the "title" (see below for the open/close state snapshot). Right now, as you can see, I call a function toggleHeader() in my controller, and all it does is:
$scope.toggleHeader = function()
{
$scope.isScheduleVisible = ! $scope.isScheduleVisible;
}
I want to replace it with ng-click="isScheduleVisible = !isScheduleVisible". However, this does not work. This will only toggle the header (the grey banner) and not the actual content (the schedule).
Why?!

jQuery - Having the same HTML twice renders my script inoperative

I'm quite new to jQuery and I have come up with script which affects the HTML below. The script works perfectly and I have gotten it to whether I would like. The problem I am having
is when I'm duplicating the HTML and the script, once clicked, only shows the last project-info and project-images within the document. I've tried quite a few different methods just as
$(this).children()
but I can't seem to get any to work. Any help would be much appreciated.
Thank you
jQuery
$(document).ready(function() {
$('.apple').click(function() {
$('#darken').addClass('dark');
$('.project-info').delay('1000').slideDown('slow');
$('.project-images').delay('1000').fadeIn('slow');
});
});
$(document).ready(function() {
$('.close').click(function() {
$(".project-info, .project-images").fadeOut('slow');
});
});
HTML
<div class="apple">
<img src="http://mybroadband.co.za/photos/data/500/apple-logo.jpg"/>
</div>
<div class="project-info" style="display:none;">
<div class="project-title">
<h1>hello world</h1>
</div>
<div class="details">
<p>dkusdufhu suskueh sukh suefhuksdfnkuesnfukneukf nseuknfukenfuk nukefnuksn fukfuksukfnuksenf unseukfunfukfunufen u u u ef euhfuehfeufu g gfd gerjkg rjgrjg j js grg rgsg dkusdufhu suskueh sukh</p>
<div class="links">
link
</div>
<div class="close"></div>
</div><!-- end of project info -->
</div>
<div class="project-images" style="display:none;">
<div class="-images">
<img src="http://cdn4.spiegel.de/images/image-499233-galleryV9-grcy.jpg" />
<img src="http://cdn4.spiegel.de/images/image-499233-galleryV9-grcy.jpg" />
</div>
<div class="close end"></div>
</div> <!-- Project Images -->
</div> <!-- # Darken -- >
You're nearly there. Children wouldn't work in the above example because the divs with class 'apple' don't have any children. You need to move that first closing tag to the bottom of the portfolio item so that your html for each portfolio item is structured like this:
<!--PORTFOLIO ITEM-->
<div class="apple">
<!-- ICON GOES HERE-->
<img src="http://mybroadband.co.za/photos/data/500/apple-logo.jpg"/>
<!-- PROJECT INFO GOES HERE-->
<div class="project-info" style="display:none;">
</div>
<!-- PROJECT IMAGES GOES HERE-->
<div class="project-images" style="display:none;">
</div>
</div>
I.e. the divs with classes 'project-info' and 'project-images' are inside the 'apple' div. Then change this:
$('.project-info').delay('1000').slideDown('slow');
$('.project-images').delay('1000').fadeIn('slow');
to this:
$(this).children('.project-info').delay('1000').slideDown('slow');
$(this).children('.project-images',this).delay('1000').fadeIn('slow');
If you've updated your html correctly, $(this) will be pointing to a div element that does indeed have children with classes 'project-info' and 'project-images'. Here's an updated JSFiddle that should do you what you want: http://jsfiddle.net/8k3Ms/1/

.slideToggle() is being triggered many times?

I'm trying to create a Tumblr theme in which the links and post information slide in when you click a + sign. (My test blog is at http://noitsnotitsnotokay.tumblr.com/)
I'm quite the begginner at JavaScript, but I was able to work it out for a links menu with the following code:
<span class="btn">+</span>
<ul class="lks">
<!-- various links are here -->
</ul>
<script>
$("ul.lks").hide();
$("span.btn").click(function () {
$("ul.lks").slideToggle("slow");
});
</script>
But I also have a piece of code that applies to all posts, for the post information. I used nearly the same code, but, as you can probably see, it slides in and out various times.
<div class="pstinfo">
<!-- info is here -->
</div>
<span class="plsign">+</span>
<script>
$("div.pstinfo").hide();
$("span.plsign").click(function () {
$("div.pstinfo").slideToggle("slow");
});
</script>
It seems that the button's order and the way I name the classes in the JavaScript isn't changing much...any tips?
If you you don't want to open all the '.pstinfo' elements when you click on '.plsign', just the related one, try this code:
HTML:
<div class='parentContainer'> <!--put your elements in a parent Container -->
<div class='info'>
Info 1
</div>
<div class='plsign'>
+ Open
</div>
</div>
<div class='parentContainer'>
<div class='info'>
Info 2
</div>
<div class='plsign'>
+ Open
</div>
</div>
<div class='parentContainer'>
<div class='info'>
Info 3
</div>
<div class='plsign'>
+ Open
</div>
</div>
JS:
$(".plsign").on('click',function ()
{
$(this).parent().find('.info').slideToggle("slow");
});
Link to jsFiddle
code block 01
<span class="btn">+</span>
<ul class="lks">
<!-- various links are here -->
</ul>
<script>
$("ul.lks").hide();
$("span.btn").click(function () {
$("ul.lks").stop().slideToggle("slow");
});
</script>
Code block 02
<div class="pstinfo">
<!-- info is here -->
</div>
<span class="plsign">+</span>
<script>
$("div.pstinfo").hide();
$("span.plsign").click(function () {
$("div.pstinfo").stop().slideToggle("slow");
});
</script>
Try this code and Update the result :)

Categories