How to disable Save button until input field value is validated? - javascript

I have form in the system that has a field that should be validated before user submits the form. The first field on the form is 'Type' input field, and second is 'User ID' input field. Here is working example of my current code:
var data = {
93169: "John Rives",
33442: "Mike Cook",
70354: "Tammy Bull",
22078: "Nick Adams"
};
$("#user_id").on("keyup", function() {
var inputFld = $(this),
msgFld = $(this).closest("div").find(".invalid-feedback");
if (!inputFld.val().length) {
inputFld.removeClass("is-invalid").val("");
msgFld.text("");
$("#save").prop("disabled", false);
}
});
$("#user_type").on("change", function() {
var inputVal = $(this).val();
if (inputVal) {
$("#user_id").prop("disabled", false);
} else {
$("#user_id").prop("disabled", true);
}
// Every time on change reset affiliate field and remove the calss.
$("#user_id").removeClass("is-invalid").val("");
$("#user_name").text("N/A");
$("#save").prop("disabled", false);
});
$("#search_user").on("click", function() {
var inputFld = $(this).parent().parent().children("input"),
msgFld = inputFld.closest("div").find(".invalid-feedback"),
typeID = $("#user_type").val(),
saveBtn = $("#save"),
userID = inputFld.val(),
regex = /^([0-9]{1,5})$/;
if (userID) {
if (regex.test(userID) === false) {
saveBtn.prop("disabled", true);
inputFld.addClass("is-invalid");
msgFld.text("User ID has to be numeric 1-5 digits long.");
$("#user_name").text("N/A");
} else {
var userName = data[userID];
populateUser(userName, inputFld, msgFld, saveBtn);
}
} else {
inputFld.removeClass('is-invalid');
$('#user_name').text('N/A');
}
});
function populateUser(userName, inputFld, msgFld, saveBtn) {
if (!userName) {
saveBtn.prop('disabled', true);
inputFld.addClass('is-invalid');
msgFld.text("User doesn't exist.");
$("#user_name").text("N/A");
} else {
inputFld.removeClass("is-invalid");
$("#user_name").text(userName);
}
}
#search_user {
border-top-right-radius: 0.25rem !important;
border-bottom-right-radius: 0.25rem !important;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<script src="https://use.fontawesome.com/a6e6aa2b6e.js"></script>
<div class="container">
<form name="my_frm" id="my_frm" autocomplete="off">
<div class="form-row">
<div class="form-group col-4">
<label>User Type:</label>
<select class="custom-select browser-default" name="user_type" id="user_type" required>
<option value="">--Select Type--</option>
<option value="1">Director</option>
<option value="2">Project Manager</option>
<option value="3">Assistant Manager</option>
</select>
</div>
<div class="form-group col-4">
<label class="control-label" for="user_id">User ID:</label>
<div class="input-group">
<div class="input-group addon">
<input class="form-control" type="text" name="user_id" id="user_id" maxlength="5" placeholder="Enter User ID" disabled>
<div class="input-group-append">
<button class="btn btn-secondary" type="button" name="search_user" id="search_user"><i class="fa fa-search"></i></button>
</div>
<div class="invalid-feedback"></div>
</div>
</div>
</div>
<div class="form-group col-4">
<p>User Name:</p>
<p id="user_name">N/A</p>
</div>
</div>
<div class="row">
<div class="col-12 text-center">
<button class="btn btn-outline-secondary" type="button" name="save" id="save">Save</button>
</div>
</div>
</form>
</div>
In the example above you will be able to see function with some examples. One thing that I'm concerned about is what if user enters user ID and doesn't click on search button? In that case user is still able to submit the form before user ID is validated. I'm wondering if there is a way to prevent form submission/ disable Save button until User ID has value in the field and that value is not validated. If someone can help me fix that or if you have any suggestions please let me know. I'm also open to hear if you have better ways to achieve this validation.

You can add a disabled attribute (or class) to your save button, then after the successfull validation, remove it.
In the callback for the button, you will check if the button is disabled or not
$("#save").click(function() {
if ($(this).hasClass("disabled")) {
console.log("wait for validation!")
return;
}
//do stuff
});
$("#val").click(function() {
$("#save").removeClass("disabled");
});
.disabled {
opacity: .7;
cursor: not-allowed;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="btn btn-outline-secondary disabled" type="button" name="save" id="save">Save</button>
<button class="btn btn-outline-secondary" type="button" name="val" id="val">Validate</button>

Related

Select Options disappearing

What's happening:
I have a form in a modal where the user inputs data. The form is only populated with data when opening the modal, not after submission. The form's action InsertLabelDefectRobotsT returns a return NoContent(); When the form is submitted the modal stays open and I clear the input values to allow new submissions.
Now, I have two dropdowns (Célula and Defeito), when changing the first one the visible options of the second one will change. My problem is that after submitting a set of values, if I change the first dropdown value and then change it back the option I submitted before disappears (this only happens if I submit the form and only the option I submitted disappears).
I have no clue why this is happening... and this is a very specific question, but if you have any leads I appreciate it.
Modal
Modal.html
<form id="formDefectsRobots" method="post" asp-action="InsertLabelDefectRobotsT" asp-controller="Labels" onsubmit="onSubmit(this);onSubmit2()">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-row">
<div class="form-group col-md-12">
<label asp-for="CellId"></label>
<select id="select1DefectsRobots" asp-for="CellId" asp-items="Model.Cells" class="custom-select">
<option value="">--</option>
</select>
<span asp-validation-for="CellId" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12">
<label asp-for="DefectName"></label>
<select id="select2DefectsRobots" asp-for="DefectName" asp-items="Model.Defects" class="custom-select defectsSelect">
<option value="">--</option>
</select>
<span asp-validation-for="DefectName" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12">
<label asp-for="Quantity"></label>
<input class="form-control form-control-sm numpad defectsSelect" asp-for="Quantity" />
<span asp-validation-for="Quantity" class="text-danger"></span>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12">
<label asp-for="Details"></label>
<input type="text" class="form-control form-control-sm defectsSelect" asp-for="Details" />
<span asp-validation-for="Details" class="text-danger"></span>
</div>
</div>
<div class="row mb-3">
<div class="col-md-12">
<button type="button" class="btn btn-dark" data-dismiss="modal"><i class="fas fa-arrow-left mr-2"></i>Cancelar</button>
<button type="button" class="btn btn-success" onclick="doSomething();submitDefectsRobots(this)"><i class="fas fa-play-circle mr-2"></i>Introduzir Defeito</button>
</div>
</div>
</form>
<script>
//Changes second Select based on the first
$("#select1DefectsRobots").change(function () {
if ($(this).data('options') === undefined) {
//Taking an array of all options-2 and kind of embedding it on the select1
$(this).data('options', $('#select2DefectsRobots option').clone());
}
var id = $(this).val();
var options = $(this).data('options').filter('[value=' + id + ']');
$('#select2DefectsRobots').html(options);
});
//This changes the val of the select option to it's text.
function doSomething() {
$('#select2DefectsRobots option:selected').val($('#select2DefectsRobots option:selected').text());
};
//Clear some values
function onSubmit2() {
setTimeout(function () {
$('.defectsSelect').val('');
}, 1000);
};
</script>
script.js
function submitDefectsRobots(button) {
$form = $('#formDefectsRobots');
if ($form.valid()) {
Swal.fire({
title: "Inserir Defeito?",
text: "Esta acção irá inserir um novo registo de defeito.",
type: 'warning',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
cancelButtonText: 'Cancelar',
confirmButtonText: 'Confirmar',
animation: false,
focusCancel: true
}).then((willSubmit) => {
if (willSubmit.value) {
$form.submit();
hideOverlay();
setTimeout(function () {
toastr.success("Defeitos Inseridos");
}, 1000);
}
})
}
}
Before submission (two "defeito" options appear on 3.9.V and one on 3.9.Y)
After submission on 3.9.V (Values Cleared, Still two options on 3.9.V)
After submission (Changed to "Célula" 3.9.Y and when changing back to 3.9.V only one "defeito" option appears now)
I found it: since I was changing the val of the selected option on submit, it would not work on the next time.
//This changes the val of the select option to it's text.
function doSomething() {
$('#select2DefectsRobots option:selected').val($('#select2DefectsRobots option:selected').text());
};

How to implement previously declared jquery.validate rules on dynamically added form fields [duplicate]

This question already has answers here:
Validate dynamic field jquery
(2 answers)
Closed 2 years ago.
I have to clone the certain section of form and have to implement same validation rules defined previously.
As I researched on this issue, almost all them recommended to add new rules again in the newly generated elements. So, I had tried by adding new rule with following code
let $contactItem = $(".contact")
.first()
.clone()
.insertAfter($(".contact").last());
$contactItem.find("input").each(function(){
$(this).rules("add", {
required : true,
messages : { required : 'field is required.' }
});
});
But my bad luck, this technique did not solve my issue. So I am looking for another solution for it.
Some details on library I am using:
jQuery v1.9.1
jQuery Validation Plugin v1.17.0
$(document).ready(function() {
let $validator;
$("#btnAddNew")
.off("click")
.on("click", function() {
let $contactItem = $(".contact")
.first()
.clone()
.insertAfter($(".contact").last());
});
$validator = $("#contactForm").validate({
rules: {
firstName: {
required: true
},
lastName: {
required: true
}
},
messages: {
firstName: {
required: "* Required"
},
lastName: {
required: "* Required"
}
},
ignore: ":hidden, :disabled"
});
$("#btnSave")
.off("click")
.on("click", function() {
if ($validator.form()) {
console.log("ok");
}
});
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-validation#1.19.2/dist/jquery.validate.js"></script>
<div class="container">
<form id="contactForm">
<div class="contact">
<h5 class="card-title">Contact Info</h5>
<div class="form-row">
<div class="form-group col-md-6">
<label for="inputEmail4">First Name</label>
<input type="text" class="form-control" name="firstName" placeholder="Your First Name">
</div>
<div class="form-group col-md-6">
<label for="inputEmail4">Last Name</label>
<input type="text" class="form-control" name="lastName" placeholder="Your Last Name">
</div>
</div>
</div>
<button type="button" id="btnAddNew" class="btn btn-primary">Add Next</button>
<button type="button" id="btnSave" class="btn btn-primary">Save</button>
</form>
</div>
Just adding required to the elements is probably the simplest solution and modify the default message.
I've also commented out an approach for setting class rules.
Note you also need to modify the names in order for them to be unique. I've used very simple incremental logic , modify if you will be adding and removing
$.extend($.validator.messages, {
required: "* required."
})
// Alternate using class rules
/*jQuery.validator.addClassRules("name-field", {
required: true
});*/
$(document).ready(function() {
let $validator;
$("#btnAddNew")
.off("click")
.on("click", function() {
let $contact = $(".contact");
let $contactItem = $contact
.first()
.clone()
.insertAfter($(".contact").last());
// increment input names
$contactItem.find('input').attr('name', function(_, curr) {
return curr + $contact.length
});
});
$validator = $("#contactForm").validate();
$("#btnSave")
.off("click")
.on("click", function() {
if ($validator.form()) {
console.log("ok");
}
});
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-validation#1.19.2/dist/jquery.validate.js"></script>
<div class="container">
<form id="contactForm">
<div class="contact">
<h5 class="card-title">Contact Info</h5>
<div class="form-row">
<div class="form-group col-md-6">
<label for="inputEmail4">First Name</label>
<input type="text" class="form-control name-field" name="firstName" placeholder="Your First Name" required>
</div>
<div class="form-group col-md-6">
<label for="inputEmail4">Last Name</label>
<input type="text" class="form-control name-field" name="lastName" placeholder="Your Last Name" required>
</div>
</div>
</div>
<button type="button" id="btnAddNew" class="btn btn-primary">Add Next</button>
<button type="button" id="btnSave" class="btn btn-primary">Save</button>
</form>
</div>

bootstrap 4 validation disable submit button until form validated

In the following example of my problem I have 2 fields needing to be validate.
Until all (2 in this case) fields are validated, the submit button should be disabled.
If both are validated it should be enabled.
My problem: The minute the first field is validated - the button is enabled, which is too early.
I understand (ot think that I do) that this occurs because of where I placed $("#submitBtn").attr("disabled",false);
Any hint of how to get it work would be greatly appreciated.
EDIT: For an example of a full registration form with the submit button enabled ONLY when all the form's elements are validated, see this.
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<style>
input[type="submit"]:disabled {
background-color: red; }
</style>
</head>
<body>
<div class="container mt-2">
<div class="row">
<div class="col-md-4 offset-md-4">
<form action="page2.php" id="myForm1" class="needs-validation" novalidate>
<div class="form-group">
<input type="text" class="form-control" pattern="^[a-z]{3,6}$" required autofocus>
<div class="valid-feedback">Valid</div>
<div class="invalid-feedback">a to z only (3 to 6 long)</div>
</div>
<div class="form-group">
<input type="text" class="form-control" pattern="^[a-z]{3,6}$" required>
<div class="valid-feedback">Valid</div>
<div class="invalid-feedback">a to z only (3 to 6 long)</div>
</div>
<div class="form-group">
<button id="submitBtn" type="submit" class="btn btn-primary submit-button" disabled>Submit</button>
</div>
</form>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<script>
window.addEventListener('load', function() {
let currForm1 = document.getElementById('myForm1');
// Validate on input:
currForm1.querySelectorAll('.form-control').forEach(input => {
input.addEventListener(('input'), () => {
if (input.checkValidity()) {
input.classList.remove('is-invalid')
input.classList.add('is-valid');
$("#submitBtn").attr("disabled",false); <<<<======== ??????
} else {
input.classList.remove('is-valid')
input.classList.add('is-invalid');
}
});
});
// Validate on submit:
currForm1.addEventListener('submit', function(event) {
if (currForm1.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
currForm1.classList.add('was-validated');
}, false);
});
</script>
Inside your input event listener check if all the inputs have an is-valid class. If all your inputs have an is-valid class, turn off the disabled button.
currForm1.querySelectorAll('.form-control').forEach(input => {
input.addEventListener(('input'), () => {
if (input.checkValidity()) {
input.classList.remove('is-invalid')
input.classList.add('is-valid');
// $("#submitBtn").attr("disabled",false); <<<<======== ??????
} else {
input.classList.remove('is-valid')
input.classList.add('is-invalid');
}
var is_valid = $('.form-control').length === $('.form-control.is-valid').length;
$("#submitBtn").attr("disabled", !is_valid);
});
});
I don't know this is good approach or not and it also depend on your requirement if it fulfil your need so that's fine..
here i'm removing some line and adding some line
remove disable button code from first condition and added at the last
if(input.checkValidity() && index ===1) {
$("#submitBtn").attr("disabled", false);
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<style>
input[type="submit"]:disabled {
background-color: red; }
</style>
</head>
<body>
<div class="container mt-2">
<div class="row">
<div class="col-md-4 offset-md-4">
<form action="page2.php" id="myForm1" class="needs-validation" novalidate>
<div class="form-group">
<input type="text" class="form-control" pattern="^[a-z]{3,6}$" required autofocus>
<div class="valid-feedback">Valid</div>
<div class="invalid-feedback">a to z only (3 to 6 long)</div>
</div>
<div class="form-group">
<input type="text" class="form-control" pattern="^[a-z]{3,6}$" required>
<div class="valid-feedback">Valid</div>
<div class="invalid-feedback">a to z only (3 to 6 long)</div>
</div>
<div class="form-group">
<button id="submitBtn" type="submit" class="btn btn-primary submit-button" disabled>Submit</button>
</div>
</form>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<script>
window.addEventListener('load', function() {
let currForm1 = document.getElementById('myForm1');
// Validate on input:
currForm1.querySelectorAll('.form-control').forEach((input, index) => {
input.addEventListener(('input'), () => {
if (input.checkValidity()) {
console.log(input.checkValidity());
input.classList.remove('is-invalid')
input.classList.add('is-valid');
} else {
input.classList.remove('is-valid')
input.classList.add('is-invalid');
}
if(input.checkValidity() && index ===1) {
$("#submitBtn").attr("disabled", false);
}
});
});
// Validate on submit:
currForm1.addEventListener('submit', function(event) {
if (currForm1.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
currForm1.classList.add('was-validated');
}, false);
});
</script>
</body>
</html>
We need to check if all the other inputs are also valid before assuming that we can just enable it
let currForm1 = document.getElementById('myForm1');
// Validate on input:
currForm1.querySelectorAll('.form-control').forEach(input => {
input.addEventListener(('input'), () => {
if (input.checkValidity()) {
/* IF IT PASSES WE NEED TO CHECK THE OTHER INPUTS */
/* STORE ALL THE INPUTS THAT PASS THE CHECKVALIDITY */
let allValid = currForm1.querySelectorAll('.form-control').filter(input =>
{ return input.checkValidity() })
/* WE CAN NOW UPDATE THE SUBMIT BASED ON THE NUMBER OF VALID
INPUTS WE HAVE */
$("#submitBtn").attr("disabled", allValid.length === currForm1.querySelectorAll('.form-control').length);
input.classList.remove('is-invalid')
input.classList.add('is-valid');
} else {
/* IF IT FAILS WE DONT NEED TO CHECK WE WANT THE VALIDATOR AS FALSE */
$("#submitBtn").attr("disabled", true);
input.classList.remove('is-valid')
input.classList.add('is-invalid');
}
});
});
/* FINALLY WE CAN UPDATE THE SUBMIT, BASED ON OUR VARIABLE */
$("#submitBtn").attr("disabled", validatorForSubmit );

Jquery validator moves input field

I've got three fields inline and one of them is a inpt field, this is how it look like when they are validated
https://ibb.co/X8c1jDZ
the problem is when I enter some values into the input fiedl then it moves all the other fields as you can see from the image
https://ibb.co/Fn666cw
I believe something is wrong with the way I unhighlight the field once has been filled but not sure, maybe someone can help me. Please let me know if you need more details. many thanks
This is my html code
<div class="row">
<div class="form-group fieldGroup">
<div class="col-md-4">
<div class="form-group">
<label class="control-label">Tipologia proprietario</label>
<select class="form-control bs-select" id="kmg_admin_new_building_owner_type-1" name="kmg_admin_new_building_owner_type[]" data-live-search="true" title="Seleziona tipologia proprietario">
<option value="1">Proprietario</option>
<option value="2">Co-Proprietario</option>
<option value="3">Nudo proprietario</option>
<option value="4">Usufruttuario</option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="control-label">Proprietario</label>
<select class="form-control bs-select" id="kmg_admin_new_building_owner-1" name="kmg_admin_new_building_owner[]" data-live-search="true" title="Seleziona tipologia proprietario">
<option value="1">Proprietario</option>
<option value="2">Co-Proprietario</option>
<option value="3">Nudo proprietario</option>
<option value="4">Usufruttuario</option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="control-label">Se
<span class="required"> * </span>
</label>
<div class="input-group">
<input type="text" class="form-control prova" id="kmg_admin_new_building_owner_quota-1" name="kmg_admin_new_building_owner_quota[]" placeholder="Quota titolare">
<span class="input-group-btn input-group-btn input-space">
<button class="btn btn-default addMore" type="button">Aggiungi proprietario</button>
</span>
<span class="input-group-btn input-group-btn input-space">
<button class="btn btn-default remove" type="button">Rimuovi proprietario</button>
</span>
</div>
</div>
</div>
</div>
</div>
This is my javascript code
form.validate({
// doNotHideMessage: true, //this option enables to show the error/success messages on tab switch.
errorElement: 'span', //default input error message container
errorClass: 'help-block help-block-error', // default input error message class
focusInvalid: false, // do not focus the last invalid input
rules: {
kmg_admin_new_building_increment: {
required: true,
digits: true,
remote: {
type: 'POST',
data: {
ajax_action: 'kmg_new_building_check_increment',
kmg_new_building_increment: function() {
return $( "#kmg_admin_new_building_increment" ).val();
}
}
}
},
kmg_admin_new_building_type: { required: true },
kmg_admin_new_building_palazzina: { required: true },
kmg_admin_new_building_interno: { required: true },
"kmg_admin_new_building_owner_type[]": {required: true},
"kmg_admin_new_building_owner[]": { required: true },
"kmg_admin_new_building_owner_quota[]": {
required: true,
number: true,
min: 0,
max: 100
},
kmg_admin_new_building_metri: {
required: false,
digits: true
}
},
messages: {
kmg_admin_new_building_increment: {
required: "Specifica un ordine di stampa univoco",
digits: "L'ordine di stampa può solo essere un numero",
remote: "Ordine di stampa è già registrato!",
},
kmg_admin_new_building_type: "Specifica la tipologia dell'unità immobiliare",
kmg_admin_new_building_palazzina: "Specifica la palazzina dell'unità immobiliare",
kmg_admin_new_building_interno: "Inserisci il valore d'interno",
"kmg_admin_new_building_owner_type[]": "Seleziona tipologia di proprietario",
"kmg_admin_new_building_owner[]": "Seleziona proprietario",
"kmg_admin_new_building_owner_quota[]": {
required: "Specifica la quota",
number: "solo numeri",
min: "minimo 0",
max: "massimo 100"
},
kmg_admin_new_building_metri: {digits: "Inserisci valore numerico"}
},
errorPlacement: function(error, element) { // render error placement for each input type
if (element.parent(".input-group").length > 0) {
error.insertAfter(element.parent(".input-group"));
} else {
error.appendTo(element.closest('.form-group'));
}
},
invalidHandler: function(event, validator) { //display error alert on form submit
success.hide();
error.show();
App.scrollTo(error, -200);
},
highlight: function(element) { // hightlight error inputs
$(element).closest('.form-group').removeClass('has-success').addClass('has-error');
},
unhighlight: function(element) { // revert the change done by hightlight
$(element).closest('.form-group').removeClass('has-error'); // set error class to the control group
},
success: function(label) {
label.addClass('valid').closest('.form-group').removeClass('has-error').addClass('has-success'); // set success class to the control group
},
This is how i clone the fields
//add more fields group
var fieldGroup = $(".fieldGroup").clone();
// Hide remove button
$(".remove").parent('span').hide();
$(".addMore").click(function(e) {
var fgc = $('body').find('.fieldGroup').length;
var fieldHTML = '<div class="form-group fieldGroup">' + fieldGroup.html() + '</div>';
fieldHTML = fieldHTML.replace('kmg_admin_new_building_owner_type-1', 'kmg_admin_new_building_owner_type-' + (fgc + 1));
fieldHTML = fieldHTML.replace('kmg_admin_new_building_owner-1', 'kmg_admin_new_building_owner-' + (fgc + 1));
fieldHTML = fieldHTML.replace('kmg_admin_new_building_owner_quota-1', 'fkmg_admin_new_building_owner_quota-' + (fgc + 1));
$('body').find('.fieldGroup:last').after(fieldHTML);
var el = $('.fieldGroup').next();
// Hide add new button
el.find('.addMore').parent('span').hide();
// Show remove button
el.find('.remove').parent('span').show();
// Load selectpicker again after cloning the inputs
$('.bs-select').selectpicker({
iconBase: 'fa',
tickIcon: 'fa-check',
dropupAuto: false
});
});
//remove fields group
$("body").on("click", ".remove", function() {
$(this).parents(".fieldGroup").remove();
});
This is not a serious problem, I think, you just have to think of the changes of the layout, and prepare for them in your CSS.
Here's an example of what's happening:
(You can find a short explanation at the bottom of the answer.)
jQuery(document).ready(function($) {
$(".modify").on('click', function(e) {
// $.fn.toggle() switches between display: none and
// display: block
$('#il3').find('label').toggle()
})
})
.inputandlabel {
float: left;
}
input[type="text"],
label {
display: block;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<div class="container">
<div class="row">
<div class="col-6">
<button type="button" class="btn btn-primary modify">Just push it to see the problem</button>
</div>
</div>
<div class="row">
<div class="col-12">
<div id="il1" class="inputandlabel">
<label for="form1">Form1</label>
<input id="form1" type="text" />
</div>
<div id="il2" class="inputandlabel">
<label for="form2">Form2</label>
<input id="form2" type="text" />
</div>
<div id="il3" class="inputandlabel">
<label for="form3">Form3</label>
<input id="form3" type="text" />
</div>
<div id="il4" class="inputandlabel">
<label for="form4">Form4</label>
<input id="form4" type="text" />
</div>
<div id="il5" class="inputandlabel">
<label for="form5">Form5</label>
<input id="form5" type="text" />
</div>
<div id="il6" class="inputandlabel">
<label for="form6">Form6</label>
<input id="form6" type="text" />
</div>
</div>
</div>
</div>
And here's a solution:
jQuery(document).ready(function($) {
$(".modify").on('click', function(e) {
e.preventDefault()
if ($('#il3').find('label').css('visibility') !== 'hidden') {
$('#il3').find('label').css('visibility', 'hidden')
} else {
$('#il3').find('label').css('visibility', 'visible')
}
})
})
.inputandlabel {
float: left;
}
input[type="text"],
label {
display: block;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<div class="container">
<div class="row">
<div class="col-6">
<button type="button" class="btn btn-primary modify">Just push it to see "nothing"</button>
</div>
</div>
<div class="row">
<div class="col-12">
<div id="il1" class="inputandlabel">
<label for="form1">Form1</label>
<input id="form1" type="text" />
</div>
<div id="il2" class="inputandlabel">
<label for="form2">Form2</label>
<input id="form2" type="text" />
</div>
<div id="il3" class="inputandlabel">
<label for="form3">Form3</label>
<input id="form3" type="text" />
</div>
<div id="il4" class="inputandlabel">
<label for="form4">Form4</label>
<input id="form4" type="text" />
</div>
<div id="il5" class="inputandlabel">
<label for="form5">Form5</label>
<input id="form5" type="text" />
</div>
<div id="il6" class="inputandlabel">
<label for="form6">Form6</label>
<input id="form6" type="text" />
</div>
</div>
</div>
</div>
You can see from the two snippets, that by setting display: none; on the label scrambles the layout. display: none; takes the element out of the flow (not the DOM itself, but from the object flow), while visibility: hidden; just makes the element invisible. Quite a difference, isn't it?
So, setting the display CSS property to none "removes the height" that kept your layout in order - try setting the elements visibility to hidden with JS.
If that's not working, then give the form-group a fixed height (the height with success / error message), and don't change that value on success / error.

Do not submit form before jquery validate is okay

I am looking for a way, so that my FormMethod.Post Dosen't submit, before jquery validation is done. I have tried by making it so that the button just is at disabled, and then remove disable on keydown, if form is okay. But that didn't work, and neither isn't secure. What can i do?
Html
#using (Html.BeginForm("_Kontakt", "Home", FormMethod.Post))
{
<div class="row">
<div class="col-sm-6">
<div class="col-sm-12">
<b>Facebook Url</b>
<input id="FacebookUrl" name="FacebookUrl" type="text" class="form-control" />
</div>
<div class="col-sm-12">
<b>Steam Url</b>
<input id="SteamUrl" name="SteamUrl" type="text" class="form-control" />
</div>
<div class="col-sm-12">
<button id="SendBtn" class="btn btn-success pull-right" onclick="return validateUrl();">Send</button>
</div>
</div>
</div>
}
Jquery/Javascript
function validateUrl() {
facebookURL = $("#FacebookUrl").val();
steamURL = $("#SteamUrl").val();
var facebook = /^(?:(?:http|https):\/\/)?(?:www.)?facebook.com\/(?:(?:\w)*#!\/)?(?:pages\/)?(?:[?\w\-]*\/)?(?:profile.php\?id=(?=\d.*))?([\w\-]*)?$/;
var steam = /(?:https?:\/\/)?steamcommunity\.com\/(?:profiles|id)\/[a-zA-Z0-9]+/;
if (facebook.test(facebookURL)) {
}
else {
alert("Ikke et facebook gyldigt url!");
}
if (steam.test(steamURL)) {
}
else {
alert("Ikke et steam gyldigt url!");
}
return facebook.test(facebookURL);
return steam.test(steamURL);
}
ANSWERE
return facebook.test(facebookURL) && steam.test(steamURL);
There is an "onsubmit" event that allows you to control form submission http://www.w3schools.com/tags/ev_onsubmit.asp
If you put the inputs and button in a form element and use the pattern and required attributes in combination with the :invalid selector the browser can do the validation for you:
/* Add the .focused class when the user focuses
an input to only show the error message once */
$("#the-form input").focus(function(){
this.classList.add("focused");
});
.input-error-message {
color: red;
}
/* Show elements with the class .input-error-message
if they come after an input with invalid data if the
user isn't typing or if it has not been focused yet */
:invalid:not(:focus).focused + .input-error-message {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<form class="col-sm-6" id="the-form" onsubmit="return isValid()">
<div class="col-sm-12">
<b>Facebook Url</b>
<input id="FacebookUrl" name="FacebookUrl" type="text" class="form-control" pattern="^(?:(?:http|https):\/\/)?(?:www.)?facebook.com\/(?:(?:\w)*#!\/)?(?:pages\/)?(?:[?\w\-]*\/)?(?:profile.php\?id=(?=\d.*))?([\w\-]*)?$" required/>
<div class="input-error-message" hidden>Ikke et facebook gyldigt url!</div>
</div>
<div class="col-sm-12">
<b>Steam Url</b>
<input id="SteamUrl" name="SteamUrl" type="text" class="form-control" pattern="(?:https?:\/\/)?steamcommunity\.com\/(?:profiles|id)\/[a-zA-Z0-9]+" required/>
<div class="input-error-message" hidden>Ikke et steam gyldigt url!</div>
</div>
<div class="col-sm-12">
<button id="SendBtn" class="btn btn-success pull-right">Send</button>
</div>
</form>
</div>

Categories