Interesting behavior in my US Number formatting code - javascript

I'm trying to make 10 digits look like a US telephone number (i.e.(###) ###-####). My code does accomplish this first goal, but it also does something I can't quite figure out. When typing in the digits, the characters "()" show up before typing any other digits. I want the open parenthesis to appear first and the closing parathesis to appear after entering the third digit. Please don't give me a new solution; try to pin point the issue I'm describing.
<script type="text/javascript">
$('.drumbi-caller-number').live('keydown', function (event) {
if (event.keyCode == 8 || event.keyCode == 37 || event.keyCode == 39) {
} else {
inputval = $(this).val();
var string = inputval.replace(/[^0-9]/g, "");
var first3 = string.substring(0,3);
var next3 = string.substring(3,6);
var next4 = string.substring(6,9);
var string = ("(" + first3 + ")" + next3 + "-" + next4);
$(this).val(string);
}
});
</script>
Here's a jsFiddle that displays this behavior: http://jsfiddle.net/bigthyme/j6kHn/3/

replace keydown with keyup, on keydown the value of the input element isn't updated
also set your string conditionally, only if long enough:
var string = string.length > 2 ? ("(" + first3 + ")" + next3 + "-" + next4) : first3;
here is the code: http://jsfiddle.net/j6kHn/10
btw: you should also replace .live(...) with .on(...) as .live() is deprecated..

You need to check the length of first3 before appending the paren:
var string = ("(" + first3 + ((first3.length>=3)?")":"") + next3 + "-" + next4);
And although not in your question, you can do the same for the hyphen:
var string = ("(" + first3 +
// only append the ) if the you have 3+ chars
((first3.length>=3)?")":"") +
next3 +
// only append the - if the you have 6+ chars
(((first3+next3).length>=6)?"-":"") +
next4);
You should also use .on() instead of live();
See it all working in this jsFiddle

Go with
$('.foo').on('keyup', function (event) {
$(this).val($(this).val().replace(/\D/g, "").replace(/(\d{0,3})(\d{0,3})(\d{0,4}).*/, "($1) $2-$3"));
});
Test this code here.

Try using this code, it should fix all of your issues:
Demo: http://jsfiddle.net/bN6Rh/3/
jQuery:
$('.foo').on('keyup', function(event) {
if (event.keyCode == (8 || 37 || 39)) { }
else {
inputval = $(this).val();
var string = inputval.replace(/[^0-9]/g, "");
var first3 = string.substring(0, 3);
var next3 = " " + string.substring(3, 6);
var next4 = string.substring(6, 10);
if (string.length < 3) { // Less than 3
var string = "(" + first3;
}
else if (string.length > 2 && string.length < 7) { // More than 2 and less than 7
var string = "(" + first3 + ")" + next3;
}
else { // Anything else
var string = "(" + first3 + ")" + next3 + "-" + next4;
}
$(this).val(string);
}
});​
The problem was that you weren't checking the number of characters so as soon as anything was entered it put in ()-, the above code also adds the space you mentioned wanting.
The code could of course be more compressed:
$('.foo').on('keyup', function(e) {
if (e.keyCode == (8 || 37 || 39));
else {
var str = this.value.replace(/[^0-9]/g, "");
var f3 = str.substring(0, 3),
n3 = " " + str.substring(3, 6),
n4 = str.substring(6, 10);
if (str.length<3) str = "(" + f3;
else if (str.length>2&&str.length<7) str="("+f3+")"+n3;
else str="("+f3+")"+n3+"-"+n4;
this.value = str;
}
});​

Related

Replacing null with 0 when summing values

I have a function that sums my values and everything works fine, but only when all inputs have a value entered. However, I would like default to have 0 assigned to it.so that the function works when at least one value is given . How to do it ?.
var DeductiblepercentageM = thisPointer.entity.getValue('number.DeductiblepercentageM[' + i + ']');
var InsuranceLimitM = thisPointer.entity.getValue('number.InsuranceLimitM[' + i + ']');
var insuranceRaitingM = thisPointer.entity.getValue('number.insuranceRaitingM[' + i + ']');
var InsurerNumberM = thisPointer.entity.getValue('number.InsurerNumberM[' + i + ']');
DeductiblepercentageM = DeductiblepercentageM.replace(",", ".");
DeductiblepercentageM = parseFloat(DeductiblepercentageM)
InsuranceLimitM = InsuranceLimitM.replace(",", ".");
InsuranceLimitM = parseFloat(InsuranceLimitM)
insuranceRaitingM = insuranceRaitingM.replace(",", ".");
insuranceRaitingM = parseFloat(insuranceRaitingM)
InsurerNumberM = InsurerNumberM.replace(",", ".");
InsurerNumberM = parseFloat(InsurerNumberM)
//log the outcome of decimal separator change
var positionSum = +(DeductiblepercentageM + InsuranceLimitM +insuranceRaitingM + InsurerNumberM);
jQ('[id="DeductibleM[' + i + ']"]').val(positionSum);
thisPointer.entity.setValue('DeductibleM[' + i + ']', positionSum);
thisPointer.entity.mergeLocal(true);
if (totalSum != "NaN") {
totalSum = +(totalSum + positionSum).toFixed();
}
}
else {
totalSum = "-";
}
According to #Terry
var InsuranceLimitM = thisPointer.entity.getValue('number.InsuranceLimitM[' + i + ']') || 0;
adding || 0 to the end of the code helps and makes the code count right away

Javascript for Phone Number Formatting in Dynamics 365

Javascript we had for Unified interface of Dynamics 365 to format phone numbers was working perfectly until the latest update, now it only works in custom interface and has stopped working in UI, anybody has any idea how this can be fixed?
var XXX = window.XXX || {};
(function() {
// Code to run in the form OnLoad event
this.formOnLoad = function(executionContext) {
var formContext = executionContext.getFormContext();
// display the form level notification as an INFO
formContext.ui.setFormNotification(message, "INFO", myUniqueId);
// Wait for 5 seconds before clearing the notification
window.setTimeout(function() {
formContext.ui.clearFormNotification(myUniqueId);
}, 5000);
}
// Code to run in the attribute OnChange event
this.mobilePhoneFormatting = function(executionContext) {
var formContext = executionContext.getFormContext();
var mobilePhone = formContext.getAttribute("mobilephone").getValue();
var formatPhone = "";
try {
if (mobilePhone != null) {
var phoneNumbers = mobilePhone.replace(/\D/g, '');
if (phoneNumbers.length == 10) { //10 digit case. Output adds +1 and proper format
formatPhone = ("+1 (" + phoneNumbers.substring(0, 3) + ") " + phoneNumbers.substring(3, 6) + "-" + phoneNumbers.substring(6, 10));
} else if (phoneNumbers.length == 11) { //11 digit case. Output proper format
formatPhone = ("+" + phoneNumbers.substring(0, 1) + " (" + phoneNumbers.substring(1, 4) + ") " + phoneNumbers.substring(4, 7) + "-" + phoneNumbers.substring(7, 11));
} else if (phoneNumbers.length == 14) { //14 digit case. Without Country code and with extension
formatPhone = ("+1 (" + phoneNumbers.substring(0, 3) + ") " + phoneNumbers.substring(3, 6) + "-" + phoneNumbers.substring(6, 10) + " x" + phoneNumbers.substring(10, 14));
} else if (phoneNumbers.length == 15) { //15 digit case. With Country code and extension
formatPhone = ("+" + phoneNumbers.substring(0, 1) + " (" + phoneNumbers.substring(1, 4) + ") " + phoneNumbers.substring(4, 7) + "-" + phoneNumbers.substring(7, 11) + " x" + phoneNumbers.substring(11, 15));
} else if (phoneNumbers.length == 4) { //4 digit case. Extension Only
formatPhone = ("x" + phoneNumbers.substring(0, 4));
} else {
formatPhone = mobilePhone;
}
formContext.getAttribute("mobilephone").setValue(formatPhone);
formContext.data.entity.save();
}
} catch (err) {
txt = "There was an error formatting the Phone Number.\n\n";
txt += "Error description: " + err.message + "\n\n";
txt += "Click OK to continue.\n\n";
alert(txt);
}
}

MathML generation algorithm for Javascript. Any recommended references

I am trying to build code that can generate MathML for Traditional Math Input. I am using JavaScript for coding. Are there any references or recommended readings I can go through to get a grasp of required algorithm? I am reading W3C standards for MathML which is a reference for standards but not for algorithm.
For Instance, for a sample input of
sqrt 9 * 5 + 20
I want to generate the MathML expression like below
<math xmlns='w3.org/1998/Math/MathML'>; <mrow> <mrow> <mn>5</mn> <mo>⁢</mo> <mn>9</mn> <mo>⁢</mo> <mi>SQRT</mi> </mrow> <mo>+</mo> <mn>20</mn> </mrow> </math>
I found a nice tutorial on MathML here: http://rypress.com/tutorials/mathml/basic-algebra.html and started to work out a very basic algebraic parser (for example, 4*sqrt(x+6)=(5-z)*y/7) with a crude stack for handling parentheses and an example sqrt function. Is this the direction you are after?
jsfiddle here: http://jsfiddle.net/alhambra1/bSJyE/
JavaScript code:
<script>
document.write('<p><input id="input" size=50>')
document.write('<button onclick="convertToMathML()">Convert</button></p>')
document.write('<div id="output"></div>')
function lex(str,ptr){
var ascii = str.charCodeAt(ptr),
lexeme = {string: "", type: ""},
operators = {"+": "+"
, "-": "-"
, "*": "×"
, "/": "÷"
, "=": "="},
functions = {sqrt: "msqrt"}
//identify type
if (ascii == 41)
lexeme.type = "closeBracket"
else if (ascii == 40){
lexeme.type = "func"
lexeme.func = "mfenced"
}
else if (ascii > 45 && ascii < 58 && ascii != 47)
lexeme.type = "mn"
else if ((ascii > 64 && ascii < 91) || (ascii > 96 && ascii < 123)){
for (i in functions){
if (str.substr(ptr,i.length).toLowerCase() == i){
lexeme.type = "func"
lexeme.func = functions[i]
ptr += i.length - 1
} else
lexeme.type = "mi"
}
} else if (!operators[str.charAt(ptr)])
return {string: str.charAt(ptr), type: "error", pointer: ptr}
else
lexeme.type = "mo"
switch (lexeme.type){
case "mo":
lexeme.string = operators[str.charAt(ptr++)]
break
default:
lexeme.string = str.charAt(ptr++)
break
}
ascii = str.charCodeAt(ptr)
//identify numbers and functions
if (lexeme.type == "mn"){
while (ptr < str.length && ascii > 45 && ascii < 58 && ascii != 47){
lexeme.string += str.charAt(ptr)
ascii = str.charCodeAt(++ptr)
}
} else if (lexeme.type == "func" && lexeme.func != "mfenced"){
while (ptr < str.length && str.substr(ptr).match(/^\s/)){
ascii = str.charCodeAt(++ptr)
}
if (str.charAt(ptr) != "(")
return {string: str.charAt(ptr), type: "error", pointer: ptr}
else
ptr++
}
lexeme["pointer"] = ptr
return lexeme
}
function markup(lexeme){
return "<" + lexeme.type + ">\n"
+ lexeme.string + "\n"
+ "</" + lexeme.type + ">\n"
}
function convertToMathML(){
var str = document.getElementById('input').value,
expression = "",
ptr = 0,
stack = []
while (ptr < str.length){
var currLexeme = lex(str,ptr)
if (currLexeme.type == "closeBracket"){
if (stack.length == 0)
expression = "Extra bracket at: " + (currLexeme.pointer - 1)
else
expression += "</" + stack.pop().func + ">\n"
+ "</mrow>"
ptr = currLexeme.pointer
} else if (currLexeme.type == "error"){
expression = "Cannot parse \"" + currLexeme.string
+ "\" at " + currLexeme.pointer
break
} else if (currLexeme.type == "func"){
expression += "<" + currLexeme.func + ">\n"
+ "<mrow>\n"
stack.push(currLexeme)
ptr = currLexeme.pointer
} else {
expression += markup (currLexeme)
ptr = currLexeme.pointer
}
}
if (ptr >= str.length && stack.length > 0)
expression = "Missing " + stack.length + " closing bracket/s."
expression = "<math xmlns='http://www.w3.org/1998/Math/MathML'>"
+ expression + "</math>"
document.getElementById('output').innerHTML = expression
}
</script>

Javascript validation control

I wrote a Javascript to validate a few simple fields on my form. My issue is that the code works even when there are no errors on the form.
Specifically it throws an error at if(openHour > closeHour)
This is the code:
function checkForm()
{
var openHour;
var closeHour;
var i;
for(i=1;i<8;i++)
{
openHour = document.getElementById("openHours" + i).value;
closeHour= document.getElementById("closeHours" + i).value;
if(openHour > closeHour)
{
document.getElementById('error').innerHTML= "Opening Error at " + i;
return false;
}
if(openHour == "0" && closeHour > 0)
{
document.getElementById('error').innerHTML= "Closing Error at " + i;
return false;
}
}
}
Are there always default values in the openHours and closeHours fields?
Try setting some defaults, for example:
var openHour = 0;
var closeHour = 0;
Then check to see if openHours and closedHours have values in them before assigning them:
if (document.getElementById("openHours" + i).value != null && document.getElementById("openHours" + i).value != "")
openHour = document.getElementById("openHours" + i).value;
if (document.getElementById("closeHours" + i).value != null && document.getElementById("closeHours" + i).value != "")
closeHour = document.getElementById("closeHours" + i).value;
openHour = parseInt(document.getElementById("openHours" + i).value);
closeHour = parseInt(document.getElementById("closeHours" + i).value);
I just needed to parse the values to integers in order to be able to compare them.
Thanks all for your help

adding two variables together

I have been trying for... about 4 hours now lmao.
currentCalc returns 50
currentSum returns 0 when i alert them. Yet I cannot add them together with parseInt????
what am i doing wrong :'(
var identRow = $('tr.identRow');
identRow.each(function () {
var getIdentClass = $(this).attr('class').split(' ').slice(1);
$('tr.ohp' + getIdentClass + ' td.EURm').each(function (index) {
var currentCalc = parseInt($(this).text().replace('.', ''), 10);
var currentSum = $('tr.' + getIdentClass + ' td.totalEURm', this).text().replace('.', '');
total = parseInt(currentCalc, 10) + parseInt(currentSum, 10);
$('tr.' + getIdentClass + ' td.totalEURm').text(total);
if (index == 6) {
alert(total);
}
});
});
EDIT:
Oh goodness. Im completely confused now. I putr the break there. It says total = 50.
I want each iteration to add itself to the total. That is why I add currentCalc to the text of the field im plopping the currentCalc into.
$('tr.' + getIdentClass + ' td.totalEURm').text(total);
with my code now like this:
var identRow = $('tr.identRow');
identRow.each(function () {
var getIdentClass = $(this).attr('class').split(' ').slice(1);
$('tr.ohp' + getIdentClass + ' td.EURm').each(
function (index) {
var currentCalc = parseInt($(this).text().replace('.', ''), 10) || 0;
var currentSum = parseInt($('tr.' + getIdentClass + ' td.totalEURm', this).text().replace('.', ''), 10) || 0;
var total = currentCalc + currentSum;
$('tr.' + getIdentClass + ' td.totalEURm').text(total);
if (index === 6) {
alert(total);
}
});
});
it alerts: 50, then 0, then 50, then 0.
EDIT:
How do I add currentCalc to its last value?
So first iteration its 10, seconds its 20. How do i make it so on the 2nd iteration it equals 30. currentCalc++ is just adding 1 to it.
Now you understand how crap i am :)
I am no expert in JS, but I saw that currentCalc is already an int:
var currentCalc = parseInt($(this).text().replace('.',''), 10);
//...
total = parseInt(currentCalc, 10) + parseInt(currentSum, 10);
so probably the parseInt on an int instead that on a string fails (?)
If you get two alerts, that likely means either your outer or inner .each statements is matching two entries.
If you're using firebug, use console.debug(total); instead of alert(). I recommend using console.debug(this) at some point to make sure it has what you think it has, too. Put it above the alert(). That information would be useful to see.
I do some code formatting and cleanup, try this:
var identRow = $('tr.identRow');
identRow.each(function () {
var getIdentClass = $(this).attr('class').split(' ').slice(1);
$('tr.ohp' + getIdentClass + ' td.EURm').each(
function (index) {
var currentCalc = parseInt($(this).text().replace('.', ''), 10) || 0;
var currentSum = parseInt($('tr.' + getIdentClass + ' td.totalEURm', this).text().replace('.', ''), 10) || 0;
var total = currentCalc + currentSum;
$('tr.' + getIdentClass + ' td.totalEURm').text(total);
if (index === 6) {
alert(total);
}
});
});
I added condition if parseInt fails the vars currentCalc and currentSum will be 0.
Also, like in answer above i'm avoiding double parseInt
Can you give an example html page to try out?
//SUM OF COLUMNS
var total = 0;
var identRow = $('tr.identRow');
identRow.each(function () {
var getIdentClass = $(this).attr('class').split(' ').slice(1);
$('tr.ohp' + getIdentClass + ' td.EURm').each(
function (index) {
var currentCalc = $(this).text().replace('.', '');
total = parseInt(currentCalc)+total;
$('tr.' + getIdentClass + ' td.totalEURm').text(total);
});
});
did the trick.
Now i just gotta set the total to 0 when it gets to the second category because at the moment it keeps adding from where it left off. Progress though. Thanks for everything

Categories