I try to detect on change with dart. Example html:
<div>
<input id="photoUpload" type="file" name="photo" (onchange)="update()" multiple>
</div>
Dart:
#Component(
selector: "photo-upload-dialog", templateUrl: "photo_upload_dialog.html")
class PhotoUploadDialog {
update() async {
print('Changed!');
}
}
But nothing in a console.
onChange is the default event handler name, not the event name.
Use instead
(change)="update()"
Related
I'm trying to set up a drag&drop component to upload multiple files. However, when I attempt to access elements on the DOM with the querySelector method, I end up with null.
I've tried to implement the AfterViewInit class to no avail. Here's my current dart code for the component:
import 'dart:html';
import 'package:dnd/dnd.dart';
import 'package:angular/angular.dart';
#Component(
selector: 'upload',
templateUrl: 'upload.html',
styleUrls: [
'upload.css'
]
)
class Upload implements AfterViewInit {
#override
void ngAfterViewInit() {
// TODO: implement ngOnInit
Draggable d = new Draggable(document.querySelectorAll('.page'), avatarHandler : new AvatarHandler.clone());
var del = document.querySelector('.upload');
print(del); //prints null
Dropzone dropzone = new Dropzone(document.querySelector('.upload')); //throws an error, as it doesn't expect null.
dropzone.onDrop.listen((DropzoneEvent event){
print(event);
});
}
}
Also, my upload.html file is as follows:
<div class="center-me page" uk-grid>
<div class="uk-align-center text-align-center">
<h2 class="text-align-center" >Upload a file</h2>
<div class="upload uk-placeholder uk-text-center">
<span uk-icon="icon: cloud-upload"></span>
<span class="uk-text-middle">Attach binaries by dropping them here or</span>
<div uk-form-custom>
<input type="file" multiple>
<span class="uk-link">selecting one</span>
</div>
</div>
<progress id="progressbar" class="uk-progress" value="0" max="100" hidden></progress>
</div>
</div>
Thanks in advance.
So this looks like it should work. I wouldn't actually suggest doing it this way as it will get any element with an upload class which if you reuse the component will be a lot.
I would suggest using the ViewChild syntax instead
class Upload implements AfterViewInit {
#ViewChild('upload')
void uploadElm(HtmlElement elm) {
Dropzone dropzone = new Dropzone(elm);
dropzone.onDrop.listen((DropzoneEvent event){
print(event);
});
}
}
In the template:
<div class="uk-placeholder uk-text-center" #upload>
That said you shouldn't be getting null from the querySelect, but from the code you have shown I'm not sure why.
I have a parent component like this
<div>
<div class="selection-area active" style="max-height:initial;" contact-details [(contactDetailsD)]="conDetailsUI"></div>
</div>
<div>
Next
</div>
The child component
<div>
<form>
<input type="text" name="name" value="{{contactDetailsD?.firstName}}">
<input type="text" name="email" value="{{contactDetailsD?.email}}">
<input type="text" name="phone" value="{{contactDetailsD?.phone}}">
</form>
</div>
Can you help me to get the child form values in parent component, onclick of Next button that present in the parent component.
Use services.. Have some getters and setters in the services and inject the service in the parent component set the values and inject the service in the child component and get the values and assign them to some variables and bind them in the template. Here is the example of service
import { Injectable } from '#angular/core';
#Injectable()
export class ActiveclassService {
constructor() { }
private rolesclass:any;
setrolesclass(rolesclass){
this.rolesclass=rolesclass;
}
getrolesclass(){
return this.rolesclass;
}
Parent listens for child event
The child component exposes an EventEmitter property with which it emits events when something happens. The parent binds to that event property and reacts to those events.
The child's EventEmitter property is an output property, typically adorned with an #Output decoration as seen in this VoterComponent:
import { Component, EventEmitter, Input, Output } from '#angular/core';
#Component({
selector: 'my-voter',
template: `
<h4>{{name}}</h4>
<button (click)="vote(true)" [disabled]="voted">Agree</button>
<button (click)="vote(false)" [disabled]="voted">Disagree</button>
`
})
export class VoterComponent {
#Input() name: string;
#Output() onVoted = new EventEmitter<boolean>();
voted = false;
vote(agreed: boolean) {
this.onVoted.emit(agreed);
this.voted = true;
}
}
Clicking a button triggers emission of a true or false, the boolean payload.
The parent VoteTakerComponent binds an event handler called onVoted() that responds to the child event payload $event and updates a counter. VoterParentComponet:
import { Component } from '#angular/core';
#Component({
selector: 'vote-taker',
template: `
<h2>Should mankind colonize the Universe?</h2>
<h3>Agree: {{agreed}}, Disagree: {{disagreed}}</h3>
<my-voter *ngFor="let voter of voters"
[name]="voter"
(onVoted)="onVoted($event)">
</my-voter>
`
})
export class VoteTakerComponent {
agreed = 0;
disagreed = 0;
voters = ['Mr. IQ', 'Ms. Universe', 'Bombasto'];
onVoted(agreed: boolean) {
agreed ? this.agreed++ : this.disagreed++;
}
}
SRC: https://angular.io/guide/component-interaction#parent-listens-for-child-event
I try to implement async(isUnique) and sync(cannotContainSpace) validation functions for username field, I want to see "this username already in use alert msg, if textbox value is "yener". sync function works fine but i think ss below can help explain my issue;
Note:canNotContain sync validation func works fine, aafter I added isUnique async function this exception occured..
how can I fix it ?
usernamevalidator.ts
import {FormControl} from '#angular/forms';
export class UsernameValidator{
static isUnique(control:FormControl){
return new Promise((resolve, reject)=>{
setTimeout(function(){
debugger
if(control.value =="yener")
resolve({isUnique:true})
else
resolve(null)
},1000);
});
}
static cannotContainSpace(control:FormControl){
if(control.value.indexOf(' ')>=0)
return { cannotContainSpace:true };
return null;
}
}
postmessage.component.ts
import { Component } from '#angular/core';
import {FormControl,FormGroup,FormBuilder,Validators} from '#angular/forms';
import {UsernameValidator} from '../../validators/usernamevalidator';
#Component({
moduleId:module.id,
selector: 'post-message',
templateUrl: '../../templates/postmessage.component.html'
})
export class PostComponent {
form : FormGroup;
constructor(fb:FormBuilder){
this.form = fb.group({
username:['', Validators.compose([Validators.required, UsernameValidator.cannotContainSpace]),Validators.compose([UsernameValidator.isUnique])],
email:['', Validators.required],
message:['', Validators.required]
});
}
signup(){
console.log(this.form.value);
}
}
here is html template:
<form class="from-horizontal" [formGroup]="form" (ngSubmit)="signup()">
<div class="form-group row">
<label for="username" class="control-label col-md-2">Name:</label>
<div class="col-md-6">
<input type="text" id="username" class="form-control" formControlName="username">
<div *ngIf="form.controls['username'].touched && form.controls['username'].errors">
<div class="alert alert-danger"
*ngIf="form.controls['username'].errors.required">
User name is required.
</div>
<div class="alert alert-danger"
*ngIf="form.controls['username'].errors.cannotContainSpace">
User name can not contain space
</div>
<div class="alert alert-danger" *ngIf="form.controls['username'].errors.isUnique">
This user name already in use.
</div>
</div>
</div>...
it's strange, i though we can use "Validators.compose()" function in form builder initializer as async parameters but angular2 dont agree with me..
I just changed;
username:['', Validators.compose([Validators.required,
UsernameValidator.cannotContainSpace]),Validators.compose([UsernameValidator.isUnique])],
to
username:['', Validators.compose([Validators.required,
UsernameValidator.cannotContainSpace]),UsernameValidator.isUnique],
and it works
EDITED:
also I figured out if you want to use multiple async validators in a component use
Validators.composeAsync()
function.
I wrote this component:
#Component({
selector: 'formfield',
template: `
<div>
<label>{{label}}</label>
<div>
<input class="form-control" type="text" [(ngModel)]="model">
</div>
</div>
`
})
export class Formfield {
#Input() label: string;
#Input() model: string;
}
I use it here:
<formfield label="something" model="somevalue"></formfield>
Not surprisingly the input field shows the string "somevalue". How can I make it to hold the value of the variable somevalue?
You need to use the following:
<formfield label="something" [model]="someprop"></formfield>
where someprop is a property of the component that uses the formfield component.
For example:
#Component({
(...)
})
export class SomeComponent {
someprop:string = 'some value';
}
I would like to disable my jQuery button based on form validation. According to the docs this is fairly easy with regular buttons using syntax such as:
<button ng-click="save(user)" ng-disabled="form.$invalid">Save</button>
However, when changing to a jQuery UI button this no longer works. I assume that Angular has no real binding between jQuery UI and AngularJS and thus would require a directive to do the following:
$("button" ).button( "option", "disabled" );
Is that the case or are there other alternatives? A jsFiddle of what I'm trying to do is here: http://jsfiddle.net/blakewell/vbMnN/.
My code looks like this:
View
<div ng-app ng-controller="MyCtrl">
<form name="form" novalidate class="my-form">
Name: <input type="text" ng-model="user.name" required /><br/>
Email: <input type="text" ng-model="user.email" required/><br/>
<button ng-click="save(user)" ng-disabled="form.$invalid">Save</button>
</form>
</div>
Controller
function MyCtrl($scope) {
$scope.save = function (user) {
console.log(user.name);
};
$scope.user = {};
};
$(function () {
$("button").button();
});
Well the thing is with angular, you're supposed to be making directives to apply your JQuery plugins.
So here you could to this:
//NOTE: directives default to be attribute based.
app.directive('jqButton', {
link: function(scope, elem, attr) {
//set up your button.
elem.button();
//watch whatever is passed into the jq-button-disabled attribute
// and use that value to toggle the disabled status.
scope.$watch(attr.jqButtonDisabled, function(value) {
$("button" ).button( "option", "disabled", value );
});
}
});
and then in markup
<button jq-button jq-button-disabled="myForm.$invalid" ng-click="doWhatever()">My Button</button>
This worked for me:
app.directive('jqButton', function() {
return function(scope, element, attrs) {
element.button();
scope.$watch(attrs.jqButtonDisabled, function(value) {
element.button("option", "disabled", value);
});
};
});
With this markup:
<input type="button" value="Button" jq-button jq-button-disabled="myForm.$invalid" />