I have multiple dropdowns in my application which are populating through a json (which is a map basically) given in controller.
For first dropdown if I select xyz value, then corresponding xyz1 values should come in dropdown and similarly for third dropdown. This all is happening fine currently. But now I want these user selected values to get in json form so that I can send back to backend for further processing. I am not getting selected values but the wrong second dropdown values if I print on console.
codepen and
working plunker
I understand that you need to get values from the dynamic input elements. For that, you need to set ng-model to the input elements, not to the div.
The below updated part would help.
<div ng-init="pageObjectName.pageObjParam={}" ng-repeat="(key , value) in pageObjectName.pageObjMethod">
<input ng-model='pageObjectName.pageObjParam[key]' value='' placeholder="{{key}} - {{value}}"></input>
</div>
Now you can get those values from $scope.pageObjectName.pageObjParam.
Updated Plunker
EDIT
I hope the above part helped to get value from dynamic input fields. Now I suggest you to update the code block like below to get the selected values from dropdown (ie, use one hidden input field for each select) and you will get what you want.
<select id="pageObj" ng-model="pageObjectName.pageObj" ng-options="key for (key,value) in pageData" ng-change="pageObjectName.pageObjParam.pageObj=pageObjectName.pageObj">
<option value=''>Select Page Object</option>
</select>
<input ng-model='pageObjectName.pageObjParam.pageObj' hidden/>
You can have a look at the same plunker now
Your codepen seems to be confusing and not working. As you already have the implemention for dropdown I will continue from here about how to get the data from the drop down and convert the data into a JSON.
After getting the data from the dropdown create a JSON object and store it.
I have written a small example to show how to store the data.
$scope.selectedState = function(item) {
var output = {};
output.name = item.name;
$scope.viewOutput = output;
};
Update:
I tried hard but could not get the values using angular way. If you are still looking for an answer then we can use basic javascript way. Refer plunker for the same.
$scope.submitMyForm = function() {
/* while compiling form , angular created this object*/
var pgObj = $scope.pageObj;
var pgClass = $scope.pageClass;
var pgMethod = $scope.pageObjMethod;
var pgObjvalue = document.getElementById('pageObj').value;
var pgClassvalue = document.getElementById('pageClass').value;
var pgMethodvalue = document.getElementById('pageMethod').value;
$scope.output = {'object' : pgObjvalue, 'class': pgClassvalue, 'method': pgMethodvalue};
console.log(data);
};
Working Plunker.
P.S: If you figured out the answer using angular way then do let me know after posting it in the answer section.
Related
I am trying to make a dependent dropdown but somehow the second dropdown is always leaving a blank if i am changing the first dropdown.
<select class="form-control DB_Control" id="Sector" ng-model="selected_sector" ng-init="selected_sector = initial_selected_sector" ng-options="each.sector for each in data track by each.sector" ng-change="getSubsector()">
<select class="form-control DB_Control" ng-model='related_subsector3' ng-options="subsector for subsector in sub_sectors track by subsector" >
$scope.getSubsector = function() {
$scope.related_subsector3 = $scope.sub_sectors[0]
}
Just for more information, if i am printing the value of $scope.related_subsector3 in function getSubsector, its printing correct value but its not setting the value in template.
I don't think that would work. What I would try is to create another function called "$scope.getSubSectorChildren()" which would populate the second dropdown on the change of the first one. That way you can keep the data population more flexible and it would be easier to test/debug.
So I have 2 drop downs which need selecting before a third one can be populated.
The problem is even with data coming back the 3rd one isn't populating.
Because of how it is designed each dropdown has it's own controller, with another one for the whole window.
Source widget:
<select class="form-control" required name="dataDomain"
ng-model="customFilters.dataDomain.value"
ng-options="dataDomain.code as dataDomain.shortName for dataDomain in dataDomains"
ng-change="customFilters.dataDomain.loadExtraData()">
<option value="" translate>_NONE_</option>
</select>
source controller:
(function init() {
$scope.customFilters = reportsService.filters;
$scope.customFilters.dataDomain = {
value: undefined,
loadExtraData: function() {
var reportType;
if(this.containsData() && !this.isDisabled()) {
reportType = reportsService.filters.reportType.value;
dictionaryService.getCustomReports({"dataDomain": 'WEE', "country": 'UK')
.then(function ({data}) {
$scope.customReports = data.customReport;
});
}
}
};
})();
The target widget:
<select class="form-control" required name="custom"
ng-model="customFilters.custom.value"
ng-options="c.reportUrl as c.reportName for c in customReports">
<option value="" translate>_NONE_</option>
</select>
whole window controller:
$scope.customReports = [];
As a test to ensure My target widget is looking at the correct location I have also tried in the whole window controller The target dropdown was populated with frank and Joe.
$scope.customReports = [{reportUrl:'hello',reportName:'Frank'},{reportUrl:'hello2',reportName:'Joe'}];
Why isn't the dropdown being populated after the ajax call? (see edit 3)
Edit 1: I have removed excess ajax calls and conditional
functionality from the source widget controller. Hopefully to make
it easier to see. I may have got my brackets wrong.
Edit 2: I did some debugging and the scope ID in the source was 47
and in the target it was 50. I have no idea what these numbers mean,
but it shows I am not storing my data in the same space.
Edit 3: I FIXED IT (by just trying everything), But i don't know why
I moved the customReports data to $scope.customFilters.customReports so the question has changed to WHY IS THIS WORKING!!!!
Because of how it is designed each dropdown has it's own controller,
with another one for the whole window.
This is the key! You have defined $scope.customReports inside wholeController which has a different scope than your dropdown. That is the reason you were able to fix it once you moved it inside $scope.customFilters.customReports which is the same scope as that of the dropdown.
From angularjs documentation
Each AngularJS application has exactly one root scope, but may have
several child scopes.
This blog explains it in detail about Understanding Angularjs scope $rootScope and $scope.
I have been most part of the morning working on a solution for when I need to assign several values to an entity on my form.
So, the idea is I have an Entity called QualityData and this entity can have different MechanismIdentifiers.
Best solution I thought of, use a multiple select.
All works fine combining both these solutions:
AngularJS selecting multiple options
Get value when selected ng-option changes
I can access the array of selected options, assign it to my entity, etc... But I have a "minor" fallback, which is that I can't get the preselected options (the ones that would come from the server when loading data for editing) to be highlighted in the select field when using a dynamic approach such as <option ng-repeat> or ng-options, it will only work when hardcoding the options. Another bug is that if I wish to add more values than those that are in the preselected array, it will erase all values present in it when using a dynamic approach, working fine when harcoding.
The markup:
<select multiple ng-change="showAlert(selectedValues)" ng-model="selectedValues">
<!--ng-options="resDatasIdOfMechanism as resDatasIdOfMechanism.name for resDatasIdOfMechanism in resDatasIdOfMechanisms track by resDatasIdOfMechanism.id" value="resDatasIdOfMechanism.id">-->
<option value="1">{{resDatasIdOfMechanisms[0].name}}</option>
<option value="2">{{resDatasIdOfMechanisms[1].name}}</option>
<option value="3">{{resDatasIdOfMechanisms[2].name}}</option>
</select>
If I try to use the line that is commented, it's when the marked option will not work
The controller:
$scope.selectedAlready = [{id:1, name:"Based on Antibiogram"}];
$scope.selectedMechanisms=[];
$scope.resDatasIdOfMechanisms = [{id:1,name:"Based on Antibiogram"}, {id:2,name:"Molecular"}, {id:3,name:"Genetic"}];
$scope.selected = $scope.selectedAlready;
$scope.selectedValues = [];
$scope.$watch('selected', function(nowSelected){
$scope.selectedValues = [];
if( ! nowSelected ){
return;
}
angular.forEach(nowSelected, function(val){
$scope.selectedValues.push( val.id.toString());
console.log("look");
});
});
$scope.showAlert=function(listOfMultipleChoices){
//alert(object);
}
EDIT to add jsfiddle link which is working but I still haven't found solution to original question: https://jsfiddle.net/StevenEvenSteven/ybapx09w/
There is a typo in your code.
Add a comma after '$scope' in your controller definition
fiddleApp.controller('myFiddle', ['$scope', function($scope) {
I've forked your jsfiddle and it is working as you expected.
I'm using selects to allow a user to switch between events and years. Each change will pull appropriate data from the server, return and update the page. However, the select box goes from the selected value to an empty value. I've looked at numerous solutions and they aren't working.
<select
ng-model="eventName"
ng-options="item.value for item in eventOptions track by item.value"
ng-change="changeEvent(eventName.value)">
</select>
This is the changeEvent function:
$scope.changeEvent = function(eventName){
$scope.eventName = eventName; //wrongly assumed this would update the selected value
$scope.getData($scope.eventName,$scope.eventYear); //this returns the json - correct
$scope.updateSelected(); //meant to update the select field value on the page - fails
};
$scope.eventName or $scope.eventYear values will properly update on a change, but has no effect on the page. The selects just empty of a selected value.
UPDATED (with corrected code)
I wanted to post the changes I made more clearly than the comment allows.
I removed the object param "value" from the options and the argument from the function call (eventName.value).
<select
ng-model="eventName"
ng-options="item for item in eventOptions track by item"
ng-change="changeEvent()">
</select>
And the changeEvent function gets simplified to:
$scope.changeEvent = function(){
$scope.getData($scope.eventName,$scope.eventYear);
};
It all works as expected! Thanks to all, especially Delta who got me looking at it the right way.
So, your event name variable is set to be item. not item.value so instead of passing in changeEvent(eventName.value) try passing in changeEvent(eventName). either way the value you are passing into your method doesnt match the value of your model's variable
item.value for item in eventOptions track by item.value
so for this statement, you are saying make my options ng-model=item but make their value=item.value so they show what you want them to show but still have all the information you need from each one.
Upon further inspection is looks like you dont need:
$scope.eventName = eventName;
$scope.updateSelected();
Angular should be updating your eventName for you, you just need to call the change method.
I'm not sure you need:
ng-change="changeEvent(eventName.value)"
if you use ng-options the model will be updated in the scope automatically on selection. You could watch the value in the controller if you want to do other stuff when it changes:
$scope.$watch('eventName', function() {
//do stuff
});
I am facing problem in populating default values for dynamically generated form fields in using angular. So, I have a login form that generates itself based on the attribtes returned by aREST interface. Therefore for my html page, I just have :
<li ng-repeat="element in elements">
<label>UserName</label>
<input type="{{element.inputType}}" ng-model="{{element.fieldName[element]}}" required="required"/>
The default values are returned in an attribute called placehoder in elements object. following tag gives an idea of the task that I am trying to achieve
<input type="{{element.inputType}}" ng-model="{{element.fieldName[element]}}" required="required" placeholder="{{element.placeholder}}"/>
Finally, when the user clicks submit , I need to post the default value of text field if it has not been changed.
Any help would be highly appreciated.
Thanks
If you can add/use a library like underscorejs or lodash, then you can use their _.defaults() :
var object = { 'name': 'barney' };
_.defaults(object, { 'name': 'fred', 'employer': 'slate' });
// → { 'name': 'barney', 'employer': 'slate' }
with angular only, you could add a directive to your form, that watches 'submit' and sets the default values for you.
Thanks for replying #nilsK, I am very new to javascript frameworks and Angular is the first one that I am having my hand on.
So in my R&D with it , I solved my issue by adding the two arrays of values i.e. FieldName and Placeholder to the scope object that I use to post data to my backend. I assign values to these arrays from the objects(placeholder and fieldName) that recieve from REST service as:
$scope.user={};
$scope.user.FieldNames=[];
$scope.user.FieldValues=[];
angular.forEach($scope.elements,function(value,index){
$scope.user.fieldValues[index] = $scope.elements[index].placeholder;
$scope.user.fieldNames[index] = $scope.elements[index].fieldName;
})
and on the html form, I bind ng-model to the scope array of values that I want to display as defaults in text field.
<input type="{{element.inputType}}" ng-model="user.fieldValues[$index]" required="required" />
Therefore, the default values are posted if user does not change them and if there is a change, updated values are posted.
Any suggestions to improve this solution are most welcome.