I overtook a project from another dev'er.
The code allows me to get data from the form's text inputs, but not from the checkbox inputs.
The original developer wrote these functions (amongst others):
protected function getObjectString($key,$html=false,$escape=false)
{
$string = isset($this->classData[$key]) ? $this->classData[$key]."" : "";
if($html == true) $string = htmlspecialchars($string);
if($escape == true) $string = addslashes($string);
return $string;
}
and
protected function getObjectBool($key,$toString=false,$trueVal="yes",$falseVal="no")
{
$bool = intval(isset($this->classData[$key]) ? $this->classData[$key] : 0);
//$bool = intval(isset($this->classData[$key]) ? 1 : 0);
if($toString == true)
{
if($bool > 0) return $trueVal;
else return $falseVal;
}
return $bool > 0;
}
When I use
getObjectString("Email",false,false);
I get the value of form element
<div class="row">
<div class="col-lg-3 formlabel">E-mail</div>
<div class="col-lg-9"><input type="text" class="form-control" name="Email" value=""></div>
</div>
But when I use
getObjectBool("EmailMandatory",false,"yes","no");
I should get the value (checked=1, unchecked=0) from
<div class="row">
<div class="col-lg-3 formlabel">Mandatory</div>
<div class="col-lg-9">
<label style="font-weight: normal;">
<input type="checkbox" name="EmailMandatory" value="1" checked>
Use of mail address is mandatory
</label>
</div>
</div>
However, the value (from getObjectBool) is always empty. What am I doing wrong?
Addition, as requested by Professor Abronsius:
abstract class common_library_dbbase
{
/** CLASS PROPERTIES **/
protected $classData = array();
/** CONSTRUCTOR **/
function __construct($data,$tableName,$primaryIDName,$accountTable=false,$cacheEnabled = true)
{
// Set member data
$this->tableName = $tableName;
$this->primaryIDName = $primaryIDName;
$this->cacheEnabled = $cacheEnabled;
$this->accountTable = $accountTable;
// Is same class
if(is_object($data) && get_class($this) == get_class($data))
{
$this->classData = $data->toArray;
}
// Is array data
else if(is_array($data))
{
$this->classData = $data;
}
// Is number, load from db
else if(intval($data) > 0)
{
$this->classData = $this->loadByID($data);
}
}
}
When you pass false as second parameter the function returns a boolean, not an integer. You could do
getObjectBool("EmailMandatory",false,"yes","no") ? 1 : 0
Or
getObjectBool("EmailMandatory",true,1,0)
Related
I'm trying to create a checkbox list where a user is supposed to be able to choose one or more options, based on the choice: this is supposed to be inserted to a database table, where the id of the choice is inserted. (This is on a page where a user can "edit garage"), therefore the garageid is also supposed to be fetched and both the garageid and the choice id should be inserted to a cross table, that I have created as following:
[ID]
,[GarageID]
,[RequestProperty]
,[CreatedDate]
,[CreatedBy]
,[UpdatedDate]
,[UpdatedBy]
I also have a stored procedure for the insert:
ALTER PROCEDURE [dbo].[spGarageGetRequestTypes]
-- Add the parameters for the stored procedure here
#GarageID INT,
#RequestType INT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
INSERT INTO GarageCrossRequestType
(GarageID, RequestProperty)
VALUES (#GarageID, #RequestType)
END
And the "edit page" is working and functioning, it's where I get the garageId as well. It looks like following in view:
<div class="form-group">
<div class="row">
<label class="col-xs-2 control-label">Garage</label>
<input type="text" class="col-lg-10 form-control" name="GarageName" id="GarageName" placeholder="Name" required="" />
</div>
</div>
<div class="form-group">
<div class="row">
<label class="col-xs-2 control-label">Contact person</label>
<input type="text" class="col-lg-10 form-control" name="ContactPerson" id="ContactPerson" placeholder="ContactPerson" required="" />
</div>
</div>
<div class="form-group">
<div class="row">
<label class="col-xs-2 control-label">Email</label>
<input type="email" class="col-lg-10 form-control" name="Email" id="Email" placeholder="Email" required="" onblur="validateEmail(this.value);" /><p id="InvalidMeg" style="font-size: 25px; color: red">Invalid e-mail address</p>
</div>
</div>
<script type="text/javascript">
function editGarage(e) {
e.preventDefault();
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
var garageId = dataItem.GarageId;
countryId = dataItem.CountryId;
var email = dataItem.Email;
var contactperson = dataItem.ContactPerson;
if (garageId != 0) {
$("#EditGarageBtn").show();
$("#saveNewGarageBtn").hide();
$("#GarageName").val(name);
$("#Country").val(countryId);
$("#ContactPerson").val(contactperson);
$("#Email").val(email);
}
}
$("#EditGarageBtn").click(function () {
var customerNumber = customerNumberOfEditingGarage;
name = $("#GarageName").val();
countryId = $("#Country").val();
var garageId = $("#garageId").val();
var contactperson = $("#ContactPerson").val();
var email = $("#Email").val();
$("#EditGarageBtn").hide();
if (name.length > 0 && email.length > 0 && contactperson.length > 0) {
$.ajax({
url: '#Url.Action("EditGarage", "Garage")',
dataType: 'JSON',
data: {
name: name, countryId: countryId, garageId: garageId,
contactperson: contactperson, email: email
},
success: function (data) {
if (data == "Failure") {
toastr["error"]("Error editing Garage");
}
else {
toastr["success"]("Garage successfully updated");
customerNumberOfEditingGarage = null;
refreshGrid();
}
},
error: function () {
}
});
} else {
toastr["error"]("Error editing Garage");
}
});
</script>
Model:
public class GarageModel
{
public int GarageTypeId { get; set; }
public int CountryId { get; set; }
public string ContactPerson { get; set; }
public string Email { get; set; }
public int GarageId { get; set; }
// for the choices in the checkbox
public int ScheduledService { get; set; } = 1;
public int Tires { get; set; } = 2;
}
Method:
public bool EditGarage(GarageModel model)
{
var valid = false;
var cmd = new SqlCommand("spGarageEditGarage", Connection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#GarageId", model.GarageId);
cmd.Parameters.AddWithValue("#CountryId", model.CountryId);
cmd.Parameters.AddWithValue("#Name", model.Name);
cmd.Parameters.AddWithValue("#ContactPerson", model.ContactPerson);
cmd.Parameters.AddWithValue("#Email", model.Email);
try
{
int result = cmd.ExecuteNonQuery();
if (result == 1)
valid = true;
}
catch (SqlException ex)
{
throw new Exception(ex.Message);
}
finally
{
Connection.Close();
}
// for the choices in the checkbox (not working!)
List<int> newlist = new List<int>();
newlist.Add(model.Tires);
newlist.Add(model.ScheduledService);
foreach (var item in newlist)
{
if (newlist != null)
{
var cmd1 = new SqlCommand("spGarageGetRequestTypes", Connection);
cmd1.CommandType = CommandType.StoredProcedure;
cmd1.Parameters.AddWithValue("#GarageId", model.GarageId);
cmd1.Parameters.AddWithValue("#RequestType", newlist.First());
int result = cmd1.ExecuteNonQuery();
if (result == 1)
valid = true;
}
}
return valid;
}
If you look at my comments in the model and the method, you can see what I've added for the "choices" function I'm trying to implement. Here's the html i created for the input type as well:
#foreach (var items in Model)
{
<div class='form-group' style="margin-left: 60%;">
<div class="row">
<label class="ab">Tires</label>
<input type="checkbox" class="checkbclass" name="#items.Tires" id="Tires" placeholder="Tires" required="" value="#items.Tires" />
</div>
</div>
<div class='form-group' style="margin-left: 60%;">
<div class="row">
<label class="ab">Scheduled Service</label>
<input type="checkbox" class="checkbclass" name="#items.ScheduledService" id="Scheduled" placeholder="Scheduled" required="" value="#items.ScheduledService" />
</div>
</div>
}
Now, to the problems:
1: I need some sort of method for making sure which or if a checkbox is checked, and this needs to be returned to the model or controller in some way. I only want to return it's numeric value, as seen in the model I want Tires to have the numeric value of 2 etcetera.
The datebase insert works (so at least that's something), but the table only accepts RequestProperty and GarageID, meaning that if a user chooses 2 of the checkboxes, I need to update the database twice, creating 2 rows, but with the same garageid.
I tried posting a question about this earlier, but it was poorly explained from my side, so I'm trying again, and hoping I included everything this time. I'm open to any help/solutions that can help me solve this.
First, You need to remove all GarageCrossRequestType that containe current GarageID as the checkbox may be checked and unhacked later on edit.
This how I would do it.
Note: make sure to read the comment
javascript
$("#EditGarageBtn").click(function() {
var customerNumber = customerNumberOfEditingGarage;
// I assumed that you want name as the int of RequestType eg 1 or 2 that are checked
var garageCrossRequestType = $(".checkbclass:checked").map(function(x) {
return parseInt($(x).attr("name"));
});
name = $("#GarageName").val();
countryId = $("#Country").val();
var garageId = $("#garageId").val();
var contactperson = $("#ContactPerson").val();
var email = $("#Email").val();
$("#EditGarageBtn").hide();
if (name.length > 0 && email.length > 0 && contactperson.length > 0) {
$.ajax({
url: '#Url.Action("EditGarage", "Garage")',
dataType: 'JSON',
data: {
name: name,
countryId: countryId,
garageId: garageId,
contactperson: contactperson,
email: email,
garageCrossRequestType: garageCrossRequestType // here send the checked checkedboxes
},
success: function(data) {
if (data == "Failure") {
toastr["error"]("Error editing Garage");
} else {
toastr["success"]("Garage successfully updated");
customerNumberOfEditingGarage = null;
refreshGrid();
}
},
error: function() {
}
});
} else {
toastr["error"]("Error editing Garage");
}
});
C#
// create an sqlProcedure or something instead of this, this is only to show how it work
// You have to clear all GarageCrossRequestType that containe the current GarageID
// An after insert the newly checked items
new SqlCommand("delete GarageCrossRequestType where GarageID = " + model.GarageId, Connection).ExecuteNonQuery();
List <int> newlist = new List<int>();
if (model.garageCrossRequestType != null)
newlist.AddRange(model.garageCrossRequestType);
foreach(var item in newlist) {
//newlist cant be null becouse you are already in a loop.
// and also newlist is never null
// if (newlist != null)
var cmd1 = new SqlCommand("spGarageGetRequestTypes", Connection);
cmd1.CommandType = CommandType.StoredProcedure;
cmd1.Parameters.AddWithValue("#GarageId", model.GarageId);
// instead of newlist.First() you are looping throw newlist eg checkboxes then it should be item
cmd1.Parameters.AddWithValue("#RequestType", item);
int result = cmd1.ExecuteNonQuery();
if (result == 1)
valid = true;
}
I have a bug that I could not figure out in my validation method. I have a function that validate the "code" table in my database to make sure the user can not input duplicate data. It is all working as expected and here is the code:
function validateCode() {
$('#code-error').html('')
if ($('#code').val() != '') {
$.ajax({
url: '${createLink(action:'checkCode')}',
type: 'GET',
data: {
'code': $('#code').val(),
},
// dataType:'json',
success: function (data) {
if (data == 'true') {
$('#code-error').html('Code already exist')
$(':input[type="submit"]').prop('disabled', true);
} else {
// $('#code-error').html('Code not exist')
$(':input[type="submit"]').prop('disabled', false);
}
},
error: function (request, error) {
alert("Request: " + JSON.stringify(request));
}
});
}
}
But it is not stable.First the message and the button are disabled in the first couples of tried but if I continue to test it by re-enter the code that exist and the code that does not exist the button disabled however the error message is not showing under the input box.
Here is my html code :
<div class = "row" style = "margin-top:15px;">
<div class = "col-md-12">
<div class = "row">
<div class = "col-md-5 text-right" style = "font-weight: bold"><span class="placeholder">Code</span></div>
<div class = "col-md-7">
<div class="form-group">
<input style = "width: 50%"type="text" class="form-control" onkeyup="validateCode()" id="code" placeholder="Enter code" name="code">
<input type="hidden" name="current-code" id = "current-code">
<div class = "row">
<div id = "code-error" class = "col-md-12" style ="color:red"></div>
</div>
</div>
</div>
</div>
</div>
</div>
And here is my controller function for validating the code:
def checkCode() {
def allow
String compareCode = params?.code
def customer = Customer.findByCode(compareCode)
if (customer == null) {
allow = false //not exist
} else if (customer != null) {
allow = true //exist
}
render allow
}
I'm a beginner in web development and I have an HTML form where a person can add his address , address number, region and postal code . In this form the address and the region have to contain only char letters .
(ex. Lakewood : correct Lakewood13 : error) . If any of these two variables contains a number I have to enter my data again to continue . Else, I move to the next page . I'm a complete beginner in javascript which I need to use to check my variable types and I would appreciate your help with guiding me to solve this problem .
This is my code with my HTML form with the address number and the region which are the variables we need in this problem :
function checkdata(){
//the two elements we need to check
var a = document.getElementById("address");
var r = document.getElementById("region");
if(typeof(a.value) === 'string'&&(typeof b.value) ==='string'){
//continue to next page(but how can I check if numbers are in the strings ?)
}
else{
//go back to form and enter again(how can I enter the elements again ? )
}
}
<div class = "form-area" id = "forma">
<form action="/action.page.html" class = "sign-form" >
<div class = "form-container">
<h1> Enter purchase data below : </h1>
<label for="addrs"> Address Name</label>
<input type = "text" placeholder = "Enter address name " id = "address" name = "addr" required/>
<label for="regn" > Region </label>
<input type = "text" placeholder = "Enter region " id = "region" name = "reg" required/>
</div>
<button type="submit" class="continuebtn" onclick = "checkdata()">Continue</button>
</form>
</div>
Thank you in advance .
You can try using regex to check if string contains any number in it:
if(!(/\d/.test(a.value)) && !(/\d/.test(b.value))){
Please Note: You also have to return false to prevent the default event if the condition is false and prefix return the function call in onclick attribute.
Demo:
function checkdata(){
//the two elements we need to check
var a = document.getElementById("address");
var r = document.getElementById("region");
if(!(/\d/.test(a.value)) && !(/\d/.test(r.value))){
alert('form submit');
}
else{
alert('no submit');
return false;
}
}
<div class = "form-area" id = "forma">
<form action="/action.page.html" class = "sign-form" >
<div class = "form-container">
<h1> Enter purchase data below : </h1>
<label for="addrs" Address Name</label>
<input type = "text" placeholder = "Enter address name " id = "address" name = "addr" required/>
<label for="regn" > Region </label>
<input type = "text" placeholder = "Enter region " id = "region" name = "reg" required/>
</div>
<button type="submit" class="continuebtn" onclick = "return checkdata()">Continue</button>
</form>
</div>
You can write a function for validity, then you can check for dependencies based on that **
function checkData() {
let adress = document.getElementById('address');
let region = document.getElementById('region');
function isValid(e) {
let isTrue;
for (let char in e) {
typeof e[char] !== 'string' ? alert('Please only type strings') : (isTrue = true);
}
return isTrue;
}
isValid(adress.value) && isValid(region.value) ? console.log('next page') : console.log('error');
}
checkData();
**
So need to check if the strings are containing numbers or not
hope you find more insight here: Check whether an input string contains a number in javascript
working demo :
// check if string contains number
function hasNumber(myString) {
return /\d/.test(myString);
}
function checkdata(e) {
e.preventDefault()
//the two elements we need to check
var a = document.getElementById("address");
var r = document.getElementById("region");
var isAddressContainsNumber = hasNumber(a.value);
var isRegionContainsNumber = hasNumber(r.value);
console.log(isAddressContainsNumber, isRegionContainsNumber)
if (isAddressContainsNumber === false && isRegionContainsNumber === false) {
console.log('None of string contains number')
} else {
console.log('One or Both string contains number')
}
}
const form = document.querySelector('.sign-form');
form.addEventListener('submit', checkdata);
<div class="form-area" id="forma">
<form class="sign-form">
<div class="form-container">
<h1> Enter purchase data below : </h1>
<label for "addrs" Address Name</label>
<input type="text" placeholder="Enter address name " id="address" name="addr" required/>
</label>
<label for "regn" > Region </label>
<input type="text" placeholder="Enter region " id="region" name="reg" required/>
</label>
</div>
<button type="submit" class="continuebtn">Continue</button>
</form>
</div>
I would recommend going through the string and getting the ASCII value of each character. Numbers 0-9 are ASCII characters 48-57. Javascript uses UTF-16 and the appropriate method (charCodeAt) returns a 16-bit UTF-16 value, but UTF-16 characters 0-127 match ASCII. So:
var testString = "abcd123";
var isValid = true;
for (var i=0;i<testString.length;i++)
{
if (testString.charCodeAt(i) > 47 && testString.charCodeAt(i) < 58)
{
isValid = false;
}
}
if (!isValid)
{
//Code here to alert the user
alert("There's a number in there!");
}
You are using typeof in wrong way, try this way
typeOf(variable you want to check)
I am having a few problems with javascript. I am trying to create a function for when I click a radio button it will run that function. (I got this to work).
My problem is when I click the radio button to order alphabetically it orders but then when i clicked the other radio buttons to change function it is still ordered alphabetically due to "APPEND" my question is how can I get my program to work so when I kill alphabetically ordered it only orders for that and when i click back to something else its ordered how it was originally.
Here is part of my code:
Javascript:
function radiobuttonclicked() {
var allChampions1 = $(".masterychampsforsum > .colzz");
var selectedcheckyesnochest = document.getElementsByName("optioncheckradiomasterychamps");
if (selectedcheckyesnochest[0].checked == true) {
allChampions1.show();
}
else if (selectedcheckyesnochest[1].checked == true) {
var selectedChampions1 = $(".masterychampsforsum > .colzz[data-chest-champion^='yes']");
allChampions1.hide();
selectedChampions1.show();
}
else if (selectedcheckyesnochest[2].checked == true) {
var selectedChampions1 = $(".masterychampsforsum > .colzz[data-ranked-champion^='yes']");
allChampions1.hide();
selectedChampions1.show();
} else if (selectedcheckyesnochest[3].checked == true) {
var alphabeticallyOrderedDivs = $('.colzz').sort(function(a, b) {
return String.prototype.localeCompare.call($(a).data('championalphabeta').toLowerCase(), $(b).data('championalphabeta').toLowerCase());
});
var container = $("#masterychampsforum");
container.detach().empty().append(alphabeticallyOrderedDivs);
$('.summonerLayout-summary').append(container);
}
}
HTML:
<div class="tabItem Content SummonerLayoutContent summonerLayout-summary" data-tab-spinner-height="800" data-tab-is-loaded-already="true">
<div class="SearchChampion" style="margin-top:20px;padding: 10px;border: 1px solid #000;background-color: #111111;">
<form class="SearchChampionForm" onsubmit="return false;" style="position: relative;">
<input name="optioncheckradiomasterychamps" style="margin-left:15px;vertical-align: middle;margin-top: -1px;" type="radio" value="Chest" id="option_all" onclick="radiobuttonclicked();" checked/> <label for="option_all" style="font-size:16px;">ALL</label>
<input name="optioncheckradiomasterychamps" style="margin-left:15px;vertical-align: middle;margin-top: -1px;" type="radio" value="Chest" id="option_chest" onclick="radiobuttonclicked();"/> <label for="option_chest" style="font-size:16px;">CHEST</label>
<input name="optioncheckradiomasterychamps" style="margin-left:15px;vertical-align: middle;margin-top: -1px;" type="radio" value="Ranked" id="option_ranked" onclick="radiobuttonclicked();"/> <label for="option_ranked" style="font-size:16px;">RANKED</label>
<input name="optioncheckradiomasterychamps" style="margin-left:15px;vertical-align: middle;margin-top: -1px;" type="radio" value="Ranked" id="option_alpha" onclick="radiobuttonclicked();"/> <label for="option_alpha" style="font-size:16px;">ALPHABETICAL</label>
</form>
</div>
<div class="masterychampsforsum" id="masterychampsforum">
<div class="colzz" data-champion-name="'.$getLeagueKeyNamelistsidez.'" data-champion-key="'.$getLeagueKeyNamelistsidez.'" data-chest-champion="'.$champchestyes.'" data-ranked-champion="'.$checkchampionidyesnotrue.'" data-championalphabeta="'.$getLeagueKeyNamelistsidez.'">
</div>
</div>
The data in the data-championalphabeta is Names.
Link to what i got currently
Barmar is right, you have to make a copy first and then you can sort against this copy.
When the last case of your if statement is executed, the DOM is updated.
As the function radiobuttonclicked always retrieves the list from the DOM (the line: var allChampions1 = $(".masterychampsforsum > .colzz")), all the next executions of the function are retrieving the previously ordered list and your original order is lost.
Instead try that (not the best code ever but with this context that will do):
var allChampions1
function radiobuttonclicked() {
if(!allChampions1)
allChampions1 = $(".masterychampsforsum > .colzz").clone();
var selectedcheckyesnochest = document.getElementsByName("optioncheckradiomasterychamps");
if (selectedcheckyesnochest[0].checked == true) {
updateContainer(allChampions1);
} else if (selectedcheckyesnochest[1].checked == true) {
var selectedChampions1 = allChampions1.filter("[data-chest-champion^='yes']");
updateContainer(selectedChampions1);
} else if (selectedcheckyesnochest[2].checked == true) {
var selectedChampions1 = allChampions1.filter("[data-ranked-champion^='yes']");
updateContainer(selectedChampions1);
} else if (selectedcheckyesnochest[3].checked == true) {
var alphabeticallyOrderedDivs = allChampions1.clone().sort(function(a, b) {
return String.prototype.localeCompare.call($(a).data('championalphabeta').toLowerCase(), $(b).data('championalphabeta').toLowerCase());
});
updateContainer(alphabeticallyOrderedDivs);
}
}
function updateContainer(newList){
var container = $("#masterychampsforum");
container.detach().empty().append(newList);
$('.summonerLayout-summary').append(container);
}
I have 3 sections of input fields separated with different heading(Laser Pass, The Giggsy, The set up) generated from a JSON array. Here is what it looks like:
I want to compare two fields Score and Attempts and show an error message if the value of Score is larger then Attempts. Something like this:
But some section like, The Giggsy have a different type of input fields and no need to compare/check those fields. Only where it has SCORE and ATTEMPTS should compare.
When the section is filled up Show success message like this:
What I can do to make those things in angular way. Here is what I've done so far: PLUNKER
HTML:
<div class="row" ng-repeat="all in options">
<h4> {{ all.name}} </h4>
<div class="col-sm-5ths" ng-repeat="measurement in all.measurements">
<div class="form-group no-margin form-oneline">
<label style="width: 100%">{{ measurement.name }}</label>
<input ng-model="measurement.value" type="{{ measurement.type }}" min="{{ measurement.min }}" max="{{ measurement.max }}" class="form-control display-inline" required>
<label style="width: 100%">{{ measurement.scale }}</label>
</div>
</div>
<span style="color:red;" ng-show="testDataFieldWarning(options.measurements)">
Score can't be larger then Attempts
</span>
<span style="color:Green;" >
Done!!
</span>
</div>
<button type="submit" style="margin-top:50px;" ng-disable="">Submit</button>
JS
$scope.testDataFieldWarning = function (measurements) {
var score = 0 , attempts = 0;
angular.forEach(measurements, function(measurement) {
if((measurement.name) == 'Score'){
score = measurement.value;
}
if((measurement.name) == 'Attempts'){
attempts = measurement.value;
}
});
return attempts < score;
}
$scope.testDataFieldValidate = function (measurement) {
var isInvalid = false;
angular.forEach(measurement, function(v) {
if(typeof (v.value) == 'undefined'){
isInvalid = true;
}
});
return (isInvalid);
}
Sorry for bad English and explanation.
I forked your plunker and added some additional validating functions...
function isScoreField(measurements) {
if (measurements[1].name === 'Score' && measurements[2].name ==='Attempts') {
return true;
} else {
return false;
}
}
$scope.testDataFieldInvalid = function (measurements) {
if (isScoreField(measurements) && parseInt(measurements[2].value) < parseInt(measurements[1].value)) {
return true;
} else {
return false;
}
};
$scope.testDataFieldsEntered = function (measurements) {
if (measurements[1].value && measurements[2].value) {
return true;
} else {
return false;
}
};
... that will conditionally show/hide the done/error messages.
<span style="color:red;" ng-show="testDataFieldInvalid(all.measurements)">
Score can't be larger than Attempts
</span>
<span style="color:Green;" ng-show="testDataFieldsEntered(all.measurements) && !testDataFieldInvalid(all.measurements)">
Done!!
</span>
Hope this helps!