Angular Populate dropdown options dynamically while selecting dropdown in runtime - javascript

I have a JSON object containing names of dropdown and looks something like this -
$scope.obj = {
"dp1" :{},
"dp2" :{}
}
Objects dp1 and dp2 correspond to respective dropdowns. These objects will be referred by dropdown to populate their options tag.
Next I have a REST call function like this -
$scope.getData = function(category, type) {
var params = { "dp1" : category, "dp1__type": type};
PromiseService.getPromiseData("GET", "/api/get_data/?" + $httpParamSerializer(params)).then(function(response) {
$scope.obj.dp1= response;
});
}
I am able to assign the response to $scope.obj.dp1 The reponse object looks like this-
{ "id" : 1, "name" : "john" }
Finally, my dropdown looks like this -
<select id="d1" ng-model="d1">
    <option ng-repeat="opt in obj.dp1" t>{{opt.id}}_{{opt.name}}</option>
</select>
I want to populate the obj JSON object based on response, which I able to. Then I want to go to sub object in obj and apply ng-repeat on that to populate the options tag.
Current implementation of ng-repeat gives me undefined undefined .

try this-
$scope.obj = {
"dropdown1" :{id:"dp2", data:"", options:[]},
"dropdown2":{id:"dp1", data:"", options:[]}
}
$scope.getData = function(category, type){
var params = { "dp1" : category, "dp1__type": type};
PromiseService.getPromiseData("GET", "/api/get_data/?" + $httpParamSerializer(params)).then(function(response){
$scope.obj.dropdown1.options = response;
});
}
html page -
<div ng-repeat="dropdown in obj">
<select id="{{dropdown.id}}" ng-model="dropdown.data" ng-options="option.name for option in dropdown.options">
</div>

Related

AngularJS - Get printed value from scope inside an attribute?

I'm currently working on an AngularJS project and I got stuck in this specific requirement.
We have a service that has all the data, DataFactoryService. Then, I have a controller called DataFactoryController that is making the magic and then plot it in the view.
<div ng-repeat = "list in collection">
{{list.name}}
...
</div>
Now, we have a requirement that pass multiple data into one element. I thought an "ng-repeat" would do, but we need to have it inside an element attribute.
The scenarios are:
At one of the pages, we have multiple lists with multiple data.
Each data has a unique code or ID that should be passed when we do an execution or button click.
There are instances that we're passing multiple data.
Something like this (if we have 3 items in a list or lists, so we're passing the 3 item codes of the list):
<a href = "#" class = "btn btn-primary" data-factory = "code1;code2;code3;">
Submit
</a>
<a href = "#" class = "btn btn-default" data-factory = "code1;code2;code3;">
Cancel
</a>
In the example above, code1,code2,code3 came from the list data. I tried several approach like "ng-repeat", "angular.each", array, "ng-model" but I got no success.
From all I've tried, I knew that "ng-model" is the most possible way to resolve my problem but I didn't know where to start. the code below didn't work though.
<span ng-model = "dataFactorySet.code">{{list.code}}</span>
{{dataFactorySet.code}}
The data is coming from the service, then being called in the controller, and being plot on the HTML page.
// Controller
$scope.list = dataFactoryService.getAllServices();
The data on the list are being loaded upon initialization and hoping to have the data tags initialized as well together with the list data.
The unique code(s) is/are part of the $scope.list.
// Sample JSON structure
[
{ // list level
name: 'My Docs',
debug: false,
contents: [ // list contents level
{
code: 'AHDV3128',
text: 'Directory of documents',
...
},
{
code: 'AHDV3155',
text: 'Directory of pictures',
...
},
],
....
},
{ // list level
name: 'My Features',
debug: false,
contents: [ // list contents level
{
code: 'AHGE5161',
text: 'Directory of documents',
...
},
{
code: 'AHGE1727',
text: 'Directory of pictures',
...
},
],
....
}
]
How can I do this?
PLUNKER -> http://plnkr.co/edit/Hb6bNi7hHbcFa9RtoaMU?p=preview
The solution for this particular problem could be writing 2 functions which will return the baseId and code with respect to the list in loop.
I would suggest to do it like below
Submit
Cancel
//inside your controller write the methods -
$scope.getDataFactory = function(list){
var factory = list.map( (a) => a.code );
factory = factory.join(";");
return factory;
}
$scope.getDataBase= function(list){
var base= list.map( (a) => a.baseId);
base= base.join(";");
return base;
}
Let me know if you see any issue in doing this. This will definitely solve your problem.
You don't really have to pass multiple data from UI if you are using Angular.
Two-way data binding is like blessing which is provided by Angular.
check your updated plunker here [http://plnkr.co/edit/mTzAIiMmiVzQfSkHGgoU?p=preview]1
What I have done here :
I assumed that there must be some unique id (I added Id in the list) in the list.
Pass that Id on click (ng-click) of Submit button.
You already have list in your controller and got the Id which item has been clicked, so you can easily fetch all the data of that Id from the list.
Hope this will help you... cheers.
So basing from Ashvin777's post. I came up with this solution in the Controller.
$scope.getFactoryData = function(list) {
var listData = list.contents;
listData = listData.map(function(i,j) {
return i.code;
});
return listData.join(';');
}

how to display name of a particular code from a javascript object in angular js and html5

I have a angular controller that has the following array which has 3 values.
controller.medicalInstitues;
I want to take the 4th object in the array with code "AUS". Then further, I want to display the name of only 2 medical institutes with the code as "SYD" and "MEL" within that choosen bject from the parent array.
something like below:
var country = select controller.medicalInstitues.countryCode = "AUS"
var institues = select controller.medicalInstitues.name from country.code="SYD" and "MEL";
now I need to bind these in the UI (Angular).
<span class="code"> {{ controller.institutes.name }}</span>
Suppose you have got your list of values in medicalInstitues, then in the angularjs controller you can do
$scope.institues = medicalInstitues.filter(function(value){
return value.countryCode == "AUS" && (value.code == "SYD" || value.code == "MEL");
});
In HTML you can use ng-repeat:
<div controller="controller">
....
<span ng-repeat="institue in institues">{{institue.name}}</span>
....
</div>
In your controller, to bind the 4th object in your array you can set:
$scope.AUS = yourArray[3]
Then in the html you can show the object properties:
{{ AUS."object path to name" }}
Well, if I understood your question well, you can do the following:
// If you have an array that you already know that will come 4 items with the same country code, you can simply do:
$scope.medicalInstitues = array[3];
// Otherwise:
$scope.medicalInstitues = array.filter(function (value) {
return value.countryCode == "AUS";
})[3];
// To get all 'institues' with the countryCode equals to 'SYD' or 'MEL':
$scope.institues = array.filter(function (value) {
return value.countryCode == "SYD" || value.countryCode == "MEL";
});

Create a dynamic multiple dropdown select

I'm fetching a list of objects from a database, say articles, that have a category attribute, and I'll be adding a filtering capability to my angularjs app where I can select multiple articles based on the subcategories, grouped by category
I'm trying to do as follows in my html:
<select multiple >
<option value="" disabled selected>Choose your option</option>
<optgroup ng-repeat="category in categories" label="{{category.category}}">
<option ng-repeat="subcategory in category.subcategories" value="{{subcategory}}">{{subcategory}}</option>
</optgroup>
</select>
but the categories and subcategories can be diverse and I don't want to hardcode it on my app, rather, grouping that information from all the articles I retrieve from the database, so in my Controller, in the function I use to fetch all the articles I have the following
function getAllArticles(){
var promise = article.getAll();
promise.then(function( articles ){
$scope.articles = articles.data
var result = $scope.articles.map(function(a) {return a.category.category;});
var res = arrayUnique(result);
for(var i = 0; i < res.length; i++){
$scope.categories[i] = {'category': res[i] }
var result2 = $scope.articles.map(function(a) {
if (a.category.category === res[i]) {
return a.category.subcategory;
}
});
$scope.categories[i]['subcategories']
$scope.categories[i]['subcategories'] = arrayUnique(result2);
}
});
}
var arrayUnique = function(a) {
return a.reduce(function(p, c) {
if (p.indexOf(c) < 0 && c != undefined) p.push(c);
return p;
}, []);
};
In a way I'm using map/reduce to get the categories and subcategories, but my problem is that with all of these, in my html, the ng-repeat doesn't show anything, as if the $scope.categories is still empty, even we I console.log it I get the following result:
{ 0: {category: "category1",
subcategories: [{subcategory: "sub1"},{subcategory: "sub2"}]
},
1: {category: "category2",
subcategories: [{subcategory: "sub1"},{subcategory: "sub2"}]
}, ...
}
EDIT:
when I do the following:
<div ng-repeat="category in categories">
{{category.category}}
<div ng-repeat="subcategory in category.subcategories">{{subcategory}}</div>
</div>
It prints as it should the list of categories and subcategories, the main difference is that I'm using <div> instead of <optgroup> <option>
If your console.log is accurate then you are using ng-repeat over an object not an array. This is doable but requires special syntax such as:
<div ng-repeat="(key, value) in myObj"> ... </div>
you can find the documentation here.
Otherwise, try translating the results into an array before using them in ng-repeat.
As a side note, angular offers the ng-options directive for ng-select. That way you can assign a data model to it instead of hard coding a template.
The problem was with materializecss select. It was instantiating before updating $scope.categories, which was empty
The solution can be
$(document).ready(function() {
$('select').material_select();
$('input.select-dropdown').click(function(e){
$('select').material_select();
});
});
solves the problem but it's a horrible hack, but I'll be moving to a timeout solution or instantiating after updating $scope.categories

Angular filtering doesn't work

In my template I have this code:
<li class="row timeline-item" data-ng-repeat="item in data | filter:workoutFilter" data-ng-include="getTemplateUrl(item)"></li>
And in my controller I have:
$scope.workoutFilter = null;
$rootScope.$on('workout', function(e, data) {
$scope.workoutFilter = "{Type: 'workout'}";
});
When I click button workouts, everything just disappears as if there are no items that match this filter, but that isn't the case (and I know this for a fact because getTemplateUrl detects type workout and returns right template)
Why is this happening ? Is there any other way I can filter items which have property Type "workout" ?
EDIT
Here is what happens when I click button:
In my other controller :
$scope.onWorkoutsClick = function () {
feedService.setWorkoutFilter();
};
In service:
setWorkoutFilter : function() {
$rootScope.$broadcast('workout');
}
And in my main controller:
$rootScope.$on('workout', function(e, data) {
$scope.workoutFilter = "{Type: 'workout'}";
});
I assume you're trying to filter based on item.Type == 'workout'?
You need to set your filter to an object rather than a string:
$scope.workoutFilter = {Type: 'workout'};

Trying to get Jquery working with dynamic select forms in Rails and Active Admin

I'm trying to update a select box based on another..
In my active admin resource, I did the following just for some test data:
controller do
def getcols
list = new Hash
list = {"OPTION1" => "OPTION1", "OPTION2" => "OPTION2"}
list.to_json
end
end
In active_admin.js I have the following
$('#worksheet_type').change(function() {
$.post("/admin/getmanifestcols/", { ws_type: $(this).val() }, function(data) {
populateDropdown($("#column_0"), data);
});
});
function populateDropdown(select, data) {
 select.html('');
alert('hi');
$.each(data, function(id, option) {
select.append($('<option></option>').val(option.value).html(option.name));
});      
}
The above is working in the sense that when my primary select box is changed, the jquery is called and I even get the alert box of 'hi' to be called. However, it's not replacing the contents of the select box with my test OPTION1 and OPTION2 data.
I think I'm passing in the JSON wrong or something, or it's not being read.
What am i missing?
It looks to me as if you're not properly iterating over the map.
What about:
$.each(data, function(value, name) {
select.append($('<option></option>').val(value).html(name));
});
?

Categories