It seems that when an input or select is disabled in angularjs, the model value remains the same. My problem is that this is not the same as native form behaviour in HTML, and that I have to invoke some extra behaviour via an ng-change scope method in order to get the proper behaviour, which is for the value to be set to null if the input or select input is disabled.
Here is my example:
<div ng-app="myApp">
<select ng-disabled="disableIt" ng-model="data">
<option>1</option>
<option>2</option>
</select>
<input type="text" ng-model="textData" ng-disabled="disableIt" />
<br />
<input type="checkbox" ng-model="disableIt"/>
<br />
Select Data: {{selectData}}
<br/>
Text Data: {{textData}}
</div>
<script>
var myApp = angular.module('myApp',[]);
myApp.run(function($rootScope){
$rootScope.selectData = 1;
$rootScope.textData = "test";
});
</script>
You can test it out on jsfiddle here: http://jsfiddle.net/9wbtnhno/1/
The desired result is for the textData and selectData models to be null when disabled.
Related
I have some code that gets a value from unselected options in a select dropdown. This displays in console.log as an array with the correct values. However, serialize(); is not returning any values for this select when i console.log(data);. If I console.log(boxintake); this shows me the correct values being passed.
Options are being added from button click and are working correctly. Assume all names and form names are correct.
I would be grateful if someone could enlighten me as to why this is not working. Many thanks.
html
<div class="form-group">
<label class="labelStyle" for="box_ni">Select Your Box(es)</label><br />
<select disabled id="box_ni" multiple name="box_ni[]" size="15">
<option value="">
</option>
</select>
<div id="nidstrmessage"></div>
<div class="servicesHelp"><lead id="serviceHelp" class="form-text text-muted help">
Read help <img src="/domain/admin/images/qmark.png" width="24px" height="24px" class="helpintk"/>
</lead>
</div>
<div class="noBrtvBoxes" style="color:white;"></div>
</div>
js
$("#USRboxni").submit(function(e) {
e.preventDefault();
var boxintake = $("#box_ni option").map(function(){
return this.value;
}).get();
console.log(boxintake);
var data = $("#USRboxni").serialize();
console.log(data);
});
Couple of issues:
.serialize() will exclude any controls that are disabled
.serialize() on a multi select will only return the selected values
As your select is both disabled and doesn't have anything actually selected, you get no results.
When you add your items, I suggest you also make them selected at that time; this might solve many of your issues.
That's what <select multiple is for - giving the user a number of options and allowing them to select which ones they want. But you're not using it for that, you're using it as a "the user selected these". You might be better off using a hidden input store and a div to show the selected values.
Example snippet with disabled removed and one item selected shows that it only returns that one item:
//$("#USRboxni").submit(function(e) {
//e.preventDefault();
var boxintake = $("#box_ni option").map(function() {
return this.value;
}).get();
console.log(boxintake);
var data = $("#USRboxni").serialize();
console.log(data);
//});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form id='USRboxni'>
<div class="form-group">
<label class="labelStyle" for="box_ni">Select Your Box(es)</label><br />
<select /*disabled*/ id="box_ni" multiple name="box_ni[]" size="15">
<option value="1" selected>one</option>
<option value="2">two</option>
</select>
</div>
</form>
You could remove the 'disabled' just before serialize() then add it back, but you'll still need to select the items.
I want to select the first option in a select box by default. The challenge here is that the page might have multiple select boxes as they are created dynamically.
You will understand what I am trying to achieve by looking at my code.
HTML :
<form class="form-inline">
<div class="form-group form-group-grid" ng-repeat="fields in selectedTabData.requiredField" ng-switch="fields.paramType">
<label>{{fields.paramName}}<span class="asterisk" ng-if="fields.mandatory==true">*</span></label>
<input type="text" class="form-control" ng-switch-when="Text" ng-model="fields.fieldValue" ng-attr-id="{{fields.paramName}}Id">
<select class="form-control" ng-switch-when="DropDown" ng-options="field.paramKey as field.paramValue for field in fields.paramData" ng-model="fields.fieldValue" ng-attr-id="{{fields.paramName}}Id">
</select>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary form-inline-grid-button" ng-click="getReport()">Run Report</button>
</div>
</form>
The selected data is available under the model $scope.selectedTabData.requiredField
In Controller I push the selected values in to a variable like :
$scope.selectedTabData.requiredField.forEach(function(item)
{
paramValue.push(item.fieldValue);
paramName.push(item.paramName);
})
I tried doing this :ng-init="fields.fieldValue = fields.paramData[0]"
<select class="form-control" ng-switch-when="DropDown" ng-options="field.paramKey as field.paramValue for field in fields.paramData" ng-model="fields.fieldValue" ng-init="fields.fieldValue = fields.paramData[0]" ng-attr-id="{{fields.paramName}}Id">
</select>
I am not sure how it will work. Can anyone help me out with this?
you can make it possible by ng-repeat inside tag
<select ng-model="fields.fieldValue">
<option ng-repeat="field in fields.paramData" value="{{field.paramKey}}">
{{field.value}}
<option>
</select>
and in controller add this line
$scope.fields.fieldValue = x;
and in this example, x is "field.value" that you want as default selected option.
This is the plunkr for your problem
https://plnkr.co/edit/mahONdv5xQBa5eUZJSoX
I want to save selected color value from dd box into $scope.color.
Index.html:
<label class="item item-select" name="selectName">
<span class="input-label">What is your favourite colour?</span>
<select id="colorid">
<option ng-repeat="x in colorList"{{x}}</option>
</select>
</label>
controller.js:
var colorCtrl = function($scope){
$scope.color = "";
$scope.colorList =["red","blue","yellow"];
console.info("color is "+$scope.color);
}
For binding value, use ng-model:
<select id="colorid" ng-model="color">...
for trigger event, use ng-change (calls $scope.onChange() ):
<select id="colorid" ng-model="color" ng-change="onChange()">...
And be careful to your options format! (it is the value which is binded, not the content!)
Full code:
<label class="item item-select" name="selectName">
<span class="input-label">What is your favourite colour?</span>
<select id="colorid" ng-model="color" ng-change="onChange()">
<option ng-repeat="x in colorList" value="{{x}}">{{x}}</option>
</select>
</label>
And JS:
var colorCtrl = function($scope)
{
$scope.color = "";
$scope.colorList =["red","blue","yellow"
];
$scope.onChange = function()
{
//trigerred on color change
console.info("color is "+$scope.color);
}
}
You aleady got many answers here.Just for add on i will suggest you to do this way:
<select style="background:{{color}}" ng-model='color' ng-options='color as color for color in colorList' ng-change='selectionChanged(color)'>
</select>
or you can also try with
<select ng-model='color' ng-change='selectionChanged(color)'>
<options style="background:{{color}}" ng-repeat="color as color for color in colorList" value={{color}}>
{{color}}</options>
</select>
First, there is a syntax error in your code.
In you want to take input from the DOM you have to tell angular which variable to store the input in.
This is done via the ng-model directive.
As given in the documentation.
The ngModel directive binds an input,select, textarea (or custom form
control) to a property on the scope using NgModelController, which is
created and exposed by this directive.
ngModel is responsible for:
Binding the view into the model, which other directives such as input,
textarea or select require.
Providing validation behavior (i.e.
required, number, email, url).
So, if I want to take input I will initialise the input element as,
<input type="text" ng-model="val" />
Via this, I have initialised a variable "val" on the scope (The Model) and I have told angular, whatever input is entered into the input element will be bound to that variable.
<label class="item item-select" name="selectName">
<span class="input-label">What is your favourite colour?</span>
<select id="colorid" ng-model="color">
<option ng-repeat="x in colorList">{{x}}</option>
</select>
</label>
Please check this example.
I have two forms on a php page. They post to different pages when they are submitted. Both forms need the value of a dropbox that is inside form A. How do I get this value posted when form B is submitted?
Create a hidden input in form B and put a change event on the dropdown in form A which copies it's value to that.
Example (using jQuery - if you want to do it with another library or plain javascript you'll need to adapt it).
<script type="text/javascript">
$(function(){
$('#copy-src').change(function(){
$('#copy-target').val( $(this).val() );
}).change();
});
</script>
<form id="a" action="/a">
<input type="text" name="a_only" />
<select id="copy-src" name="also_b">
<option value=""></option>
<option value="foo">Foo</option>
<option value="bar">Bar</option>
</select>
<button type="submit">Submit</button>
</form>
<form id="b" action="/b">
<input type="text" name="b_only" />
<input type="hidden" name="also_a" id="copy-target" />
<button type="submit">Submit</button>
</form>
The .change(function(){}) creates a change event to copy the value while the final .change() triggers that event (on page load) to ensure the value is right initially.
You can copy dropbox value to Form B while submitting;
On formB;
<form onsubmit="getDropdownValue()">
.....
</form>
And in function;
function getDropdownValue() {
var formB = document.getElementById("formB");
// Get selected value from FormA
var e = document.getElementById("formADropdown");
var value = e.options[e.selectedIndex].value;
// Append it to formB
var input = document.createElement("input");
input.type = "hidden";
input.name = "dropdownValue";
formB.appendChild(input);
}
You can see demo: Demo . I demo when you click submit, you will see dropdownvalue from form A will be copied to formB before submit
I've experienced some code of enable/disable multiple html element by javascript:
<script type="text/javascript">
function enableDisable(bEnable, text_no1, text_no2, opt_no1, opt_no2){
document.getElementById(text_no1).disabled = !bEnable
document.getElementById(text_no2).disabled = !bEnable
document.getElementById(opt_no1).disabled = !bEnable
document.getElementById(opt_no2).disabled = !bEnable
}
</script>
<label for="toggler"><input type="checkbox" id="toggler" autocomplete="off"
checked="false"
onclick="enableDisable(this.checked, 'text_no1','text_no2','opt_no1','opt_no2')";>
Toggler</label>
<br>
<input type="text" name="text_no1"><br>
<input type="text" name="text_no1"><br>
<select name="opt_no1">
<option>1</option>
</select>
<select name="opt_no2">
<option>1</option>
</select>
I made a simple script of what you are trying to achieve.
(Tested in Chrome 21, Firefox 14, Internet Explorer 9)
The JavaScript
function Switch() {
var checkbox = document.getElementById("Switch")
var val = checkbox.checked
document.getElementById("textbox").disabled = val
}
The HTML
<input type="checkbox" id="Switch" onChange="Switch()" />Disable/Enable
<br />
<input type="text" id="textbox"/>
Live Example: http://jsfiddle.net/jHVNE/1/
I'll guess that your issue is that "it doesn't work", that is, that the elements aren't disabled. That is partly because you are using getElementById to access elements that don't have an ID attribute (though likely it works in IE since it thinks IDs and names are the same thing).
You can either change the name attributes to ID attributes (since you aren't using a form that shouldn't be an issue), or keep the names and put the controls in a form, then access them as named properties of the form.
Edit
There are a couple of errors and omissions in your code:
The checked attribute does not have a value, it's a boolean attribute whose presence indicates "true" and absence is "false", so …checked="false"… is true and checks the checkbox.
There are two inputs with a name of *text_no1*
It seems checking the checkbox should enable the controls, the label should indicate that.
Using a form makes life easier to access form controls
Some working code:
<script type="text/javascript">
function enableDisable(el) {
var f = el.form;
var bEnable = el.checked;
if (!f) return; // Stop if form not found
for (var i=1, iLen=arguments.length; i<iLen; i++) {
f[arguments[i]].disabled = !bEnable;
}
}
</script>
<form>
<label for="toggler">
<input type="checkbox" id="tggler" name="toggler" autocomplete="off" checked
onclick="enableDisable(this, 'text_no1','text_no2','opt_no1','opt_no2')";>
Controls enabled</label>
<br>
<input name="text_no1"><br>
<input name="text_no2"><br>
<select name="opt_no1">
<option>1
</select><br>
<select name="opt_no2">
<option>2
</select>
</form>