Custom Directive for Required/ngRequired - html

I want to validate a dropdown with required. Default required only works if value is null or blank (correct me if I'm wrong). I want required to give error and make form invalid true if value is 'not assigned'.
<select name="first" class="select" title="Select Approver" ng-model="applications.first" ng-options="x.id as x.value for x in list1" ng-change="SetToAll(applications.first,'1')" required></select>
Using this I can show error message but this does make form invalid
<span class="error" ng-show="applications.first == 'not assigned'?true:false">Select Approver</span>
SOLUTION:-
1) If you want to use required then Check Shannon Hochkins solution.
<form name="formName">
<select name="first" class="select" title="Select Approver" ng-model="applications.first" ng-options="x.id as x.value for x in list1" ng-change="SetToAll(applications.first,'1')" required="true">
<option value="">Not Assigned</option>
</select>
<span class="error" ng-show="formName.first.$invalid ?true:false">Select Approver</span>
<pre>{{formName | json}}</pre>
</form>
He Added a option with blank value <option value="">Not Assigned</option>. and set required="true" in select. This works perfectly.
2) Using custom directive.
app.directive('req', [
function() {
var link = function($scope, $element, $attrs, ctrl) {
var validate = function(viewValue) {
var comparisonModel = $attrs.req;
var invalid = $attrs.invalid;
if (viewValue == invalid) {
// It's valid because we have nothing to compare against
ctrl.$setValidity('req', false);
} else {
ctrl.$setValidity('req', true);
}
};
$attrs.$observe('req', function(comparisonModel) {
// Whenever the comparison model changes we'll re-validate
return validate(ctrl.$viewValue);
});
};
return {
require: 'ngModel',
link: link
};
}
]);
And Your html code :
<select invalid="not assigned" req={{applications.first}} name="first" class="select" ng-model="applications.first" ng-options="x.id as x.value for x in list1" title="Select Approver" ></select>
<span class="error" ng-show="Step5.first.$error.req">Select Approver</span>
Here you will have to set invalid="not assigned" or any value like invalid='0' or invalid=' '. In directive it compares with invalid attribute if value matches it will show error.

Add the required value to the select element, then you can use the FORM object to check if the field is valid or not.
You can also use the forms name, to access fields in the form to check validity.
If you want to add a 'default' option, to the dropdown, you can add in an option with an empty value which is technically invalid on a required dropdown menu. You can choose to hide it if it is valid so the user can't pick it again after a correct option has been chosen.
<form name="formName" ng-controller="testCtrl">
<select name="first" ng-options="x.id as x.value for x in list1" ng-model="applications.first" required>
<option value="" ng-hide="formName.first.$valid">Not Assigned</option>
</select>
<pre>{{formName.first.$invalid | json}}</pre>
</form>
Inside your controller, setup some options:
angular.module('sandbox', []).controller('testCtrl', function($scope) {
$scope.list1 = [{
id: 1,
value: 'apples'
}, {
id: 2,
value: 'oranges'
}];
});
Demo: https://jsfiddle.net/suunyz3e/304/

Related

Get id and value from selected Dropdown

i need id and value from selected dropdown. i tried things but not getting id, only value is coming. how do i get both id and value?
below is my code
.html
<div class="form-group">
<label>Item</label>
<select id='itemCode' name="" class="form-control">
<option value="" disabled selected>Choose Item</option>
<option *ngFor="let itemValue of itemslistvalue"
[ngValue]="{id: itemValue.itemCode, name: itemValue.itemName}">
{{itemValue.itemName}}
</option>
</select>
</div>
<div class="form-group"><br>
<button type="button" (click)="add()" style=" margin-left:10px;"></button>
</div>
.TS
add() {
var itemName = (<HTMLInputElement>document.getElementById('')).value;
var itemCode = (<HTMLInputElement>document.getElementById('')).value;
if (itemName !== null && itemName !== '' && itemCode !== null && itemCode !== '') {
this.newDynamic = { itemCode: itemCode, ItemName: itemName };
console.log(this.newDynamic);
this.dynamicArray.push(this.newDynamic);
return true;
}
}
just use a variable and ngModel
//In .ts
item:any=null;
<select id='itemCode' [(ngModel)]="item" name="" class="form-control">
<!--see that by defect is [ngValue]="null"-->
<option [ngValue]="null" disabled hidden>Choose Item</option>
...
</select>
And you has stored in item the value
You can call to change if it's necesary separate the [(ngModel)]
<select id='itemCode' [ngModel]="item"
(ngModelChange)="item=$event;doSomething($event)" name="" class="form-control">
...
</select>
//in your .ts
doSomething(item:any){
console.log(item);
}
If you don't want store the variable, use a template reference
<select #itemId id='itemCode' (change)="doSomething(itemId.value)"
name="" class="form-control">
...
</select>
If you use a template reference variable, you only can get the "value" of the select (in this case only the name)
<select #itemId id='itemCode' (change)="doSomething(itemId.value)"
name="" class="form-control">
...
</select>
doSomething(item:string){
console.log(item); //<--it's only the "name"
}
a stackblitz
the referecences:
about ngModel
about template reference variables
Update if we want to add a new element to the array, we declare two variables
newItemName:string=null;
newItemCode:string=null;
And in our .html
<input [(ngModel)]="newItemName">
<input [(ngModel)]="newItemName">
<button (click)="add()">Add</button>
Before the funciton add we need take account that when we use a select with store an object. WE can take two approach
1.-use a function compare, is only write some like
compareFn(a,b){
return !a && !b ||(a && b && a.itemCode==b.itemCode)
}
//or in abreviate mode:
compareFn=(a,b)=>!a && !b ||(a && b && a.itemCode==b.itemCode)
And in .html our select like:
<select [(ngModel)]="item" .. [compareWith]="compareFn">
2.- use the own elements of the array
<option *ngFor="let itemValue of itemslistvalue"
[ngValue]="itemValue">
{{itemValue.itemName}}
</option>
But in this case we need equal to an object of an array, e.g.
item=itemslistvalue[2]
Well, our function add, can use the values of the variables. this is the significance of two-binding-way, the value of the variable is in the input, when change the input the variable change
add() {
//see that inside a function you use "this"
if (this.newItemName && this.newItemCode) {
//if only want to add value if there no selecte any thing
//replace by
// if (this.newItemName && this.newItemCode && !this.item ) {..}
//try to find one with the same code
const item = this.itemslistvalue.find(
x => x.itemCode == +this.newItemCode
);
if (!item) { //if not find
//add
this.itemslistvalue.push({
itemCode: +this.newItemCode,
itemName: this.newItemName
});
//if we want that the select gets the value added
this.item = this.itemslistvalue[this.itemslistvalue.length - 1];
} else {
this.item = item; //just equal the element found
}
}
}
.Html
<div class="form-group">
<label>Item</label>
<select id='itemCode' name="" class="form-control">
<option value="" disabled selected>Choose Item</option>
<option *ngFor="let itemValue of itemslistvalue"
[ngValue]="{{{itemValue | json}}}">
{{itemValue.itemName}}
</option>
</select>
.Ts
add() {
var itemName = (<HTMLInputElement>document.getElementById('itemCode')).value;
console.log(itemName);
let myObj = JSON.parse(itemName);
itemCode = myObj.itemCode;
itemName = myObj.itemName;}

Make "name" not appear on url using a <select>

I'm writing a simple form, but I've encountered a problem. The form must generate an url like this
https://website.com/properties/hotelvinadelmar?locale=es&check_in_date=22-03-2019&check_out_date=25-03-2019&number_adults=4&number_children=9
The part after /properties/ (in this case, "hotelvinadelmar") is a code for an especific hotel, while the rest is the information the customer provide to check if there's availability.
I wrote this form:
Sucursal: <br>
<select name="test" id="id" required>
<option value="hotelvinadelmar?locale=es">Viña del Mar</option>
<option value="hotelsantiago1?locale=es">Nueva Providencia</option>
<option value="hotelsantiago2?locale=es">Providencia</option></select>
<br><br>
</select>
this almost work, but generates an url like this (...)/properties/?test=hotelvinadelmar?locale=es&number_adults=1(...)
Which is creating an url structured like this
[form action (the url I entered)][Option Name][selected Option Value]
But the thing must be like this
[form action (the url I entered)][selected Option Value]
How can this be achieved? Thanks in advance!
this is the correct behavior because the submitted form data test=hotelvinadelmar will be added after the URL
(...)/properties/, in order the achieve the desired result you can try to add action attribute to your form as <form action="/hotel"> and change the select as:
<select name="hotelname" required>
<option value="hotelvinadelmar">Viña del Mar</option>
<option value="hotelsantiago1">Nueva Providencia</option>
<option value="hotelsantiago2">Providencia</option></select>
<br><br>
</select>
the generated link will be: (...)/properties/hotel?name=hotelvinadelmar(...)
or you can use a javascript function with onSubmit event, for example:
<script>
function submitForm(){
var hotelName = document.getElementById('hotelName').value;
var param1Value = document.getElementById('id').value;
switch(hotelName) {
case 'hotelvinadelmar':
window.location.href = '/hotelvinadelmar?param1=' + param1Value + '&param2=' + (...);
break;
case 'hotelsantiago1':
window.location.href = '/hotelsantiago1?param1=' + param1Value;
break;
}
// stop submit
return false;
}
</script>
<form onsubmit="submitForm()" method="get">
<select id="hotelName" required>
<option value="hotelvinadelmar">Viña del Mar</option>
<option value="hotelsantiago1">Nueva Providencia</option>
<option value="hotelsantiago2">Providencia</option></select>
</select>
<input type="submit" value="submit"/>
</form>
Capture the submission event and update the form action attribute to append the hotel name to the submission path:
document.forms[0].addEventListener("submit", function (evt) {
let ff = evt.target;
ff.action = "/properties/" + ff.hotelname.options[ff.hotelname.selectedIndex].value;
});
You'll need remove the locale property from your select input. Simply add a hidden form element (or selectable option) to your form:
<input type="hidden" name="locale" value="es">
An example url:
https://website.com/properties/hotelvinadelmar?locale=es&hotelname=hotelvinadelmar&val1=one&val2=two
Here's a demonstration how the form action attribute can be updated:
document.forms[0].addEventListener("submit", function (evt) {
evt.preventDefault(); // demonstration only
let ff = evt.target;
ff.action = "/properties/" + ff.hotelname.options[ff.hotelname.selectedIndex].value;
console.log(ff.action); // demonstration only
return false; // demonstration only
});
<form action="/properties/" method="get">
<input type="hidden" name="locale" value="es">
Sucursal:
<select name="hotelname" id="id" required>
<option value="hotelvinadelmar">Viña del Mar</option>
<option value="hotelsantiago1">Nueva Providencia</option>
<option value="hotelsantiago2">Providencia</option>
</select>
<input type="hidden" name="val1" value="one">
<input type="hidden" name="val2" value="two">
<input type="submit">
</form>

Required attribute with tag select doesn't work

I tried with required="true" and with th:required="required" and using only required(this throws an error since i am using thymeleaf), added the empty value value="",but still doesn't work.I tried added value="dumb" and value="" for the second option tag, same...doesn't work and tried using bootstrap validator.When I submit the form I have an pop-up, if I press OK then form is submitted.
I am using chrome and I have another form where I am using input + required and there it's working.
Any help will be appreciated. Thanks!
<form th:action="#{/appointment/create}" method="post" id="appointmentForm">
<div class="form-group">
<label for="location">Alege institutia:</label>
<select class="form-control" required="required"
th:value="${appointment.institutie}"name="institutie"
id="institutie">
<option value="" disabled="disabled" selected="selected" >
-- alege institutia --</option>
<option th:each="institutie : ${institutieList}"
th:text="${institutie.numeInstitutie}" ></option>
</select>
</div></form>
var confirm = function() {
bootbox.confirm({
title : "Confirmare programare",
message : "Doriti sa creeati programarea?",
buttons : {
cancel : {
label : '<i class="fa fa-times"></i> Nu'
},
confirm : {
label : '<i class="fa fa-check"></i> Da'
}
},
callback : function(result) {
if (result == true) {
$('#appointmentForm').submit();
} else {
console.log("Confirmare anulata.");
}
}
});
};
UPDATE
The controller which takes care to populate the "institutieList"
#RequestMapping(value="/create", method=RequestMethod.GET)
public String createAppointmentPost(Model model, #ModelAttribute("city")
City city, #ModelAttribute("agency") Agency agency, Principal principal){
User user = userService.findByUsername(principal.getName());
Appointment appointment=new Appointment();
model.addAttribute("appointment", appointment);
model.addAttribute("dateString", "");
model.addAttribute("cities", cityService.findAll());
model.addAttribute("institutieList", instituteService.findAll());
model.addAttribute("myFiles", userService.listAllUploadedFiles(user));
return "appointment";
}
UPDATE 2:
The problem was with the submit button, I've forgot type="submit".
The correct usage for required isn't required="true" but only required, like so:
<select class="form-control" required
th:value="${appointment.institutie}"name="institutie"
id="institutie">

Datapickers cmp with today to exe jQuery code

I have created this code:
<div class="option">
<label for="date">Date de debut de reservation</label>
<input type="date" id="datepickerFrom" ui-date="dateOptionsFrom" ng-model="datepickerFrom" class="form-control ng-empty hasDatepicker ng-touched ng-dirty ng-valid-parse ng-invalid ng-invalid-ui-date-validator" name="datepickersFrom" placeholder="dd/mm/yyyy" min="<?php echo $today; ?>" required>
<script>
var today = new Date().toISOString().split('T')[0];
document.getElementsByName("datepickersFrom")[0].setAttribute('min', today);
</script>
</div>
I want to compare the date selected with date of today.
If it is the case that today's day is selected I would like to run this code below:
$("#exptype").append('<option value="fast" selected>Ultra-express 1 heure</option>');
otherwise if today's date is not selected, I would like to execute this code:
$("#exptype").append('<option value="stand">Livraison standard 24-48h</option>');
How can I do that?
You are using angular, right? I presume this given that you have the ng-model attribute set on your date input. If that is the case, you can use the angular controller to handle this - see example below.
Also, presuming you are using angular, then you could look at using the angular date picker controls for a richer/more robust UI control...
angular.module('myApp',[]).controller('dateController',function($scope) {
var today = new Date().toISOString().split('T')[0];
$scope.datepickerFrom = today;
$scope.todaySelected = true;
//this replaces that line you had:
//document.getElementsByName("datepickersFrom")[0].setAttribute('min', today);
$scope.minDate = today;
//when the date changes, store a boolean in our controller scope, to be used in the filter function below
$scope.dateChanged = function() {
$scope.todaySelected = ($scope.datepickerFrom == today);
};
//define our options - please adjust for your needs
$scope.expTypeOptions = [
{ value: "four hours", text: "4 heure" },
{ value: "fast", text: "Ultra-express 1 heure" },
{ value: "stand", text: "Livraison standard 24-48h" },
];
//this function handles showing the expType options in the select list,
//based on the selected date
$scope.filterOptionsByDate = function(expType) {
if ($scope.todaySelected) { //hide the 'stand' option
return expType.value != "stand";
}
else { //otherwise show everything except the 'fast' option
return expType.value != "fast";
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="option" ng-app="myApp" ng-controller="dateController">
<label for="date">Date de debut de reservation</label>
<input type="date" id="datepickerFrom" ui-date="dateOptionsFrom" ng-model="datepickerFrom" class="form-control ng-empty hasDatepicker ng-touched ng-dirty ng-valid-parse ng-invalid ng-invalid-ui-date-validator" min="{{ minDate }}" ng-change="dateChanged()" name="datepickersFrom" placeholder="dd/mm/yyyy" required >
<div>
<select ng-model="expType" ng-options="expType.text for expType in expTypeOptions | filter:filterOptionsByDate">
</select>
</div>

How i should set javascript global variable to get its value properly

I have two html elements on my page. One is dropdown and other is text field(which is working as autocomplete).
<select id="match_engine_brand" name="match_engine[brand]" class="hidden-field"><option value="">Select Brand</option><option value="3">addidas</option>
<option value="5">cat</option>
<option value="2">nike</option>
<option value="4">panther</option>
<option value="6">tower</option></select>
while text field is
<input class="string required ui-autocomplete-input" id="match_engine_shoe_model" name="match_engine[shoe_model]" placeholder="select model of shoe using autocomplete" required="required" size="50" type="text" autocomplete="off">
My cofeescript code is below
$(document).ready ->
$("#match_engine_brand").change ->
window.flag_value = $(this).val()
alert(window.flag_value) #value display in alert
$('#match_engine_shoe_model').autocomplete
source: "/user/match_shoes/shoes?id="+window.flag_value
select: (event, ui) -> $("#match_engine_shoe_model").val(ui.item.id)
In autocomplete function
window.flag_value #give me undefined value
$('#match_engine_brand :selected').val() #give me undefined value
How i can get dropdown value in autocomplete function.
Thanks for help
You need to have an initiated value of window.flag_value. Otherwise if you don't change #match_engine_branch, this var has no value. That's the reason of undefined value.
The way to solve it is to define this var before
$(document).ready ->
window.flag_value = "something"
...
However I think it's unnecessary to use global var. Check it in function should work.
$('#match_engine_shoe_model').autocomplete ->
dropdown_value = $("#match_engine_brand").val() ? "something"