Horizontal Fields - angularjs

Looking at this example: http://angular-formly.com/#/example/bootstrap-specific/advanced-layout
What makes the fields display horizontally? Is it the row class on the field group? Or at the col-xs-6 classes on the individual fields (when looking just at the First/Last name fields)?
I am asking because at my work we are unable to use the twitter bootstrap (arg!) and I am having trouble making fields get on the same lines like this example when not using the bootstrap.
Do you have to use the bootstrap classes in order to get fields on the same row?

CSS. They are wrapped in a div with the col-xs-6 class applied. That class is floated left and has a width of 50%.
.col-xs-6 {
width:50%;
float:left;
}
https://jsfiddle.net/6njkou1g/

Depending on the browser support you need, you might consider this example which doesn't require bootstrap at all and instead uses flexbox to do layout. Otherwise, what Brian said about implementing a subset of bootstrap's grid system yourself wouldn't be too tricky...

Use col-xs-6 for two columns.
<form class="form">
<div class="row">
<div class="col-xs-6">
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1" placeholder="Email">
</div>
</div>
<div class="col-xs-6">
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
</div>
</div>
</div>
</form>
http://jsfiddle.net/rwfje779/

Related

Angular 6: display login form along with controls to the center of the screen

I'm creating a Reactive form in Angular 6.
In typescript file I'm getting the form instance and form controls.
after that iterating through the form controls and printing the user given values.
When do ng serve in the console of the browser I'm getting the error.
Here is the code.
html
<div >
<h2>Login</h2>
<form class='form' [formGroup]='loginForm' (ngSubmit)='onSubmit()'>
<div class="form-group">
<label for="username">Username</label>
<input type="text" class="form-control" id="username"
placeholder="Username"
[ngClass]="{ 'is-invalid': submitted && f.username.errors }"/>
<div *ngIf="submitted && f.username.errors" class="invalid-feedback">
<div *ngIf="f.username.errors.required">Username is required</div>
</div>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" id="password"
placeholder="Password"
[ngClass]="{ 'is-invalid': submitted && f.password.errors }"/>
<div *ngIf="submitted && f.password.errors" class="invalid-feedback">
<div *ngIf="f.password.errors.required">Password is required</div>
</div>
</div>
<div class="form-group">
<label><input type="checkbox"> Remember me</label>
</div>
<div class="form-group">
<button [disabled]="loading" type="submit" class="btn btn-
primary">Login</button>
</div>
My form fields are displaying whole screen. Please see the attached image.
But I want to display all the controls to the center of the screen.
i.e. I need place left,right,top and bottom equal space.
Please help me in solving this issue.
The error throws because of the wrong formGroup name. In the ts file you have created the formGroup name as loginFormGroup and in the html the formGroup name is 'loginForm'. change it like this
<form class='form' [formGroup]='loginFormGroup' (ngSubmit)='onSubmit()'>
give your top most div class suppose makeItCenter and add following css
.makeItCenter {
width: 50rem;
height:100vh;
display:flex;
align-items: center;
justify-content:center;
}
place the whole form tag in
<div class="row">
<div class="col-sm-6 col-lg-offset-3">
set your form here
</div>
</div>
this is simple bootstrap

Angular bootstrap conditionally-required fields

This seems to be very common, yet the solutions for it seem complex.
I've got a section of my form that is optional. If enabled, then its fields are required.
<!-- begin optional section -->
<label>
<h4>Trailer </h4>
<span>( optional </span>
<input class="input-inline" ng-model="hasTrailer" type="checkbox"/>
<span>)</span>
<h4 style="display: inline"> :</h4>
</label>
<div class="form-group">
<label for="trailerNumber"> Number:</label>
<div>
<input
type="text"
name="trailerNumber"
ng-disabled="!hasTrailer"
ng-model="vm.Manifest.Trailer.number"
required />
</div>
<div>
<div
class="error-message"
ng-show="hasTrailer && form.trailerNumber.$invalid && form.trailerNumber.$touched || form.submitted">
<span> Trailer Number is required.</span >
</div>
</div>
</div>
<!-- end optional section -->
So, at the top of the section there is a checkbox, whose model is 'trailer'.
If checked, the fields are required.
What I really want is ideally:
<input type="text" required="hasTrailer">
or maybe
<input type="text" ng-attr({'required':hasTrailer})
i.e. if hasTrailer===true then required=true
You could use ng-required directive which will conditionally make input required when provided expression becomes true.
<input type="text" ng-required="hasTrailer">
You can achieve that by using ngRequired. You can read about it here
It is basically used like this in the html element
<input type="text" ng-required="hasTrailer">
hasTrailer should be a boolean property in the scope.
I was about to go with this option, which does the same thing, but additionally makes the whole section disappear.
<div ng-if="hasTrailer">
<!-- all my optional fields-->
</div>

How can I have two ng-contents in the same template controlled by *ngIf

I have an angular 2 component for displaying a bootstrap 3 button group. The component can either have a label or it can stand alone.
My solution was to use two ng-contents controlled by an *ngIf however, it refuses to display either of the ng-contents and does not throw an error.
Here's btn-multi.html:
<div class="form-group"
*ngIf="label">
<label class="control-label col-lg-2 col-md-3">
{{ label }}
</label>
<div class="col-lg-10 col-md-9">
<div class="btn-group">
<ng-content></ng-content>
</div>
</div>
</div>
<div class="btn-group"
*ngIf="!label">
<ng-content></ng-content>
</div>
And here is how it is used:
<btn-multi label="Some Label"
[(value)]="someValue">
<btn [value]="true">Yes</btn>
<btn [value]="false">No</btn>
</btn-multi>
And this is it working with just the one ng-content:
I'm currently on angular 2 beta-15.
Thanks!
NgIf is getting in the way of including the content since ng-content is being rendered after NgIf is evaluated.
You need to take another approach on it, maybe something like this:
<div [ngClass]="{'form-group': label}">
<label *ngIf="label" class="control-label col-lg-2 col-md-3">
{{ label }}
</label>
<div [ngClass]="{'col-lg-10 col-md-9': label}">
<div class="btn-group">
<ng-content></ng-content>
</div>
</div>
</div>
And there are also even better ways to do it, it all depends on how you want this component to be consumed.
FYI, just did this on the fly so its not tested, but just to give you a general idea.

AngularJS Validation - ng-messages-multiple not displaying multiple errors

All,
I am working on an AngularJS form and am trying to see how the ng-messages directive works with ng-messages-multiple. I can't seem to get it to pick up multiple errors. I expect to see both the required and minimum errors at the same time but for some reason I only see required, then minimum. I posted the HTML below. I have the ng-messages included using bower, the script call in my index.html page, and I am injecting into my app.js module as required.
I am using AngularJS v1.3.2 in this project.
<div class="panel panel-default">
<div class="panel-heading">
<h1>Validation Test Form</h1>
</div>
<div class="panel-body">
<form class="form" name="form" role="form" ng-submit="submit(form)">
<div class="row">
<div class="form-group" show-errors>
<label for="name">Name:</label>
<input
class="form-control"
type="text"
name="name"
ng-model="formModel.name"
minlength="5"
required/>
<div ng-messages="form.name.$error" ng-messages-multiple class="has-error">
<div ng-message="required">Required!</div>
<div ng-message="minlength">Minimum length is 5</div>
</div>
</div>
</div>
<div class="row">
<div class="form-group">
<button class="btn btn-success" type="submit">Save</button>
</div>
</div>
</form>
</div>
<div class="panel-footer">
{{formError}}
</div>
</div>
Try to use ng-minlength instead minlength
<input
class="form-control"
type="text"
name="name"
ng-model="formModel.name"
ng-minlength="5"
required/>
instead
<input
class="form-control"
type="text"
name="name"
ng-model="formModel.name"
minlength="5"
required/>
EDIT
It is normal behaviour for ng-minlength directive, this directive validate only when we have not 0 size of input, entered a value it must be at least 5 characters long, but it's ok to leave the field empty, and, unfortunately, in anyway you don't achieve, that you want. I offer you to create your custom directive or see in direction ng-pattern directive with need behaviour, if you very want that showing two message.

Unique identifiers in dynamic form (ng-repeat)

I have a form with input texts that are looped in a ng-repeat.
For every input field there is a switch with which the user sets "Use default value" to YES/NO.
Every row of input fields are basically two fields, with one hidden one at a time, whether you want to show the default value (switch: YES, input text = disabled) or set a custom value (switch: NO)
I need each element to have a unique identifier to be able to save it on submit, for example **id="title_{{spec.id}}".
The switches work so that the switch-variable is used to create 2way binding, but it is the value of the checkbox within the Switch-DIV that will be saved to the database.
What I think I need to do is apply the spec.id value to the switch-variable="useDefaultValue_{{spec.id}}" and set the same value to the ng-show="useDefaultValue_{{spec.id}}" and ng-hide, but I don't know how to.
HTML:
<div class="row form-group" ng-repeat="spec in specsList">
<div class="col-xs-6 col-md-6">
<label for="specification_">{{spec.title}} <span ng-show="spec.unit.length">({{spec.unit}})</span></label>
<input class="form-control" type="text" name="title_{{spec.id}}" id="title_{{spec.id}}" placeholder="Not visible" ng-model="spec.value" ng-hide="useDefaultValue">
<input class="form-control" type="text" ng-model="spec.defaultValue" ng-show="useDefaultValue" disabled>
</div>
<div class="col-xs-6 col-md-6">
<label for="useDefaultValue_">Use default value</label> - {{spec.useDefaultValue}}<br />
<div class="switch" init-switch switch-variable="useDefaultValue">
<input type="checkbox" id="useDefaultValue_{{spec.id}}" name="useDefaultValue_{{spec.id}}" ng-model="spec.useDefaultValue">
</div>
</div>
</div>
Since your checkbox is backed by the row-dependent spec.defaultValue, you can come up with a simpler solution and don't need the switch. Just reference spec.useDefaultValue instead of your current useDefaultValue to directly access it.
<div class="row form-group" ng-repeat="spec in specsList">
<div class="col-xs-6 col-md-6">
<label for="specification_">{{spec.title}} <span ng-show="spec.unit.length">({{spec.unit}})</span></label>
<input class="form-control" type="text" name="title_{{spec.id}}" id="title_{{spec.id}}" placeholder="Not visible" ng-model="spec.value" ng-hide="spec.useDefaultValue">
<input class="form-control" type="text" name="title_{{spec.id}}" id="title_{{spec.id}}" ng-model="spec.defaultValue" ng-show="spec.useDefaultValue" disabled>
</div>
<div class="col-xs-6 col-md-6">
<label for="useDefaultValue_">Use default value</label> - {{spec.useDefaultValue}}<br />
<input type="checkbox" ng-model="spec.useDefaultValue">
</div>
</div>
As an aside, I would also use ng-if instead of ng-show and ng-hide to lighten the page and make the transitions smoother.
EDIT Submit function :
$scope.submit = function() {
angular.forEach(specsList, function(spec, index) {
if (spec.useDefaultValue) {
$scope.user[spec.title] = spec.defaultValue;
}
else {
$scope.user[spec.title] = spec.value;
}
});
User.save(user).$promise.then(function(persisted) {
// do some post-save cleanup
});
};
Of course, this is assuming you save spec values on the user. They could be stored somewhere else.

Resources