ngSubmit HTML attribute using angular template variable - html

I have two methods ngMake and ngUpdate. I have one form, PostForm. I want to reuse the same form, but add different functionality depending on the url.
I gain information about the url using
Controller
if ($location.path() === '/makepost') {
$scope.FormTitle = 'Make a Post';
$scope.FormAction = 'server/blog/makepost.php';
$scope.FormMethod = 'POST';
$scope.FormSubmit = "ngMake()"
};
if ($location.path().indexOf('update') !== -1) {
$scope.FormTitle = 'Update a Post';
$scope.FormAction = null;
$scope.FormMethod = 'POST';
$scope.FormSubmit = "ngUpdate()";
};
HTML Form
<div ng-controller="BlogController as blog">
<h3 class="text-center">{{FormTitle}}</h3>
<form ng-show='user != null' ng-submit="{{FormSubmit}}" role="form" class="form-group" name="PostForm">
<label>Title: </label>
<div ng-class="(PostForm.Title.$dirty && PostForm.Title.$invalid) ? 'has-warning' : 'has-success'" class="form-group has-feedback">
<input data-ng-model="post.Title" data-ng-minlength="3" data-ng-maxlength="255" name="Title" type="text" class="form-control" placeholder="Title" required/>
<span ng-class="(PostForm.Title.$dirty && PostForm.Title.$invalid) ? 'glyphicon-warning-sign' : 'glyphicon-ok'" class="glyphicon form-control-feedback"></span>
</div>
<label>Content: </label>
<div ng-class="(PostForm.Content.$dirty && PostForm.Content.$invalid) ? 'has-warning' : 'has-success'" class="form-group has-feedback">
<textarea data-ng-model="post.Content" rows="8" name="Content" type="text" class="form-control" placeholder="Content" required></textarea>
<span ng-class="(PostForm.Content.$dirty && PostForm.Content.$invalid) ? 'glyphicon-warning-sign' : 'glyphicon-ok'" class="glyphicon form-control-feedback"></span>
</div>
<div ng-controller="AuthController as auth">
<input class="ng-hide" type="number" data-ng-model="post.UserID" name="UserID" value="{{user.ID}}">
</div>
<br>
<input type="submit" ng-class="(PostForm.$valid) ? 'btn-success' : 'disabled'" class="btn btn-block btn-default">
</form>
<p ng-show='user == null' class="text-center">You must be logged in in order to {{FormTitle | lowercase}}</p>
Explination
The {{FormSubmit}} template variable probably executes afterwards and causes a problem which doesn't permit the form to execute. I am open to suggestions, I want to reuse the same form. I read that ngSubmit requires a type="submit" button or input element contained within the form tags, I have that. I do not have any ng-clicks which might hinder the form.
I am open to suggestions
If there are any other problems with the form or the entire project please let me know, even if it is just a "bette practice".
The full project
https://github.com/AquaSolid/RAMA_Angular_PHP

Basically, I wised up. I contained the logic in the back-end. I created a function to choose which function to use. Meanwhile the the form contains the attribute ng-submit="chooseSubmit()". That's about it..
$scope.chooseSubmit = function() {
if ($scope.FormSubmit) {
if ($scope.FormSubmit === 'ngMake()') {
$scope.ngMake();
} else {
$scope.ngUpdate();
};
}
};

Related

Reactive Form (Cannot Read property error of null)

Error:
Cannot read property errors of null in form group.
I am creating a reactive form with some validation but i'm getting this error.Below is my whole form control
<div class="container mt-5">
<form
[formGroup] = 'loginForm'
(ngSubmit) = 'onSubmit()'
>
<div class="form-group">
<label>User Name</label>
<input
type="text" class="form-control"
placeholder="Enter User Name"
formControlName = "userName"
[ngClass]="{'is-invalid': (
loginForm.get('userName').dirty &&
!loginForm.get('userName').valid
)}"
>
<span class="invalid-feedback">
<span *ngIf = "loginForm.get('firstName').errors?.required">
Please Enter User Name.
</span>
</span>
</div>
<div class="form-group">
<label>Password</label>
<input
type="password"
class="form-control"
placeholder="Password"
formControlName = "password"
>
</div>
<button
type="submit"
class="btn btn-primary"
[disabled] = "!loginForm.valid">Submit</button>
</form>
{{loginForm.valid}}
Looking at your code, the possible reason for this error seems like you are accessing the firstName formcontrol when it is not defined in the loginForm.
It seems that you have gonna wrong with the formControlName, either it is not added in .ts file or by mistake you have mentioned 'firstName' in the error span
Replace firstName with userName in the error span
Please replace this code -
<span *ngIf = "loginForm.get('firstName').errors?.required">
Please Enter User Name.
</span>
With
<span *ngIf = "loginForm.get('userName').errors?.required"> // Here is the change
Please Enter User Name.
</span>
OMG, one hour working on it, realized I had
this.ContactInfoFG.get('phoneNumberFG') as FormGroup;
instead of
this.contactInfoFG.get('phoneNumberFG') as FormGroup;
Just check the characters for this issue nothing else!
Your solutions helped as well.

requiring min 1 out of 3 form input fields

i am making a database programm where the user has to submit some of his contact information.
<form action="add_action.php" method="POST">
<div class="modal-body">
Name: <br>
<input type="text" name="name" placeholder="Name" required><br>
Telefon Nr. <br>
<input type="text" name="telNr" placeholder="Telefon Nr."><br>
Handy Nr. <br>
<input type="text" name="handyNr" placeholder="Handy Nr."><br>
Skype ID <br>
<input type="text" name="skypeId" placeholder="Skype ID"><br>
<div class="modal-footer">
<input type="submit" class="btn btn-default" value="Hinzufügen">
</div>
</form>
i have been researching a while now, but i cant seem to figure out how i can set the form so at least 1 out of "Telefon Nr.", "Handy Nr." and "Skype ID" is required. if you have any sugestions of what i should do i would apreciate your input.
Consider reading this. I'll be showing, only, how to check for the presence of the field named name alongside at least one field from the others.
Sever side verification:
Ps: you didn't give the submit button a name, i'll give it a name="submit", for example, to make checking for form submission possible within php.
if{isset($_POST["submit"])
// don't rely on HTML required attribute, a user with a bit of knowledge can remove/bypass it, I mean check for the presence of the name either
$name = trim($_POST["name"]);
$telNr = trim($_POST["telNr"]);
$handyNr = trim($_POST["handyNr"]);
$skypeId = trim($_POST["skypeId"]);
if(isset($name[0]) && (isset($telNr[0]) || isset($handyNr[0]) || isset($skypeId[0]))) {
echo "At least one field is present alongside with the name";
} else {
echo "The name and/or the other fields are empty";
}
}
Client side verification:
Ps: let me give an ID to the form tag, let's say id="my-form".
var myForm = document.getElementById("my-form");
myForm.addEventListener("submit", function(event){
// get all the fields values, and trim them on the fly
var name = document.getElementsByName("name")[0].value().trim(),
telNr = document.getElementsByName("telNr")[0].value().trim(),
handyNr = document.getElementsByName("handyNr")[0].value().trim(),
skypeId = document.getElementsByName("skypeId")[0].value().trim();
// we want the name and at least one other field to be filled
if(name !== "" && (telNr !== "" || handyNr !== "" || skypeId !== "" )) {
alert("we're good to go, the name is provided alongside with at least another field");
} else {
event.preventDefault(); // we cancel form submission as the name and/or the other fields are empty using the Event argument
alert("Cancelled, please fill in the name and at least one other field");
}
});
Hope I pushed you further to more understand how things work
Ps: that's a really basic example, don't rely on this in production phase as the code I provided may be vulnerable to some attacks(such as XSS aka Cross-Site-Scripting, SQL injection...).
You'd need to use some javascript to do this. The only thing you can do with HTML is add the "required" attribute as you've done with the name already.
This is the way i created it in a form i made a while back. I have edited it for you so place it in and should work off the bat.
<script>
function validateForm() {
var a,b,c,d = document.forms["form"]["name","telNr","handyNr","skypeId"].value;
if (a,b,c,d==null || a,b,c,d=="")
{
alert("Please complete all Required Fields *");
return false;
}
}
</script>
<body>
<form name="form" action="add_action.php" onsubmit="return validateForm()" method="POST">
<div class="modal-body">
Name: <br>
<input type="text" name="name" placeholder="Name"><br>
Telefon Nr. <br>
<input type="text" name="telNr" placeholder="Telefon Nr."><br>
Handy Nr. <br>
<input type="text" name="handyNr" placeholder="Handy Nr."><br>
Skype ID <br>
<input type="text" name="skypeId" placeholder="Skype ID"><br>
<div class="modal-footer">
<button type="submit" class="btn btn-default" value="Hinzufügen" >Sign In</button>
</div>
</form>

input field or help text doesn't turn red when field is invalid

I used to implement an Angular 2/4 application with Bootstrap 3 and used the Reactive Forms approach. I had a field-validation where the border of the input-field turned red and an error message appeared under the field in red font color.
it looks like this:
<div class="form-group row"
[ngClass]="{'has-error': (sourcesForm.get('sourceName').touched ||
sourcesForm.get('sourceName').dirty) &&
!sourcesForm.get('sourceName').valid }">
<label class="col-md-2 col-form-label"
for="sourceNameId">Source Name</label>
<div class="col-md-8">
<input class="form-control"
id="sourceNameId"
type="text"
placeholder="Source Name (required)"
formControlName="sourceName" />
<span class="help-block" *ngIf="(sourcesForm.get('sourceName').touched ||
sourcesForm.get('sourceName').dirty) &&
sourcesForm.get('sourceName').errors">
<span *ngIf="sourcesForm.get('sourceName').errors.required">
Please enter the Source Name.
</span>
<span *ngIf="sourcesForm.get('sourceName').errors.minlength">
The Source Name must be longer than 3 characters.
</span>
<span *ngIf="sourcesForm.get('sourceName').errors.maxlength">
The Source Name is too long.
</span>
</span>
</div>
</div>
Now i have to use Bootstrap 4 and neither the error message or the input-field turns red. How do i realise this? I tried to change the class of the parent span-block to "form-text" but it didn't work.
For beta version of Bootstrap v4, you can check out Form validation docs. There you can read about the new way, supported by all modern browsers for HTML5 way of form-validation with valid/invalid css classes. There Bootstrap uses the .was-validated and .invalid-feedback classes for what you want to achieve (see code snippet).
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" rel="stylesheet"/>
<form class="container" id="needs-validation" novalidate>
<label for="validationCustom02">Last name</label>
<input type="text" class="form-control" id="validationCustom02" placeholder="Last name" value="Otto" required>
<label for="validationCustom03">City</label>
<input type="text" class="form-control" id="validationCustom03" placeholder="City" required>
<div class="invalid-feedback">
Please provide a valid city.
</div>
<button class="btn btn-primary" type="submit">Submit form</button>
</form>
<script>
// Example starter JavaScript for disabling form submissions if there are invalid fields
(function() {
"use strict";
window.addEventListener("load", function() {
var form = document.getElementById("needs-validation");
form.addEventListener("submit", function(event) {
if (form.checkValidity() == false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add("was-validated");
}, false);
}, false);
}());
</script>
If you want something more similar to Bootstrap 3, you can use what they call server-side validation, as it is written:
As a fallback, .is-invalid and .is-valid classes may be used instead of the pseudo-classes for server side validation. They do not require a .was-validated parent class.
Previous answer for alpha version of Bootstrap V4 (if you must use this).
On Bootstrap V4 Form Validation Docs there is the following example:
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<div class="form-group has-danger">
<label class="form-control-label" for="inputDanger1">Input with danger</label>
<input type="text" class="form-control form-control-danger" id="inputDanger1">
<div class="form-control-feedback">Sorry, that username's taken. Try another?</div>
<small class="form-text text-muted">Example help text that remains unchanged.</small>
</div>
So i think you just need to change the has-error class to has-danger
This is the solution:
<div class="form-group row">
<label class="col-md-2 col-form-label"
for="sourceNameId">Source Name</label>
<div class="col-md-8">
<input class="form-control"
[ngClass]="{'is-invalid': (sourcesForm.get('sourceName').touched ||
sourcesForm.get('sourceName').dirty) &&
!sourcesForm.get('sourceName').valid }"
id="sourceNameId"
type="text"
placeholder="Source Name (required)"
formControlName="sourceName" >
<span class="invalid-feedback" *ngIf="(sourcesForm.get('sourceName').touched ||
sourcesForm.get('sourceName').dirty) &&
sourcesForm.get('sourceName').errors">
<span *ngIf="sourcesForm.get('sourceName').errors.required">
Please enter the Source Name.
</span>
<span *ngIf="sourcesForm.get('sourceName').errors.minlength">
The Source Name must be longer than 3 characters.
</span>
<span *ngIf="sourcesForm.get('sourceName').errors.maxlength">
The Source Name is too long.
</span>
</span>
</div>
</div>
i needed to put the [ngClass]into the input-tag. Then i had to define the class as is-invalid and set the parent span-class to invalid-feedback
i know that your question is for long time ago, but it is the best way to validate the form-control input field by reactive form technique and bootstrap 4 to display the validation. first you need to write some code for your form :
in html section:
<form [formGroup]="myForm">
<div class="form-group">
<label for="name">first Name: </label>
<input type="text" class="form-control" formControlName="firstName" id="name">
<div *ngIf="firstName.touched && firstName.invalid" class="alert alert-danger">
<div *ngIf="firstName.errors.required">filling name is required!</div>
</div>
</div>
in ts file, you should implement the logic to conduct the validation.
in ts file:
myForm = new FormGroup({
'firstName':new FormControl('',Validators.required)
})
//getter method
get firstName(){
this.myForm.get('firstName');
}
now you can see that the validation is working. now to give style to input field to show the red border around the invalid input, just go to css file of component and add this class to the css file:
.form-control.ng-touched.ng-invalid{border:2px solid red;}
and simply you can see the result.

AngularJS validation message and showing no results and results div issue on submit

The following form shows a list of data on submit. I am trying to show no results found when there is no data on submit. I tried like shown below,it shows and hides the div. But when there is no options selected on form and click submit button it shows the no result div.How to show the no results div only when form validation succeeds and there is no data to display.
HTML
<div class="form-group" >
<label class="radio-inline">
<input name="sampleinlineradio" value="3" type="radio" ng-model="radioption"
ng-required="!radioption"> MAIN 1</label>
<label class="radio-inline">
<input name="sampleinlineradio" value="1" type="radio" ng-model="radioption" >
Main 2</label>
<div ng-show="!radioption && buttonClicked">Please select one.</div>
</div>
<div class="form-group">
<label ng-repeat="branch in branches">
<input type="checkbox" name="selectedBranches[]" value="{{branch.value}}"
ng-model="branch.selected" ng-required="isOptionsRequired()" >
{{branch.name}}</label>
<div ng-show="isOptionsRequired() && buttonClicked">Please select one.</div>
</div>
<input type="button" ng-click="fetchresults()" value="submit" >
<div ng-show="buttonClicked">
<table> <thead>.....</thead>
<tbody>
<tr ng-show="results.length!=0" ng-repeat="r in results">
<td></td></tbody></table>
</div>
<div ng-show="buttonClicked">
<span ng-show="results.length==0 ">No results.</span>
</div>
Minimal Controller Code
$scope.fetchresults = function(){
$scope.results = Result.query({main: $scope.radioption, branch: $scope.selection[0], });
$scope.buttonClicked = true;
}
EDIT:
I used model to validate and $valid is also working, as suggested below.But Got a couple of glitches. If i click the button it does not show div. but after validation is over it shows automatically "no results" from the click before. How to stop this.And while it lists data when its available it shows "no results" for a second or so
Give your form a name
<form name="formName">
Then you can do
ng-show="results.length==0 && formName.$valid"
Some more information on angularJS form validation
You can check the below snippet, I have changed most of them in angular way with $invalid, $pristine, $submitted and $valid.
You can check the angular documentation to read about them.
Link 1, Link 2
Note: You can use a submit button and get rid of ng-click event and use ng-submit instead which can't be used in this snippet as form submit is not allowed. Comment the line form.$submitted = true; when you use a submit button.
var app = angular.module('app', []);
app.controller('TestController', function($scope){
$scope.isFieldInvalid = function(field) {
var form = $scope.testForm;
return form[field].$invalid && (!form[field].$pristine || form.$submitted);
};
$scope.fetchResults = function(){
var form = $scope.testForm;
form.$submitted = true; // comment this line if button type="submit"
if(form.$valid){
$scope.searching = true;
$scope.results = [];
var rnd = Math.random();
if(rnd >= 0.5) {
$scope.results = [{id: 1}, {id: 2}];
}
//$scope.results = Result.query({main: $scope.radioption, branch: $scope.selection[0], });
$scope.buttonClicked = true;
$scope.searching = false;
}
};
});
angular.bootstrap(document, ['app']);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<form name="testForm" ng-controller="TestController" ng-submit="fetchResults()" role="form" novalidate="">
<div class="form-group" ng-controller="TestController">
<label class="radio-inline">
<input name="sampleinlineradio" value="3" type="radio" ng-model="radioption" ng-required="true"> MAIN 1</label>
<label class="radio-inline">
<input name="sampleinlineradio" value="1" type="radio" ng-model="radioption" ng-required="true" >
Main 2</label>
<div ng-show="isFieldInvalid('sampleinlineradio')">Please select one.</div>
</div>
<div class="form-group">
<label ng-repeat="branch in branches">
<input type="checkbox" name="selectedBranches[]" value="{{branch.value}}"
ng-model="branch.selected" ng-required="isOptionsRequired()" >
{{branch.name}}</label>
<div ng-show="isOptionsRequired() && buttonClicked">Please select one.</div>
</div>
<input type="button" value="submit" ng-click="fetchResults()" >
<div ng-show="buttonClicked && !searching">
<table> <thead></thead>
<tbody>
<tr ng-show="results.length!=0" ng-repeat="r in results">
<td>{{r.id}}</td></tbody></table>
</div>
<div ng-show="buttonClicked && !searching">
<span ng-show="results.length==0 ">No results.</span>
</div>
</form>

Why wont <button type="submit"> work?

I have a standard HTML form, and the button is not working. I know it is directing to the correct page, and as far as I can see everything looks perfect.
It lets me click the button, but then nothing happens, it doesn't direct me to the send.php page or anything.
<form method="post" action="http://www.URL.net/send.php">
<p>
<label for="name">Name <span class="required">*</span></label>
<input type="text" name="name" id="name">
</p>
<p>
<label for="email">Email <span class="required">*</span></label>
<input type="text" name="email" id="email">
</p>
<p>
<label for="subject">Subject</label>
<input type="text" name="subject" id="subject">
</p>
<p>
<label for="subject">Message <span class="required">*</span></label>
<textarea name="message" id="message" cols="45" rows="10"></textarea>
</p>
<div class="fBtn">
<button type="submit" name="submit" id="submit" class="regButton"><i class="icon-paper-plane"></i>Send Message</button>
</div>
</form>
Also, I have tried using <input type="submit" name="submit" id="submit" class="regButton" value="Send Message" /> as well, but it also isn't working for some odd reason.
Tested in Chrome and IE11.
EDIT Here is the JS for form vaildation:
$('#submit').click(function(){
$('input#name').removeClass("errorForm");
$('textarea#message').removeClass("errorForm");
$('input#email').removeClass("errorForm");
var error = false;
var name = $('input#name').val();
if(name == "" || name == " ") {
error = true;
$('input#name').addClass("errorForm");
}
var msg = $('textarea#message').val();
if(msg == "" || msg == " ") {
error = true;
$('textarea#message').addClass("errorForm");
}
var email_compare = /^[a-zA-Z0-9._-]+#[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/i;
var email = $('input#email').val();
if (email == "" || email == " ") {
$('input#email').addClass("errorForm");
error = true;
}else if (!email_compare.test(email)) {
$('input#email').addClass("errorForm");
error = true;
}
if(error == true) {
return false;
}
var data_string = $('.contactForm form').serialize();
$.ajax({
type: "POST",
url: $('.contactForm form').attr('action'),
data: data_string,
success: function(message) {
if(message == 'SENDING'){
$('#success').fadeIn('slow');
}
else{
$('#error').fadeIn('slow');
}
}
});
return false;
});
You appear to have some JavaScript that automatically submits every form using AJAX. Since you’re on the domain trishajohnson.net, the same-origin policy prevents JavaScript from opening requests to a (slightly) different domain – www.trishajohnson.net.
There’s an easy fix, though – just use the path part. It’s cleaner anyway.
<form method="POST" action="/tj/send.php">