add new select element whenever previous one is clicked in angularjs - angularjs

I want to add new select list whenever the exisisting and which is last one is clicked.
I want to have a select list, a text box infront of it and remove option to remove the row.
So far I have added a view for the default select list which will be there when form opens i.e.
<div id="inputMaterialContainer">
<md-select aria-label="selectMaterial" ng-model="inputMaterial" ng-change="appendSelectOption()" md-on-open="loadMaterials()">
<md-option><em>None</em></md-option>
<md-option ng-repeat="material in inputMaterialArray" ng-value="material">{{material}}</md-option>
</md-select>
</div>
I have a controller for the form which is as follows
app.controller('AddPeopleDialogCtrl', AddPeopleDialogCtrl);
function AddPeopleDialogCtrl($scope, $timeout)
{
var $materialSelectHTML = "<md-select ng-change='appendSelectOption' ng-model='inputMaterialArray'><md-option><em>None</em></md-option><md-option ng-repeat='material in inputMaterial' ng-value='material'>{{material}}</md-option></md-select>";
$scope.materialArray.push($materialSelectHTML);
$scope.appendSelectOption = function(){
var materialContainer = angular.element(document.querySelector('#inputMaterialContainer'));
materialContainer.append($materialSelectHTML);
$compile($materialSelectHTML)($scope);
};
$scope.loadMaterials = function(){
return $timeout(function(){
$scope.inputMaterialArray = $scope.inputMaterialArray || ['sensor1','sensor2','sensor3','sensor4','plate1','plate2','material1','material2'];
}, 650);
};
}
But it fails to get the output as I need.

you should not use jquery in your angular application, you can do something like this when you are appending the md select.
Maintain an array of the select elements in your controller(just objects, not actual html elements) and render them using ng-repeat.
Whenever you want to add or delete just add or delete from the array in the controller and angular will do the rest.
In the html change to this
<div id="inputMaterialContainer">
<md-select aria-label="selectMaterial"
ng-model="inputMaterial"
ng-repeat="selectOption in materialSelectArray"
ng-change="appendSelectOption()"
md-on-open="loadMaterials()">
<md-option><em>None</em></md-option>
<md-option ng-repeat="material in inputMaterialArray"
ng-value="material">{{material}}</md-option>
</md-select>
</div>
And in the controller just initialize the array and add new object to it every time you want to append a new select
something like this
app.controller('AddPeopleDialogCtrl', AddPeopleDialogCtrl);
function AddPeopleDialogCtrl($scope, $timeout){
$scope.materialSelectArray = [
{
name:'select0'
}
]
$scope.appendSelectOption = function(){
$scope.materialSelectArray.push({
name:'select'+ $scope.materialSelectArray.length
})
};
$scope.loadMaterials = function(){
return $timeout(function(){
$scope.inputMaterialArray = $scope.inputMaterialArray || ['sensor1','sensor2','sensor3','sensor4','plate1','plate2','material1','material2'];
}, 650);
};
}

Related

AngularJs Auto Complete Search

So this works with static data, but when I push data with a $http this autocomplete does not work. The data pushes to the empty array of airport_list but something is happening when I try to use airport_list in for the autocomplete. Not sure what is is. I can only find answers which pertain to static data.
This is updated per everyones help.
Here is the controller
app.controller('selectCtrl', function($scope, $http) {
$scope.airport_list = null;
$http({
url: 'someUrl.com',
method: 'GET'
})
.then((response) => {
angular.forEach(response.data.airports, function(value, key) {
$scope.airport_list = response.data.airports;
})
$scope.airports = $scope.airport_list;
});
$scope.selectAirport = function(string) {
$scope.airport = string;
$scope.hidelist = true;
};
})
Here is the template
<div class="control">
<div>
<input
type="text"
name="airport"
id="airport"
ng-model="airport"
ng-change="searchFor(airport)"
placeholder="From..."
/>
<div class="airport-container-dropdown" ng-hide="hidelist">
<div
class="airport-list"
ng-repeat="airport in airports"
ng-click="selectAirport(airport)"
>
{{ airport.name }}
</div>
</div>
</div>
</div>
I really would like to do this without using bootstrap typeahead.
Thank you for looking at this.
I have made changes as recommended by below answers and the $http request is feeding into the autocomplete as a whole list but searching by name does not work and clicking on name sets [object, object]
this would be the code which is specific to that functionality.
$scope.searchFor = function(string) {
$scope.hidelist = false;
const output = [];
angular.forEach($scope.airport_list, function(airport) {
if (airport[0].toLowerCase().indexOf(string.toLowerCase(airport)) >=
0) {
output.push(airport);
}
});
$scope.airports = output;
};
$scope.selectAirport = function(string) {
$scope.airport = string;
$scope.hidelist = true;
};
Try this:
$scope.airport_list = response.data.airports;
What I am seeing is that you have an array: $scope.airport_list = [];
When you make your http request, you push what I would understand to be an array of airports into that array. So you end up with your airport array from the backend at the first position of $scope.airport_list, vs. $scope.airport_list being the actual list.
For your search method, you should change the following:
In your HTML:
ng-change="searchFor(airport.name)"
In your JS:
I've renamed your function and changed the input variable to be more clear. You were passing in a full airport, but treating it as a string. You need to compare your provided airport name to that of the airports in the array. So you iterate over the array, and compare each element's name property to what you pass in.
$scope.searchFor = function(airportName) {
$scope.hidelist = false;
const output = [];
angular.forEach($scope.airport_list, function(airport) {
if (airport.name.toLowerCase() === airportName) {
output.push(airport);
}
});
$scope.airports = output;
console.log($scope.airports);
};
I have provided minimal changes to your code to implement this, however I suggest you look at this SO post to filter drop down data more appropriately.
Angularjs Filter data with dropdown
If you want to simply filter out what is displayed in the UI, you can try this in your HTML template. It will provide a text field where you supply a partial of the airport name. If at least one character is entered in that box, the list will display on the page, with the appropriate filtering applied. This will avoid having to call functions on change, having a separate array, etc.
<input type="text" name="airport" id="airport" ng-model="airportSearch.name" placeholder="From..." />
<div class="airport-container-dropdown" ng-hide="!airportSearch.name">
<div class="airport-list"
ng-repeat="airport in airport_list | filter:airportSearch"
ng-click="selectAirport(airport)">
{{ airport.name }}
</div>
</div>

Angularjs select2 set options selected

I want to build select list (select2) options when user clicks on html button.
My HTML:
<select id="mySel2" class="form-control" multiple="multiple">
<option ng-repeat="item in items" ng-selected="item.selected"
ng-model="item.tag">
{{item.tag}}
</option>
</select>
Angular js function code on button click:
var fruits=angular.module("myApp",[]);
fruits.controller('ctrlTags', function($scope){
/* I HAVE SET DEFAULT VALUE TO SELECT LIST*/
/* IT WORKING PERFECT WITH SHOWING SELECTED VALUES*/
var tagsData = [
{id:1,tag:'Apple'},
{id:2,tag:'Banana'},
{id:3,tag:'Cherry'},
{id:4,tag:'Cantelope'},
{id:5,tag:'Grapefruit'},
{id:6,tag:'Grapes',selected:true},
{id:7,tag:'Lemon'},
{id:8,tag:'Lime'},
{id:9,tag:'Melon',selected:true},
{id:10,tag:'Orange'},
{id:11,tag:'Strawberry'},
{id:11,tag:'Watermelon'}
];
$scope.items = tagsData;
/*NOW ON BUTTON CLICK GETKEY() FUNCTION WILL BE CALLED*/
/* AND I WANT TO RENDER/REFRESH SELECT LIST WITH NEW DATA */
$scope.getKey=function(data){
var newData = [
{id:4,tag:'car'},
{id:5,tag:'bat',selected:true},
{id:6,tag:'cat',selected:true},
{id:7,tag:'Lemon'},
{id:8,tag:'Lime'},
];
$scope.items=newData;
};
});
ISSUE:ON BUTTON CLICK IT IS UPDATING SELECT LIST VALUES BUT NOT SHOWING DEFAULT SELECTED VALUES
PLEASE TELL ME HOW TO REFRESH SELECTED VALUE AS WELL.
Use select2 (form-widgets.js)
$('[name="NAME"]').select2({placeholder: ''}).val(VAL).change();
You need to add model into select section ng-model="selected".
You can add for example first index
in controller $scope.selected = tagsData[0]

UI AngularJS Sortable - Getting an undefined error when attaching to scope

I am using the AngularJS UI Sortable directive and I am trying to pull the data from my view into my controller and update/stop the sorting on every click. I am creating a blank array and then attaching the $scope.areas to the blank array. I am able to display the content through the ng-repeat. However, when I console.log(areas), I am getting an undefined.
VIEW
<div class="panel-body">
<ul ui-sortable="sortableOptions" ng-model="areas" class="uk-nestable">
<li data-item="{{area.label}}" data-item-id="{{area.order}}" ng-repeat="area in areas">
<div class="uk-nestable-item mainarea-blue">
<div class="uk-nestable-handle mainarea-text-white"></div>
<div data-nestable-action="toggle"></div>
<div class="list-white">{{area.label}}</div>
</div>
</li>
</ul>
</div>
CONTROLLER
//create a blank array
var tmpList = [];
//attaches ng-model scope to tmpList
$scope.areas = tmpList;
console.log(areas);
//changed old sort to new sort
$scope.sortingLog = [];
$scope.sortableOptions = {
//creates a log entry of the new update view
update: function(e, ui) {
var logEntry = tmpList.map(function(i){
return i.value;
}).join(', ');
//displays the update text and array
$scope.sortingLog.push('Update: ' + logEntry);
},
stop: function(e, ui) {
// this callback has the changed model
var logEntry = tmpList.map(function(i){
return i.value;
}).join(', ');
$scope.sortingLog.push('Stop: ' + logEntry);
}
};
My goal is to display the area.label in the correct sort order. For example; I have 3 unordered lists - floor, basement, kitchen and I want to change the order to basement, floor, kitchen. As I am changing the sort order it is updating and stop the sorts.
I am probably not doing the best job explaining myself so here is a similar codepen...http://codepen.io/thgreasi/pen/jlkhr.

dynamically change options in dropdown list in angular js

i tried to create dynamically changing dropdown list in angularJS
angulars.js
var option1Options = ["Class","Category","Option","Question","Group"];
var option2Options = [["Group","ProductModel"],
["Class","ProductModel"],
["Class","Group","ProductModel"],
["Group","ProductModel"],
["ProductModel"]];
$scope.myCtrl= function()
{
$scope.options1 = option1Options;
$scope.options2 = [];
$scope.getOptions2 = function(){
var key = $scope.options1.indexOf($scope.child);
$scope.options2 = option2Options[2];
};
}
page.html
<div id="CreateChild" ng-controller="myCtrl">
<select ng-model="child" ng-options="option for option in options1" ng-change="getOptions2()">
</select>
<select ng-model="parent" ng-options="option for option in options2">
</select>
</div>
in angulars.js i was unable to get the index of first dropdown list array. the value of key is assigned as -1 and the option2 is assigned as undefined.
can any one help me with this
I did a small workaround for this requirement, though it is not a straight answer, I believe this would help you...
Add this to your controller...
$scope.getOptions1Idx = function(){
var mySelectedOption = $scope.child;
var i = 0;
for(i=0;i< option1Options.length;i++){
if(option1Options[i]==mySelectedOption){
break;
}
}
return i;
}
and change your getOptions2 function as follows
$scope.getOptions2 = function(){
$scope.options2 = option2Options[getOptions1Idx()];
};
This can be done in much better fashion by avoiding for loop provided if you choose to change your array structure with predefined index some thing like var option1Options = [{id:0,option:"Class"},{id:1,option:"Category"},{id:2,option:"Option"},{id:3,option:"Question","Group"}];
Had a very similar problem with this. In terms of styling I found my way around it by creating a list instead of a select option
<div class='btn-group'>
<button class='form-control col-md-3' data-toggle='dropdown'>
{{value}} <span class='caret'></span>
</button>
<ul class='dropdown-menu'>
<li ng-repeat='type in callType' class='col-md-3'>
<a href='#' ng-click='select(type)'>{{type.name}}</a>
</li>
</ul>
</div>
Then the controller is used to take in the objects, call a method to change each object and then set a default for the drop down list. You can see it at the link below.
http://plnkr.co/edit/nwXmMif8vjj92pQmalb2

How make related selects in Angular?

I have two select list HTML.
How I can make easy them related? I mean when I select option from first select, some options from second select are shown to hidden?
Selects lists HTML created by PHP.
There are a few ways using angular. One way is to use the ng-change:
<select ng-model="selectedItem1" ng-options="item in items1" ng-change="update(selectedItem1)"></select>
and then have the update(selectedItem1) function update your items2 list. And vice versa for your items2 drop down.
$scope.update = function(selectedItem1) {
$scope.items2 = // logic to filter items 2 based on selectedItem1
}
<select ng-model="selectedItem2" ng-options="item in items2" ng-change="updateSet1(selectedItem2)"></select>
Alternatively, you could use a $watch function, to watch selectedItem1 and update items2 list in this function.
If you need to use a custom filter, see here:
https://docs.angularjs.org/tutorial/step_09
angular.module('myModule', []).filter('items2', function() {
return function(selectedItem1, items2) {
for (var i = 0; i < items2.length; i++) {
// return items you want
}
};
});
Then in your controller, include this filter as dependency items2Filter by appending Filter and you can update $scope.items2 like so:
$scope.items2 = items2Filter($scope.selectedItem1, $scope.items2);

Resources