How to reference a value of an object by property? - angularjs

I have an angularjs object like this:
$scope.afterLogin = [
{value: 'customers|follow-ups', text: 'Follow Ups'},
{value: '', text: 'not set'}
];
I'm trying to use it with xeditable as follows:
<span
editable-select="user.default_module"
e-ng-options="s.value as s.text for s in afterLogin"
e-name="default_module"
e-form="rowform">{{s[user.default_module] as s.text for s in afterLogin}}</span>
What I am trying is to show the text-property in afterLogin that is defined by user.default_module. What am I doing wrong? I am getting parse errors on s[user.default_module] as - how do I reference a property of an object in this scope?
Note: this is wrapped with ng-repeat="user in users".

You are trying to display currently selected value in a very strage way. In the official example they are using filter for this purpose. However, you can simplify it by builing a value: label map, i.e.:
$scope.afterLoginLabels = {};
for (var i = 0; i < $scope.afterLogin.length; i++) {
$scope.afterLoginLabels[$scope.afterLogin[i].value] = $scope.afterLogin[i].text;
}
Then, display text value as:
<span [...]>{{ afterLoginLabels[user.default_module] }}</span>
See JSFiddle.

Related

how to make dropdown select a certain value from getting the id from the database?

The code below show a dropdown list from using ng-repeat. When I edit this entity, I have to make them show a certain value selected already than just showing a whole list. I know that I can put selected keyword when I want to select a certain value.
Then what if I used ng-repeat to populate a dropdown? How can I make a dropdown choose a certain value using the id?
<div ng-if="field.name=='ClienteleId'" class="input-group inputFill">
<select ng-disabled="defaultSaveButtons[$index]" class="form-control inputFill2"
ng-model="field.value" ng-options="clientele.id as clientele.name for clientele in dropdown.clienteleOptions | orderBy:'name' track by clientele.id"></select>
/div>
To set the value of a <select> in AngularJS, you need to change the variable that is set as its ng-model to one of the values in your options.
In your case, you have field.value as your ng-model, and your options use the name attribute as their label and the id attribute as their value. To have one of the items in dropdown.clienteleOptions selected by default, you need to set field.value to the id attribute of the corresponding entry in dropdown.clienteleOptions.
Imagine your options and fields look like this:
$scope.clienteleOptions = [
{id: 1, name: 'test 1'},
{id: 2, name: 'test 2'}
];
$scope.fields = [
{name: 'ClienteleId', value: null}
// ...
];
In your controller somewhere, you would have something like this to have test 2 selected:
$scope.fields[0].value = 2;
Or to make it more dynamic:
$scope.fields.forEach(function (field) {
if (field.name === 'ClienteleId') {
field.value = 2;
}
});

Using angularjs how can I get checked and unchecked values

Here I am binding values to ng-click as
<input type="checkbox" ng-model="a.CheckAssign"ng-click="myFunctionnew(a.ENQUIRY_CODE,a.CheckAssign)" />
enquiryArr=[]
$scope.myFunctionnew = function(enqcode,checkassign)
{
enquiryArr.push(enqcode + '&' + checkassign)
var uniqueNames = [];
$.each(enquiryArr, function (i, el) {
if ($.inArray(el, uniqueNames) === -1) {
uniqueNames.push(el);
console.log(uniqueNames)
}
else
{
console.log(uniqueNames);
}
}
Here when I check and uncheck the checkbox the value is storing multiple
Please help me how can I store Enquiry code and T/F values.
If I understand your issue correctly, you're running into duplicate entries in your enquiryArr. You're running into this because you're trying to manually keep track of the array in an odd fashion. While there are ways to correct the way you're storing it, it's even easier to have angular track what is checked and what is not.
Using the following DataSet:
$scope.enquiries = [
{ENQUIRY_CODE: 'ENQUIRY_1', ENQUIRY_NAME: 'First Enquiry', selected: false},
{ENQUIRY_CODE: 'ENQUIRY_2', ENQUIRY_NAME: 'Second Enquiry', selected: false},
{ENQUIRY_CODE: 'ENQUIRY_3', ENQUIRY_NAME: 'Third Enquiry', selected: false},
{ENQUIRY_CODE: 'ENQUIRY_4', ENQUIRY_NAME: 'Fourth Enquiry', selected: false}
];
And binding the selected field to your checkboxes ng-model
<div ng-repeat="e in enquiries">
<input type="checkbox" ng-model="e.selected" />
{{e.ENQUIRY_NAME}}
</div>
You can determine which one is checked simply by looking at the $scope.enquiries array and looking for selected: true (or false if you want to know the ones not checked).
In javascript you can use a simple Array Filter to get the selected values as such:
$scope.enquiries.filter(e => e.selected);
Or if you want to get them in your template, you can also use the filter pipe as such:
{{(enquiries | filter:{selected:true})}}
Here is an interactive plunkr that you can view this.
Misc Note: If you do want to run something when the checkbox is clicked, you can still use an ng-click and run your custom code, however, I would recommend using ng-change as there are other ways to change the selected value of a checkbox other than clicking.
I have test your code and its working fine. your problem is not so much clear so you can check following test code.
<div ng-controller="MyController">
<div ng-repeat="dt in data">
<input type="checkbox" ng-model="CheckAssign" ng-click="myFunctionnew(dt.name,dt.volume)" />
</div>
</div>
Javascript
$scope.myFunctionnew = function(enqcode,checkassign)
{
enquiryArr.push(enqcode + '&' + checkassign)
var uniqueNames = [];
for(i=0; i <enquiryArr.length; i++) {
if ($.inArray(enquiryArr[i], uniqueNames) == -1) {
uniqueNames.push(enquiryArr[i]);
console.log(uniqueNames)
}
else
{
console.log(uniqueNames);
}
}
}
JSFiddle

Ng-click filter between 2 scopes

I am new to Angular.js so I am not sure if this is the right approach. I have two scopes that are used to display 2 sets of buttons. The second set should be dependent on the button I click in the first set.
<!-- Insulation placement -->
$rootScope.roofs = [
{
type: 'roof',
label: 'Pitched Roof'
},
{
type: 'attic',
label: 'Floor of Attic'
}
];
<!-- Roof insulation types -->
$rootScope.roofInsulation = [
{
target: 'roof',
type: 'between_rafters',
label: 'Between Rafters'
},
{
target: 'roof',
type: 'between_rafters_counter_batten',
label: 'Between Rafters With A Counter Batten'
},
{
target: 'roof',
type: 'between_rafters_calibel',
label: 'Between Rafters With Calibel'
},
{
target: 'roof',
type: 'between_rafters_thermal_laminate',
label: 'Between Rafters With Thermal Laminate'
},
{
target: 'attic',
type: 'test',
label: 'Test'
}
];
and my HTML
<div ng-repeat="types in roofs">
<button ng-click="myFilter = {target: '{{types.type}}'}" class="btn btn-primary" type="button">{{types.label}}</button>
</div>
<div>
<button ng-repeat="variants in roofInsulation | filter: myFilter" class="btn btn-secondary" type="button">{{variants.label}}</button>
</div>
I realize that myFilter in the ng-click is a bit of a hack, but aside from that I can't get it to filter the results of ng-repeat. The myFilter variable does return the proper result {target: 'roof'} (for the first button). Do I assume correctly that it's because the first set of buttons is in a different scope than the second one?
You are not really using 2 different scopes here. If you had been using 2 different controllers or different directives then you would have got 2 different scopes. You are using $rootScope which is common across the entire angular app.
The reason myFilter is not working is because angular is unable to parse the expression in ng-click correctly, it's better you write a method (exposed to the scope) and change the value of myFilter in the method. It's a good practice as well as a better way to achieve what you are trying to do.
HTML
<button ng-click="setFilter(types)" class="btn btn-primary" type="button">{{types.label}}</button>
JS
$rootScope.setFilter = function(types) {
$rootScope.myFilter = {target: types.type};
}
Check this fiddle here, I have created a working example based on your code.
EDIT
Even if your target variable is an array there shouldn't be any issue because Anguar's pipe filter will take care of it.
I have updated and created a new fiddle to show it, check it here.
So if target is an array having 2 values - ['roof', 'attic'], that particular element will be shown for both the buttons.

How to set a custom object value in angular ng-options?

I have a array opts with the different options for a <select> element. Array's objects have a property text for display and a property value for get the value and set in a variable $scope.opt2.
Controller:
function MyCtrl($scope) {
$scope.opts = [
{value: 10, text: '1st' },
{value: 20, text: '2nd' }
];
}
I want set:
$scope.opt2 = {ref: 10} and show 1st when the first option is selected
$scope.opt2 = {ref: 20} and show 2nd when the second option is selected
I tried:
<select ng-model="opt2" ng-options="{ref: obj.value} as obj.text for obj in opts">
The value sets correctly but the text is not show. Any solution?
Examples for testing: http://codepen.io/ces/pen/azbLzX
While Philipps response will work, it's a little more complicated then you need it to be, change your select to this:
<select ng-model="opt2.ref" ng-options="obj.value as obj.text for obj in opts">
See the edited codepen here: http://codepen.io/anon/pen/XJWeVQ

angular-ui/ui-select: how to set initial selected object correctly

This is my ui select in the view:
<ui-select ng-model="selectedLabel.selected" ng-disabled="fetchingLabels || working">
<ui-select-match placeholder="">{{$select.selected.code}}</ui-select-match>
<ui-select-choices repeat="label in labels| filterBy: ['name', 'code']: $select.search">
<div ng-bind-html="label.code | highlight: $select.search"></div>
<small ng-bind-html="label.name | highlight: $select.search"></small>
</ui-select-choices>
</ui-select>
And this is the relevant code in my controller:
$scope.labels = [];
$scope.selectedLabel = {};
$scope.selectedLabel.selected = $scope.passedLabel; // This is an object passed
// from the previous controller.
// The scope comes with it.
$scope.fetchLabels(); // This fetches the labels from the server
// and puts them in $scope.labels
The labels brought from the server are theoretically like these:
[{'labelId': 20, 'code': 'L20', 'name': 'some label'},
{'labelId': 21, 'code': 'L21', 'name': 'other label'}, ...]
And the passed from-outside label, 'passedLabel', is theoretically like ONE of those in $scope.labels too, eg:
passedLabel = {'labelId': 21, 'code': 'L21', 'name': 'other label'}
...I say theoretically because, empirically, I'm seeing that they are different because of the things that angular adds to them (eg. $$hashKey, or __proto__).
So, because of that difference, the $scope.selectedLabel.selected = $scope.passedLabel isn't matching the corresponding item in the ui-select (they are not the same object), and thus, the result of that is this behavior:
How can I set the initial selection correctly? is there a way I can use id's instead of object comparisson? I want to avoid having a for like this:
for (i=0; i<$scope.labels; i++) {
if ($scope.labels[i].labelId == $scope.passedLabel.labelId) {
$scope.selectedLabel.selected = $scope.labels[i]
}
}
which I'm pretty sure it would work as expected, but I would have to call that for after the ajax has returned... and I have other ui-selects too
If you want to achieve the state that you have mentioned, then simply pass the correct reference to your model.
So after the success of the fetchlabel call you set the values in labels. Now in the success of this function you need to call the function that fetches presentLabel.
As soon as you get the data of present label you can get the index of that object in the labels scope.
var idx;
_.find($scope.labels, function(label, labelIdx){
if(label.labelId == parentLabel.labelId){ idx = labelIdx; return true;};
});
$scope.selectedLabel = {};
$scope.selectedLabel.selected = $scope.labels[idx];
This will solve your purpose.

Resources