I have created an application in AngularJS with edit, save and cancel options, but the problem is that when I click the edit I am not getting the value for editing and saving.
The textfield and dropdowns are been provided through ng-transclude
Can anyone please tell me some solution for this
DEMO
HTML
<div ng-controller="LocationFormCtrl">
<h2>Editors</h2>
<span ng-repeat="location in location">
<div class="field">
<strong>State:</strong>
<div click-to-edit="location.state"><input ng-model="view.editableValue"/></div>
</div>
<div class="field">
<strong>City:</strong>
<div click-to-edit="location.city"><select ng-model="view.editableValue" ng-options="loc.city for loc in location"></select></div>
</div>
<div class="field">
<strong>Neighbourhood:</strong>
<div click-to-edit="location.neighbourhood"><input ng-model="view.editableValue"/></div>
</div>
<h2>Values</h2>
<p><strong>State:</strong> {{location.state}}</p>
<p><strong>City:</strong> {{location.city}}</p>
<p><strong>Neighbourhood:</strong> {{location.neighbourhood}}</p>
<hr>
</span>
</div>
Don't really know why, I was just playing around with the code, but seems working, at least with the text fields, using ng-if instead of ng-show/ng-hide: http://jsfiddle.net/T6rA9/1/
I'll update my answer if I find a reason...
Update: I think this is what you're looking for: http://jsfiddle.net/T6rA9/7/
The difference is that instead of saving the value on save, I am reverting the changes on cancel, which is easier due to angular two-way data-binding.
Because of that, I also removed the view.editableValue ng-model directive and used the fields as you would normally do.
Transclusion and isolated scopes does not work the way you may think. You can read more about it here http://angular-tips.com/blog/2014/03/transclusion-and-scopes/
If you i.e. make this change you will already see a difference
<div click-to-edit="location.state"><input ng-model="location.state"/></div>
What about creating ngClick function which add input element inside your div with previous value?
<div class="newInput" ng-show="hidden">
<label> {{ inputValue }} </label>
</div>
<div class="newInput" ng-show="!hidden">
<input ng-model="inputValue" />
</div>
And main.js file:
app.controller('MyCtrl', function($scope) {
$scope.hidden = true;
$scope.inputValue = 'Edit me!';
$scope.addInput = function() {
$scope.hidden = !$scope.hidden;
}
});
Here you have Plunker
Related
I am facing some issue. I have some nested controller within one parent controller and I need it to execute as per some condition using Angular.js. I am explaining my code below.
NABH.html:
<div ng-controller=NABHParentController>
<div ng-show="showNabh">
<div ng-include="'nabh1.html'"></div>
</div>
<div ng-show="showNabh1">
<div ng-include="'nabh2.html'"></div>
</div>
</div>
nabh1.html:
<div class="right_panel" style="display:block;" id="auditnabh" ng-controller="NABHController">
<td class="sticky-cell" ng-click="initiateNABH(nabh.NABHAuditID)">
</td>
</div>
nabh2.html:
<div class="right_panel" ng-controller="NABH2Controller">
<h2 class="page-title">NABH (INT012017001)</h2>
<div>
NABHParentController.js:
var app=angular.module('demo');
app.controller('NABHParentController',function($scope,$http,$state,$window,$location,$filter){
$scope.showNabh=true;
$scope.showNabh1=false;
})
NABHController.js:
var app=angular.module('demo');
app.controller('NABHController',function($scope,$http,$state,$window,$location,$filter,getBothIdToAuditDetailPage)
{
$scope.initiateNABH = function(aid) {
$scope.$parent.$parent.showNabh=false;
$scope.$parent.$parent.showNabh1=true;
}
})
Here Initially all controller are loading and nabh1.html is displaying first. When user will click on that td click event the second part html is showing. Here I need when user will click on that ng-click="initiateNABH(nabh.NABHAuditID)" the second view will open and the resepective controller will start execute. Initially only displaying view related controller will execute. Please help.
It sounds like using ng-if instead of ng-show will solve your problem:
<div ng-if="showNabh">
<div ng-include="'nabh1.html'"></div>
</div>
<div ng-if="showNabh1">
<div ng-include="'nabh2.html'"></div>
</div>
The difference is that while ng-show will "only" hide the element using css when the expression is falsy, ng-if will not create the element if it's falsy and as a result will not initiate the controller until ng-if is truthy.
Also, I would probably move the initiateNABH function to the parent controller - it will still be available in the child controller but makes the code less likely to break since you don't have to use $parent:
var app=angular.module('demo');
app.controller('NABHParentController',function($scope,$http,$state,$window,$location,$filter){
$scope.showNabh=true;
$scope.showNabh1=false;
$scope.initiateNABH = function(aid) {
$scope.showNabh=false;
$scope.showNabh1=true;
}
})
I am learning to use Angular (1.3.10), I have two input fields that specify the suit and value for a hand of playing card. As you can see from the image below, when I try to hardcode the suit and value, the card shows up fine (one on the right). But when I use ng-model to bind it, the card_value is not displaying correctly although it is picked up by the browser. What am I doing wrong?
<div ng-app = "cards">
<form>
<div>
<input ng-model = "card_value">
<span>of</span>
<input ng-model = "card_suit">
</div>
</form>
<div>
<p>Entered: {{card_value}} of {{card_suit}}</p>
<!-- card.value is not binding up perfectly fine -->
<card value = "{{card_value}}" suit = "{{card_suit}}"></card>
<!-- -->
<!-- this shows up perfectly fine -->
<card value = "5" suit = "Clubs" ></card>
<!-- -->
</div>
</div>
What I see being displayed:
Chrome inspector: the part that is highlighted is where ng-binding fails, should be 5
ng-bind has one-way data binding.
ng-model is intended to be put inside of form elements and has two-way data binding
You should use ng-bind
<div ng-bind-html="card_value"></div>
DEMO APP
I generated my project using JHipster and one of my entities uses pagination (). Everything is working fine, however I want to include a page size option along with pagination. But I don't see any option for that in UI Bootstrap documentation. Therefore I wrapped the uib-pagination directive in a custom directive.
Here is the directive:
'use strict';
//angularJS directive for Spring Pagination with page size control.
angular.module('myApp')
.directive('springPagination', function(){
return{
restrict: 'AE',
replace: true,
scope: true,
templateUrl: 'scripts/components/pagination/spring-pagination.html',
controller: 'my_entity_controller'
};
})
Here is the template (HTML):
<div class="row row-sm-height" id="pagination_div">
<div class="col-md-6 pagination_panel col-xs-12" id="pagination_left">
<uib-pagination class="pagination-md" total-items="totalItems"
ng-model="page" ng-change="loadAll()" rotate="false"
boundary-links="true" boundary-link-numbers="true" max-size="7"></uib-pagination>
</div>
<div class="col-md-6 pagination_panel col-xs-12" id="pagination_right">
<div class="row pagination_panel_row">
<div class="col-xs-4 pagination_panel_item">
<label>Items Per Page:</label>
</div>
<div class="col-xs-4 pagination_panel_item">
<input class="form-control" placeholder="Items per Page"
type="number" min="5" max="100" ng-model="newItemPerPage"></input>
</div>
<div class="col-xs-4 pagination_panel_item">
<button type="button" class="btn btn-info"
ng-click="setItemPerPage()">Set</button>
</div>
</div>
</div>
</div>
When i click on the item on my custom directive, for example the page number or set page size to 50, AngularJS is able to get the new value and send a REST request to the server and the server response with new data. However, my table remains the same page without any changes.
Can someone give me some directions please? Why is my data not updating like it supposed to without the custom directive? Perhaps there is a build-in option for ui.bootstrap.pagination to display page size so that I don't need to create a custom directive so that there is less hassle??
Silly me. Turns out my approach is doable, but I just forgot to use apostrophe on the boolean. So basically:
scope: true
should be:
scope: 'true'
I am pretty sure I saw other tutorials which use
scope: true
without the apostrophe too. But oh well, at least my problem is solved...
also, there is no need to put controller and replace option (well, at least for my use case i don't need to) because I want my directive to share the same controller from the html that I applied this custom directive to.
AngularJS Verion: 1.3.8
JSFiddle: http://jsfiddle.net/uYFE9/4/
I've been working on a small AngularJS application, and ran into a bit of a problem. I have an ng-repeat on a page, which fills in the contents of a form. The amount of items in the form is defined by a dropdown bound to a model, and populated using ng-options. Something like:
<select id="testAmount" ng-model="selectedItem" ng-options="item.name for item in items"></select>
<form role="form" name="testForm" ng-if="!complete">
<div ng-repeat="i in getNumber(selectedItem.number) track by $index">
{{$index}}
</div>
</form>
Complete is set to false in the beginning, and hitting a Next button will toggle complete and hide the form and dropdown. A Back button will then toggle complete back, and show the form again.
The problem I'm having is with the ng-if on the select (and previously, I had the form wrapped in a div with the same ng-if - same problem). The ng-repeat no longer updates when the select dropdown is changed. Removing the ng-if on the select restores the ng-repeat to working order.
I'm wondering if there's something strange I'm doing with the nesting here, or if it's actually a bug? You can test it out on the JSFiddle linked above. The $index should be printed the number of times on the dropdown, but isn't.
Interestingly enough - when debugging the problem on my local machine, having FireBug open fixed the issue.
This is because of ng-if creating a child scope and how prototypical inheritance works with primitives. In this case, the primitive is selectedItem that you are setting by the <select>, but is actually being set on the child scope and shadows/hides the parent scope property.
In general you should always use a dot (.) with ng-models:
$scope.selection = {selectedItem: undefined};
And in the View:
<div ng-if="!complete">
<select ng-model="selection.selectedItem"
ng-options="item.name for item in items"></select>
</div>
ng-if is causing you some scoping issues (which messes with the binding).
Here is an updated jsfiddle that you could use as a work around. Essentially, this example wraps another div around the items that you want to end up hiding. And then adds a next function so that the same scope is affected during the click that sets complete to true.
HTML:
<div ng-app="test">
<div ng-controller="TestCtrl">
<div ng-if="!complete">
<div>
<label for="testAmount">Amount:</label>
<select id="testAmount" ng-model="selectedItem" ng-options="item.name for item in items"></select>
</div>
<form role="form" name="testForm">
<div ng-repeat="i in getNumber(selectedItem.number) track by $index">
{{$index + 'hi'}}
</div>
<button class="btn btn-default" value="Next" title="Next" ng-click="next()">Next</button>
</form>
</div>
<div ng-if="complete">
</div>
</div>
</div>
JS:
angular.module('test', [])
.controller('TestCtrl', function($scope) {
$scope.complete = false;
$scope.items = [
{ name: '2', number: 2 },
{ name: '3', number: 3 },
{ name: '4', number: 4 }
];
$scope.selectedItem = $scope.items[0];
$scope.getNumber = function (number) {
return new Array(number);
};
$scope.next = function() {
$scope.complete = true;
};
})
I believe the problem is with your select statement inside an ng-if the selectedItem is never getting set. If you just don't want to show that dropdown when !complete change it to an ng-show and it works fine.
<div ng-show="!complete">
As to WHY the ng-model is not being bound inside the ng-if, I don't really know but it does make some sense in that you are trying to do a conditional bind which is a bit screwy
I have a problem when binding ng-models with ng-repeat in a input tag type checkbox.
I will first attach my code and then explain more in detail.
app/main.html:
<div ng-repeat="feature in features">
<input type="checkbox" ng-model="features[$index].name">{{features[$index].name}}
</div>
<br></br>
<div class="highlighter">
<span ng-class="{emo:Emotions}">Manually</span> <span ng-class="{feel:Feelings}">create</span> the <span ng-class="{emo:Emotions}">entire</span>
</div>
main.js
angular.module('webClientApp')
.controller('MainCtrl', function ($scope,$http) {
[...other variables...]
$scope.features = [{'name':'Emotions'},{'name':'Feelings'}];
[...other parts of code]
});
Let's also assume that in the main.css file there are references to the classes .emo' and.feel' respectively to highlight the target word when the user ticks the box relative to the feature.
Now, the application works correctly when I listed all the inputs one by one like the following:
<input type="checkbox" ng-model="Emotions">Emotions
<input type="checkbox" ng-model="Feelings">Feelings
but I wanted to wrap it into an ng-repeat and list the features in the controller scope, since the features I will considered will be more. When I try the code above when I tick on the box the name changes to `true'.
I have read a lot about how to bind models to an ng-repeat inside a input tag but none of the solutions apply to my case.
Can someone please help me?
I changed thigs up quite a bit from your original model but... I did get something to behave similar to what you are looking for.
HTML
<div ng-app="webClientApp">
<div ng-controller="MainCtrl">
<div ng-repeat="(feature,enabled) in features">
<input type="checkbox" ng-model="features[feature]">{{feature}}</input>
</div>
<div class="highlighter">
<span ng-class="{emo:features.Emotions}">Manually</span> <span ng-class="{feel:features.Feelings}">create</span> the <span ng-class="{emo:features.Emotions}">entire</span>
</div>
{{features}}<br>
{{features.Emotions}}<br>
{{features.Feelings}}
</div>
JS
var app = angular.module('webClientApp', []);
app.controller('MainCtrl', function($scope, $http) {
$scope.features = {Emotions: true, Feelings: true};
});
Here's the fiddle: http://jsfiddle.net/rodhartzell/8YrxQ/
Hope this helps.
(i should add this as a comment, but I don't have enough rep. yet)
There is an issue on github which concerns your issue: https://github.com/angular/angular.js/issues/1404 and the comment of caitp shows some workarounds: https://github.com/angular/angular.js/issues/1404#issuecomment-30859987
You could (also) define a new javascript object in your controller and map the elements to that.
In controller: $scope.awnsers = {};
In template: ng-model="awnsers[feature.name]"
I hope this helps
You must use ng-checked instead of ng-model.
Check out this jsfiddle
http://jsfiddle.net/fizerkhan/z5z9s/24/
ngModel and ngChecked are not meant to be used together.
ngChecked is expecting an expression, so by saying ng-checked="master". If the expression is truthy, then special attribute "checked" will be set on the element
You should be able to just use ngModel, tied to a boolean property on your model. If you want something else, then you either need to use ngTrueValue and ngFalseValue (which only support strings right now), or write your own directive.