Empty input counting as full - javascript

So I have a form and you get the percent of the form you've completed. The problem is on one of the inputs, I get a result even though its empty. I'm not sure how to fix this. Heres the code
countMissing();
function countMissing() {
//Get total inputs
console.log("Total inputs " + form.getElementsByTagName('input').length);
//Divide by complete inputs out of 100% and get percent
console.log("The percentage is " + 100 / form.getElementsByTagName('input').length + "%");
var tot = 100 / form.getElementsByTagName('input').length + "%"
//Check
var cback=function(){
bad=0;
$('.form :text').each(function (i,e) {
if ($.trim($(e).val()) == "") bad++;
//Change width
$('.top').css('width', bad + '%');
});
//Missing amount of fields
if (bad > 0) $('.congrats').css("display", "block").text(100/bad + ' Completed ');
else $('.congrats').hide();
}
$(document).delegate('.form :text','focus',cback);
$(document).delegate('.form :text','keyup',cback);
}
And a link to the demo http://jsbin.com/xijemuli/2/edit Any ideas?

FIDDLE : http://jsfiddle.net/abdennour/3mH6w/3/
function count(){
console.log("Total inputs " + $('.form :text').length);
//Divide by complete inputs out of 100% and get percent
console.log("The percentage is " + bad / $('.form :text').length + "%");
return 100-(bad / $('.form :text').length)*100 + "%"
}
UPDATE :
Another example with form of 10 inputs : http://jsfiddle.net/abdennour/3mH6w/6/

I think you need to specify .value().length (not sure if it includes the brackets or not - from memory:
form.getElementsByTagName('input').value.length

There were several things going on with your code, but the primary problem you were having is calculating the percentage.
To find the percentage of form remaining, the math is:
(total_fields - empty_fields / total_fields)
After making that change (and a few others), your tested and working code is as follows:
countMissing();
function countMissing() {
var i = $('input').not('[type="button"]').length;
var cback=function(){
bad=0;
$('.form :text').each(function (i,e) {
if ($.trim($(e).val()) === "") bad++;
$('.top').css('width', bad + '%');
});
// Missing amount of fields
if (bad > 0) {
$('.congrats').css("display", "block").text(((i - bad)/ i) * 100 + ' Completed ');
} else {
$('.congrats').hide();
}
$(document).delegate('.form :text','focus',cback);
$(document).delegate('.form :text','keyup',cback);
}

I am pretty sure your code tried to kill my computer. Here is the approach I'd take:
$('form').on('input', function(e) {
var $inputs = $(this).find('input'),
$empties = $inputs.filter(function(){
return $.trim(this.value).length === 0;
});
$('.info').text($empties.length + ' of ' + $inputs.length + ' are empty!');
}).trigger('input');
along with a small demo: http://jsbin.com/gitef/4/edit?js,output

Related

why my for loop is infinite here

below is the js code for wikipedia search project. I am getting infinite for loop even though it had condition to stop repeating the loop. I am stuck in this problem.
$(document).ready(function() {
$('.enter').click(function() {
var srcv = $('#search').val(); //variable get the input value
//statement to check empty input
if (srcv == "") {
alert("enter something to search");
}
else {
$.getJSON('https://en.wikipedia.org/w/api.php?action=opensearch&search=' + srcv + '&format=json&limit=20&callback=?', function(json) {
$('.content').html("<p> <a href ='" + json[3][0] + "'target='_blank'>" + json[1][0] + "</a><br>" + json[2][0] + "</p>");
/*for loop to display the content of the json object*/
for (i = 1; i < 20; i++) {
$('p').append("<p><a href ='" + json[3][i] + "'target='_blank'>" + json[1][i] + "</a>" + json[2][i] + "</p>");
}
});
}
});
});
You are appending to each and every one of <p> in page.
Since your for loop appends even more <p> (and you possibly have a high number of <p> elements in your page beforehand) you overflow your call stack.
You probably wanted to append to a specific <p>. Try giving an id to your selector.
from what i can see in the url you need to do the following:
loop over the terms found and select the link based on the index of the element, chose a single element .contentto append the data not a set of elements p, this will increase the number of duplicated results
$.getJSON('https://en.wikipedia.org/w/api.php?action=opensearch&search='+srcv+'&format=json&limit=20&callback=?', function(json){
$.each(json[1],function(i,v){
$('.content').append("<p><a href ='"+json[2][i]+"'target='_blank'>"+json[0]+"</a>"+v+"</p>");
});
});
see demo: https://jsfiddle.net/x79zzp5a/
Try this
$(document).ready(function() {
$('.enter').click(function() {
var srcv = $('#search').val(); //variable get the input value
//statement to check empty input
if (srcv == "") {
alert("enter something to search");
}
else {
$.getJSON('https://en.wikipedia.org/w/api.php?action=opensearch&search=' + srcv + '&format=json&limit=20&callback=?', function(json) {
$('.content').html("<p> <a href ='" + json[3][0] + "'target='_blank'>" + json[1][0] + "</a><br>" + json[2][0] + "</p>");
/*for loop to display the content of the json object*/
var i = 1;
for (i; i < 20; i++) {
$('p').append("<p><a href ='" + json[3][i] + "'target='_blank'>" + json[1][i] + "</a>" + json[2][i] + "</p>");
}
});
}
});
});

Auto filling parentheses and hyphen for phone number input jquery

I want to have a user's input auto fill the punctuation of a phone number to look like this (xxx) xxx-xxxx. I have written an example jfiddle here but it breaks when filling in the last 4 digits of the phone number.
$("#phone").on("change keyup paste", function () {
var output;
var input = $("#phone").val();
input = input.replace(/[^0-9]/g, '');
var area = input.substr(0, 3);
var pre = input.substr(3, 4);
var tel = input.substr(6, 4);
if (area.length < 3) {
output = "(" + area;
} else if (area.length == 3 && pre.length < 3) {
output = "(" + area + ")" + " " + pre;
} else if (area.length == 3 && pre.length == 3) {
output = "(" + area + ")" + " " + pre + "-" + tel;
}
$("#phone").val(output);
});
HTMl:
<input id='phone'></input>
I realize this post is older but i found it quite useful and made some minor modifications to enhance it for all telephone fields and to allow for deleting characters if the user makes a mistake.
$("input[type='tel']").each(function(){
$(this).on("change keyup paste", function (e) {
var output,
$this = $(this),
input = $this.val();
if(e.keyCode != 8) {
input = input.replace(/[^0-9]/g, '');
var area = input.substr(0, 3);
var pre = input.substr(3, 3);
var tel = input.substr(6, 4);
if (area.length < 3) {
output = "(" + area;
} else if (area.length == 3 && pre.length < 3) {
output = "(" + area + ")" + " " + pre;
} else if (area.length == 3 && pre.length == 3) {
output = "(" + area + ")" + " " + pre + "-" + tel;
}
$this.val(output);
}
});
});
<input type="tel" placeholder="(XXX) XXX-XXXX" />
When you're getting the pre code from the number, you're trying to get the index of 4, instead of four digits. So change that, and it should start working:
var pre = input.substr(3, 3);
If you don't want the dynamic filling, the other posted answers might be useful.
Regular expressions are your friend.
var ok = phNum.search(/^\(?\d{3}\D*\d{3}\D*\d{4}$/);
if (ok==0) {
var parts = phNum.match(/^\(?(\d{3})\D*(\d{3})\D*(\d{4})$/);
output.value='('+parts[1]+') '+parts[2]+'-'+parts[3];
}
Accepts: 404-555-1234, 4045551234, (404) 555-1234, etc.
Returns: (404) 555-1234
If you started to use regexp, why dont you go whole way through. Below the code that filter input value and convert it to your look.
Beware, this code only for value that contains only digits. You could block any other types via plugins or your own code. (jquery.numeric plugin is a good choice)
jquery
$(document).on('change', '.js-phone-number', function() {
var
$this = $(this),
number = $this.val();
number = number.replace(/(\d{3})(\d{3})(\d{4})/, '($1)-$2-$3');
$this.val(number);
});
You are fetching variable pre as substring of length 4 and then checking it for it is less than or equal to 3. So, basically your last else if block will never be true.
Change var pre = input.substr(3,3);
Your code will work fine.

Only input text is working correctly

So I have a script that gets the total number of inputs and get the percentage thats left to complete. But my script only gets type="text". Any ideas on how I can fix this? Here's my code
var bad = 0;
var cback=function(){
bad=0;
$('.form :text').each(function (i,e) {
if ($.trim($(e).val()) == "") bad++;
});
$('.congrats').css("display", "block").text(bad + ' missing(Completed '+count()+')');
//else $('.congrats').hide();
$(".top").css("width", 100-(bad / $('.form :text').length)*100 + "%");
}
$(document).delegate('.form :text','focus',cback);
$(document).delegate('.form :text','keyup',cback)
function count(){
return 100-(bad / $('.form :text').length)*100 + "%"
};
So how can I have type="password" and so fourth? Do I do the same code for all of them? Whats your approach guys?
You'd do that like this
var inputs = $('.form :input').not('button, [type="button"], [type="submit"]').on({input: cback});
function cback() {
var bad = inputs.filter(function() {
return !this.value.length;
}).length,
total = inputs.length;
$('.congrats').show().text(bad + ' missing(Completed ' + ((100 - (bad / total) * 100).toFixed(2) + "%") + ')');
$(".top").css("width", 100 - (bad / total) * 100 + "%");
}
FIDDLE
Try
Attribute Equals Selector [name="value"]
$('.form [type="password"]') //selector for type="password" inside element with form class
$('.form :text, .form [type="password"]')//select type="text" and type="password"
You can get all inputs with following selector
$('.form input')
$('.form input').not(':input[type=submit]');
see fiddle for result:
http://jsfiddle.net/NtL6f/

toMatch Not Working

Does anyone know why this isn't passing?
function correctColorDisplay(message, player_turn, selector) {
if ((message > 0) && (player_turn != 0)) {
return $(selector).append("<li>" + message + " " + "color(s) are present but not in the correct position in Round " + player_turn + ".</li>");
}
}
Jasmine:
describe('#correctColorDisplay', function(){
it('returns a message to the user displaying if a correct color (not positions) was chosen', function(){
var message = 2
var playerTurn = 2
var selector = $('<li></li>')
correctColorDisplay(message,playerTurn, selector)
expect(selector).toMatch("<li>" + message + " " + "color(s) are present but not in the correct position in Round " + playerTurn + ".</li>")
});
});
The error I keep getting is this giant message: Expected { 0 : HTMLNode, length : 1, jquery : '1.11.0', constructor : Function, selector : '', toArray : Function, get : Function, pushStack : Function, each, etc (it goes on much longer)
You are trying to match a newly created HTMLNode with a regular expression (that is basically just a string in this case).
The toMatch function of Jasmine is for regular expressions.
I'm not entirely familiar with Jasmine, but I'm guessing you're looking for something like:
describe('#correctColorDisplay', function(){
it('returns a message to the user displaying if a correct color (not positions) was chosen', function() {
var message = 2;
var playerTurn = 2;
var selector = $('<li></li>');
selector = correctColorDisplay(message, playerTurn, selector);
expect(selector).toEqual( $("<li><li>" + message + " " + "color(s) are present but not in the correct position in Round " + playerTurn + ".</li></li>") );
});
});
If that doesn't work, I suggest you look into jasmine-jquery.

Checking if input values are empty

I'm trying to create a tool that allows users to generate CSS code. At the moment I'm working on input - when a user leaves a text input empty, I'd like a message to appear. The code I have at the moment doesn't seem to work in doing so, any ideas?
$("#btn-css").click(function() {
if( $('input').attr(value) = "" ) {
$('#output').append('All boxes must be completed');
} else {
$('.preview').attr('style', 'box-shadow: ' + $("#h-value").val() + 'px ' + $("#v-value").val() + 'px ' + $("#blur").val() + 'px ' + $("#spread").val() + 'px #' + $("#colour").val() + ';');
$('#output').append('box-shadow: ' + $("#h-value").val() + 'px ' + $("#v-value").val() + 'px ' + $("#blur").val() + 'px ' + $("#spread").val() + 'px #' + $("#colour").val() + ';');
}
});
How about this it will select all text inputs on the page then filter them to be the ones that are empty.
$("#btn-css").click(function() {
var emptyInputs = $('input:text').filter(function() { return this.value == ""; });
if (emptyInputs.length === 0) {
// Everything filled in
} else {
$('#output').append('All boxes must be completed');
}
});
You might also want to do:
var emptyInputs = $('input:text').filter(function() { return $.trim(this.value) == ""; });
This will also pick up text inputs with just whitespace.
use .val().. val() does the exact same thing you mentioned..
if( $('input').val() == "" ) {
to check for all input..
var inputVallength=$('input').filter(function(){
return this.value==""
}).length;
if(inputVallength == 0 || inputVallength < $('input').length){
$('#output').append('All boxes must be completed');
}
$('input').attr(value)
This selects ALL input elements on the entire page.
And also what #Mike Christensen said, you need at least 2 equal signs.
Just do
$(':input').each(function(){
if(!$(this).val()){
//logic
}
});
a Quick fiddle

Categories