AngularJS disabling one dropdown in ng-repeat - javascript

I have the following ng-repeat in my HTML code:
<div ng-repeat="a in items">
<div>
<span>{{a.name}}</span>
</div>
<div>
<select ng-model="a.c_id" ng-options="d.c_id as d.description for d in loclist" ng-disabled="display" ng-change="selected(a.c_id)">
</select>
</div>
Then in my controller I have:
$scope.display = false;
$scope.selected = function (value) {
$scope.te = value;
if ($scope.te == 3) {
$scope.display = true;
}
};
Problem I am facing is that when I change the selection in the drop down it is supposed to disable or enable the dropdown based on value. However when I change the selection in one of the drop down that has value of 3 all the dropdowns change to disabled state rather than that particular one.
Please let me know how to fix this code so when after ng-repeat has displayed all rows and I change the dropdown value of one of the rows it just disables that particular one rather than disabling all the dropdowns in all rows.

Angular ng-repeat creates child scopes inherited from parent scope. In your case, all your ng-repeat's scopes inherit the display property from parent scope. Therefore when this property changes, it reflects on all scopes.
Try this instead of $scope to access the current scope of ng-repeat:
$scope.selected = function (value) {
this.te = value;
if (this.te == 3) {
this.display = true;
}
};

Related

Knockout js - How to change dropdown value to previous value if certain condition is not matched

knockout js - In my HTML page, I have a dropdown and JQgrid in which user can add new rows. if user changes dropdown value before saving grid data , i want to alert user if he wants to save grid data or continue. if user wants to save data, dropdown value should be old value else new value.
I am facing issue that dropdown value is getting changed to new value.
i have knockout js subscribe method on selectedItem of dropdown. in subscribe method, logic to populate grid is present.
The subscribe method on an observable tells you what the value has been changed to after it's been changed, so unfortunately it's already too late to cancel. I think you could accomplish what you want by binding to the change event instead of using the value binding, and manually updating the observable with the new value if it passes your conditions.
var viewModel = function() {
var self = this;
self.Options = [1, 2, 3, 4];
self.selectedOption = ko.observable();
self.selectedOption.subscribe(function(newValue) {
console.log(newValue);
});
self.isOptionValid = function(value) {
return (value > 2);
}
self.onChange = function(viewModel, event) {
var target = event.target;
var newValue = $(target).val();
if (self.isOptionValid(newValue)) {
self.selectedOption(newValue);
} else {
console.log('Invalid selection');
$(target).val(self.selectedOption()); //reset to previous value
}
}
}
ko.applyBindings(new viewModel());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div>
<span>Pick a number greater than 2</span><br/>
<Select data-bind="options: Options, optionsCaption: '', event: {change: onChange}">
</Select>
</div>
This has the disadvantage of only being a one-way binding meaning that if your observable's value changes from some other source then the dropdown will not be updated with that new value. If you need to preserve a two-way binding then you might want to try a custom binding handler instead, something like: gated value binding

dynamically change ng-repeat

I have an object made like this:
var examples = {
'example1': {
ex1: {},
ex2: {},
ex3: {}
},
'example2': {
ex1: {},
ex2: {},
ex3: {}
}
}
There is a button linked to a function which fills the example1 object with values on the first click, and the example2 object on a second click.
First click: example1 get values.
Second click: example2 get values.
Then i loop through the object using ng-repeat, like this:
data-ng-repeat="example in examples.example1.ex1"
data-ng-repeat="example in examples.example1.ex2"
data-ng-repeat="example in examples.example1.ex3"
The problem here is, i need the ng-repeat to somehow change and loop through the example2 object aswell when the button is clicked a second time. So my question is, is there a way to change ng-repeat dynamically?
EDIT: The goal is for the first list of appear after the first click, and then for BOTH lists appear together after the second click.
I tried to make a $scope with the value 2 and put it in the ng-repeat, but that didn't work.
$scope.counter = 2; //in a controller
data-ng-repeat="example in examples.example(counter).ex1"
Use dynamic property name
$scope.prop = 'example1';
$scope.click = function (newProp) {
$scope.prop = newProp;
// do whatever you want here
// change prop to example2 or
// or simply toggle Boolean to change prop text
}
And in html use
ng-repeat="example in examples[prop].ex1"
Would it be a solution to loop through "examples" instead, and then have a ng-repeat inside an ng-repeat?
Something like this:
<div data-ng-repeat="example in examples">
<div data-ng-repeat="ext in example">
{{ext.ex1}} {{ext.ex2}} {{ext.ex3}}
</div>
</div>
Do something like Jannik's answer in the html and this in the JS:
$scope.examples = {};
function example(exes) {
this.exes = exes;
}
$scope.onClick = function(exes) {
$scope.examples.push(new example(exes));
}
The exes is a list of ex1,ex2,etc. You may need a $scope.$apply() at the end of this to update the UI.

xeditable Grid's drop down values cannot change from the outside dropdown

I'm using xeditable angular directive.I need to set the grid's all the drop down values of Status column according to the value of the outside drop down.
I have set up the JsFiddle here.But it's not working.Could you tell me Why ? Thanks in advance.
Update: When I click the cancel button then it's updated.Very strange :( Could you tell me how to sort out this issue ?
HTML
<span editable-select="bulkPaymentType" e-form="tableform" e-ng-options="s.value as s.text for s in statuses" e-ng-change="setBulkPaymentType($data)">
</span>
js
$scope.setBulkPaymentType = function (data) {
for (var i = $scope.users.length; i--;) {
var user = $scope.users[i];
user.status = data;
};
};
JSFiddle
I have found the solution.Here it is :)
HTML
<span editable-select="bulkPaymentType" e-form="tableform" e-ng-options="s.value as s.text for s in statuses" e-ng-change="setBulkPaymentType($data,tableform)">
</span>
JS
$scope.setBulkPaymentType = function (data,tableform) {
for (var i = 0; i < tableform.$editables.length; i++) {
if (tableform.$editables[i].name === 'user.status') {
tableform.$editables[i].scope.$data = data;
}
}
};
Play with it : JSFiddle
Your setBulkPaymentType method is updating the users in your controller scope.
But the value in the editable input is actually a copy from your controller scope. So when you call setBulkPaymentType, you don't see them change. And when you hit cancel button, the form will display with the value in your controller scope which you updated with setBulkPaymentType, that is the reason. I don't think you can modify the $data within each editable directly since they are using isolated scope. There is no way to get access to $data from outside.

ng-click under ng-repeat under Angular

I have a ng-repeat under that
i have ng-click
like
<div ng-repeat="">
<div ng-click="someFunction(name)"></div>
<input type="text" class="common btnDarkGrey editDashboardCategory" data-ng-model="inputCategory" ng-hide="!item.show">
</div>
Now my code
$scope.someFunction = function(name) {
$scope.scroller.items[index].show = true;
$scope.inputCategory=name;
});
Which is working fine on very first click.
When i click second time. my first div pick second value
Any idea ? how to do this
Thanks
If you want individual showName values per rendered row you need to set it to individual child scope. Right now you are setting the value to the parent scope showName which is shared by all child scopes ngRepeat creates.
The simple fix is to refer child scope with this keyword:
$scope.someFunction = function(name) {
var new_name = /* some other calculations */
this.showName = new_name;
};

edit functionality is not working in knockout js

I just created an editable using an example available on net.in this when i am trying to edit the grid then it doesn't show the value it shows the input field blank.can any body help ?
in edit i am calling this function
self.editFruit = function (fruit) {
if (self.editingItem() == null) {
// start the transaction
fruit.beginEdit(self.editTransaction);
// shows the edit fields
self.editingItem(fruit);
}
};
here is fiddle jsfiddle
At the time the binding is evaluated for the first time the editValue child observable of each of fruit's observables ( data-bind="value: name.editValue" ) doesn't exist. When you click on the "edit" link the editValue observable is created but knockout doesn't know that it has to rebind.
You can solve this 2 ways.
1 . Create a virtual if binding around each input. When the if becomes true, the content will be reinserted back into the DOM causing the bindings to re-evaluate. Make sure that editValue observable is attached to its parent BEFORE editingItem observable is set, otherwise you are in the same situation
<!-- ko if: $root.isItemEditing($data) -->
<input data-bind="..."></input>
<!-- /ko -->
2 . Make sure that all observables have the editValue observable attached to the parent observable before the model is bound, the set editValue observable's value in the beginEdit fn.
function Fruit(data) {
var self = this;
self.name = ko.observable(data.name || "");
self.name.editValue = ko.observable();
self.rate = ko.observable(data.rate || "");
self.rate.editValue = ko.observable();
}
ko.observable.fn.beginEdit = function (transaction) {
...
if (self.slice)
self.editValue(self.slice());
else
self.editValue(self());
...
}

Categories

Resources