Unexpected localeCompare Behavior - javascript

I have a few lines of code that attempt to detect the last field that the user interacted (typed) with.
The following event handler functions correctly, but the first case of the if/else always runs regardless if the user input text into field #input1 or #input2. Is there an unexpected behavior of localeCompare in this example?
JS:
$("#input1, #input2").keyup(function () {
if (("input1").localeCompare($(this).attr("id"))) {
calculateA();
} else if (("input2").localeCompare($(this).attr("id"))) {
calculateD();
});
}
HTML:
<div id="input1">
<div class="input-prepend">
<span class="add-on"></span>
<input id="foo" class="span7" type="text">
</div>
<br>
<div class="input-prepend">
<span class="add-on"></span>
<input id="bar" class="span7" type="text">
</div>
</div>
EDIT: It turns out that the error was not entirely on account of the code posted above. The two comparisons in the .js snippet were actually the body of a setTimeout callback function; as such, I did not realize that the execution context (and subsequently, the value of 'this') would change!

It seems you want to use event.target instead of this:
var id = event.target.id;
if (id === 'foo') {
// ...
}

You test can't never return 0, because you don't have any input with id input1, and the div with this id won't be this when the keyup event is raised.
Supposing you give the id input1 and input2 to your inputs, your code is still too complex. You don't need localeCompare to test string equality. And I suspect you didn't get that the result pass as true in a if test when the strings are different. You seem to want
$("#input1, #input2").keyup(function() {
if ("input1"===this.id) {
calculateA();
} else if ("input2"===this.id) {
calculateD();
}
});

Related

Error with Javascript TypeError code, variable undefined

I am trying to get the element with the ID 1a, 2a, 3a etc. according to whenever the function is run.
It then compares that elements value (using jQuery) with the value of the input where the function is wrong
It brings up an error saying:
TypeError: var1.toUpperCase is not a function. (in 'var2.toUpperCase()','var1.toUpperCase' is undefined)
Any help would be appreciated.
Thanks
(UPDATE usually there would be text in questionNumber like: 1, 2, 3 etc every time the another function is run.)
EDIT: Every time a different function is run, questionNumber is increased by 1. I save questionNumber's text in a variable called word. I then add the letter a to that variable. Then, I get the element that has ID of the variable word, then compare it's contents to the value of the input, but the comparison is uppercase to avoid problems. If they are equal, the input is replaced with a div with green text. Hope this makes it clearer.
function textVerify(item) {
var word= document.getElementById(($('#questionNumber').text()+'a'));
if (item.value.toUpperCase() === word.toUpperCase()){
item.style.color = "green";
$( item ).replaceWith( "<div style='color:green;'>"+word+"</div>" );
main()
} else {
item.style.color = "black";
}
<span class="ihide" id="questionNumber"></span>
<p id="1a" class="ihide">Seven</p>
<input id="1" name="Seven" type="text" value="" onkeyup="textVerify(this)" autofocus="">
The var word is p tag, so you need to get the inner text of it and compare it with the input text. Also, when replacing it, access the text() property of it. See below. main() is commented out here, but you can keep as per the need.
function textVerify(item) {
var word = document.getElementById(($('#questionNumber').text() + 'a'));
if (item.value.toUpperCase() === $(word).text().toUpperCase()) {
item.style.color = "green";
$(item).replaceWith("<div style='color:green;'>" + $(word).text() + "</div>");
//main()
} else {
item.style.color = "black";
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<span class="ihide" id="questionNumber">1</span>
<p id="1a" class="ihide">Seven</p>
<input id="1" name="Seven" type="text" value="" onkeyup="textVerify(this)" autofocus="">
In your code ($('#questionNumber').text()+'a') this part returns just 'a', as text of the id questionNumber is nothing.
And in your HTML there is no such id. I think you need to make this changes to your HTML code:
<span class="ihide" id="questionNumber">1</span>
This should work.
EDIT: Also, can you please share the JS code associated with 'item', there can be an error in that part too.

Javascript keyup function throwing wrong alert message

With the following script, i am trying to validate whether the refund amount wlt_ln_refund_amt is greater than the balance amount wlt_ln_bal using keyup function.
In my html read only field wlt_ln_bal (field type = number) i have a an amount 222.00
the other field wlt_ln_refund_amt (field type = number)
The testcase
for the value 3 the system is throwing an error message like "Refund amount Rs.3 is greater than Balance Rs.222.
for the values 1, 2 or 2000 the system is not throwing any errors
Here is my html code:
<form id="lnrefund" name="lnrefund"
method="post" role="form"
class="form-horizontal"
action="<?php echo $_SERVER['PHP_SELF']; ?>"
onsubmit="return (checkform() && confirm_update())">
<div class="form-group">
<label class="col-md-2 col-xs-12 control-label">Loan Balance</label>
<div class="col-md-3 col-xs-12">
<input id="wlt_ln_bal" Name="wlt_ln_bal"
type="number"value ="<?php echo $bal ?>"
class="form-control required" readonly/>
<span class="help-block">Required</span>
</div>
</div>
<label class="col-md-2 col-xs-12 control-label">Refund Amount</label>
<div class="col-md-3 col-xs-12">
<input id="wlt_ln_refund_amt"
Name="wlt_ln_refund_amt"type="number" step="0.01"
class="form-control" required/>
<span class="help-block">Required</span>
</div>
</form>
And this is the javascript
<script type="text/javascript">
$(function(){
$("#wlt_ln_refund_amt").keyup(function () {
var ref = document.lnrefund.wlt_ln_refund_amt.value;
var bal = document.lnrefund.wlt_ln_bal.value;
if (ref>bal)
{
alert('Refund amount Rs.'+ref+ '\nis greater than Available Balance Rs.'+bal)
return true;
}
});
});
</script>
It looks like the variables are being compared as strings (i.e. alphabetically) you should try something like
var ref = parseInt(document.lnrefund.wlt_ln_refund_amt.value);
var bal = parseInt(document.lnrefund.wlt_ln_bal.value);
or maybe
var ref = parseFloat(document.lnrefund.wlt_ln_refund_amt.value);
var bal = parseFloat(document.lnrefund.wlt_ln_bal.value);
if you're expectiong decimals
Since you asked for suggestions... :P
I'd use jQuery to get the values of the two inputs. You're already using jQuery for the document ready function, so why not use:
var $refund = $('#wlt_ln_refund_amt'),
$balance = $('#wlt_ln_bal.value');
What you're doing works fine - as long as the structure of your HTML never changes. Using jQuery like this means you don't have to worry about ever wrapping your inputs in a containing DIV or changing the form to a popup dialog later on.
Next, I wouldn't use the keyup event, I'd use the blur event. Perhaps your use case requires the check after every keystroke, but that usually annoys users. If you bind to the blur instead of the keyup, your user will have an opportunity to correct a mistake during typing before getting yelled at by your function.
$refund.on('blur', function(){
var refAmount = parseInt($refund.val()),
balAmount = $balance.val() * 1;
if (refAmount > balAmount)
{
alert('Refund amount Rs.' +
refAmount +
'\nis greater than Available Balance Rs.' +
balAmount);
$refund.focus();
}
});
As someone else suggested, make sure the values you're comparing are numeric. You can use the parseInt as suggested (the preferred way) or force type conversion by multiplying the value by 1. Either way will result in a NaN (not a number) if the user enters something other than numbers.
After the alert, I'd return focus back to the refund amount to give the user another shot at the entry.
As a final suggestion, I'd recommend using readable variable names. Perhaps you shortened them just for this question, but descriptive variable names are much easier to deal with than obscure abbreviations.
Good luck!

Changing to an Error Class

I need to validate the length of a string in the inputbox. If the string is invalid it will trigger an onblur event. When this event is triggered, it must turn the label of the object associated with the trigger red. However, there is a css class that exist that contains the style, so I just need to change the class to that class.
The prefix is some value being passed in.
Here is sample code.
var input = $(this).val();
var findLabel = document.getElementById`enter code here`(prefix+'findLabel');
if(input.length < min || input.length > max){
//alert is to check the values for testing
alert('Value for selected country '+selectedCountry+' must be between '+min+' and '+max+' characters');
}
example
<div class="Value_s123" id="a1Values123" style="float:left;">
<span class="avalue" id="a1value">
<label class="classOff" id="a1ValueLabel">some value</label>
<span style="white-space: nowrap;">
<input id="a1CatchValue" maxlength="15" name="a1Value" onblur="requiredFieldValidation("a1Postal")" size="15" tabindex="13" type="text"><img alt="Required" height="9" id="a1ValueReqdImg" src="/img/icn_dia.gif" width="11">
</span>
</span>
</div>
I need to get the a1ValueLabel and the class classOff and turn it to classON
Use this:
$("#a1ValueLabel").removeClass("classOff").addClass("classOn");
Here's what I came up with. The script is run every time someone types, once it reaches more than 5 characters the script adds the class "classOn" to the label tag. If there are 5 or less characters, it removes the "classOn" and adds the "classOff" class.
This is not a sustainable way to do it however, if you wanted to run this script on multiple items.
$(document).ready(function(){
$('#a1CatchValue').on('keyup',function(){
if ($(this).val().length > 5) {
$('#a1ValueLabel').removeClass('classOff');
$('#a1ValueLabel').addClass('classOn');
}
else {
$('#a1ValueLabel').removeClass('classOn');
$('#a1ValueLabel').addClass('classOff');
}
});
});

onkeyup not working on hide()

I'm trying to show and hide div contents depends on the input of the user.
Here are my codes:
<input type="text" name="pass" id="pass" onkeyup="check_input(this.value)">
<div id="repeated_pattern" style="display:none">
<b>REPEATED PATTERN</b>
<p>Repeated characters</p>
</div>
<script>
function check_input(value){
//this would check if there are 3 or more characters repeated consecutively
var repeat_pattern = /(.)\1\1/.test(value);
if(repeat_pattern) {
$("#repeated_pattern").show(500);
}else{
$("#repeated_pattern").hide(500);
}
}
</script>
Tests:
When I try to input gg, the div contents did not show so the result is ok
When I try to input ggg, the div contents show so the result is ok
But when I try to remove the one g so it is now gg. It supposed to be the div contents must be hide but still it showing. onkeyup is not working properly with the hide() function.
How to onkeyup work with hide() or vice versa?
I'm getting this error:
ReferenceError: check_input is not defined
Try setting up the event handlers in Javascript so they are in scope:
http://jsfiddle.net/vHREF/1/
Javascript:
// Event handlers
if(document.addEventListener)
document.getElementById('pass').addEventListener('keyup',check_input,false);
// Good old Internet Explorer event handling code
if(document.attachEvent)
document.getElementById('pass').attachEvent('keyup',check_input);
function check_input() {
var value = $(this).val();
//this would check if there are 3 or more characters repeated consecutively
var repeat_pattern = /(.)\1\1/.test(value);
if (repeat_pattern) {
$("#repeated_pattern").show(500);
} else {
$("#repeated_pattern").hide(500);
}
}
HTML:
I'm trying to show and hide div contents depends on the input of the user. Here are my codes:
<input type="text" name="pass" id="pass">
<div id="repeated_pattern" style="display:none"> <b>REPEATED PATTERN</b>
<p>Repeated characters</p>
</div>

AngularJS: How do I manually set input to $valid in controller?

Using the TokenInput plugin and using AngularJS built-in formController validation.
Right now I'm trying to check if the field contains text, and then set field to valid if it does. The issue with using the plugin is it creates it's own input and then a ul+li for stlying.
I have access to addItem (formname) and my capablities in the controller, I just need to set it to $valid.
Markup.
<form class="form-horizontal add-inventory-item" name="addItem">
<input id="capabilities" name="capabilities" token-input data-ng-model="inventoryCapabilitiesAutoComplete" data-on-add="addCapability()" data-on-delete="removeCapability()" required>
<div class="required" data-ng-show="addItem.capabilities.$error.required" title="Please enter capability."></div>
</form>
JS.
$scope.capabilityValidation = function (capability) {
if (capability.name !== "") {
addItem.capabilities.$valid = true;
addItem.capabilities.$error.required = false;
} else {
addItem.capabilities.$valid = false;
addItem.capabilities.$error.required = true;
}
};
I'm running the capabilityValidation function when TokenInput has something entered and passing in the object.
EDIT:
Found out ng-model on my input does stuff and gets the autocomplete results, which is why I can't get ng-valid to work since it's based on the model.
$scope.inventoryCapabilitiesAutoComplete = {
options: {
tokenLimit: null
},
source: urlHelper.getAutoComplete('capability')
};
I didn't write this autocomplete implementation, is there another way to do this where I would have access to the ng-model attr and move the model function somewhere else?
You cannot directly change a form's validity. If all the descendant inputs are valid, the form is valid, if not, then it is not.
What you should do is to set the validity of the input element. Like so;
addItem.capabilities.$setValidity("youAreFat", false);
Now the input (and so the form) is invalid.
You can also see which error causes invalidation.
addItem.capabilities.errors.youAreFat == true;
The answers above didn't help me solve my problem. After a long search I bumped into this partial solution.
I've finally solved my problem with this code to set the input field manually to ng-invalid (to set to ng-valid set it to 'true'):
$scope.myForm.inputName.$setValidity('required', false);
I came across this post w/a similar issue.
My fix was to add a hidden field to hold my invalid state for me.
<input type="hidden" ng-model="vm.application.isValid" required="" />
In my case I had a nullable bool which a person had to select one of two different buttons. if they answer yes, an entity is added to the collection and the state of the button changes. Until all of the questions get answered, (one of the buttons in each of the pairs has a click) the form is not valid.
vm.hasHighSchool = function (attended) {
vm.application.hasHighSchool = attended;
applicationSvc.addSchool(attended, 1, vm.application);
}
<input type="hidden" ng-model="vm.application.hasHighSchool" required="" />
<div class="row">
<div class="col-lg-3"><label>Did You Attend High School?</label><label class="required" ng-hide="vm.application.hasHighSchool != undefined">*</label></div>
<div class="col-lg-2">
<button value="Yes" title="Yes" ng-click="vm.hasHighSchool(true)" class="btn btn-default" ng-class="{'btn-success': vm.application.hasHighSchool == true}">Yes</button>
<button value="No" title="No" ng-click="vm.hasHighSchool(false)" class="btn btn-default" ng-class="{'btn-success': vm.application.hasHighSchool == false}">No</button>
</div>
</div>
It is very simple. For example :
in you JS controller use this:
$scope.inputngmodel.$valid = false;
or
$scope.inputngmodel.$invalid = true;
or
$scope.formname.inputngmodel.$valid = false;
or
$scope.formname.inputngmodel.$invalid = true;
All works for me for different requirement. Hit up if this solve your problem.
to get this working for a date error I had to delete the error first before calling $setValidity for the form to be marked valid.
delete currentmodal.form.$error.date;
currentmodal.form.$setValidity('myDate', true);

Categories