I am slowly advancing into angular. At this point I have form with several steps, each step is made of ng-form, since each step contains "continue" button and common headers I have following loop
<section ng-from="form12.{{step.id}}" ng-repeat="step in steps" id="{{step.id}}" ng-class="{active: currentSection == $index}">
<h1 class="header">{{$index + 1}}. {{step.title}}</h1>
<div class="content">
<ng-include src="step.template"></ng-include>
</div>
<!--and button code-->
<div class="content-body" ng-show="currentSection == $index">
<button ng-show="$index != 0" class="btn prev" ng-click="prevSection()">Previous</button>
<button class="btn next" ng-click="nextSection()" ng-disabled="step{{$index+1}}.$invalid">{{isLastStep($index)}}</button>
<div style="clear: both;"> </div>
</div>
</section>
So in that way I am not repeating same buttons code for each ng-form.
Before that I was using only ng-include and sections were hard coded, I suppose I am missing $scope now, as ng-include creates one as well as ng-repeat, could someone advise me on how can I make Continue button dependant on each ng-form validation result? (How can I access each individual ng-form results in topmost $scope?)
Each button has access to that form's $error, so you could have this for example:
<button class="btn next" ng-click="nextSection()" ng-disabled="form12.{{step.id}}.$invalid">
You also have ng-form spelled incorrectly (ng-from), although I assume that was an artifact from you pasting/typing in.
If you want to disable button if one of the forms is invalid
How can I access each individual ng-form results in topmost $scope?
You can wrap ng-repeat in ng-form and top ng-form will be invalid if any child form in ng-repeat is invalid.
Or if you wan't to block button per form then
<button class="btn next" ng-click="nextSection()" ng-disabled="form12.{{step.id}}.$invalid">{{isLastStep($index)}}</button>
Related
I am new to AngularJS.
I have created <li> to which I used ng-repeat.
<li> contains images and buttons like like, comment and share which is inside <li> and created by ng-repeat.
I have made function which will replace empty like button to filled like button (By changing background image of button).
But problem is this trigger applies to only first like button and other buttons does not change.
How can I fix this?
Code:
HTML:
<html>
<body>
<ul>
<li ng-repeat="media in images"><div class="imgsub">
<label class="usrlabel">Username</label>
<div class="imagedb">
<input type="hidden" value="{{media.id}}">
<img ng-src="{{ media.imgurl }}" alt="Your photos"/>
</div>
<!-- <br><hr width="50%"> -->
<div class="desc">
<p>{{media.alt}}</p>
<input type="button" class="likebutton" id="likeb" ng-click="like(media.id)" ng-dblclick="dislike(media .id)"/>
<input type="button" class="commentbutton"/>
<input type="button" class="sharebutton"/>
</div>
</div> <br>
</li><br><br><br>
</ul>
</body>
</html>
JS:
$scope.like = function(imgid)
{
document.
getElementById("likeb").
style.backgroundImage = "url(src/assets/like-filled.png)";
alert(imgid);
}
$scope.dislike = function(imgid)
{
document.
getElementById("likeb").
style.backgroundImage = "url(src/assets/like-empty.png)";
}
Thanks for help & suggestions :)
The id for each button should be unique but in your case, it's the same for all buttons ('likeb').
You can set the value of the attribute 'id' for each button dynamically by using '$index' and passing '$index' to the functions as follows:
<input type="button" class="likebutton" id="{{$index}}" ng-click="like($index)" ng-dblclick="dislike($index)"/>
Then in your controller, you can use the functions with the passed value.
For example,
$scope.like = function(index)
{
document.
getElementById(index).
style.backgroundImage = "url(src/assets/like-filled.png)";
}
Another good alternative in your case would be to use the directive ngClass.
use 2 css class for styling liked and disliked state, and then put the class conditionally with ng-class instead of DOM handling. and if you really want to perform a DOM operation (I will not recommend) then you can pass $event and style $event.currentTarget in order to perform some operation on that DOM object.
I'm trying to make use of wj-popup inside an ng-repeat in an AngularJS application, but am having difficulty.
Basically, I've used the demo example for wj-popup and wrapped it in an ng-repeat as follows. I have an array of posts, each has a property that is its indexValue (post.indexValue).
Each button needs to have a different ID, so I expect that using post.indexValue should work, and it does set the button ID on each repetition correctly, but the calling function doesn't work and the popup doesn't appear, and I'm not sure what I'm doing wrong.
<div ng-repeat="post in posts">
Click to open, move focus away to close:
<button id="{{post.indexValue}}" type="button" class="btn">
Click
</button>
<wj-popup class="popover" owner="#{{post.indexValue}}" show-trigger="Click" hide-trigger="Blur">
<ng-include src="'includes/popup.htm'"></ng-include>
</wj-popup>
</div>
Issue is with id. Pop up is not working even if there is no ng-repeat and owner id starts with any number. Changing button id to "btn{{post.indexValue}}" worked for me. Try this fiddle.
<div ng-repeat="post in posts">
Click to open, move focus away to close:
<button id="btn{{post.indexValue}}" type="button" class="btn">
Click
</button>
<wj-popup class="popover" owner="#btn{{post.indexValue}}" show-trigger="Click" hide-trigger="Blur">
<ng-include src="'includes/popup.htm'"></ng-include>
</wj-popup>
</div>
On the process of trying to learn angularjs, I am creating a set of divs using ng-repeat. I have five divs in all. I am only displaying the first div using $firstdirective component.
<div class="container" ng-app="demoApp" ng-controller="demoController">
<div class="row" ng-repeat="job in jobs" ng-hide="!$first">
<div class="col-md-4">
{{job}}
</div>
<div class="col-md-4">
<button class="btn-primary btn-xs add" ng-click="showNext($event)" ng-hide="$last">Add</button>
<button class="btn-primary btn-xs delete" style="display: none;">Delete</button>
</div>
</div>
</div>
That works.
Now, each div has two buttons, Add and Delete. When I click add I want to hide the add button and delete button of the current row and open the next row. So I wrote,
$scope.showNext = function(evt) {
var elm = evt.target;
$(elm).hide();
$(elm).next().hide();
$(elm).closest("div.row").next().slideDown();
};
This is not working as ng-hide is overriding my slideDown. What is the angularjs way of doing it?
Also I would like the delete button only on the $last visible row && !first. How to find last visible row in ng-repeat?
Fiddle: https://jsfiddle.net/codeandcloud/u4penpxw/
You shouldn't manipulate the DOM with things like $(elm).hide();, you should use ng-class= to let Angular add classes that hide or show the elements. If you switch your ng-repeat to ng-repeat="job in jobs track by $index", you could write something like that in your showNext()-function:
$scope.showNext = function(index) {
$scope.currentJob = $scope.jobs[index]
}
and call it like ng-click="showNext($index) - of course you'd need to do some refactoring as well. But then you could write something like ng-class="{hidden: (job == currentJob}" to hide all buttons except in the current row.
There's a lot of good thoughts in this q&a: "Thinking in AngularJS" if I have a jQuery background?
Can I place a conditional statement into the collapse directive for AngularUI?
I have the following setup, which has 3 radio-style buttons:
<div class="controls controls-row">
<div class="btn-group" data-toggle="buttons-radio">
<button type="button" class="btn" ng-model="radioPurpose" btn-radio="'meeting'">Meeting</button>
<button type="button" class="btn" ng-model="radioPurpose" btn-radio="'tour'">Tour</button>
<button type="button" class="btn" ng-model="radioPurpose" btn-radio="'other'">Other...</button>
</div>
</div>
<div class="controls controls-row">
<textarea class="span6" placeholder="Why are you here?" ng-model="textPurpose" collapse="{{ radioPurpose == 'other' }}"></textarea>
</div>
I would like textarea to show/hide according to the value of the radioPurpose buttons. I know the statement is evaluating to true at the appropriate time, but the directive always shows the textarea.
Copied answer from comment:
I haven't used AngularUI, but I'm guessing collapse expects an expression. Remove the curly braces: collapse="radioPurpose == 'other'"
Collapse is actually not the best way of doing a simple show/hide. A collapsed item has its height set to 0, rather than being set to display: none; it might not always have the effect you're expecting. I would suggest instead using ng-show or ng-hide.
http://docs.angularjs.org/api/ng.directive:ngShow
I saw that you solved it, and so did I and can share my JSFiddle; Toggle Collapse with Radiobuttons.
However, I see what S McCrohan mean, since I got a problem in my app. The collapse for the table did not work fully in my app first, since it collapsed but left the top row visible. It seems to require that you separate the divs, i.e. a div with collapse and a div with span# class, like following...:
<!-- START CHART AREA -->
<div collapse="chartCollapsed">
<div class="span12 well well-small">
<div id="chart_div" style="width: 600px; height: 400px;"></div>
</div>
</div>
<!-- END CHART AREA -->
<!-- START TABLE AREA -->
<div collapse="tableCollapsed">
<div class="span12">
<!-- TABLE OMITTED -->
</div>
</div>
<!-- END TABLE AREA -->
i repeat things in ng repeat like so
<div class="" ng-repeat="deutscheBankEvent in deutscheBankEvents">
<div class="schrottler-opened schrottler" title="">
<span class="presse_ueber" style="font-size:22px;margin-left:10px;font-weight: normal;margin-top:5px">{{deutscheBankEvent.name}}</span>
</div>
<!-- data-ng-repeat also possible-->
<div class="">
<div class="presse_content">
<Div style="color:white">{{deutscheBankEvent.name}}</div>
<ul class="liste_k">
<li ng-repeat="list in deutscheBankEvent.list">
{{list}}
</li>
</ul>
</div>
</div>
later down the code comes up a form to register to events. the form is hidden until user selects a place and date via select. this is triggered like so:
<span ng-show="myForm.locationDate.$valid">
my issue now is: this shows up all hidden form elements when one select is valid.
how can i set the scope to only this one changed?
Since ng-repeat creates a new scope, changing ng-show/ng-hide conditions to scope bound properties will work perfectly (example).