Can't get current value from select in Ember 2 - select

I'm trying to get the value every time the user changes the select component. But the value always returns 'undefined'.
I've been through all Stackoverflow questions and other sites, but without success. I feel like I'm missing something here.
I'm using Ember 2.8.
My component template:
<div class="form-group">
<label for="{{selectId}}">{{selectTitle}}</label>
<select name="{{selectId}}" id="{{selectId}}" class="form-control" {{action "getSelectValue" on="change" value="target.value"}}>
<option value="0" selected>{{selectDefault}}</option>
{{#each model as |choice|}}
<option value={{choice.id}}>{{choice.name}}</option>
{{/each}}
</select>
</div>
My component logic:
import Ember from 'ember';
export default Ember.Component.extend({
tagName: '',
currentValue: null,
actions: {
getSelectValue(value) {
console.log(value); //always returns undefined
}
}
});
I'm calling it like this:
{{select-control model=model.tasks selectTitle="Task" selectDefault="Choose Task" selectId="taskSelect"}}
In the template I've also used the onchange="{{action...}}" syntax, but then the action wasn't called.
At this point I have no logic in my route or controller handling this.
Thanks for your help!

<select name="{{selectId}}" id="{{selectId}}" class="form-control" {{action "getSelectValue" on="change" value="target.value"}}>
change the above line to
<select name="{{selectId}}" id="{{selectId}}" class="form-control" onchange={{action "getSelectValue" value="target.value"}}>

Related

Angular 2 Template Driven Forms - Array Input Elements

I have been struggling for 1 and half day and still couldn't find any solution to the problem. I am working on simple form which has select and checkboxes element.When I try submitting the form I do not get the values of select and checkboxes but rather I just get true in the console.
I am working on template driven form.
<form (ngSubmit)="addSubcontractor(subcontractorForm)" #subcontractorForm="ngForm">
<h5>Type :</h5>
<div class="form-group">
<div *ngFor="let contractor_type of contractor_types;let i = index;" class="pull-left margin-right">
<label htmlFor="{{ contractor_type | lowercase }}">
{{ contractor_type }} :
</label>
<input type="checkbox" name="_contractor_type[{{i}}]" [value]="contractor_type" ngModel>
</div>
<div class="form-group">
<select class="form-control costcodelist" name="_cc_id[]" multiple="true" ngModel>
//When I put ngModel on select I just keep getting error
//TypeError: values.map is not a function
<option *ngFor="let costcode of costcodes" [selected]="costcode.id == -1" [value]="costcode.id">{{ costcode.costcode_description }}</option>
</select>
</div>
</form>
Component Section
export class SubcontractorComponent implements OnInit, OnDestroy {
private contractor_types = ['Subcontractor', 'Supplier', 'Bank', 'Utility'];
constructor(private costcodeService: CostcodeService,
private subcontractorService: SubcontractorService) {
this.subcontractorService.initializeServices();
}
ngOnInit() {
this.costcode_subscription = this.costcodeService.getAll()
.subscribe(
(costcodes) => {
this.costcodes = costcodes;
});
}
addSubcontractor(form: NgForm) {
console.log(form.value);
}
}
When I remove ngModel from select element the code runs fine and When I submit the form I get the following output.
_contractor_type[0]:true
_contractor_type[1]:true
_contractor_type[2]:true
_contractor_type[3]:""
I do not get the checkboxes values as well the selected options from select element.
Your comments and answer will appreciated a lot.
Thanks
Here is a simple selection that i use with my Template driven form.
<form #f="ngForm" (submit)="addOperator(f.valid)" novalidate>
<label>Name</label>
<input [(ngModel)]="operator.name" name="name">
<label >Service</label>
<select #service="ngModel" name="service" [(ngModel)]="operator.service">
<option *ngFor='let service of services' [ngValue]='service'>{{service.name}}</option>
</select>
<label >Enabled</label>
<label>
<input type="checkbox" name="enabled" [(ngModel)]="operator.enabled">
</label>
<button type="submit">Create Operator</button>
</form>
.ts
operator: Operator;
ngOnInit() {
this.operator = <Operator>{}; // // Initialize empty object, type assertion, with this we loose type safety
}
addOperator(isValid: boolean) {
if (isValid) {
this.operatorsService.addOperator(this.operator).then(operator => {
this.goBack();
});
}
}
Also im importing this
import { FormsModule, ReactiveFormsModule } from '#angular/forms';

How to get selected option from select and assign it to select ngModel

I have the following select menu:
<div class="medium-3 columns">
<label>First Menu
<select name="first-menu">
<option *ngFor="let i of items" [value]="i.name">{{i.name}}</option>
</select>
</label>
</div>
I would assing a model to the select menu so i edited the code in the following way (i see it here):
<div class="medium-3 columns">
<label>First menu
<select [ngModel]="myForm.firstMenu" (ngModelChange)="onSelected($event)" name="first-menu">
<option *ngFor="let i of items" [value]="i.name">{{i.name}}</option>
</select>
</label>
</div>
On ngModelChange it triggers the following method in the component:
onSelectedFirstMenu(e: any): void {
myForm.firstMenu = e;
}
Since i have to add several menu, i would make code reuse so i do not want to create multiple methods like onSelectedSecondMenu, onSelectedThirdMenu and so on for every html menu.
So i just want to use a different ngModel for every menu (myForm.secondMenu, myForm.thirdMenu and so on...) to get the selected option.
Is it possible in Angular2?
I solved and there are 2 ways to get the same behaviour:
First way (preferred):
<div class="medium-3 columns">
<label>First Menu
<select [(ngModel)]="myForm.firstMenu" name="first-menu">
<option *ngFor="let i of items" [value]="i.name">{{i.name}}</option>
</select>
</label>
</div>
Second way:
<div class="medium-3 columns">
<label>First Menu
<select [ngModel]="myForm.firstMenu" (ngModelChange)="myForm.firstMenu = $event" name="first-menu">
<option *ngFor="let i of items" [value]="i.name">{{i.name}}</option>
</select>
</label>
</div>
More info here
If i understand your question correctly, every single menu has a different purpose, therefore, trying to somehow combine the invoked method for all of those menus is incorrect.
Having a method for each of those <select>s is the right approach, each one of them should have its' own logic
Please let me know if i misunderstood
Use [(MyForm.firstMenu)] to bind the select to your firstMenu property
Something like this should do depending on your concrete requirements:
<select [(ngModel)]="myForm.firstMenu"
constructor() {
this.myForm.firstMenu = items[0];
}

.asp validate_form wrong somehow?

I've got a little problems with my "contact us" form, whenever i submit it i get the error message 500. IE tells me it's a error at line 62, and that validate_form is not specified.
My code goes like this:.
<form method="POST" action="/cgi-bin/emailer.asp" onsubmit="return validate_form(this); ">
I really don't know anything about .asp, .php, .js etc. so some help would really be needed.
Thanks
-Niko
Update:
function validate_Form(form)
{
var x=document.forms["yhteys"]["email"].value;
var atpos=x.indexOf("#");
var dotpos=x.lastIndexOf(".");
if (atpos<1 || dotpos<atpos+2 || dotpos+2>=x.length)
{
alert("Sähköposti osoite ei ole oikein.");
return false;
}
}
that's how the code looks right now, but it still isn't working.
<form name="yhteys" method="POST" action="/cgi-bin/emailer.asp" onsubmit="return validate_form(this);">
<div style="float:left;">
Aihe:<b>*</b><br>
<select name="Aihe" required="required" id="Aihe">
<option value="Yhteydenotto">Yhteydenotto</option>
<option value="Arviokäynti">Arviokäynti</option>
<option value="Esitetilaus">Esitetilaus</option>
<option value="Esittelyajan varaus">Esittelyajan varaus</option>
<option value="Palaute">Palaute</option>
<option value="Muu viesti">Muu viesti</option>
</select><br><br>
Nimi:<b>*</b><br>
<input type="text" required="required" name="nimi" size="35"><br><br>
Osoite:<b>*</b><br>
<input type="text" required="required" name="osoite" size="35"><br><br>
Puhelin:<b>*</b><br>
<input type="text" required="required" name="puh" size="35"><br><br>
Sähköposti:<b>*</b><br>
<input type="text" required="required" name="email" size="35"><br><br>
Viesti:<b>*</b><br>
<textarea rows="5" name="viesti" cols="45" required="required" id="Viesti"></textarea>
<div style=" margin-right: 2px; margin-top: 2px;"><input type="submit" value="Lähetä" name="B1"></div><br />
<p>Tähdellä merkityt kohdat ovat pakollisia.</p>
</form>
</div>
There is the whole form section, just so you could tell me more specifically what's wrong.
validate_form(this) is a call to a JavaScript function you have to define.
it might look something like this:
function validate_form(form){
if (form.fieldname.value /* fulfills some condition */)
{
//this will abort the submit
return false;
}
//will only get called when the if-statement does not return true
//this allows the submit to procede
return true;
};
alternatively you can declare a function like this:
var validate_form = function(form){/*your code here*/};
you should put that block of code in the <head>-section of your page inside of:
<script type="text/javascript" >
// your code
</script>
EDIT:
As of your javascript:
If you send this to your function, you do not have to crawl DOM to get your elements.
--> to get any field in your form (which you pass to function with this-Keyword) you can do the following:
form.fieldname
this allows you to access your email like that:
var email = form.email.value;
You can now check your email with a custom-validation, but i recommend using a freely available regex to check it. you can find a nice one in the answer no.3 here
if (!isValid(email)){ //if the given email is not Valid by the function you call
alert("Sähköposti osoite ei ole oikein.");
return false;
}

Pass data-attribute from DOM to function in AngularJS controller

I'm using AngularJs to change visibility of certain DOM elements. The visibility depends on what value was selected in a dropdownlist. More specifically, on a data-attribute of the selected option tag. I cannot populate the dropdown via AngularJs, because it's an existing ASP.NET control.
I thought about using ng-change and call a method on my controller but I'd have to pass an argument. This argument is in the DOM and not in my controller. Obviously, I'd like to keep it this way, and not access the DOM in my controller.
I've made a jsFiddle, but this is my code:
HTML
<body ng-app>
<div ng-controller="VehicleDetailsCtrl">
<select ng-model="selectedValue" ng-change="update()">
<option value="1" data-carType="Car">Car 1</option>
<option value="2" data-carType="Car">Car 2</option>
<option value="3" data-carType="Truck">Truck</option>
</select>
<div ng-hide="isTruck">
Hide if a truck was selected.
</div>
</div>
</body>
Javascript
function VehicleDetailsCtrl($scope) {
$scope.isTruck = false;
$scope.selectedValue = null;
$scope.update = function() {
$scope.isTruck = !$scope.isTruck;
// hide div here?
// but then I'd need to know the selected option,
// but I don't want to reference the DOM here.
};
}
Am I approaching this in the wrong way?
Keep in mind that I cannot let AngularJs populate the select because ASP.NET already does that for me (and I can't change that at the moment).
Also, I need both the selectedValue (for post-back and saving it to the database) and the data-carType (for changing the DOM). I don't know at runtime what the id (or value) of the Truck option is.
Use a directive to create an object of vehicle types and watch the model value of the select to update your isTruck variable:
HTML:
<select ng-model="selectedValue" check-is-truck>
JS:
var app = angular.module('myApp', []);
app.directive('checkIsTruck', function(){
return function(scope, element, attrs){
scope.vehicleTypes = {};
scope.selectedType = false;
angular.forEach(element.find('option'), function(item, idx) {
scope.vehicleTypes[item.value] = item.dataset.cartype;
});
scope.$watch('selectedValue', function() {
scope.selectedType=scope.vehicleTypes[scope.selectedValue];
scope.isTruck = scope.selectedType == 'Truck'
})
};
})
function VehicleDetailsCtrl($scope) {
$scope.isTruck = false;
$scope.selectedValue = null;
}
DEMO: http://jsfiddle.net/7ttr6/2/
You don't need ng-change to update the value because ng-model takes care of that. And in ng-hide you need to simply compare the selectedValue with the value of 'Truck' option (int 3):
<select ng-model="selectedValue">
<option value="1" data-carType="Car">Car 1</option>
<option value="2" data-carType="Car">Car 2</option>
<option value="3" data-carType="Truck">Truck</option>
</select>
<div ng-hide="selectedValue==3">
Hide if a truck was selected.
</div>
Fiddle

Detecting form change get id

I am trying to get the form id when an option in a drop down is selected:
HTML
<form id="test">
<select id="option1">
<option id="opt1">Hello</option>
</select>
</form>
JS:
$("#test").change(function(){
var formid=$("test").parent("form");
alert(formid);
});
The output in the alert is "object object". I have also tried closest which gives the same output.
$("#test").change(function(){
var formid=$("test").parent("form").attr('id');
alert(formid);
});