I have a form with md-select and md-radio-button fields. The options under radio button will be displayed according to the option selected in md-select. Please visit the plunker.
You can see I have created the form with the sub-organism radio-button field to be required. It works on the first load. But if we select any sub radio button option and then change the organism select box, the form is still valid, without having a valid sub-orgranism value. I need the form to be invalid, if the sub radio button is not checked. Please help.
Question 2 : Also in the plunk, please uncomment the following lines after line 47 in app.component.ts so that there will be a default value for the fields. The sub organism radio buttons will be displayed, but the selectbox will be blank. There is the selected value and thats the reason why sub organism fields are displayed. Not sure why the option is not selected for organisms md-select.
Add a change event to md-select so that if the selection changes, and the form was validated, you can reset the value of selected.sub_organism_id to null. That will make the form invalid.
Code snippets:
html:
<md-select [formControl]="form.controls['organism']"
style="width:100%;"
[(ngModel)]="selected.organism_id"
(change)="resetForm($event)">
<md-option *ngFor="let organism_id of getIds()" [value]="organism_id">
{{ organisms[organism_id].name }}
</md-option>
</md-select>
ts:
resetForm(org){
if(this.form.valid){
this.selected.sub_organism_id = null;
};
}
Edited Plunk
Update:
Like #WillHowell said in his comment, "md-select compares values by object reference not object value" which is true. I modified your data to an array-object relation, and md-select default value worked here.
Related
here is a simple problem I can't find a solution to. I have a typeahead directive in input which lets a user to choose a category ( category array example -> [{ id: 1as1d, name: 'some category'},...]
How to set the id value to the FormControl field (which will appear in the submitted form) and display the name on the input (which will be showed in on the input while user is choosing)? Is there a way to separate what will be in the sent form and what is being showed while using FormControl?
I could only find a way to display and set the same variable either only id or only name.
<input
formControlName="category"
[formControl]="userForm.controls['category']"
[typeahead]="categoriesObservable"
(typeaheadLoading)="toggleLoadingCategories($event)"
(typeaheadNoResults)="toggleNoCategoriesFound($event)"
(typeaheadOnBlur)="categoryFieldSelected($event)"
(typeaheadOnSelect)="categoryFieldSelected($event)"
typeaheadOptionsLimit="7"
typeaheadOptionField="name"
placeholder="Choose a category"
class="form-control"/>
What you want to do is use a template for the options.
Taken from the documentation at http://valor-software.com/ngx-bootstrap/#/typeahead:
<ng-template #customItemTemplate let-model="item" let-index="index">
<h5>This is: {{model | json}} Index: {{ index }}</h5>
</ng-template>
<pre class="card card-block card-header">Model: {{selected | json}}</pre>
<input [(ngModel)]="selected"
[typeahead]="states"
[typeaheadItemTemplate]="customItemTemplate"
class="form-control">
In this example the customItemTemplate is used to display the model and index but any property of the model can be used. On selection the whole object of your selection can be sent, then in the function it is sent to you can take the id out of the object and use it for anything you need.
You use template like in a prevous answer to choose how you want to show options in the dropdown and you use function categoryFieldSelected(v: any) to choose what happens when you select one of the options. This way the input field witll have the value of the id+name of the selected category, but the selectedCategoryCode will be the value you use when you submit the form.
private selectedCategoryCode: string = '';
categoryFieldSelected(v: any): void {
this.selectedCategoryCode = v.item.id;
this.form.get('category').setValue(v.item.id+' '+v.item.name);
}
This will sound crazy but stay with me.
Just use a hidden input for the submit form and in the event typeaheadOnSelect assign the id value to the hidden input.
In case of loading data (editing old data) just use the category id to get the text and assign the name value to the typeahead.
Don't forget to use control.updateValueAndValidity() on the hidden input in typeaheadOnSelect event.
I am using angular and have a radio input like this (in a form, if it matters):
<input type="radio"
name="inputName"
id="someId"
data-ng-value=true <!-- This select "true" for my ng-model when clicked-->
ng-model = "nameOfMyVarIn$scope"
ng-change = "thisRunsWhenSelectionIsmade(true)"
required></input>
I want to clear this input. Clearing the variable bound to ng-model clears the variable, but not the checkbox. I can't find how to clear the radio button itself in the docs or in random articles - it stays selected. I made a quick copy of the example from the docs and added $scope.clearSelection - the goal is to have this function de-select the selected input. In the real application I have other inputs in the form, so I can't just clear the whole form.
Plnkr
Using your Plnkr, I've set color to null and it cleared the value. Is this what you want?
$scope.clearSelection = function(){
$scope.color = null;
}
Here is the updated Plnkr
In my view model I have a field. This field can be selected from a drop down list or entered in a textbox. I have two radio buttons which allows to select between drop and textbox.
<div class="frm_row" id="contractorRow">
#Html.RadioButton("IsContractorNew", "false", true)
#Html.Label(#Resources.SomeLabels.Existing)
#Html.RadioButton("IsContractorNew", "true", false)
#Html.Label(#Resources.SomeLabels.New)
<div class="frm_row_input" id="contractorDropDownList">
#Html.DropDownListFor(model => model.CONTRACTOR, Model.Contractors)
#Html.ValidationMessageFor(model => model.CONTRACTOR)
</div>
<div class="frm_row_input" id="contractorTextBox" style="display: none;">
#Html.TextBoxFor(model => model.CONTRACTOR)
#Html.ValidationMessageFor(model => model.CONTRACTOR)
</div>
</div>
I prepared a javascript code for hiding, showing and clearing controls while selecting radio buttons. The problem is - field is bound only to the first control (drop down list).
EDIT:
I solved this problem by creating one hidden field and scripting whole logic to bind active control with it and therefore with the model. Anyway if anyone knows simpler solution, please post it.
I know this is an old question, but for those dealing with this issue, here's a solution:
Explanation
When a form is submitted, input elements are bound to the model by their name attribute. Let's say you use HTML helpers to generate your form, and you generate two input fields which bind to the same property on the model. When rendered to the DOM, they both have the same name attribute.
<input name="Passport.BirthPlace" id="birthPlaceDropDown" ... >
<input name="Passport.BirthPlace" id="birthPlaceInfoTextbox" ... >
When the form is submitted, it will bind the first (in the DOM) input it finds to Passport.BirthPlace
A Solution
The quick and easy way to fix this is to use JQuery to change the name of the field you don't want bound on submit. For me, I use a checkbox to toggle which field shows. When the checkbox changes, I hide one control, change its name attribute, and show the other one (and change it's name attribute to Passport.BirthPlace) It looks like this, basically:
First, I run this on document ready
$('#birthPlaceInfoTextbox').attr('name', 'nosubmit'); // Change name to avoid binding on inactive element
Then, I create a listener for my checkbox which toggles which control should be bound:
$('#notBornUSCheckbox').change(function() {
if (this.checked) {
// Not born us was checked, hide state dropdown and show freeform text box
$('#stateDropDownSection').addClass('d-none'); // Hide drop down
$('#birthPlaceDropDown').attr('name', 'nosubmit'); // Change name to something other than Passport.BirthPlace
$('#birthPlaceInfoTextbox').attr('name', 'Passport.BirthPlace'); // Set this one to be bound to the model
$('#stateTextboxSection').removeClass('d-none'); // Show the textbox field
} else { // Opposite of above lines
$('#stateDropDownSection').removeClass('d-none');
$('#stateTextboxSection').addClass('d-none');
$('#birthPlaceInfoTextbox').attr('name', 'nosubmit');
$('#birthPlaceDropDown').attr('name', 'Passport.BirthPlace');
}
});
Instead of using Razor #Html.TextBoxFor... for your textbox, you could try using raw HTML e.g. <input />. Also, have your JavaScript code remove the other field from the DOM entirely when a radio button is clicked, before submitting the form.
I would like manage with AngularJS UI which allows to pick one of the options (displayed as radio buttons group) or a custom value typed in a input-text.
It should look like:
http://jsbin.com/foyujali/7/edit
Here is the code that you can see also in the link below:
HTML
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js"></script>
<div ng-app="tagsApp" ng-controller="TagsCtrl">
<input type="radio" id="conversion_type_sale" ng-model="tag.conversion_type" value="sale"/>
<label for=conversion_type_sale>Sale</label>
<input type="radio" id="conversion_type_lead" ng-model="tag.conversion_type" value="lead"/>
<label for=conversion_type_lead>Lead</label>
<input type="radio" id="conversion_type_custom" ng-model="tag.conversion_type" value="{{tag.conversion_type_custom_value}}"/>
<input type="text" placeholder="Custom" ng-model="tag.conversion_type_custom_value" id="conversion_type_custom_value"/>
<p>
The choosen conversion type is: <strong>{{tag.conversion_type}}</strong>
</p>
</div>
And JS:
angular.module('tagsApp', []).
controller('TagsCtrl', function ($scope) {
$scope.tag = {conversion_type: 'lead'};
});
I would prefer not to use ngChange directive so I just bind the value or ng-value (I tried both) to the model of the input-text. It doesn't work properly this way, but I suppose there is an elegant AngularJS solution. Any suggestions?
Thanks in advance!
P.S. Just to clarify - I want the following functionality: http://jsbin.com/foyujali/10/edit but I want to avoid using ngChange directive.
This is what you're looking for: http://jsfiddle.net/colares/shcv8e1h/2/
Explaning the behavior
By focusing on the text field, the radio on the left is selected and chosen value is updated regarding the value of the text field;
By focusing on radio on the left of the text field, the chosen value is updated according to what is in the text field as well;
By changing the value of the text field, the chosen value is also updated;
Finally, by focusing on any other label or radio, the custom value remains, while the chosen value is update regarding the selected option.
To do so, I had to use a few more things in custom option input:
ng-focus: when I click on the text field, it updates the chosen value regarding the text field;
ng-change: as I update the text field, the final value is also updated;
ng-model: to store the auxiliar variable customColor, which remains regardless of the selected value.
Remember, the ng-value is used to set the value of the radio (or an <option>) from a given expression when we select it. This makes the radio and input text "bound", because they have the same value.
You could use $scope.$watch and look for the change in your controller like so:
http://jsfiddle.net/2R6aN/
var app = angular.module('tagsApp',[]);
app.controller('TagsCtrl', function ($scope) {
$scope.tag = {conversion_type: 'lead'};
$scope.$watch('conversion_type_custom_value',function(new_val) {
if (new_val) {
$scope.tag.conversion_type = new_val;
}
});
});
$watch is best option. Also, Instead of using modelName in 1st parameter of $watch, you can create your own stuff(eg. watching length of input box) and do desired action on it with second parameter.
I have an address form and I want to have a select box for states if the country is the U.S. and change it to a textbox if it's a foreign country so that the state/province can be typed in.
I generate the code in PHP (such as the states select and country select) and I was thinking of outputting both the select and textbox and initially hiding and disabling the textbox, then if the user changes the country unhide and enable the textbox and hide and disable the select.
My question is, is it valid if both inputs have the same name, assuming one of them will be disabled when the form is submitted?
As a bonus question, is there a better way of doing this?
Yes, it is possible and it is the best way to do this, since disabled inputs are not sent along in the request and it generates a valid and semantic HTML.
As show in w3:
When set, the disabled attribute has the following effects on an element:
Disabled controls do not receive focus.
Disabled controls are skipped in tabbing navigation.
Disabled controls cannot be successful.
[...]
In this example, the INPUT element is disabled. Therefore, it cannot receive user input nor will its value be submitted with the form.
Assuming you use jQuery, you could do something like this:
HTML:
<select id="countries">
<option>Countries</option>
</select>
<select id="states" style="display: none"> <!-- States in US -->
<option>States</option>
</select>
<textarea id="address" style="display: none">
</textarea>
JS:
// Cache states list and address box beforehand so we don't have to query every time.
var $states = $("#states"),
$address = $("#address");
$("#countries").change(function () { // Bind to change event for checking if US selected
var isUnitedStates = $(this).val() == "United States";
if (isUnitedStates) { // US is selected, show States
$states.attr("id", "address").show()
$address.attr("id", "_address").hide()
} else { // US is not selected, show Address box
$states.attr("id", "_address").hide()
$address.attr("id", "address").show()
}
})
This is not very convenient but if you really want to make sure, this is an option for you.