Given the following markup:
<input name="active" type="hidden" value="0" />
<input id="active" name="active" type="checkbox" value="1" />
When the checkbox is unchecked and the form is submitted the server will get a value of "0" for the "active" param. When the checkbox is checked and the form is submitted the server will get a value of "1" for the "active" param. This works just fine.
What I want to do is capture the proper value in JavaScript based upon that. The trick, however, is I don't know if the input is a checkbox or not. As far as my script is concerned it is just acting on a set of inputs.
I have created a JSFiddle here: http://jsfiddle.net/bcardarella/5QRjF/ that demonstrates the issue.
TL;DR I want to ensure the value I capture from each input is the actual value sent to the server.
Don't know if you actually want to check for the checkbox or not, but this code works:
$(function() {
var getCheckBoxValue = function() {
if ($('[name="active"]:checkbox').attr("checked")) {
return $('[name="active"]:checkbox').val();
} else {
return $('[name="active"]').val();
}
}
var result = $('#result');
result.append($('<p/>', {text: 'Expected value 0, got: ' + getCheckBoxValue()}));
$(':checkbox')[0].checked = true;
result.append($('<p/>', {text: 'Expected value 1, got: ' + getCheckBoxValue()}));
});
Basically if the checkbox is checked, use that, otherwise, go with the default value from the hidden input.
Edit
Turned my comment into a fiddle, I've also added another field, a text field, to show better the idea behind it: http://jsfiddle.net/45qup/
Hope it helps!
Write up the click event for the checkbox..
$('#active').on('click', function(){
var isChecked = this.checked;
var val = 0;
if(isChecked){
val = 1
}
});
Try somthing like
$("form#formID :input").each(function(){
if ($(this).attr() == 'checkbox') return $(this).checked();
else return $(this).val();
});
Not sure if if Iād go with this ;) , but it works:
var getCheckBoxValue = function() {
var values = $('[name="active"]')
.filter(':checked, :hidden')
.map(function(){
return parseInt($(this).val(), 10);
}
);
return Math.max.apply(Math, values);
}
http://jsfiddle.net/Xc5H7/1/
Inspired by #Deleteman's idea, this is a slightly simpler way of doing it:
var getCheckBoxValue = function() {
var input = $('[name="active"]');
return $(input[1].checked ? input[1] : input[0]).val();
}
This assumes there's only two fields with this name, which is a sane assumption for what you're trying to do.
It also assumes the hidden field always comes before the checkbox, which again, since this is, I assume, for Rails, is a sane assumption :)
Related
I have a select box. Currently, this select box make an ajax call on change.
Now, I want to make call only when a condition is met.
So, here is my code:
$('#buildingSelect').on('change', function(){
var result = checkDirtyStatus();
//this checkDirtyStatus alert message if there is some changes on the form.
//if cancel return false, if confirm return true.
if(result === false) {
return;
}
//make ajax call
});
This prevents from making ajax call, however, this change the selected option of the select i.e, if option1 is selected at the begining and if I try to select next option then it will change the selected option to option2 then only check the status.
On searching on the internet, I got the option of focusin.
$('#buildingSelect').on('focusin', function(){
// console.log("Saving value " + $(this).val());
var result = checkDirtyStatus();
if(result === false) {
return;
}
}).on('change', function(){
g_building_id = $(this).val();
getAmenitiesDetails(g_building_id);
});
However, using this focusin options makes the alert box to appear everytime no matter either I click cancel or ok. This might be because, it call focusin again whenevr I click Ok or Cancel.
What would be the best option to check this status, and if result is false, I don't want to change the selected option as well.
Update
Answer from marked as duplicate not preventing from changing the selected option. Its making ajax call on click i.e. before checking condition.
CodePen Link
function checkDirtyStatus(){
dirtyStatus = true;
if(dirtyStatus === true){
if (confirm("Changes you made may not be saved.")) {
return true;
}else{
return false;
}
}
}
Finally, by mixing the link from Rory and idea of organizing code from some. I have find a solution for my problem. So, if anyone got stuck on the similar problem here is my solution.
$(function(){
var lastSel;
$('#buildingSelect').on('focusin', function(){
lastSel = $("#buildingSelect option:selected");
}).on('change', function(){
if(!checkDirtyStatus()) {
lastSel.prop("selected", true);
return;
}else{
//made ajax call
//$.ajax({})
}
});
});
function checkDirtyStatus(){
let dirtyStatus = getDirtyStatus();
if(dirtyStatus){
return confirm("Changes you made may not be saved.");
}
return true;
}
Let us look at your function:
function checkDirtyStatus(){
dirtyStatus = true; // I assume this is only for testing
if(dirtyStatus === true){ // This can be simplified.
if (confirm("Changes you made may not be saved.")) {
return true;
}else{
return false;
}
}
}
confirm returns a Boolean that is either true or false, so you can simplify your function like this:
function checkDirtyStatus(){
dirtyStatus = true;
if(dirtyStatus){
return confirm("Changes you made may not be saved.");
}
// Notice that you do not return anything here. That means that
// the function will return undefined.
}
Your other function can be simplified like this:
$('#buildingSelect').on('change', function(){
if(!checkDirtyStatus()){
// Here you probably want to set the value of the select-element to the
// last valid state. I don't know if you have saved it somewhere.
return;
}
//make ajax call
});
I played with your codepen and you have some errors in your selectors. As I get confused by your explanation I will try to explain what you could update and how to use it in your code and I hope this is what you need to solve your problem.
First I would change your js to this:
var lastSel = $("#buildingSelect").val();
$("#buildingSelect").on("change", function(){
if ($(this).val()==="2") {
$(this).val(lastSel);
return false;
}
});
The proper way to get the value of a select box in jquery is with the .val(). In your case you selected the entire selected option element.
I store this value in the lastSel variable. Then in the change function the new value of the select list is $(this).val(). I check against this value and if it equals 2 I revert it to the value stored in the lastSel variable with this $(this).val(lastSel).
Keep in mind that the value of a select list is always a string, if you want to check against a number you must first cast it to a numeric value e.g. by using parseInt.
If you want to use the checkDirtyStatus for the check then you should only call this function in the change and pass as parameters the lastSel and the newSel like this:
$("#buildingSelect").on("change", function(){
checkDirtyStatus(lastSel, $(this).val());
});
Then you can transfer the logic from the change function into the checkDirtyStatus function and do your checks there. In this case if you wish to revert the select value instead of $(this).val(lastSel) you will do a $("#buildingSelect").val(lastSel).
I hope this helps.
Friends i am new to javascript, I am trying to write a script to validate the entire form whenever any input field value is changed of input fiels with the data attribute of required.
HTML
<form>
<input type="text" name="FirstName" class="inputField" data-required="true"></input>
<input type="text" name="MiddleName" class="inputField"></input>
<input type="text" name="LastName" class="inputField" data-required="true"></input>
</form>
SCRIPT
var field, required, isValid, fieldVal;
function validatedForm() {
field = document.querySelectorAll('.inputField');
document.getElementById("submitButton").disabled = true;
var isValid = true;
for(var i=0; i < field.length; i++){
required = field[i].dataset.required;
if(required){
field[i].addEventListener('blur', function(e){
fieldVal = this.value;
if(fieldVal == ''){
isValid = false;
}
checkSubmitBtn();
}, true);
}
}
function checkSubmitBtn() {
if(isValid = true) {
console.log(isValid);
document.getElementById("submitButton").disabled = false;
}
}
}
window.addEventListener("load", validatedForm);
PROBLEM 1:
The isValid is not updating hence even an empty blur on the input field makes the button disable to be false.
PROBLEM 2:
In case there are multiple forms on the page then how to validate only the desired forms .. just like in jQuery we add a script tag in the end to initialize the script according to it.
PROBLEM 3:
Is there a way to change the disable state of the button without the GetElementID ... I mean if that can be managed depending on the submit button of that particular form on the page where the script is suppose to work.
Any help will be highly appreciated. Thanks in advance.
I think you need something like the following form validation..
<script type="text/javascript">
var field, fieldVal, required = false;
function validatedForm() {
field = document.querySelectorAll('.inputField');
document.getElementById("submitButton").disabled = true;
field.forEach(function(elem) {
required = elem.dataset.required;
if(required){
elem.addEventListener('blur', function(e) {
checkSubmitBtn(field);
});
}
});
}
function checkSubmitBtn(field) {
var isDisabled = false;
field.forEach(function(elem) {
fieldVal = elem.value.trim();
if(fieldVal == ''){
isDisabled = true;
return false;
}
});
document.getElementById("submitButton").disabled = isDisabled;
}
window.addEventListener("load", validatedForm);
</script>
I hope it helps...
There are quite a few things going on here. First, your checkSubmitBtn function used a single = operator in the if statement. This won't actually check the variable, it instead will set the variable to that value. Here is the fixed function:
function checkSubmitBtn() {
if (isValid == true) {
document.getElementById("submitButton").disabled = false;
}
}
You mentioned not wanting to use getElementById. There are a few ways around this. One way would be to call the function once and store it in a variable to use later, like so:
var button = document.getElementById("submitButton");
...
function checkSubmitBtn() {
button.disabled = !isValid;
}
Another way would be to use jQuery. It still is technically calling getElementById in the backend, but the code is much simpler. If you wanted to avoid that, you also can still combine this with the technique I described above.
$("#submitButton").attr("disabled", !isValid);
I'd also like to point out that your code doesn't account for a situation where a form goes from invalid (starting point) to valid and back to invalid again. Say a user types in all of the fields but then backspaces everything. Your code will fall apart.
Lastly, your <input> HTML tags should not be closed. There are certain tags that are considered "self-closing", i.e. you don't have to write the closing tag, </input>.
Example, i have input where default value is 5.
But user remove it using backspace, so after that i want to set default value again.
Lets say your input is having a id test you can do like below
$('#test').on('change blur',function(){
if($(this).val().trim().length === 0){
$(this).val(5);
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="test" type="text" value = "5" />
Use defaultValue to get the default value if set originally:
$(':text').on('blur', function(e){
this.value = this.value.trim() || this.defaultValue;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type='text' value='5'>
I'd suggest not using keyup, as that would prevent the user from deleting the default value and then updating with a new value (since after keyup is triggered by the backspace key there will be no value).
Instead I'd suggest using change and blur, to give (assuming that the relevant element is held in the selector variable):
$(selector).on('change blur', function() {
// sets the value of the element based on the current-value;
// if the value is equal to an empty string ('') once the
// leading and trailing white-space is removed (using
// String.prototype.trim()) then we set the value to the
// defaultValue (the value held by the <input> on page-load)
// otherwise we set it to the current-value:
this.value = this.value.trim() === '' ? this.defaultValue : this.value;
});
If you wanted to implement the same functionality in plain JavaScript ā again assuming the relevant element is held in the selector variable ā you could use the following:
function defaultIfEmpty(){
let el = this;
el.value = el.value.trim() === '' ? el.defaultValue : el.value;
}
selector.addEventListener('change', defaultIfEmpty);
It would be better to use blur instead of keyup, and here's why.
What happens if the user wants to enter in a number (only one digit), but it's not 5, let's say it's (3). If the user backspaces the default number, which is (5) in this case, and wants to enter a single digit, the user will never be able to.
$('#test').on('blur',function(){
if($(this).val().trim().length == 0){
$(this).val(5);
}
})
Note: You should also use a keyup function to check if the value is an integer, !isNaN
A more generic solution:
HTML
<input type='text/numeric/etc' data-default='defaultValue' value='defaultValue' />
JavaScript
$('input[data-default], textarea[data-default]').on('change blur',function(){
if($(this).val().length == 0) {
$(this).val($(this).attr("data-default"));
}
}
Any input or textarea with the data-default attribute set will fallback to the default once it's emptied.
<input class="test" type="text" value = "5" />
JS
//get default value
val = $('.test').val();
$('.test').on('change blur', function() {
//check if change
if ($(this).val().trim().length === 0) {
$(this).val(val);
}
})
i have a form with few input fields with class "inputfields" need to validate each field if empty alert 'fieldname is empty' otherwise return true my jquery code is not working keep getting errors at the console log can any one help please ?
jQuery(document).ready(function() {
$('.inputfields').each.on('change keyup' ,function(){
var ope = $(this).attr('name');
if (ope.val()==''){
alert(ope+'is empty');
}else {
console.log(ope);
}
});
});
I believe you want to check different types of input fields, hence want to use change and keyup.
I tried something based on your code, but this following solution will only work, if you want to validate text type input fields. For select or other input types you have to put some more checks inside the loop or have to some other way to validate.
$('.inputfields').each(function() {
$(this).bind('change keyup', function() {
var ope = $(this).attr('name');
if ($(this).val() == '') {
console.log(ope+'is empty');
} else {
console.log(ope+ ' : ' + $(this).val());
}
});
});
Hope this will lead you to find your desired solution.
http://jsfiddle.net/B9Fub/
<tr class="fis">
Test: <input type="text" name="test" id="test" value="Test">
<tr class="fis">
Empty: <input type="text" name="empty" id="empty">
<input type="button" value="find" id="find">
$('#find').click(function() {
alert('wont work if any other fields are filled other than TEST');
});
$('#test').change(function() {
// needs to fill the form for other functionality
$('#empty').val('empty');
alert('change');
});
So here I have fields that are filled when the first input is 'changed'
But I don't want it to run [change] if they input in the first field and click the 'find' button.
I was wondering if there was a way to do this. From what I found, 'change' happens before the 'find' button if you click on it.
I've tried changing 'change' to 'focus' and give it to the other field so the first field has no event handlers, but that may give me trouble further down the way.
I need the fields to be filled but I don't want them filled if the user clicks the find button.
The mousedown event fires before the change event, so by using that and jQuery's data() method you can set a flag to see if the activeElement is in fact #test when the find button is clicked, and if so don't set the value :
$('#find').on('mousedown', function() {
$('#test').data('flag', document.activeElement.id === 'test');
});
$('#test').on('change', function() {
if ( ! $(this).data('flag') ) $('#empty').val('empty');
});
FIDDLE
Still, not sure what you want. Maybe this will help.
var frm = $('form')[0]; //assuming you have one form on that page
var fnd = $('#find');
fnd.click(function(){
var te = 0, fe = 0;
if(frm.elements[0].value !== '')te = 1;
for(var i=1,l=frm.length; i<l; i++){
if(frm.elements[i].value !== '')fe = 1;
}
if(fe === 1){
return false;
}
else{
// do your thing here
return true; // some editors show an error if you don't always return a value
}
});
$('#test').change(function(){
if(fnd.val() !== ''){
return false;
}
else{
// do your thing here
return true;
}
});
I've found the answer. Using e.stopPropagation(); on $('#find') allowed me to stop the .change() from occurring