I have a nested JSON file which keeps track of stations, and has nested fields about each tank.
I am trying to allow the user to first select which gas station they want to see info from, and then load ONLY that stations information into a UI Grid table from angular.
Code examples are much appreciated if possible
Bind select with ui-grid data with $scope.selected:
$scope.tankInfo = [];
$scope.selected;
$scope.onChange = function(){
$scope.gridOptions.data = $scope.tankInfo[$scope.selected];
};
$scope.initLoad = function () {
$http.get('tankInfo.json').success(function (data) {
$scope.selected = "Gas Station 1";
$scope.tankInfo = data;
$scope.gridOptions.data = $scope.tankInfo[$scope.selected];
});
}
and your select:
<select id="station" ng-model="selected" ng-change="onChange()"
ng-options="key as key for (key, value) in tankInfo"
></select>
Demo Plunker
Related
I got stuck at a very awful point. I am developing a web application using firebase(for database) and Javascript.
Here is the structure of my firebase database.
and I want to display these categories in a dropdown input bar but in a way that every child category display within its parent category input bar in that way
This is what I want
And this is my code
var newTask = firebase.database().ref("childCategory");
newTask.on('value', function(snapshot){
snapshot.forEach(function(childSnapshot) {
var taskValue = childSnapshot.val();
document.getElementById("selectCatigory").innerHTML +=
<optgroup label="${taskValue.parentCategory}">
snapshot.forEach(function(childSnapshot){
var tasksValue = childSnapshot.val();
document.getElementById("selectCatigory").innerHTML +=
<option label="${tasksValue.childCName}"> </option> </optgroup>
});
});
});
I have a list of statuses which are returned from an ajax call to a Ref Data service
I have this defined in my js file:
self.StatusIdList = ko.observableArray();
self.StatusTextList = ko.observableArray();
This is the success handler of my ajax call:
success: function (data, textStatus, message) {
$.each(data, function (index, item) {
self.StatusTextList.push(item.statusDescription);
self.StatusIdList.push(item.statusId);
});
},
This is what I have in my HTML
<select data-bind="options: StatusIdList, value: currentFormStatus, optionsText: StatusTextList" class="span12"></select>
If I set the options to StatusTextList then the dropdown is populated with the list of statuses as expected - however with it set to ID it is populated with the list of ids which I don't want.
So I attempted to use optionsText and was hoping it would then display the Name in the dropdown but keep the unique id per status at the option value but in the dropdown with my current code as above it is displaying as below:
<option value="1">[object Window]</option>
Where actually the unique id of statusId = 1 should be displayed as 'Order Received'
You don't need 2 separate arrays for populating the dropdown. Create an observableArray called StatusList with items which have both statusId and statusDescription properties. (more on options binding from KO website)
In your HTML:
<select data-bind="options: StatusList, value: currentFormStatus, optionsText: 'statusDescription', optionsValue: 'statusId', optionsCaption: 'Select'"></select>
The optionsText should point to whatever property in array, you want displayed as text in the dropdown. In our case it is statusDescription.
The optionsValue should point to the property which is value for the option. In this case it is statusId.
var viewModel = function (data) {
var self = this;
self.currentFormStatus = ko.observable();
self.StatusList = ko.observableArray([]);
// functions, ajax etc
};
In your success callback:
// you can push to the array in your callback like this
// each item in "data" should have "statusDescription" and "statusId" properties
success: function (data, textStatus, message) {
$.each(data, function (index, item) {
self.StatusList.push(item);
});
},
I have created a fiddle
I have a select like this:
<select class="form-control" ng-hide="Catalogos.length==0" ng-change="filtro(selected)" ng-model="selected" ng-options="item.Nombre for item in Catalogos "></select>
and it Charge it with Angular Controller like this:
function cargarCatalogo() {
apiService.get("../../api/Catalogo/GetCatalogoPadre/" + $scope.Catalogo + "/",
null,
function(res) {
$scope.Catalogos = res.data;
$scope.selected = $scope.Catalogos[0];
$scope.filtro($scope.selected);
},
errorCatalogo);
}
So I have two different context with same view: Create and Edit. If $scope.catalogoid come null I present a Create View and it come with value is an Edit View.
Problem is into Edit View, I want to present a select of actual value of Id instead first value. How can I do that?
I am brand new, just experimenting, with AngularJS framework. So I am not sure the approach I have taken is the best/right way.
I'm trying to create a 3 level chained ajax filled select boxes, and it is kind of working, except for a couple of issues.
My actual code uses ajax which is in a factory, but for the sake of the fiddle I just have a controller returning results from an array.
Demo (using arrays, not ajax): http://jsfiddle.net/xxwe1zu8/1/
Issues:
2nd and 3rd level selects don't have a "selected" attribute - ie the one you select doesn't get highlighted.
Ideally I would like the top level categories to be dynamically filled on page load via ajax (or in this example by array) using the same angular function (eg: getSubcategories = function(0, 0) {) rather than hardcoded. Top level categories have a parent of 0.
Bonus: Can the 3rd select box only be shown/visible if there is a sub sub category returned after selecting the sub category? In reality, most sub categories won't have sub sub categories.
var myAppModule = angular.module('myApp',[]);
myAppModule.controller('SearchCtrl', function($scope) {
var self = this;
self.subCategories = [];
self.getSubcategories = function(parent, level) {
theCategories = [];
angular.forEach(sub_category[parent], function(idx, val) {
theCategories.push({id: val, name: idx});
});
self.subCategories[level] = theCategories;
}
});
Thanks
I would suggest to restructure data in an array of objects and get rid of indicies which are seemingly of no use here.
var transport = [
{
name: "Cars",
models: [
{
name: "Hatchback",
variations: ["4 door", "5 door"]
},
{
name: "Sedan",
variations: ["4 door", "5 door"]
},
{
name: "SUV",
variations: ["Medium", "Large"]
}
]
},
...
This allows to make clearer code in template. I am not ControllerAs syntax here since $scope is injected in any way. And it is a better approach if you just start learning AngularJS
<select
ng-model="selectedType"
ng-options="t.name for t in transport"
ng-change = "selectedModel=null;selectedVariation=null">
<option value="">Select type</option>
</select>
<select
ng-model="selectedModel"
ng-options="model.name for model in selectedType.models"
ng-change="selectedVariation=null"
ng-show="selectedType.models">
<option value="">Select model</option>
</select>
<span ng-show="loading">Loading...</span>
<select
ng-model="selectedVariation"
ng-options="variation for variation in variations"
ng-show="variations && !loading">
<option value="">Select variation</option>
</select>
selectedType, selectedModel and selectedVariation are implicitly defined in $scope by ng-model of each select. There is even no mention of them in controller currently. At the same time this properties are used in ng-show to hide select tags which are not relevant in current selection.
The last select (sub subcategory) demonstrates a way to fetch data asynchronously. Let's imagine you don't have a complete tree of data at once and fetch variations from server on model selection. You would place a watch in controller for selectedModel and if it was selected (not emptied) you would launch a request for data and update variations on response
$scope.$watch('selectedModel', function(model){
if(model){
$scope.loading = true;
//setTimeout imitates an ajax request
setTimeout(function(){
$scope.variations = model.variations;
$scope.loading = false;
$scope.$apply();
}, 1000);
}
})
Updated fiddle
There will be two drop down lists,
First have the list of mobile vendor, and the second have the list of models per vendor.
When one select a vendor from the first drop down list, the second drop down list should populate with relevant model for that vendor dynamically. This is for mobile web site, it's better to use jquery-mobile
The option values for the second will in a json map.
<select class="mobile-vendor">
<option value="motorola">Motorola</option>
<option value="nokia">Nokia</option>
<option value="android">Android</option>
</select>
selectValues = {"nokia" : {"N97":"download-link",
"N93":"download-link"},
"motorola": {"M1":"download-link",
"M2":"download-link"}}
<select class="model">
<option></option>
</select>
For example, if the user selects nokia in the first drop down list, the second drop down list should have N97, N93 as the options.
EDIT: New javascript to take into account your updated json structure:
$(function() {
var selectValues = {
"nokia": {
"N97": "http://www.google.com",
"N93": "http://www.stackoverflow.com"
},
"motorola": {
"M1": "http://www.ebay.com",
"M2": "http://www.twitter.com"
}
};
var $vendor = $('select.mobile-vendor');
var $model = $('select.model');
$vendor.change(function() {
$model.empty().append(function() {
var output = '';
$.each(selectValues[$vendor.val()], function(key, value) {
output += '<option>' + key + '</option>';
});
return output;
});
}).change();
// bonus: how to access the download link
$model.change(function() {
$('#download-link').attr('href', selectValues[$vendor.val()][$model.val()]).show();
});
});
Working example is available in jsFiddle.
Note that this should work with jQuery mobile just fine.