How do I get ng-select to update when scope is changed? - javascript

I have a table above a form, that when a row is selected it populates a form with data. That form has a select element. Upon the first row in the table being selected, the data populates correctly and the correct selected option is shown. On the second and subsequent selection the correct selected option is not shown. In chrome dev tools I can see the values update properly, but it is not visually shown.
What am I missing? How do I get that correct option to be visually shown?
<select name="updateCategory" ng-model="selectedPermission.permission.category_id">
<option value="{{cat.id}}" ng-selected="cat.selected" ng-repeat="cat in selectedPermission.permission_categories">
{{cat.name}}
</option>
</select>
Here is function in controller that is updating the scope.
$rootScope.$watch('toolBarSelectedValue',function(){
if($rootScope.toolBarSelectedValue >0){
Permissions.getItem($rootScope.toolBarSelectedValue).then(function(res){
var pc = res.data.permission_categories;
var p = res.data.permission;
angular.forEach(pc,function(v,k){
if(v.id == p.category_id){
pc[k].selected = true;
}else{
pc[k].selected = false;
}
});
$scope.selectedPermission = {"permission":p,"permission_categories":pc};
$scope.$apply();
});
}else if($rootScope.toolBarSelectedValue == 0 || $rootScope.toolBarSelectedValue == null){
$scope.selectedPermission = {};
}
});

I would use ng-options as opposed to <option...></option> you can then relate your selection to your ng-model easily. See docs for more info.
Something like:
<select name="updateCategory" ng-model="cat" ng-options="cat.id as cat.name for cat in selectedPermission.permission_categories">
</select>
bear in mind I am not sure of you data structure, but this should get you on your way.

Related

select drop down option based on associated text

I have a drop down with a value and associated text as such:
echo '<option value="'.$row['company_id'].'">'.$row['company_name'].'</option>';
Eventually, the output of the selected option is put into a table, row by row. By each row, there is an edit button to edit that particular row and select a new drop down option. I'm trying to use JavaScript to select the text and when they hit the edit button, the option that is currently set will be the default choice.
So for instance, if the row says the company_name is: ABC Company, when they hit the edit button, the drop down will populate with that option. Since the value and text are different, I need to choose the drop down option based on text. I have tried these 2 options so far with no luck.
To get the row text:
var d = document.getElementById("itable").rows[id].cells[3].innerText;
I have tried the following to pass back the text of the row, and to select the drop down by text.
document.querySelector('#editinsurancepolicymodal select[name=editicompanydropdown]').value = d;
This option just populates the drop down, but no choice is selected.
document.querySelector('#editinsurancepolicymodal').find('option[text="InsuranceB"]').val;
This option selects the first option in the drop down, but doesn't change based on what the 'text' is.
Thank you for your help in advance.
One way will be to iterate over the option elements, selecting the one that has the same text as the text from the row, and un-selecting all the others. This is illustrated in the snippet below (I have inserted a 3 second timeout, so that you can see that the initially selected option (Two) is changed to the option with the text "Three" from the JavaScript code.
window.setTimeout(function () {
var sampleWord = "Three";
var options = document.querySelectorAll("option");
for (var i = 0; i < options.length; i++) {
var option = options[i];
if (option.innerText === sampleWord) {
option.selected = true;
} else {
option.selected = false;
}
}
}, 3000);
<select id="selector">
<option id="option-1" value="1">One</option>
<option id="option-2" value="2" selected>Two</option>
<option id="option-3" value="3">Three</option>
<option id="option-4" value="4">Four</option>
</select>
Alternately, you could store the id for the company as a data-attr attribute on the row. For example (in PHP):
echo "<td data-attr-company-id=".$row['company_id'].">".$row['company_name']."</td>"
Then, you can read the attribute from the table row, and query for the option that has the same value as your attribute value.
var options = document.querySelectorAll("option");
This will select all options from the page. If you want to get the options for a specific drop down, use the following:
var options = document.querySelector('#specificform select[name=specific_drop_down_in_the_specific_form]');
To select the option based on the text and not the value, use this loop:
for (var i=0; i<options.length; i++){
var option = options[i];
if (option.innerText === d){
option.selected = true;
}
}

How to return the length and value of a selection in a datalist?

I would like to fabricate some code, that tracks the amount of unfiltered options in a datalist. So how could I keep track of this?
Secondly when there is only one option left in the list I want to access the value of this option.
Here is a link to the w3c spec: https://www.w3.org/TR/html5/forms.html#the-datalist-element
Note: I want to use the datalist, so I don't want to create my own filter on the datalist and get the values from there.
I came up with this code so far:
Fiddle: https://jsfiddle.net/6usf7j9g/
html
<h3>Anything you'd like?</h3>
<input id="your-favourite" list="choices"/>
<datalist id="choices">
<option value="Laphroaig"></option>
<option value="Jameson"></option>
<option value="Talisker"></option>
<option value="Oban"></option>
<option value="Dalwhinnie"></option>
<option value="Glennfidich"></option>
<option value="Glenlivet"></option>
</datalist>
jQuery/js
var selectedChoices = null; //in this variable I need to know how many items are left in the list after filtering. If you type "Glen" it should be two, if you type "Glenn", "J", etc. it should give a value of 1. It only needs to work on google chrome.
$("#your-favourite").on("keyup", function(){
selectedChoices = null; //PART OF THE ISSUE: Should change the value of the variable here, depending on the options that are showing.
if(selectedChoices === 1){
let finalOption = "unknown"; //PART OF THE ISSUE: Should load the value of the remaining option
// validate success
alert("There is only one value left in the list! It is called: " + finalOption);
selectedChoices = null; // reset value to 0.
}
// log the datalist and input elements, it might have some info that helps finding a solution.
console.log($("#your-favourite"));
console.log($("#choices"));
}); // end on keyup

ng-model select dropdown update - angular

Basically i have a select dropdown
<select class="form-control" id="ursel"
ng-change="changeVal()"
ng-options="a for a in RatedVoltage" data-ng-model="TechCharacters.selectedUr">
<option value="" selected="selected">{{globalLangResource.SelectAny}}</option>
</select>
So on change of this select, have results reflecting to another select
viewModel.changeVal = function(){
var val = viewModel.TechCharacters.selectedUr;
if (val != undefined && val === "7.2kV") {
$rootScope.ud = viewModel.InsulationVoltage["7.2kV"]; // 20,30,40
}
}
The 2nd dropdown looks like this
<select class="form-control" id="udsel"
ng-change="setUd();"
ng-options="a for a in ud" data-ng-model="TechCharacters.InsulVolt">
<option value="" ng-if="false"></option>
</select>
Now i have a submit button, on submit,i am getting the main object.
console.log(TechCharacters);
Here i am not getting TechCharacters.InsulVolt value. it is showing empty.
If i have made change is the 2nd dropdown, the model is updated. until then i am not getting the changed model from 1st dropdown
Basically i want all the ng-model values inside form even it is changed or not.
if you want the first object of second dropdown on change of first one. change code to .
viewModel.changeVal = function(){
var val = viewModel.TechCharacters.selectedUr;
if (val != undefined && val === "7.2kV") {
$rootScope.ud = viewModel.InsulationVoltage["7.2kV"]; // 20,30,40
viewModel.TechCharacters.InsulVolt=$rootScope.ud[0]
}
}
hope it will help you
You can actually do this. This will work.
<select data-ng-model="TechCharacters.selectedUr"
<option ng-selected="{{obj == TechCharacters.selectedUr}}" value="{{obj}}" ng-repeat="(key,value) in RatedVoltage">
</select>
Basically you are doing ng-selected and comparing the ng-model value with that of the ng repeat value, and the selected value will be shown.

Ng-repeat and auto complete selection with modal window in Angular

I'm doing an application in Angular. It is a Table one row that contain 2 column. Each column contain one select. They are empty. When the user press a button, a modal window shows up and display a grid with all the items (from json) of the first select. When the user click on one rows and press "Confirm", modal window closes filling the first select. In the meanwhile, the second select fill with the subarray of selected item.
In a few words, there are 2 select: you choose the option on the first (by a modal window) and then you choose the item of its subarray in the second select.
Then, the user can add new rows, repeating the select.
I've tried two ways to do this, and they half work. In the FIRST CODE
you can see that, after clicked on modal window, the first select fill it self (even if it is not the first , I don't know why..). And it doesn't not iterate well, because when you choose a item in new line, it modify all the other choises, and I want to prevent this.
<select ng-model="selectedProduct" ng-options="a as a.nome for a in items" ng-change="selectLot(select1)">
<option value="">-- Select Product --</option>
</select>
<select ng-model="selectedLot" ng-options="a as a.value for a in selectedProduct.lots" ng-change="lotSelect(select2)">
<option value="">-- Select Lot --</option>
</select>
The SECOND CODE works better. It iterate well. It change automatically the second item's selection well. But when I press on the modal window, the first selection doesn't automatically fill with the choosen item.
Can you help me? I can't find a solution..... Thank you so much in advice!
The core of the issue is that if you want to have a form that edits elements in an array, you need to have separate models for each of the rows in the array. You can do this by making "selectedProduct" and "selectedLot" into objects that map the array index to the selected value for that row.
I made an updated plunker with a working example, but without looking at it here is a rundown of the changes you would need to make. You need to change your models so they reference something using the array index of the row, and also pass that index into functions that modify the row:
<button class="btn btn-default" ng-click="open($index)">OPEN!!</button>
<select ng-model="selectedProducts[$index]" ng-options="a as a.nome for a in items" ng-change="selectLot(select1, $index)">
<option value="">-- Select Product --</option>
</select>
<select ng-model="selectedLots[$index]" ng-options="a as a.value for a in selectedProducts[$index].lots" ng-change="lotSelect(select2, $index)">
<option value="">-- Select Lot --</option>
</select>
You also want to update the functions in your controller to work with the array indexes:
$scope.selectLot = function(data, index){
$scope.Subarray = [];
for(i=0; i<$scope.items.length; i++){
if(data == $scope.items[i].id){
$scope.Subarray[$index] = $scope.items[i].lots;
$scope.selectedProducts[$index] = $scope.items[i];
break;
}
}
console.log($scope.Subarray);
}
$scope.lotSelect = function(id, $index) {
for(i=0; i<$scope.Subarray[$index].length; i++){
if(id == $scope.Subarray[$index][i].id){
$scope.selectedLots[$index] = $scope.Subarray[$index][i];
break;
}
}
}
And the modal:
$scope.open = function ($index) {
// ...
modalInstance.result.then(function (selectedItem) {
$scope.selectedProducts[$index] = selectedItem;
}, function () {
$log.info('Finestra selezione prodotto chiusa alle ore: ' + new Date());
});
You probably shouldn't be using a SELECT if you are allowing the choice to happen in a modal popup. All you want to do is show the selected item which you can easily do in a number of different ways. Additionally in the first example prodIsChanged(), which is what sets the subarray, is never called. An easier solution may be something like this:
<div>{{mainProduct}}</div>
<select ng-options="a as a.value for a in selectedProduct"></select>
var myApp = myApp.controller('Cntrl', function ($scope,$watch) {
$scope.mainProduct = '';
$scope.selecedProduct = '';
$watch('mainProduct',function(old,new) {
$scope.selectedProduct = ??? // The mainProduct has changed so set the list of sub products as necessary
};
}

Search a dropdown

I have this HTML dropdown:
<form>
<input type="text" id="realtxt" onkeyup="searchSel()">
<select id="select" name="basic-combo" size="1">
<option value="2821">Something </option>
<option value="2825"> Something </option>
<option value="2842"> Something </option>
<option value="2843"> _Something </option>
<option value="15999"> _Something </option>
</select>
</form>
I need to search trough it using javascript.
This is what I have now:
function searchSel() {
var input=document.getElementById('realtxt').value.toLowerCase();
var output=document.getElementById('basic-combo').options;
for(var i=0;i<output.length;i++) {
var outputvalue = output[i].value;
var output = outputvalue.replace(/^(\s| )+|(\s| )+$/g,"");
if(output.indexOf(input)==0){
output[i].selected=true;
}
if(document.forms[0].realtxt.value==''){
output[0].selected=true;
}
}
}
The code doesn't work, and it's probably not the best.
Can anyone show me how I can search trough the dropdown items and when i hit enter find the one i want, and if i hit enter again give me the next result, using plain javascript?
Here's the fixed code. It searches for the first occurrence only:
function searchSel() {
var input = document.getElementById('realtxt').value;
var list = document.getElementById('select');
var listItems = list.options;
if(input === '')
{
listItems[0].selected = true;
return;
}
for(var i=0;i<list.length;i++) {
var val = list[i].value.toLowerCase();
if(val.indexOf(input) == 0) {
list.selectedIndex = i;
return;
}
}
}
You should not check for empty text outside the for loop.
Also, this code will do partial match i.e. if you type 'A', it will select the option 'Artikkelarkiv' option.
Right of the bat, your code won't work as you're selecting the dropdown wrong:
document.getElementById("basic-combo")
is wrong, as the id is select, while "basic-combo" is the name attribute.
And another thing to note, is that you have two variable named output. Even though they're in different scopes, it might become confusing.
For stuff like this, I'd suggest you use a JavaScript library like jQuery (http://jquery.com) to make DOM interaction easier and cross-browser compatible.
Then, you can select and traverse all the elements from your select like this:
$("#select").each(function() {
var $this = $(this); // Just a shortcut
var value = $this.val(); // The value of the option element
var content = $this.html(); // The text content of the option element
// Process as you wish
});

Categories