Javascript Simple If Else innerHTML == 'something' not working - javascript

I have a seemingly simple javascript function I am trying to create that checks the value of an elements innerHTML and spits out a value based on the answer, but for the life of me I can't get it to work and don't get any errors. This function is triggered by onclick events and doesn't need to have window.onload added. Any insight anyone could give me would be much appreciated! Here is my HTML
<div class="col-md-8 col-xs-9 product-info">
<p id="planTitle" class="bold m-b-2">20 DAY SUPPLY // 40 CAPSULES // FMF</p>
<p>Price: <span class="pull-right" id="plan-amount">$79</span></p>
<p>Tax: <span class="pull-right">Included</span></p>
<p id="shipping-line">Shipping: <span class="pull-right" id="cart-shipping-cost">$9.99</span></p>
<p class="hidden">Coupon: <span class="pull-right" id="coupon-code">firstmonthfree20day</span></p>
</div>
And my Javascript
function updateShippingCost(country_region) {
var url;
var kkdk = '';
var planTitleesd = document.getElementById('planTitle').innerHTML;
console.log(planTitleesd);
if (planTitleesd == '10 Day Supply // 20 Capsules // FMF') {
kkdk = '5.99';
console.log(kkdk);
} else if (planTitleesd == '20 Day Supply // 40 Capsules // FMF') {
kkdk = '9.99';
console.log(kkdk);
} else if (planTitleesd == '30 Day Supply // 60 Capsules // FMF') {
kkdk = '14.99';
console.log(kkdk);
}
}
Oddly, console.log(planTitleesd) returns a value, such as
"20 DAY SUPPLY // 40 CAPSULES // FMF"
but all the other console.log(kkdk) do not. Thanks for your help!

I have updated the original question with the relevant HTML, sorry about that.
You are doing a case-sensitive comparison. You've indicated that the resultant value is all caps, while you're comparing it to Title Case. Consider doing a case-insensetive comparison by calling toLowerCase on both operands before comparison. Also, please actually post your markup. Troubleshooting code questions must contain an MCVE. – CollinD 9 mins ago
This was the simple answer to the simple question I was looking for - Thanks CollinD!

Almost for sure you have newline at the beginning/end of planTitleesd.
Try to replace console.log(planTitleesd); by console.log('>' + planTitleesd + '<'); to check that.
Here is an example:
https://jsfiddle.net/324aw9zz/1/
You should avoid any spaces/newline between the tag opener/closer and the text itself:
<th id=planTitle>lala</th>
instead of
<th id=planTitle>
lala
</th>

Why not do something more along the lines of:
Using .indexOf() to check for one (or multiple) Strings?
function updateShippingCost(country_region) {
var url;
var kkdk = '';
var planTitleesd = document.getElementById('planTitle').innerHTML;
if ( planTitleesd.indexOf('10 Day') > -1 && planTitleesd.indexOf('20 Capsules') > -1 ) {
kkdk = '5.99';
} else if (planTitleesd.indexOf('20 Day')) {
kkdk = '9.99';
} else if (planTitleesd.indexOf('30 Day')) {
kkdk = '14.99';
}
}
I also agree that you should remove the case sensitive strings, as, (once again), typos and the like can occur.
Chances are there is just a typo in the value, or perhaps an empty return/newline you may be looking over.
Make sure all Carriage Returns and more are removed from the response. Seeing as, some items may actually add one that you do not notice. (Such as an openly tabbed div)
It sounds like this app is a store, something that could get pretty big. I would suggest is maybe an object that returns back the result you need.
The following a JSFiddle that I feel would simplify your process if you could create a proper JSON object.
https://jsfiddle.net/0sscf798/
function updateShippingCost(country_region) {
var url;
var kkdk = '';
var planTitleArr = [];
var planTitleObj = {};
var planTitleesd = document.getElementById('planTitle').innerHTML;
// This would most likely be a JSON response of items from the page/category
planTitleObj = {
"10 Day Supply": {
"20 Capsules": {
"FMF": 1.23
}
},
"20 Day Supply": {
"20 Capsules": {
"FMF": 4.56
}
}
};
planTitleArr = planTitleesd.split(" // ");
var price = planTitleObj[planTitleArr[0]][planTitleArr[1]][planTitleArr[2]] || "There is a problem with the price."
alert("The Price is: " + price);
}
updateShippingCost('');

Related

Javascript Math.log() help wanted

World!
I'm trying to create a program in Javascript that takes the log of a number typed into an HTML input. Unfortunately i've encountered a problem where it wont accept the string with the .replace().
Its Function:
I.E: When log(10) is calculated, the function should first remove the first 4 char's "log(" next remove the last parenthesis ")" and then take the log of the no. between.
HTML includes style elements, button and input form and an output < DIV >.
//Function
function calculate()
{
var inputString = document.getElementById("inpstr");
var output = document.getElementById("output");
//TESTING CODE
/*
if (inputString.value.startsWith("log(").endsWith(")"))
{
console.log(output.innerHTML = inputString.value.substring(4, 20).replace(")", ""));
}
else
{
output.innerHTML = "false";
}
*/
//Math.log() calc *****DOESNT WORK*****
if (inputString.value.startsWith("log(").endsWith(")"))
{
output.innerHTML = Math.log(inputString.value.replace(")", "").substring(4, 20));
}
else
{
output.innerHTML = inputString.value;
}
event.preventDefault();
}
If someone can give me an effective solution that would be much appreciated.
Thanks,
Syntax
Since Math.log() accepts only number values and you're trying to pass a string to it, you should first parse this value into a float number and then pass it to the log function:
let val = parseFloat(inputString.value.replace(")", "").substring(4, 20));
output.innerHTML = Math.log(val);
I'm guessing I got downvoted for being lazy, so here is the quick info. Gonras got it right relating to what you want to extract, but he forgot to check that what's being input is actually a log.
That's where the regex below comes in handy! I'm matching the field to:
^ start of word, since we want to match the entire field.
log(
([-.\d])) any consecutive sequence () of numbers (\d), -, and '.', represented by the []. The \(...\) makes sure to save this inner part for later.
$ is end of word, see 1.
res will be null if there is no match. Otherwise, res[0] is the entire match (so the entire input field) and res[1] is the first 'capture group', at point 3 - which is presumably the number.
This of course fails for multiple "-" inside, or "." etc... so think it over.
//Function
function calculate()
{
var inputString = document.getElementById("inpstr");
var output = document.getElementById("output");
var res = /^log\(([-.\d]*)\)$/.exec(inputString.value);
if (res)
output.innerHTML = Math.log(res[1]);
else
output.innerHTML = res;
}
document.getElementById("output").innerHTML='start';
calculate()
<div id='output'></div>
<input id='inpstr' value='log(2.71828)'></input>
If I wanted to fix your if to supplement Gonras's solution:
if (inputString.value.startsWith("log(") && inputString.value.endsWith(")"))
Yours fails since startsWith() returns a boolean, which obviously doesn't have a endsWith function.

jquery hide/show or condiiton failing

Is there anything wrong with the jQuery/JS below? I have an input field aAmt which on change calls below. ${dAmt} = "10000" from DB. It basically converts the number to $ format(eg.. 23 to $23.00) and focuses the value to the input field. Issue is the if loop (if(aAmt >= a_amount)...) fails.
Even if the condition fails it goes to if loops and shows the div which should not happen. I don't see any error in developers console.
$('#aAmt').change(function() {
var aAmt = $("#aAmt").val();
var a_amount = "${dAmt}";
curFormat(aAmt);
if(aAmt >= a_amount)
{
$("#dsDiv").show();
}else{
$("#dsDiv").hide();
}
});
function curFormat(aAmt)
{
var nAmt = Number(aAmt.replace(/[^0-9\.]+/g,""));
var fAmt = '$' + nAmt.toFixed(2).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
document.getElementById("aAmt").value = fAmt;
}
Have you tried to convert a_amount to an int, to be sure to compare two integers together:
var a_amount = parseInt("${dAmt}");

Need to get indexes from array and output them to user in JavaScript

We're displaying five input fields to user. He can type some information in them. After that, we need to find out if his input is correct. For that purpose we use an array of possible correct values.
Like:
var input = document.getElementById("input").value;
input = input.toLowerCase();
inputPos = possibleInputs.indexOf(input);
inputPosArray.push(inputPos);
The code for analysis looks like that for now:
function arrayLookup() {
var inputCorrect = true;
inputPosArray.forEach(function(item, i, inputPosArray) {
if (inputPosArray[i] == -1) {
wrongInput = cardRPos.indexOf(cardRPos[i]) + 1;
wrongInputsArray.push(wrongInput);
inputCorrect = false;
} else {
null;
}
});
if (inputCorrect == false) {
alert("Wrong input! Check field " + wrongInputsArray);
} else {
nextStep();
}}
For now it correctly finds out if input is wrong and alerts user.
The problem is in "wrongInputsArray" - it doesn't display output correctly. E.g. if user has typed wrong information in 2nd field, it will print out "2".
But if he has made mistakes in 2nd and 5th field, he gets "Wrong input! Check field 2,2" alert.
Please show me what am I doing wrong.
Kindly yours,
Richard
You are using this code to insert the wrong asnwers:
wrongInput = cardRPos.indexOf(cardRPos[i]) + 1;
If two questions has the same answer, indexOf will return always the first match. Try just using this:
wrongInput = i + 1;

Compare multiple date fields on a page through javascript

How to efficiently compare dynamic number of dates on a page from a given date?
Consider following code:
<div id="dateFields">
<input type="date" id="date1"/>
<input type="date" id="date2"/>
<input type="date" id="date3"/>
<input type="date" id="date4"/>
<input type="date" id="date5"/>
</div>
<div id="masterDate">
<input type="date" id="comparator"/>
</div>
<button onClick="compareDate()">Compare Now</button>
Consider the dates in div with id="dateFields are in random numbers. Say 5 for now. And the date in div with id="comparator is the date which we need to compare all the dates with.
Now, for example, if the comparator date is set to "March, 2015" and all the values in dateFields are set dynamically by the user (Say "Feb, 2002", "Dec, 2010", "Aug, 2016", "Jul, 2019" and "Nov, 2015"). What is the most efficient and generic code I should write in the function compareDate() so that the output brings all the dates which are greater than the comparator.
Edit:
Here is my javascript function. But, I don't feel that this is the efficient way. And even this is no good for dynamic number of values.
function compareDate() {
var v1 = document.getElementById("date1").value;
var v2 = document.getElementById("date2").value;
var v3 = document.getElementById("date3").value;
var v4 = document.getElementById("date4").value;
var v5 = document.getElementById("date5").value;
var v6 = document.getElementById("comparator").value;
var v7 = [ v1, v2, v3, v4, v5 ];
var result = "";
for (i = 0; i < v7.length; i++) {
console.log(solidify(v7[i]));
if (solidify(v6) < solidify(v7[i])) {
result += v7[i];
}
}
document.getElementById("result").innerHTML = result;
}
function solidify(date) {
var tempResult = '';
for (i = 0; i < date.length; i++) {
if (date.charAt(i) == '-') {
continue;
}
else {
tempResult += date.charAt(i);
}
}
return tempResult;
}
Edit 2:
Explanation of the requirement with example.
There need not be any text-box, it may be just a set of <td>, <p> or may be just a <div> containing number of dates, which may vary from minimum 2 dates to max 50 dates(Say).
I'm just looking for a logic and hence was trying with text-boxes.
For a real time example, consider a City Municipality Management System, which keeps track of monthly deaths that occur in that city. Now, a clerk wants to know the details of citizens who died after 15th of that month, how will he get the data?
The following code does what you are asking, but there are still some requirements that you need to nail down, in order to make it truly "generic" (see below the code):
HTML
<div id="dateFields">
<input type="date" id="date1"/>
<input type="date" id="date2"/>
<input type="date" id="date3"/>
<input type="date" id="date4"/>
<input type="date" id="date5"/>
</div>
<div id="masterDate">
<input type="date" id="comparator"/>
</div>
<div id="results">
Results: <span id="resultDates"></span>
</div>
<button onClick="compareDate()">Compare Now</button>
JavaScript
<script>
function compareDate() {
var aDates = document.getElementById("dateFields").getElementsByTagName("input");
var sCompareDate = document.getElementById("comparator").value;
var dCompareDate = formatDate(sCompareDate);
var result = "";
for (i = 0; i < aDates.length; i++) {
var sCurrDate = aDates[i].value;
if (dCompareDate < formatDate(sCurrDate)) {
if (result.length > 0) {
result += ", ";
}
result += sCurrDate;
}
}
if (result === "") {
result = "No dates less than " + sCompareDate;
}
document.getElementById("resultDates").innerHTML = result;
}
function formatDate(sDate) {
var regMonthYear = /[a-z]{3}, \d{4}/i;
if (regMonthYear.test(sDate)) {
sDate = sDate.replace(",", " 1,");
}
return new Date(sDate);
}
</script>
Things that need to be worked out still:
You must compare Date objects, not strings.
To do what you are trying to do, you must use JavaScript Date objects. Even if you are using am <input> with a type attribute of "date", its value is still a string. If you compare that, it would be like asking if "orange" is less than "house" . . . JavaScript will give you an answer, but it will be, in no way, related to what you are looking for.
The JavaScript Date object has built in comparison functionality that will do exactly what you are looking for.
2 You need to come up with some sort of standard for your date inputs and make sure that you have code to enforce them.
While the Date object is VERY flexible when it comes to what inputs it will accept when you are creating a new instance, it does have its limits. You can look at these two links for more information on valid string formats for creating dates:
the ISO date format - https://msdn.microsoft.com/en-us/library/ie/ff743760%28v=vs.94%29.aspx#ISO
other date parsing rules - https://msdn.microsoft.com/en-us/library/ie/ff743760%28v=vs.94%29.aspx#OtherDateFormats
Once you figured out which one(s) make the most sense for your needs, you really should set a common format (or group of formats) that you want to work with, and enforce that formatting on your inputs with validation rules. If you don't, you will have to add LOTS of logic to validate all of the different possibilities, so that you know that you are going to get a valid Date object when you try to create it.
3 You need to come up with some sort of standard output for your results.
Ideally, if you want to create a truly "generic" date comparison function to meet what you are asking for, you want it to focus solely on the comparison and nothing else. Something like this:
function compareDate(aDateGroup, dComparisonDate)
var aGreaterThanDates = [];
for (i = 0; i < aDateGroup.length; i++) {
if (dCompareDate < aDateGroup[i]) {
aGreaterThanDates.push(aDateGroup[i]);
}
}
return aGreaterThanDates;
}
. . . where aDateGroup is an array of Date objects and dCompareDate is a Date object as well.
The function would take in the dates, compare them, and pass back the ones that passed the test. Then you could cycle through the returned array and process those dates however you needed to.
This would also allow you to pass in dates from any source (i.e., like a collection of the <td>, <p>, and <div> elements that you mentioned in your second update), as long as they were converted to proper Date objects first.
Determine whether or not you need to be flexible in your comparison.
The above "ideal code" could actually be made even "more ideal" by adding some flexibility in the comparison function, by adding a few parameters to indicate what kind of comparison to do:
function compareDate(aDateGroup, dComparisonDate, sCompareDirection, bIncludeComparisonDate)
var aPassedDates = [];
for (i = 0; i < aDateGroup.length; i++) {
if (sCompareDirection === "before") {
if (bIncludeComparisonDate) {
if (dCompareDate >= aDateGroup[i]) {
aPassedDates.push(aDateGroup[i]);
}
}
else {
if (dCompareDate > aDateGroup[i]) {
aPassedDates.push(aDateGroup[i]);
}
}
}
else if (sCompareDirection === "after") {
if (bIncludeComparisonDate) {
if (dCompareDate <= aDateGroup[i]) {
aPassedDates.push(aDateGroup[i]);
}
}
else {
if (dCompareDate < aDateGroup[i]) {
aPassedDates.push(aDateGroup[i]);
}
}
}
else {
if (dCompareDate == aDateGroup[i]) {
aPassedDates.push(aDateGroup[i]);
}
}
}
return aPassedDates;
}
The sCompareDirection parameter would allow you to determine the direction of the comparison. "before" would check for values less than the comparison date, "after" would check for values greater than the comparison date, and any other value (or no value) would check for the dates being equal.
The bIncludeComparisonDate parameter would allow you to include the comparison date as part of the match. A value of true would turn the "greater than" comparison to "greater than or equal to" and the "less than" comparison to "less than or equal to".
Conclusion
Date comparison is actually a fairly common process, but it is also one that requires a LOT of thinking through to make flexible and foolproof. If you don't catch some of these things early, you are asking for a world of hurt down the line, when you try to reuse what you have built and in a situation that doesn't quite match what you originally set up. :)
you can do it in following way :
<script>
function compareDate() {
var v1 = document.getElementById("date1").value;
var v2 = document.getElementById("date2").value;
var v3 = document.getElementById("date3").value;
var v4 = document.getElementById("date4").value;
var v5 = document.getElementById("date5").value;
var v6 = document.getElementById("comparator").value;
var v7 = [ v1, v2, v3, v4, v5 ];
var finalResult = "";
for (k = 0; k < v7.length; k++) {
if (solidify(v6) < solidify(v7[k])) {
finalResult += v7[k];
finalResult += " and ";
}
}
document.getElementById("result").innerHTML = finalResult;
}
function solidify(date) {
var result = '';
for (i = 0; i < date.length; i++) {
if (date.charAt(i) == '-') {
continue;
} else {
result += date.charAt(i);
}
}
return result;
}
</script>
function compareDate() {
var dateFields = document.getElementById('dateFields').getElementsByTagName('input');
var comparatorDate = new Date(document.getElementById('comparator').value);
var rslt = [];
for (var i = 0; i < dateFields.length; i++) {
if (new Date(dateFields[i].value) > comparatorDate) rslt.push(dateFields[i].value);
}
return rslt;
}
This was tested in chrome

javascript timed function - expected identifier

I am having a problem with a simple script that is supposed to update a page with some values(user input) that are turned from monthly to yearly (the numbers go into numeric fields created by confirmIT)
<script>
function update() {
for (var i = 0; i < 9; i++) {
var ans = parseInt(document.getElementById("bq10a_" + i).value, 10);
if (!isNaN(ans)) {
var new = ans * 12;
document.getElementById("bq10a_" + i + "calc").value = new;
}
}
}
return;
}
setInterval("update()", 1000);
</script>
this yields an Expected identifier error on line
var new = ans*12;
and i would appreciate any help on how to solve it
The word new is a reserved word in JavaScript and cannot be used as the name of a variable.
The error means that the parser expected an "identifier", which is to say that it expected to see a valid identifier.
Change the name of the variable and things should improve. In the code you've posted I think there's a { } nesting problem; there appears to be one too many before the return of the function.
edit — also as jbabey notes in a comment, your setInterval() call should be
setInterval(update, 1000);
It's not a good idea, generally, to pass strings to setInterval(), despite the advice of thousands of mouldy old instructional websites.
Word "new" -- is special in javascript language:
line is incorrect:
var new = ans*12;
try this:
var newvalue = ans*12;
More information on:
http://javascript.about.com/library/blreserved.htm
http://www.ecma-international.org/publications/standards/Ecma-262.htm

Categories