Angular ng-options gives empty select option on splice - javascript

So I have an Angular view that has the following markup:
<select id="ddlHandheldIds"
name="ddlHandheldIds"
class="form-control"
ng-model="vm.handheldPayment.handHeldId"
ng-options="id as id for id in vm.handheldKeys track by id"
required
title="select hand held id">
<option value="">select hand held id</option>
</select>
The vm.handheldKeys when page is loaded is an array with two values [0,24].
When the page loads, the rendered HTML is the following (tabbed for readability):
<select id="ddlHandheldIds" name="ddlHandheldIds"
class="form-control ng-dirty ng-touched ng-valid-parse ng-valid ng-valid-required"
ng-model="vm.handheldPayment.handHeldId"
ng-options="id as id for id in vm.handheldKeys track by id"
required=""
title="select hand held id">
<option value="" class="">select hand held id</option>
<option value="0" label="0">0</option>
<option value="24" label="24">24</option>
</select>
This, of course, is what you'd expect.
Now, through some business logic, after the user has interacted with the page, there's a function that splices the vm.handheldKeys array. So, let's say the code looks like the following:
vm.handheldKeys.splice(0,1); // Remove the '0' from the array
Now, what I get is the following rendered HTML (notice the first select option):
<select id="ddlHandheldIds" name="ddlHandheldIds"
class="form-control ng-dirty ng-touched ng-valid-parse ng-valid ng-valid-required"
ng-model="vm.handheldPayment.handHeldId"
ng-options="id as id for id in vm.handheldKeys track by id"
required=""
title="select hand held id">
<option value="? string:0 ?"></option>
<option value="" class="">select hand held id</option>
<option value="24" label="24">24</option>
</select>
What's the best way to remove the item from the array without creating that additional option? Is this a bug?
I debug my JavaScript in WebStorm and, sure enough, there's only one item in the array after the splice.
Thanks.
UPDATE:
I also tried adding a filter and setting my options source to the filter, but I still get the same result.
vm.filteredHandheldKeys = function() {
var ids = handheldPayments.map(function(pmt) { return pmt.handHeldId; });
if (!vm.handheldKeys) return;
return vm.handheldKeys.filter(function(key) {
return ids.indexOf(key) == -1;
});
};
UPDATE 2:
Just FYI, if I was to perform
vm.handheldKeys.splice(1,1); // Remove the '24' from the array
The select option now reads:
<option value="? string:24 ?"></option>
It may have to do with this form in which the the select box is located is in a modal? Perhaps the modal isn't getting re-rendered correctly?

I think your code is perfectly fine so you check once again that you just write your code as below :
<select id="ddlHandheldIds" name="ddlHandheldIds"
class="form-control ng-dirty ng-touched ng-valid-parse ng-valid ng-valid-required"
ng-model="vm.handheldPayment.handHeldId"
ng-options="id as id for id in vm.handheldKeys track by id"
required=""
title="select hand held id">
<option value="" class="">select hand held id</option>
</select>
and for slice you use your code as like : -
<input type="button" name="name" value="Splice" ng-click="vm.splice()">
in the vm.splice function your code looks like-
vm.handheldKeys = [0,24];
vm.splice = function () {
vm.handheldKeys.splice(0,1);
}
I check it on my machine and this is perfectly fine.
"HAPPY CODING"

SOOO, my final update was correct, because it was being rendered in the modal, the option was being removed from the angular model after the modal was being rendered (in the middle of a digest). so, angular wasn't picking up the change. What I ended up doing was changing the logic to remove the item while the modal was closed.
This worked.

Related

How to add input value using jQuery

So I have a form that submits device,color and the problem(with the device) and it displays the correct price underneath nicely using jQuery but I can't figure out how to insert the jQuery result into the hidden input value so that it also sends the price to next page(checkout page) Thanks :)
<form method="POST" action="../action.php">
<select class="custom-select mr-sm-2" name="device" id="inlineFormCustomSelect">
<option value="Motorola Edge">Moto Edge</option>
<option value="Motorola Edge Plus">Moto Edge Plus</option>
</select>
<select class="custom-select mr-sm-2" name="color" id="inlineFormCustomSelect">
<option selected>Select Color..</option>
<option value="Solar Black">Solar Black</option>
<option value="Midnight Magneta">Midnight Magneta</option>
</select>
<select class="custom-select mr-sm-2" name="issue" id="inlineFormCustomSelect3">
<option data-price="£0.00" data-total="" selected>Select Problem..</option>
<option data-price="£40.00" data-total="£42.00" value="Screen Repair">Damaged Screen</option>
<option data-price="£15.00" data-total="£15.75" value="Battery Replacement">Battery Replacement</option>
<option data-price="£35.00" data-total="£36.75" value="Audio Repair">Faulty Audio</option>
<option data-price="£35.00" data-total="£36.75" value="Mic Repair">Faulty Microphone</option>
<option data-price="£35.00" data-total="£36.75" value="Cam Repair">Faulty Camera</option>
</select>
<p><i id="price"></i>+Additional Fees</p>
<p>Total:<span id="total"></span></p>
<script type="text/javascript" language="javascript">
$(function(){
$('select').change(function(){
var selected = $(this).find('option:selected');
$('#price').html(selected.data('price'));
$('#total').html(selected.data('total'));
}).change();
});
*//This is some code I tried below//*
$(document).ready(function(){
$('input[id="price"];').val(price);
});
</script>
<input type="hidden" id="price" name="price" value=''>
<button type="submit" name="submit">
In the case that you are trying to use the same values in an entirely different page. You should know that JS variables do not automatically save, you will lose them after refreshing the page or loading another page.
In order to save variables in the browser, you can use localStorage or localSession. In this particular case, I suggest localSession. localSession will delete the data when the browser is close or the cache is cleared.
Also, you could remove the semicolon ';' from $('input[id="price"];').val(price)
I do not suggest using localStorage or localSession for important forms, this requires back-end. You could use PHP, Node, Django, or any back-end for managing forms. But what you tried was ultimatly right, it's just that there was no variable set to retrive the data from. Hence, why the input could be left empty.
One way you can do this is to update the hidden field when you update the text field.
$(function(){
$('select').change(function(){
var selected = $(this).find('option:selected');
$('#price').html(selected.data('price'));
$('#total').html(selected.data('total'));
$('#hiddenPrice').val(selected.data('price'));
}).change();
});
HTML:
<input type="hidden" id="hiddenPrice" name="hiddenPrice" value="">
Notes:
In your question, the hidden input has the same Id as the text field. That's not valid HTML. So give your hidden input a different Id (such as id='hiddenPrice'). Also, be aware that hidden fields can still be modified by a user. You should validate the posted price in your server side code to verify it is the correct price.
Try these
$('select[name="issue"]').on('change', function() {
var issue = parseFloat($(this).children("option:selected").data('price'));
$('input[name="price"]').val(issue);
// or this one below
$('input[name="price"]').val(issue).trigger('change');
});
Also, try changing the id of your hidden input field and remove or extract this '£' from the data-price.

How to determine selected datalist option

Is there way to determite, which option from datalist was selected? I mean when I have duplicite names in datalist, see example below:
<input type="text" list="cities" id="search-bar" name="city" value="" autocomplete="off" placeholder="type city">
<datalist id="cities">
<option value="Olo (PT)" data-city-index="0"></option>
<option value="Olo (PT)" data-city-index="1"></option>
<option value="Olonets" data-city-index="2"></option>
<option value="Olot" data-city-index="3"></option>
</datalist>
It is part of weather app, and in some countries, there are cities with same name (but different location) - so how I can distinguih if user have clicked on first or second Olo in example? Is it even possible? I have idea, that maybe is there way to use data attribute, but I dont know if it actually solve my problem (and how...)
Please help.
EDIT:
I understand, that it is for user little bit uncomfortable to actually "don't know" which city they are selecting in datalist, but unfortunatelly I have no way to "help" them (I have only database with city names and longitude and latitude of it). So after selection of city I include link to google maps (for that location) to displaying part
you should change value of options in city's name of countries . when user click in list it
<input type="text" list="cities" id="search-bar" name="city" value="" autocomplete="off" placeholder="type city">
<datalist id="cities">
<option value="city1 (PT)" data-city-index="0"></option>
<option value="city2 (PT)" data-city-index="1"></option>
<option value="city3" data-city-index="2"></option>
<option value="city4" data-city-index="3"></option>
</datalist>

ng-select is not working in angularjs?

I am facing some problem in drop down of angular js. Below is the html code
<select class="form-control" ng-init="projectName = options[0]" ng-model="projectName" name="projectName" ng-options="project.name for project in projectsList track by project.id" ng-class="{'submitted': submitted}" ng-selected="projectName" required>
<option value="">Select Project</option>
</select>
all the things coming fine.
But what i want is after selecting value from drop down we submit the form and in success am getting the value what i have selected. Now i want to set this value for the drop down, how to do it ?
In jquery it works
$("dropdown").val('successCallBackValue');
but in angular how to do it
After the sucess of the form submit just set the value in the dropdown model value as,
$scope.projectName = yourValue; // whatever selected value you are getting.
<select class="form-control" ng-init="projectName = options[0]" ng-model="projectName" name="projectName" ng-options="project.name for project in projectsList track by project.id" ng-class="{'submitted': submitted}" required>
<option value="">Select Project</option>
</select>

How to populate a value in a select ( HTML ) list in AngularJS

I am using a select list in a particular edit form page. Whenever a particular entry has to be edited, a new state with the edit form appears. It has a select list which has to populated with one of its options (ideally the value that is fetched from the server using API has to be populated into the select).
I am using Angular JS on the client side. Could somebody please tell me how to achieve the same thing using Angular JS?
I need that initial value inserted by the user in the select to be shown up as a default when the edit page is opened.
(MOREOVER, MY PLACEHOLDER NOT WORKING:"Choose a country")
Lets say there is something like this:
<div class="col-md-8">
<select data-placeholder="Choose a Country..." class="chosen-select form-control" style="width:350px;" tabindex="2" required="" ng-model="location">
<option value="" disabled selected>Select</option>
<option ng-repeat="location in locations1" value="{{location.id}}">{{location.name}}</option>
</select>
</div>
Use ngOptions.
<select ng-options="location as location.name for location in locations track by location.id" ng-model="selected"></select>
With ng-options you can do it like this:
<div class="col-md-8">
<select ng-model="selectedLocation" ng-options="location.id as location.name for location in locations1" class="chosen-select form-control" style="width:350px;" tabindex="2">
<option value="" disabled selected>Choose a Country</option>
</select>
</div>
The location.id is set to the options value and the location.name is set to the text.
To use a placeholder in a select is kind of what the default options does for you. So I would set the default option text to "Choose a country". Se this SO answer on that topic

ng-options clears the model (and visible options) on click, what in tarnation?

So here is my ng-options markup:
<div class="form-group">
<label>Client(s)</label>
<select class="form-control" ng-model="addFirm.firmData.clients" ng-options="clients.instance.id as clients.instance.fName for clients in addFirm.firmData.clients" multiple>
</select>
</div>
Here is the resulting html:
<div class="form-group">
<label>Client(s)</label>
<select class="form-control ng-pristine ng-untouched ng-valid" ng-model="addFirm.firmData.clients" ng-options="clients.instance.id as clients.instance.fName for clients in addFirm.firmData.clients" multiple="" aria-invalid="false">
<option label="Mike" value="string:567f82a9b6daa74f16547564">Mike</option>
<option label="brian" value="string:567f83ac61b2fe4160fb4d4a">brian</option>
<option label="Bill" value="string:567f8df461b2fe4160fb4d4b">Bill</option>
</select>
</div>
Everything looks good but the moment I click on the select menu to pick one, let alone a few, the model is cleared which results in the options being completely wiped out. Any idea what might be happening? I have no rouge click events lying about and the rest of the form, which includes about 15 other standard text fields, functions fine.
The really odd thing is if I do a standard select tag with an ng-repeat, I get none of that hogwash. This works fine:
<select name="clients" id="clients" multiple>
<option ng-repeat="clients in addFirm.firmData.clients" value="{{clients.instance.id}}">{{clients.instance.fName}}</option>
</select>
Any ideas? Thanks in advance!!!
You are binding select to the same model you use to store array items:
<select class="form-control"
ng-model="addFirm.firmData.clients" <!-- <-- addFirm.firmData.clients -->
ng-options="clients.instance.id as clients.instance.fName for clients in addFirm.firmData.clients" multiple>
<!-- and here again --^ -->
</select>
See, addFirm.firmData.clients is both in ngModel and ngOptions? Bind ngModel to something else, for example:
ng-model="addFirm.firmData.clientSelected"

Categories