how to access element in directive? - html

I have a html page in which there is a directive(child html) inside as below. I want to do input validation of input1 and input2 in directive(child html) for the button in parent html, but I don't know how I can access the input1 and input2 in child (directive). I would like to know what is the right way to access input1 and input2? Thanks in advance!!
Parent html:
<div>
<child></child>
<button name="myButton" ng-disabled="????.myForm.input1.$invalid"><button>
</div>
Directive: child
<form name="myForm">
<input name="input1" required/>
<input name="input2" required/>
</form>

Try this:
Parent controller:
vm.myForm = {};
Parent Html:
<child my-form="vm.myForm"></child>
<button name="myButton" ng-disabled="vm.myForm.input1.$invalid"><button>
Child directive:
scope: {
myForm: "="
}
Child HTML:
<form name="myForm">
<input name="input1" required/>
<input name="input2" required/>
</form>

You can $emit event to your parent controller and pass needed data.
Directive:
$scope.$emit('yourCustomEvent', 'Data to send');
And catch the event in you parent controller.
Parent controller:
$scope.$on('yourCustomEvent', function (event, data) {
console.log(data); // will print "Data to send"
});
And in your case I advice you to include the button in your directive, it will be much easier to work with it.

Related

How to convert jQuery UI controls to Form element contract?

I put slider into form but found it doesn't send it's value as get parameter
https://jsfiddle.net/dimskraft/284x06da/3/
Neither slider id not slider value appear in action url. Why and how to fix?
One way to fix it would be to have a hidden input field in the form and update its value based on slider's change event.
Here, I have added input field with name input1 so you would see that in the final URL. Also, you can assign its initial value with value attribute. I have given value="0"
https://jsfiddle.net/fhp81qyb/
$( "#slider" ).slider({
change: function( event, ui ) {
$('#input1').val(ui.value);
}
});
<input type="hidden" name="input1" id="input1" value="0"></input>
Slider is not a form element; hence it is not included in the form data.
Example: https://jsfiddle.net/Twisty/qfbgh0z4/5/
HTML
<form action="http://localhost" method="get" target="_blank">
<div id="slider"></div>
<input type="hidden" name="slider-value" id="slider-value" value="0" />
<input type="submit" value="Submit">
</form>
JavaScript
$(function() {
$("#slider").slider({
slide: function(e, ui) {
$("#slider-value").val(ui.value);
}
});
});

Angular FormControl on <input> displays [object Object]

Using Angular 7.
Have an <input> tag like the following:
<input id="foo" type="text" class="bar" [formControlName]="'product'"
autocomplete="off [ngModel]="formGroup.controls.product.value" [readOnly]="true"/>
Eventually, myControl.setValue('some string'); is called.
The result is the <input> element displays [object Object].
I am trying to display the string from the setValue() call.
What am I doing incorrectly?
try like this you don't need to use [ngModel] you set product control directly
<div [formGroup]="form">
<input id="foo" type="text" class="bar" formControlName="product"
autocomplete="off" [readOnly]="true"/>
<button (click)="update()">Update</button>
</div>
component
form:FormGroup;
constructor(fb:FormBuilder) {
this.form = fb.group({
product:'init data'
});
}
update(){
this.form.get('product').setValue('Updated...')
}
demo 🚀
incase you just have single form control you have to use [formControl] directive
<input id="foo" type="text" class="bar" [formControl]="myControl"
autocomplete="off" [readOnly]="true"/>
<button (click)="update()">Update</button>
component
myControl:FormControl
constructor() {
this.myControl = new FormControl('init data')
}
update(){
this.myControl.setValue('Updated...')
}
demo 🌟
Remove the [ngModel] section of the input, that isn't needed if you're using formControlName as well.
When setting the value, we can't see how you're specifying myControl but the equivalent code would be:
this.formGroup.controls['product'].setValue('my string');

How do you get a value from a text field?

I suppose this should be straightforward, but I'm stuck to get that "cpsc" value. I tried to google this, and almost all of the search results told me to use ".value". But this particular class "control term" doesn't seem to work, and only returned "undefined".
<div class="control term">
<input type="text" value="cpsc">
</div>
My code:
document.getElementsByClassName("control term")[0].value;
You are reading from the div. You should read from input instead.
<div class="control term">
<input id="inputTag" type="text" value="cpsc">
</div>
document.getElementsBYId("inputTag").value;
The problem is that the class "control term" is on the div element and not your input. Also as a note, a class should be only one word (ie. controlTerm), having a space between them assigns two different classes to the div: control, and, term.
You have two options:
Add a class to your input
Get the child of document.getElementsByClassName("control term") and then extract its value.
Hope this helps
<div class="control">
<input class="term" type="text" value="cpsc">
</div>
document.getElementsByClassName("term")[0].value;
<div>
<input type="text" value="cpsc" class="control term">
</div>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction() {
alert(document.getElementsByClassName("control term")[0].value);
}
</script>
You have to put class attribute in input tag
You need to add class to your input and then you can get the value of input using the following code.
<div class="control term">
<input type="text" class = "test" value="cpsc">
</div>
<button onclick = "myFunction()">Click me</button>
<script>
function myFunction(){
alert(document.getElementsByClassName("test")[0].value);
}
</script>
If you have multiple input box with same class name inside "control term" div, you can access their values using following code.
<div class="control term">
<input type="text" class = "test" value="cpsc">
<input type="text" class = "test" value="cpsc1">
</div>
<button onclick = "myFunction()">Click me</button>
<script>
function myFunction(){
alert(document.getElementsByClassName("test")[0].value);
alert(document.getElementsByClassName("test")[1].value);
}
</script>
Or if you want to get all values of input box inside "control term" div, you can do something like this.
<div class="control term">
<input type="text" class = "test" value="cpsc">
<input type="text" class = "test" value="cpsc1">
</div>
<button onclick = "myFunction()">Click me</button>
<script>
function myFunction(){
var x = document.getElementsByClassName("control term");
for(var i = 0;i<=x.length;i++){
alert(x[0].getElementsByClassName("test")[i].value);
}
</script>
Hope this will help you.

HTML 5 pattern not working for onclick event of button

In a page, for getting field values I didn't use form tag, instead used Anchor tag's click event to get the values and used AJAX call to pass it to server.
Later tried out the HTML 5 pattern validation, it didn't work out; after so much try added form tag and then modified "anchor" to "button", then it worked.
Old
<div id="div1">
<input type="text" id="message" pattern="[a-zA-Z]{3}" required title="Enter valid Station" />
<a id="add" onclick="addMessage();">Add</a>
</div>
New
<form id="addMessage">
<div id="div1">
<input type="text" id="message" pattern="[a-zA-Z]{3}" required title="Enter valid Station" />
<button id="add">Add</button>
</div>
</form>
Is using a form tag and form submission the only way to trigger Pattern validation or are there any workarounds?
There's a nice overview of constraint validation in HTML5 on HTML5Rocks.
You can manually validate fields by calling the checkValidity() method on the DOM element in JavaScript:
document.getElementById('add').addEventListener('click', function() {
if (document.getElementById('message').checkValidity()) {
window.alert('valid station name');
// addMessage();
} else {
window.alert('invalid station name!');
}
});
<div id="div1">
<label>
Station
<input type="text" id="message" pattern="[a-zA-Z]{3}" required title="Enter valid Station" maxlength="3">
</label>
<a id="add" role="button">Add</a>
</div>
And also for reference: HTMLInputElement

ng-model vs ngModel - breaks form

New to angular, new to life:
I have a small email form.
This works:
<form method="post" name="form" role="form" ng-controller="contactForm" ng-submit="form.$valid && sendMessage(input)" novalidate class="form-horizontal">
<p ng-show="success"><b>We received your message</b></p>
<p ng-show="error">Something wrong happened!, please try again.</p>
<label for="name">Name:</label><br>
<input type="text" id="name" name="name" ng-model="input.name" required><br>
<label for="email">Email:</label><br>
<input type="email" id="email" name="email" ng-model="input.email" required><br>
<label for="messsage">Message:</label><br>
<textarea id="messsage" name="message" ng-model="input.message" ngMaxlength='2000' required></textarea><br>
<button type="submit" name="submit" ng-disabled="error" value="submit">Submit</button>
</form>
This does not work:
<form method="post" name="form" role="form" ng-controller="contactForm" ng-submit="form.$valid && sendMessage(input)" novalidate class="form-horizontal">
<p ng-show="success"><b>We received your message</b></p>
<p ng-show="error">Something wrong happened!, please try again.</p>
<label for="name">Name:</label><br>
<input type="text" id="name" name="name" ngModel="input.name" required><br>
<label for="email">Email:</label><br>
<input type="email" id="email" name="email" ngModel="input.email" required><br>
<label for="messsage">Message:</label><br>
<textarea id="messsage" name="message" ngModel="input.message" ngMaxlength='2000' required></textarea><br>
<button type="submit" name="submit" ng-disabled="error" value="submit">Submit</button>
</form>
for the 2 inputs and the textarea if I use 'ng-model' the email sends, but when the page loads, the form loads invalid.
If i use 'ngModel' the form loads clean, but the email wont submit.
controller here:
app.controller("contactForm", ['$scope', '$http', function($scope, $http) {
$scope.success = false;
$scope.error = false;
$scope.sendMessage = function( input ) {
$http({
method: 'POST',
url: 'processForm.php',
data: input,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})
.success( function(data) {
if ( data.success ) {
$scope.success = true;
$scope.input.name="";
$scope.input.email="";
$scope.input.message="";
} else {
$scope.error = true;
}
} );
}
You can see it live here:
http://smartestdiner.com/Bethel/indexx.html#/contact
Warning:
There is some annoying red background
.ng-invalid{
background-color:red;
}
}]);
That's how we know it is loading invalidly.
The annoying red background is the form, since you have a very generic rule set by .ng-invalid, the class will be set on the form as well. You would need to make it more specific for the inputs and controls within the form.
Example:
input.ng-invalid,
textarea.ng-invalid {
background-color:red;
}
Or just reset rule for form.ng-invalid
To add on there is nothing called ngModel it is ng-model. using the former one doesn't do anything but adds a dummy attribute on the element, it has no effect. It is angular way of directive naming, since html is case insensitive the one way angular can identify the directive from attribute or element name (based on the restriction). It converts it to camelCasing to evaluate and process respective directive (or directives attribute bindings). When you do not have ng-model specified and if the form or control does not have novalidate attribute, then the browser's HTML5 validation kicks in that is what you see as inconsistency. Using HTML5 novalidate attribute makes sure no native validation happens on the form.
ng-model is when u write the view (html part).
ngModel is used when one write a custom directive. It is placed in the "require:" param so that u can access,
variables like ngModel.$modelValue
ngModel.$modelValue will have the latest content which has been typed by the user at realtime. So, it can be used for validations, etc.
View code:-
<!doctype html>
<html ng-app="plankton">
<head>
<script src="/bower_components/angular/angular.min.js"></script>
<script src="/scripts/emailing/emailing.directive.js"></script>
</head>
<body ng-controller="EmailingCtrl">
<div>
<label>Enter Email: </label>
<emailing id="person_email" ng-model="email_entered"></emailing>
</div>
</body>
</html>
Custom directive:-
(function() {
'use strict';
angular.module('plankton', [])
.directive('emailing', function emailing(){
return {
restrict: 'AE',
replace: 'true',
template: '<input type="text"></input>',
controllerAs: 'vm',
scope: {},
require: "ngModel",
link: function(scope, elem, attrs, ngModel){
console.log(ngModel);
scope.$watch(function(){ return ngModel.$modelValue;
}, function(modelValue){
console.log(modelValue);//awesome! gets live data entered into the input text box
});
},
};
})
.controller('EmailingCtrl', function($scope){
var vm = this;
});
})();
This has been plunked here:- here