what i aim to do is a very simple currency converter. Basically, you type in a number, and press a button, a text is displayed that says "x dollars is y euros". Press the button again, a new text is displayed where the old one was, and the old one is displayed under the new one.
I've come so far that when something is entered in the field, it pops up below, and if you press the button again (with the same or a different value) it becomes a list of text.
To clarify what it is i'm saying here, take a look at this jsfiddle: http://jsfiddle.net/w8KAS/5/
Now i want to make it so that only numbers work, and so that number(x) is converted when the button is pressed and displayed below next to some fitting text (like "x dollars is y euros")
This is my js code, check the jsfiddle full code (html, js, css)
Any suggestions?
var count = 0;
function validate() {
var amount = document.querySelector("#amount");
if(amount.value.length > 0) {
amount.className = 'correct';
}
else {
amount.className = 'empty';
}
if (document.querySelector('.empty')) {
alert('Något är fel');
}
else {
addconvert(amount.value);
}
}
function addconvert(amount) {
var table = document.querySelector('#tbody');
var tr = document.createElement('tr');
var amountTd = document.createElement('td');
var amountTextNode = document.createTextNode(amount);
amountTd.appendChild(amountTextNode)
tr.appendChild(amountTd);
table.insertBefore(tr, table.firstChild);
count++;
}
var button = document.querySelector(".button");
button.onclick = validate;
Your number validation is failing. Change the first part of your validation to this:
function validate() {
var amount = document.querySelector("#amount");
var amountNum = parseFloat(amount.value); //This is the numeric value, use it for calculations
if(amount.value.length > 0 && !isNaN(amountNum) ) {
amount.className = 'correct';
amount.value = amountNum;
}
...
Working here: http://jsfiddle.net/edgarinvillegas/w8KAS/6/
Cheers
You need a conversion rate (there are APIs for that), and then you can just add them together in a string
var convRate = 1.3;
var amountTextNode = document.createTextNode(amount + " dollars is " + amount*convRate + " euros");
Regarding the API, Yahoo will tell you what you need without even the need to sign-in
$.ajax({
url: "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22USDEUR%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback="
}).done(function(data) {
convRate = data.query.results.rate.Rate
});
To make sure that only numbers work, you can test the variable amount.value using the isNaN function. This will return true if the user's input is Not-a-Number, so if it returns false, you can proceed with your conversion.
if (!isNaN(amount.value)){
addconvert(+amount.value) // the plus symbol converts to a number
} else {
// display error here
}
Inside your addconvert function, you can add code to will multiply your input amount by an exchange rate to get a rough conversion.
function addconvert(){
// ...
var euros = 0.74 * amount
var text = amount + ' dollars is ' + euros + ' euros'
var amountTextNode = document.createTextNode(text);
Related
I have this certain problem where I cannot get the number value of 'currentStock' var data inside an HTML file using JavaScript. I have this on my HTML file in script tag:
By the way, due to the HTML being too large, and also it was not originally my script, but from a friend who was asking for some help on adding some features in it, I can't upload the whole script as it will be going to be too long. The whole HTML script has 14076 characters with 289 lines.
I have only studied java and not javascript with HTML, so I need help with this one.
<script>
window.onload = function() {
var goDown = document.getElementById('uniqueNav');
var goRight = document.querySelector('.clothesNav');
var goUp = document.querySelector('.shrink');
goDown.style.marginTop = "0px";
goRight.style.marginLeft = "5px";
goUp.style.height = "0px";
}
$('document').ready(function(){
var name = "Ombre Printed Shirt";
var price = "P499.00";
var initialStock = 0;
var currentStock = initialStock;
document.querySelector('#clothTitle').innerHTML = "" +name;
document.querySelector('#clothPrice').innerHTML = "Price: " +price;
document.querySelector('#PITitle').innerHTML = "" +name;
document.querySelector('#PIPrice').innerHTML = "Price: " +price;
document.querySelector('#currentStock').innerHTML = "CurrentStocks: " +currentStock;
}); //------------------------Change This Every Document ----------------------------//
</script>
then this in my JavaScript File:
var cStocks = document.getElementById('currentStock').data;
alert(typeof cStocks);
alert("Data in cStocks = " + cStocks);
if (!cStocks) {cStocks = 0; alert("cStocks, not a valid number");}
if ((cStocks <= 0) == true)
{
document.querySelector('.clothButton').style.display='none';
document.querySelector('.clothButtonDisabled').style.display='flex';
}
else
{
document.querySelector('.clothButton').style.display='flex';
document.querySelector('.clothButtonDisabled').style.display='none';
}
upon loading the page, the alert says thaat the data type is undefined. I don't know what's happening with my code. did I miss something?
By the way, I have JQuery on my HTML page. it says JQuery v3.3.1 as a version
It doesn't look to me like #currentStock will have a data attribute, or value attribute (which is for inputs), so of course the js returns undefined. Right now it looks like #currentStock is having the innerHTML set on the document.ready to Current Stocks: 0
You do have an accessible variable, currentStock, which is defined during document.ready. Why aren't you accessing it directly? It will have the numeric value in it already. All you can get from #currentStock is the html you generated on document.ready, and you'd have to parse the number out of it, when it's available in raw form in the js variable currentStock.
What i have done:
function makeBold(strings) {
var myHTML = document.getElementsByTagName('body')[0].innerHTML;
myHTML = myHTML.replace(strings, '<b>' + strings + '</b>');
document.getElementsByTagName('body')[0].innerHTML = myHTML
}
this code works only for the paces where the texts are free from ant tags
Eg: <p class="ClassName">Some free text without any inner html elements</p>
But for sentences below this the above javascript function is not giving any result
Eg sentence which are not working:
<p class="Aclass"><span class="char-style-override-1">Starting from here, </span><span class="char-style-override-2">text resumes after the span tag</span><span class="char-style-override-1">. again text resumes.</span></p>
What I need
i need a functionality to make the above text bold when i pass that text into my js function. and by text i mean only
Starting from here,text resumes after the span tag. again text resumes.
when i call the above mentioned jas function like this
makeBold('Starting from here,text resumes after the span tag. again text resumes.');
nothing happens, the entire sentence does not gets bold nothing happens, because the js function only looks for the occurrence of that string and makes it bold, in my second example the text is mixed with html tags
so that the above mentioned text will get bold when i call my makebold function.
Please note that i dont have the id for the <p> , what i have is a couple of random strings stored in my db and load a couple of webpages, while doing so i want to bold the sentence/text from the webpage if is matches with my passed string from db
While doing my research i got a code to highlight text given to a js. this js function will select the exact text in the html page which is passed to the js function.
the second eg also works for this code. i.e i can select the exact string from the example by passing it to the function.
function selectText(text) {
if (window.find && window.getSelection) {
document.designMode = "on";
var sel = window.getSelection();
sel.collapse(document.body, 0);
while (window.find(text)) {
document.getElementById("button").blur();
document.execCommand("HiliteColor", false, "yellow");
sel.collapseToEnd();
}
document.designMode = "off";
} else if (document.body.createTextRange) {
var textRange = document.body.createTextRange();
while (textRange.findText(text)) {
textRange.execCommand("BackColor", false, "yellow");
textRange.collapse(false);
}
}
}
I tried to customize it so that instead of selecting the passed text, i tried to make it bold. but coudnt succed.
Please help me in getting this done. I am new to js.
I finally got a solution to your problem that works as you want it to (i. e. the function takes an arbitrary substring and marks anything that fits the substring bold while leaving the rest of the string untouched). If the string passed doesn't match any part of the string that you want to modify, the latter remains untouched.
Here goes (Beware: That JS section got really BIG!):
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test case for making arbitrary text bold</title>
<meta charset="UTF-8">
<script type="application/javascript">
// Takes two strings and attempts to intersect them (i. e. the end of p_str1
// must match the beginning of p_str2). The index into p_str1 is returned.
// If no intersection can be found, -1 is returned.
function intersectStrings(p_str1, p_str2)
{
var l_pos = -1;
do
{
l_pos = p_str1.indexOf(p_str2[0], l_pos + 1);
if(p_str1.substr(l_pos) == p_str2.substr(0, p_str1.length - l_pos))
// If the two substrings match, we found something. Return with the position.
break;
}
while(l_pos != -1);
return l_pos;
}
function makeBold(p_string)
{
var l_elem = document.getElementById('modify');
var l_html = l_elem.innerHTML;
var l_text = l_elem.innerText;
var l_aux = l_html.match(/<.+?>/g);
var l_here = l_text.indexOf(p_string);
var l_before;
var l_middle;
var l_behind;
if(typeof(p_string) != 'string')
throw "invalid argument";
// First of all, see whether or not we have a match at all. If no, we don't
// need to continue with this.
if(l_here == -1)
{
console.error('makeBold: Could not find desired substring ' + p_string + '! Stop...');
return;
}
// Take the plain text and split it into three distinct parts (l_middle is of
// interest for us here).
l_before = l_html.slice(0, l_here);
l_behind = l_html.slice(l_here + l_html.length);
l_middle = l_html.slice(l_here, l_here + l_html.length);
if(l_aux)
{
// If we have a set of markup tags, we need to do some additional checks to
// avoid generating tag soup.
let l_target = new Array();
let l_tag;
let l_nexttag;
let l_this;
let l_endpos = 0;
let l_in_str = false;
let l_start;
while(l_aux.length - 1)
{
l_tag = l_aux.shift();
l_target.push(l_tag);
l_nexttag = l_aux[0];
l_endpos = l_html.indexOf(l_nexttag, 1);
l_this = l_html.slice(l_tag.length, l_endpos);
l_html = l_html.slice(l_endpos);
// Skip the entire rigmarole if there are two adjacent tags!
if(l_tag.length == l_endpos)
continue;
if(!l_in_str)
{
if((l_start = l_this.indexOf(p_string)) != -1)
{
// If we find the entire passed string in a fragment of plain text, we can
// modify that, reassemble everything and exit the loop.
l_before = l_this.slice(0, l_start);
l_behind = l_this.slice(l_start + p_string.length);
l_middle = l_this.slice(l_start, l_start + p_string.length);
l_this = l_before + '<strong>' + l_middle + '</strong>' + l_behind;
l_target.push(l_this);
l_target.push(l_html);
l_html = l_target.join('');
console.info('makeBold: The passed string fit between two tags: Done!');
break;
}
// Take the possibility of having to scan across fragments into account. If
// that is the case, we need to piece things together.
if((l_start = intersectStrings(l_this, p_string)) != -1)
{
// Once we wind up here we have a partial match. Now the piecework starts...
l_before = l_this.slice(0, l_start);
l_middle = l_this.slice(l_start);
l_this = l_before + '<strong>' + l_middle + '</strong>';
l_target.push(l_this);
console.info('makeBold: Found starting point of bold string!');
l_in_str = true;
}
else
{
// Nothing to do: Push the unmodified string.
l_target.push(l_this);
}
}
else
if((l_endpos = intersectStrings(p_string, l_this)) == -1)
{
// We haven't arrived at the end position yet: Push the entire segment with
// bold markers onto the stack.
l_this = '<strong>' + l_this + '</strong>';
l_target.push(l_this);
}
else
{
// We have an end position: Treat this fragment accordingly, wrap everything up
// and exit the loop.
l_behind = l_this.slice(l_endpos + 1);
l_middle = l_this.slice(0, l_endpos + 1);
l_this = '<strong>' + l_middle + '</strong>' + l_behind;
l_target.push(l_this);
l_target.push(l_html);
l_html = l_target.join('');
console.info('makeBold: Found the end part: Done!');
break;
}
}
}
else
l_html = l_before + '<strong>' + l_middle + '</strong>' + l_behind;
l_elem.innerHTML = l_html;
}
</script>
</head>
<body>
<header><h1>Test case for making arbitrary text bold by using JavaScript</h1></header>
<main>
<p id="modify"><span class="char-style-override-1">Starting from here, </span><span class="char-style-override-2">text resumes after the span tag</span><span class="char-style-override-1">. again text resumes.</span></p>
</main>
<script type="application/javascript">
// makeBold('Starting from here, text resumes after the span tag. again text resumes.');
// makeBold('from here, text resumes');
// makeBold('resumes after the span');
makeBold('text resumes after the span tag');
</script>
</body>
</html>
Unfortunately this job couldn't be done with a short section, because you need to take various cases into account that need to be handled individually. The control logic that I have come up with addresses all these concerns.
See the annotations in the JS that I have made for details.
I have a page of items with various prices in GBP, each price is within a span with a class of price, what I would like to do is change the value of ALL the prices to that value divided by 1.2. so along the lines of
$('.price').html() / "1.2";
now i'm aware that this won't work as the format is £10,500 for example, I havent been able to find similar here but i'd like to take that £10,500 value divide it by 1.2 and have the value update to the result (£8,750). Anything I have tried thus far leaves me with NaN and i'm struggling to make progress.
Add a button for testing:
<button id="test-button">Test Currencies</button>
Add the following jQuery:
$('#test-button').on('click', function () {
// Get currency elements
var currencies = $('.price');
var newSymbol = '£';
var eRate = 0.8333;
$.each(currencies, function (index, value) {
// Change value to a number using regex
var number = Number($(this).html().replace(/[^0-9\.]+/g, ""));
// Assign new value and add number formatting
$(this).html(newSymbol + (number * eRate).toFixed(2).toLocaleString('en'));
});
});
Hope it helps.
Here you go :-)
Tested and working.
$("span").each(function()
{
var strNewString = $(this).html().replace(',','');
$(this).html(strNewString / 1.2);
});
function format_price(_input_str){
var input_str=_input_str+''; //if input integer convert to string
input_str=input_str.replace(new RegExp(' ',"g"), ''); //if exist spaces
input_str=input_str.replace(new RegExp('£',"g"), ''); //if exist simbil £
input_str=input_str.replace(new RegExp(' ',"g"), ''); //if wxist
var input_int = parseInt(input_str)||0;
if(input_int==0){ return _input_str;} //return original string
input_str=input_int+'';
var out_str='';
while(input_str.length > 3){
out_str=input_str.substr(-3)+' '+out_str;
input_str=input_str.substr(0,input_str.length-3);
}
if(input_str.length>0){out_str=input_str+' '+out_str;}
out_str='£ '+out_str;
return out_str;
}
$('.price').each(function(){
var this_price=$(this).html();
$(this).html(format_price(this_price));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="price">12345</div>
<div class="price">76 09</div>
<div class="price">4576 09</div>
<div class="price">45</div>
<div class="price">£ 12 345 678 </div>
I apologize in advance, this is the first Stack Overflow question I've posted. I was tasked with creating a new ADA compliant website for my school district's technology helpdesk. I started with minimal knowledge of HTML and have been teaching myself through w3cschools. So here's my ordeal:
I need to create a page for all of our pdf and html guides. I'm trying to create a somewhat interactable menu that is very simple and will populate a link array from an onclick event, but the title="" text attribute drops everything after the first space and I've unsuccessfully tried using a replace() method since it's coming from an array and not static text.
I know I'm probably supposed to use an example, but my work day is coming to a close soon and I wanted to get this posted so I just copied a bit of my actual code.
So here's what's happening, in example 1 of var gmaildocAlt the tooltip will drop everything after Google, but will show the entire string properly with example 2. I was hoping to create a form input for the other helpdesk personnel to add links without knowing how to code, but was unable to resolve the issue of example 1 with a
var fix = gmaildocAlt.replace(/ /g, "&nb sp;")
//minus the space
//this also happens to break the entire function if I set it below the rest of the other variables
I'm sure there are a vast number of things I'm doing wrong, but I would really appreciate the smallest tip to make my tooltip display properly without requiring a replace method.
// GMAIL----------------------------
function gmailArray() {
var gmaildocLink = ['link1', 'link2'];
var gmaildocTitle = ["title1", "title2"];
var gmaildocAlt = ["Google Cheat Sheet For Gmail", "Google 10-Minute Training For Gmail"];
var gmailvidLink = [];
var gmailvidTitle = [];
var gmailvidAlt = [];
if (document.getElementById("gmailList").innerHTML == "") {
for (i = 0; i < gmaildocTitle.length; i++) {
arrayGmail = "" + gmaildocTitle[i] + "" + "<br>";
document.getElementById("gmailList").innerHTML += arrayGmail;
}
for (i = 0; i < gmailvidTitle.length; i++) {
arrayGmail1 = "";
document.getElementById("").innerHTML += arrayGmail1;
}
} else {
document.getElementById("gmailList").innerHTML = "";
}
}
<div class="fixed1">
<p id="gmail" onclick="gmailArray()" class="gl">Gmail</p>
<ul id="gmailList"></ul>
<p id="calendar" onclick="calendarArray()" class="gl">Calendar</p>
<ul id="calendarList"></ul>
</div>
Building HTML manually with strings can cause issues like this. It's better to build them one step at a time, and let the framework handle quoting and special characters - if you're using jQuery, it could be:
var $link = jQuery("<a></a>")
.attr("href", gmaildocLink[i])
.attr("title", gmaildocAlt[i])
.html(gmaildocTitle[i]);
jQuery("#gmailList").append($link).append("<br>");
Without jQuery, something like:
var link = document.createElement("a");
link.setAttribute("href", gmaildocLink[i]);
link.setAttribute("title", gmaildocAlt[i]);
link.innerHTML = gmaildocTitle[i];
document.getElementById("gmailList").innerHTML += link.outerHTML + "<br>";
If it matters to your audience, setAttribute doesn't work in IE7, and you have to access the attributes as properties of the element: link.href = "something";.
If you add ' to either side of the variable strings then it will ensure that the whole value is read as a single string. Initially, it was assuming that the space was exiting the Title attribute.
Hope the below helps!
UPDATE: If you're worried about using apostrophes in the title strings, you can use " by escaping them using a . This forces JS to read it as a character and not as part of the code structure. See the example below.
Thanks for pointing this one out guys! Sloppy code on my part.
// GMAIL----------------------------
function gmailArray() {
var gmaildocLink = ['link1', 'link2'];
var gmaildocTitle = ["title1", "title2"];
var gmaildocAlt = ["Google's Cheat Sheet For Gmail", "Google 10-Minute Training For Gmail"];
var gmailvidLink = [];
var gmailvidTitle = [];
var gmailvidAlt = [];
if (document.getElementById("gmailList").innerHTML == "") {
for (i = 0; i < gmaildocTitle.length; i++) {
var arrayGmail = "" + gmaildocTitle[i] + "" + "<br>";
document.getElementById("gmailList").innerHTML += arrayGmail;
}
for (var i = 0; i < gmailvidTitle.length; i++) {
var arrayGmail1 = "";
document.getElementById("").innerHTML += arrayGmail1;
}
} else {
document.getElementById("gmailList").innerHTML = "";
}
}
<div class="fixed1">
<p id="gmail" onclick="gmailArray()" class="gl">Gmail</p>
<ul id="gmailList"></ul>
<p id="calendar" onclick="calendarArray()" class="gl">Calendar</p>
<ul id="calendarList"></ul>
</div>
On my HTML form, users can enter their name.
Their name will then appear in a DIV as part of a book title.
The book title uses apostrophe 's (e.g. Amy's Holiday Album).
If the user enters a name which ends in a S, I don't want the apostrophe s to appear.
(e.g. it should be Chris' Holiday Album instead of Chris's Holiday Album).
I also only want this to occur if the form has a class of apostrophe. If this class does not exist, then the name should be copied as is without any apostrophe or 's'.
I know you can use slice() to get the last character of an element, so I thought I could combine this with an if statement. But it doesn't seem to work.
Here is JSFiddle
Here is my HTML:
<div><b class="title"></b> Holiday Album</div>
Here is my Jquery (1.8.3):
$(document).ready(function() {
$('.name').keyup(function() {
var finalname = text($(this).val());
var scheck = finalname.slice(-1);
var finaltitle;
if ($(".apostrophe")[0]) {
if (scheck == 's') {
finaltitle = finalname + "'";
}
else {
finaltitle = finalname + "'s";
}
$('.title').text(finaltitle);
}
else {
$('.title').text(finalname);
}
});
});
text method is not needed on
var finalname = $(this).val();
check fiddle
Use
var finalname = $(this).val();
instead of
var finalname = text($(this).val());
Simplified version
$(document).ready(function() {
//Code fires when user starts typing:
$('.name.apostrophe').keyup(function() {
if (this.value.indexOf("'s") != -1 ) {
$('.title').text(this.value.replace(/'s/g, "'"));
} else {
$('.title').text(this.value)
}
}); /* Capture Personalised Message */
});
This will also replace all occurrences of the 's with ' only.
Hope it helps!.