Why does this Expression not work inside the ng-repeat? - javascript

I am working my way through some AngularJS tutorials. Alongside, I have made my small toy to further experiment. I have found a situation where a expression works when outside a ng-repeat but wont work inside and I would like to understand why?
The template:
<div ng-controller="TodoController">
<ul ng-init="detail = 0">
<li ng-repeat="todo in todos">
<input type="checkbox" ng-model="todo.done">
<span>{{todo.text}}</span>
<!-- This does not make the detaildiv appear -->
<input class="btn" type="submit" value="dive1" ng-click="detail = 1">
</li>
</ul>
<!-- This however will make the detaildiv appear -->
<input type="submit" value="divein" ng-click="detail = 1">
<p>Detail: {{detail}}</p>
<div id="detaildiv" ng-show="detail === 1">
<span>Some content</span>
<input type="submit" value="diveout" ng-click="detail = 0">
</div>
</div>
What is it about ng-repeat that stops this working, or am I on the wrong track?

putting my comment as an answer.
basically ng-repeat creates a child scope hence the detail inside and outside of ng-repeat is not same.
to fix this you have to use $parent.
<ul ng-init="detail = 0">
<li ng-repeat="todo in todos">
<input type="checkbox" ng-model="todo.done">
<span>{{todo.text}}</span>
<!-- This does not make the detaildiv appear -->
<input class="btn" type="submit" value="dive1" ng-click="detail = 1">
</li>
</ul>
but the best way to fix this would be never use ng-model without dot.
or even better start using controller as syntax.
both above options would avoid such issues.

Related

Angular ngFor radio buttons

I've got a few questions like 'what is something' and 4 radio buttons as answers. So it`s like 3 generated <ul>s in DOM. But the problem is, when I click some radio button, it selects the radio button in another question. How to fix this problem? Is it something with the value? Or it needs to have some unique index?
Code:
<ul *ngFor="let test of tests"> {{test.question.title}}
<li *ngFor="let answer of test.question.answers"> <input type="radio" [value]="answer" [(ngModel)]="radioSelected"> <label for="">{{answer}}</label> </li>
</ul>
<button (click)="check(radioSelected)">Send</button>
add name attribute base of index and create an answer object in the component
component
answers = {}; // 👈
template (view)
<ul *ngFor="let test of tests;let index = index"> {{test.question.title}}
<li *ngFor="let answer of test.question.answers">
<label >
<input [name]="index" type="radio" [value]="answer" [(ngModel)]="answers[index]">
{{answer}}</label>
</li>
</ul>
<button (click)="check(answers)">Send</button>
stackblitz demo 🚀🚀
You should have different ngModel for every test in ngFor, change your ngModel to
<input type="radio" [value]="answer" [(ngModel)]="test.question.radioSelected">

AngularJS: Input form does not work inside the partial

The hierarchy of the page is as follows:
<div ng-include="'partials/navbar.html'"></div>
<div ng-view></div>
<div ng-include="'partials/footer.html'" id="footer"></div>
This is the main index.html which also contains all scripts sources.
In ng-view there's another index which uses header partial:
div ng-include="'partials/header_search.html'"></div>
This header_seatch partial contains angular based input-form
<form name="searchLocation" ng-submit="search()">
<div class="input-group">
<input type="text" name="location" ng-model="location" ng-autocomplete ng-change="error = false"/>
<div class="input-group-addon">
<button type="submit">Search</button>
</div>
</div>
<span ng-if="error">No such address</span>
</form>
And here comes the issue I have - the following form does not respond when placed inside the header partial. When I copy/paste it inside the index view everything works perfectly fine. Does angular have any confusion with ng-stuff placed in partials? What should I modify to make it work inside the header partial?
Thanks in advance!
ng-include has it's own scope, which is terribly confusing. I'd recommend replacing the ng-include's with directives.
Otherwise this should work:
<form name="searchLocation" ng-submit="$parent.search()">
<div class="input-group">
<input type="text" name="location" ng-model="$parent.location" ng-autocomplete ng-change="error = false"/>
<div class="input-group-addon">
<button type="submit">Search</button>
</div>
</div>
<span ng-if="$parent.error">No such address</span>
</form>
Please note using $parent is bad practice and should be avoided.

Initial use of Bootstrap Collapse component is not working

I have an app that uses Bootstrap. I need to use the Bootstrap Collapse component. I have created a Bootply to demonstrate my problem here. My code looks like this:
<div id="items-group" class="form-group">
<div data-toggle="collapse" data-parent="#items-group" data-target="#items-list" aria-expanded="true" aria-controls="items-list" class="collapsable-group-header">
<ul class="list-inline no-padding-below" style="margin-bottom:0;">
<li><span class="glyphicon glyphicon-chevron-down"></span></li>
<li class="no-padding-x">
<h5 style="margin:0;">Items <span>(<button type="button" class="btn btn-link btn-link-padding" onclick="selectAll('items-list')">choose all</button>)</span></h5>
</li>
</ul>
</div>
<div id="items-list" style="padding-left:32px;">
<label style="font-weight:normal;">
<input type="checkbox">
<span>Item A</span>
</label><br>
<label style="font-weight:normal;">
<input type="checkbox">
<span>Item B</span>
</label><br>
<label style="font-weight:normal;">
<input type="checkbox">
<span>Item C</span>
</label><br>
</div>
</div>
If you run the Bootply, you will notice that the collapse does not work correctly on the initial load. When the page initially loads, the collapse items are visible (as expected). Then click the header. It is supposed to collapse the items. Instead, it quickly hides them and then expands the list. After the initial run, it works fine. Its just that when the page loads, I need to get it so the list collapses when you click it. I thought setting aria-expanded="true" would take care of this, however it didn't.
You are missing the classname of the group that identifies the collapse, so when you click the first time the action just toggle that classnames. Add this:
<div class="collapse in" id="items-list" style="padding-left:32px;">
UpdatedBootply

Link two radio buttons in different forms

So I have two radio buttons here, and I'm trying to link them up. Due to the fact that they are in two different forms, they don't seem to work as I expected. The forms are required in Bootstrap in order to display the correct style I desire. Here's a snippet of my code:
<ul class="list-group">
<li class="list-group-item list-heading">Notification Display Options</li>
<li class="list-group-item">
<form class="form-inline" role="form">
<div class="radio">
<label>
<input type="radio" id="noti_display_time" name="noti_display"> <span trans="shownotificationfor">Shows for</span>
<div class="form-group">
<input id="show_noti_time" type="number" class="form-control" max="60" min="1" data-requires="noti_display_time">
</div> <span trans="seconds">seconds</span>
</label>
</div>
</form>
</li>
<li class="list-group-item">
<form class="form-inline" role="form">
<div class="radio">
<label>
<input type="radio" name="noti_display">Close manually
</label>
</div>
</form>
</li>
</ul>
http://jsfiddle.net/DerekL/4YfB9/show (Do not view it inside the jsFiddle preview window since the style changes as the window size changes)
Is there a solution to this without messing up the style? Thanks.
JavaScript will be my last resort, if there is no workaround.
Just wrap one form around the <ul>. Using 2 forms just to manage style doesn't make much sense.
<form>
<ul/>
</form>
DEMO

AngularJS toggle ng-repeat visibility with checkbox

So I have a list of notices in AngularJS which I create with ng-repeat. The notices have a visibility status which determines whether the notice is shown in the list. Every notice has controls which allow that notice to be hidden, a simple button that changes the notice.status.visibility to false.
I also have a checkbox input that is supposed to show hidden notices. However, I am unsure on how to implement this and how would it work.
Here's the HTML:
<ul>
<input type="checkbox" value="Show Hidden" />
<li ng-repeat="notice on notices | filter: filter.search">
<div ng-show="notice.status.visibility">
<!-- notice details -->
</div>
</li>
</ul>
Maybe with something like this:
<ul>
<input type="checkbox" value="Show Hidden" ng-model="showHidden" />
<li ng-repeat="notice on notices | filter: filter.search">
<div ng-show="showHidden || notice.status.visibility">
<!-- notice details -->
</div>
</li>
</ul>

Categories

Resources