How to have a dynamic show/hide & required/not required control (angularjs) - html

i'm trying to have a dynamic part of my form starting from a value i get from a http call (and later a select).
The form is supposed to be required. That means every single input should be required. Of course, if the value i check on is not the "right" one, a part of the form should be hided and the inputs should be set as non-required (otherwise I can't save the data).
I already did it when the first value arrives (from the http, i just check the value and change the show/hide & required/not required part), but I can't do it on a select (the http value and the select are quite similar, but the select should be full dynamic).
I just don't understand why, the mechanic should be exactly the same.
Here the html part:
This is the static value (from http call)
<div class="form-group col-sm-12">
<label class="form-control-label">Classificazione 1</label>
<br />
{{picture.PictureClass.Class}}
</div>
And the rest
<span id="showDiv" ng-show = "false">
<div class="row">
<div class="form-group col-sm-12" ng-class="{ 'has-error' : formPicture.ReportingDetail.$invalid && formPicture.ReportingDetail.$touched}">
<label for="ReportingDetail" class="form-control-label">Analisi Segnalazione</label>
<select ng-disabled="accessLevelStatus() < 2"
class="form-control" name="ReportingDetail"
id="ReportingDetail" placeholder="ReportingDetail"
ng-model="picture.ReportingDetail">
<option value=""></option>
<option value="Segnalazione ambientale">Segnalazione ambientale</option>
<option value="Segnalazione di sicurezza">Segnalazione di sicurezza</option>
<option value="Segnalazione strutturale">Segnalazione strutturale</option>
</select>
</div>
</div>
<div class="row">
<div class="form-group col-sm-12" ng-class="{ 'has-error' : formPicture.Reason.$invalid && formPicture.Reason.$touched}">
<label for="Reason" class="form-control-label">Motivazioni</label>
<textarea ng-disabled="accessLevelStatus() < 2" id="Reason"
class="form-control" name="Reason"
ng-model="picture.Reason">
</textarea>
</div>
</div>
</span>
This is how i manage it
$scope.picture = ReportingPictureService.pictures.get({id: $stateParams.id}, function (picture) {
$scope.title = 'Modifica segnalazione';
$scope.picture.PictureDate = new Date($scope.picture.PictureDate);
//Se la Classificazione 1 >= 3 (Segnalazione/Segnalazione urgente), allora mostro i campi associati alla segnalazione
var div = angular.element('#showDiv');
var reportingDetailInput = angular.element('#ReportingDetail');
var reasonInput = angular.element('#Reason');
//Se Classificazione 1 >= 3, allora gli input sono visibili e sono tutti required
if($scope.picture.PictureClass_ID >= 3) {
div.attr('ng-show',"true");
reportingDetailInput.attr('required',"required");
reasonInput.attr('required',"required");
}
else {
div.attr('ng-show',"false");
reportingDetailInput.attr('required',"false");
reasonInput.attr('required',"false");
}
//Tengo conto anche di Classificazione 2 e uso le seguenti funzioni per modificare gli attributi degli input e dello span (show and hide)
$scope.changeClass2 = function() {
if(picture.PictureClass2_ID >= 3) {
div.attr('ng-show',"true");
reportingDetailInput.attr('required',"required");
reasonInput.attr('required',"required");
}
else {
div.attr('ng-show',"false");
reportingDetailInput.attr('required',"false");
reasonInput.attr('required',"false");
}
}
//Funzione che gestisce lo show/hide dei due input
$scope = div.scope();
$injector = div.injector();
$injector.invoke(function($compile) {
$compile(div)($scope)
});
//Funzione che gestisce il required = true/false del campo Analisi Segnalazioni
$scope = reportingDetailInput.scope();
$injector = reportingDetailInput.injector();
$injector.invoke(function($compile) {
$compile(reportingDetailInput)($scope)
});
//Funzione che gestisce il required = true/false del campo Motivazioni
$scope = reasonInput.scope();
$injector = reasonInput.injector();
$injector.invoke(function($compile) {
$compile(reasonInput)($scope)
});
downloadImage($scope.picture);
})
The span part (the show/hide part, http static value) should be visible (and required) when $scope.picture.PictureClass_ID >= 3. Of course it should be hided (and not required) when $scope.picture.PictureClass_ID < 3.
The $scope.picture.PictureClass2_ID is the same, but it should be changing dynamically with the select function.
The first part works well, but the select part is not working.
Any idea on how this is not working?

Instead of manipulating DOM attributes with the controller, use the ng-show and ng-required directives:
<select ng-disabled="accessLevelStatus() < 2"
class="form-control" name="ReportingDetail"
id="ReportingDetail" placeholder="ReportingDetail"
ng-model="picture.ReportingDetail"
ng-show="picture.PictureClass_ID >= 3"
ng-required="picture.PictureClass_ID >= 3" >
<option value=""></option>
<option value="Segnalazione ambientale">Segnalazione ambientale</option>
<option value="Segnalazione di sicurezza">Segnalazione di sicurezza</option>
<option value="Segnalazione strutturale">Segnalazione strutturale</option>
</select>
For more information, see
AngularJS ng-required Directive API Reference

Related

Jquery returned 'undefined'(s) when try to get the ID of the 'select' tag through class

I'm trying to check if my select box is empty or not by using class. However, based on the code below, the alert returned not only the id but also another 2 'undefined'. Anyone who can tell me why is this happening?
<script>
$('.test-input').each(function () {
var el = [];
if ($(this).val() === "") {
var target = $(this).attr('id');
alert(target); *// return media_type | underfined | underfined*
el.push(target);
}
})
</script>
<div class="form-group col-sm-4">
<label class="">Type:</label>
<select class="form-control required-input test-input" id="media_type" placeholder="Choose a media">
<option value="">Select a state</option>
<option value="cat">Cat</option>
<option value="dog">Dog</option>
<option value="lizard">Lizard</option>
<option value="snake">snake</option>
</select>
</div>
$('.test-input').each(function () will iterate through each element in your HTML that has the "test-input" class name, so when there you are cycling through those and getting an undefined from pulling its id via var target = $(this).attr('id');, what this means is that somewhere else in the file you must have two other classes named "test-input" without an ID.
I would console.log("Iteration"); in the loop and check your console to see how many times the loop is being run and go from there.

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>

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>

Custom Directive for Required/ngRequired

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/

How do I pass a parameter from HTML to server using href

Hi I'm trying to invoque a servlet from a JSP page, what I want to do is to pass a parameter, well 2 parameters, but one of them is not static, it's the result of a select, this is my code:
<form>
<select name="tipoReporte" id="tipoReporte">
<option value="0" selected>Seleccione el tipo de reporte que desea ver:</option>
<option value="sem">Semanal</option>
<option value="2hrs">Cada dos horas</option>
</select>
</form>
As you see, the user will choose an option and depending on it, my servlet will do different things, here's the code to pass my parameters to my servlet:
<a target=_blank href="servlet1?cmd=graphic_jetta&tipoReporte= ¿what should I pass? ">
<img src="images/je1.png" width="200" height="100" id="je" onmouseover="changeImage('images/je1.png', 'images/je2.PNG', 'je')" onmouseout="changeImage('images/je1.png', 'images/je1.png', 'je')"/>
</a>
Then on the servlet I use the request.getParameter() method, but my problem is that I don't know how to pass this value in the code above. For instance, the first parameter doesn't give me problem cause is static, but the second one is my problem.
I'm new in web developing, so I would appreciate your patience and help, thank you!!
Create a JavaScript function for submitting:
function submit() {
var tipoReporte = document.getElementById('tipoReporte').value;
window.location.assign('servlet1?cmd=graphic_jetta&tipoReporte=' + tipoReporte);
}
and replace the link with:
<a target=_blank onclick="submit()">
or avoiding that, you can make the image part of the form:
<form action="servlet1">
<select name="tipoReporte" id="tipoReporte">
<option value="0" selected>Seleccione el tipo de reporte que desea ver:</option>
<option value="sem">Semanal</option>
<option value="2hrs">Cada dos horas</option>
</select>
<input type="hidden" name="cmd" value="graphic_jetta">
<input type="image" src="images/je1.png">
</form>