I have a global controller in my AngularJS application which provides me with a array containing Attendee objects. Want i want is to modify my CourseRegistration Model which contains one specific attendee object. In the edit window I d like to get a dropdown with all possible attendees whereas there should be the current attendee selected.
I have the following code in my html:
<select ng-model="courseRegistration.attendee" ng-options="attendeeSelectItem.name for attendeeSelectItem in attendeeSelectItems"></select>
If I print out courseRegistration.attendee with JSON.stringify and do the same with the corresponding option they print out the same object (same id, same name etc.). But if I do something like (courseRegistration.attendee == attendeeSelectItem) for the two identical objects, then I get false.
So my question is how can I make sure that the currently selected item (stored in courseRegistration.attendee) gets matched with the corresponding object in my list (which is used by options) ?
Thanks a lot in advance.
JSFiddle: http://jsfiddle.net/2ddCy/
Greets
Marc
Essentially when you use an array of objects to populate a select, it selects the entire object, not just the one item you're seeing in the select list.
See this question for detail and example code: Problems when using ng-options and ng-switch together
I'm assuming that you've got something like the following in your controller?
$scope.courseRegistration = {attendee: {id: 2, name: "A Person"}}
If so, the reason the comparison fails is that although the object may have the same properties as the one currently selected, it refers to a different object in memory and therefore isn't classed as equal.
Now as a quick hack you could stringify them and then compare, however the correct approach would be either to set the current value by key:
$scope.courseRegistration = {attendee: attendeeSelectItems[1]};
Or just store the id/name and set your ng-options condition to bind to just that value:
$scope.courseRegistration = {attendee: 1};
<select ng-model="courseRegistration.attendee" ng-options="attendeeSelectItem.id as attendeeSelectItem.name for attendeeSelectItem in attendeeSelectItems"></select>
Related
I have a value that I need to compare to the values in an object. The object is like:
[{"dbid":800,"MemberID":1460,"ID":1460,"Search":"TRUE","Year_Start":"2017","Year_End":2019,"Last_Name":"XXXX","First_Name":"XXX","Middle_Initial":"X","Suffix":"","Email":"","Program_Code":"CM","Pending":"","Initials":"OS","Include":"1","Exclude":"0","Authoring_Names":""}, ... ]
and again for 100's of names.
I want to create a search box that allows the end user to compare a name to the names in the list. So I want to send the last name of the comparing value to a function that will return most of the information such as First Name, Middle Initial, Last name, Program etc. The comparing value may or may not be in the list.
I've look at
Vue JS2 find array value by id
and it's close, but I want more information than one element. Also I saw that it maybe possible to filter an object in Veux, since I store that information in there.
To find all people with a certain last name, you should use filter as it's very similar to find only it returns multiple items in an array.
const found = people.filter(({ Last_Name }) => person.Last_Name == Last_Name);
Note that to check if no people have been found you need to check if length == 0 because an empty array is still truthy.
The "selected" property of MenuItem it isn't working in Select.
Please check https://codesandbox.io/s/9j8z661lny
I tried to compare using Id, also you can only write selected={true} and it did not mark the words that are already selected
Probably I'm using the component in a wrong way, however I will accept any recommendation to obtain the behavior I desire.
Thanks in advance for your time.
Best Regards
You don't need to do anything with the selected prop on MenuItem -- it gets set automatically. What you do need is for the MenuItem value to match a value in the Select's value array.
Currently you are using objects as your values. Material-UI supports using objects, but the equality check will only work if you are using the exact same objects (=== must be true) for your selected values and your MenuItem values.
In your case, you have two sets of objects -- one for your selected groups (passed as the Select value) and one for the full set of groups (used for the MenuItem values). Though the two sets of objects contain matching information, none of the objects from the full set will be equal (===) to any of the objects in the selected groups.
I recommend that you use just the "id"s for the values. Then to produce the Chips for your selected values, you just need to be able to look up a group by its id.
Here's a working example based on your sandbox:
( i am using the backbone forms extension to create my forms: https://github.com/powmedia/backbone-forms)
I have two select boxes and when the first is changed it should change the values of the second. I have got the filtering sorted and have an array of objects that need to be used as the new values for the second select box, i have placed these in a new collection.
After ready the documentation i assumed i could do this:
var newProducts = new App.Collections.Products(correct);
form.setValue({ ProductUsed : newProducts});
Where correct is an array of objects, however my select box just goes blank and allows me to select the other options when focused.
Any advice would be great?
Cheers,
Tom
evilcelery shared this fiddle: jsfiddle.net/evilcelery/c5QHr
This resolves the issue i had.
I have a collection of objects in my view model. I'm experiencing an issue when binding a value to select control. The value is a JS object and not a primitive type. When I have more than one object in the bound collection and change the select control, all of the other object's values update to the newly selected one. It's like all of the values are bound to the same instance inside the foreach binding. The error only seems to happen when new rows are inserted, not when simply editing existing ones.
I have striped out a lot of the complexities and have an example showing the issue on JSFiddle.
http://jsfiddle.net/zero21xxx/5vgDy/
Steps to see the Error
Select Settle Type from the drop down of row 1
Select "Two" from the new drop down to the right.
Select Settle Type from the drop down of row 2
Both row 1 and row 2 will now both be set to "One" in the select box.
I would expect that a change in one row would not effect any of the other rows.
It's all a bit complicated how you have it setup, however, I think the problem is, that your ids are not what you expect,
function getValues(tabId) {
console.log("tabId " + tabId);
if (lookUp[tabId]) {
if I add that to your code, it show's the same tabId, which means you are dealing with the same objects by the looks of it.
if I change getValues so each time it does
function getValues(tabId) {
console.log("tabId " + tabId);
return [new DatabaseField(nextId(), "Name", "Attorney Name", DataType.STRING.id),
new DatabaseField(nextId(),
"Type", "Settle Type", DataType.DROPDOWN.id)];
}
also I changed all the observables with [] to observable arrays...
then it seems to work. fiddle... http://jsfiddle.net/keith_nicholas/wmxJX/
Each time that you choose a different selectedDatabaseField it rebuilds the availableOptions.options. Each of the rows are bound against these same options as choices. When the options are rebuilt, then each row's selected value is no longer a valid choice.
Even if the object looks exactly the same it is not equal unless it is a reference to the same object.
So, since the options have changed and the currently selected value is no longer valid, the value binding will assign the first option as the value (unless you have an optionsCaption specified).
So, you probably don't want to rebuild the options, if they are already built or you would want separate options for each row rather than binding against the same database field object.
Consider this jsfiddle.
I can't think of a way to ensure that if row one in the above example has already been selected in the dropdown that the next row would be prevented from selecting the same value.
I think that my problem here is that when the dropdown click event fires, the subscriber does not monitor this change when the child value has changed. Anyone able to assist?
viewModel.actualMetrics.subscribe(function(newValue) {
if (newValue) {
$.each(viewModel.actualMetrics(), function(n, item) {
if (item.MetricTypeId() == newValue.MetricTypeId)
alert("already selected this Metric");
});
}
Here is a basic sample of one way to do what you want: http://jsfiddle.net/rniemeyer/3cpUp/
Here is your sample with it: http://jsfiddle.net/rniemeyer/8bQmq/
The basic idea is that you have your list of choices, then you create a dependentObservable that is an index of the currently used choices. This saves some looping through the current choices when building each rows options. This index could be an object or an array. I used an object, but you could use an array as well with the id as the index.
Then, on each item, you could have a dependentObservable to store the filtered choices for that item. However, I used a function instead, because it does not seem like a property that is really important to the view model and bindings are implemented using dependentObservables, so you get the same effect without having the choices show up when you send it toJSON. The function loops through all of the choices and includes only the choices that do not appear on another line by checking its own value and the index.