I'm currently working on a digital assistant website which is based around JavaScript and jQuery. The user can type in questions or tell the assistant things into the textbox and the assistant will respond with something relevant to the input. What I am planning to implement is to check if the textbox contains a number (intager) and if it does some sort of function will run. The concept sounds fairly simple and but I am having trouble. I have been searching around for a bit but I can't seem to find anything which will work with my code.
I will add my JavaScript and the nessacary parts of the HTML. But I am warning you, the code is messy.
JavaScript:
// JavaScript Document
function submitted() {
var srch = document.getElementById("srch");
command();
getPlaceHolder();
srch.value = "";
}
function searchKeyPress(e) {
e = e || window.event;
if (e.keyCode == 13) {
//document.getElementById('btn').click();
submitted();
}
}
function goBtn() {
submitted();
}
function refreshBtn() {
getWelcome();
}
function stClock() {
window.setTimeout("stClock()", 1000);
today = new Date();
self.status = today.toString();
}
function getWelcome() {
var ar = new Array(20)
ar[0] = "What's on your mind?";
ar[1] = "How can I help?";
ar[2] = "Anything you need help with?";
ar[3] = "Ask me anything";
ar[4] = "What can I help you with?";
ar[5] = "What would you like me to do?";
ar[6] = "What can I do for you?";
ar[7] = "Need help with anything?";
ar[8] = "Need someone to talk to?";
ar[9] = "I'm here to help";
ar[10] = "Anything you need to know?";
ar[11] = "How else can I help?";
ar[12] = "What can I do now?";
ar[13] = "Need anything?";
ar[14] = "Any problems you need solving?";
ar[15] = "Hello, how do you do?";
ar[16] = "Hi there";
ar[17] = "Hi, I'm aurum";
ar[18] = "Hello there";
ar[19] = "How do you do?";
var now = new Date();
var sec = now.getSeconds();
document.getElementById('output').innerHTML = ar[sec % 20];
}
function getPlaceHolder() {
var ar = new Array(20)
ar[0] = "What's on your mind?";
ar[1] = "How can I help?";
ar[2] = "Anything you need help with?";
ar[3] = "Ask me anything";
ar[4] = "What can I help you with?";
ar[5] = "What would you like me to do?";
ar[6] = "What can I do for you?";
ar[7] = "Need help with anything?";
ar[8] = "Need someone to talk to?";
ar[9] = "I'm here to help";
ar[10] = "Anything you need to know?";
ar[11] = "How else can I help?";
ar[12] = "What can I do now?";
ar[13] = "Need anything?";
ar[14] = "Any problems you need solving?";
ar[15] = "Hello, how do you do?";
ar[16] = "Hi there";
ar[17] = "Hi, I'm aurum";
ar[18] = "Hello there";
ar[19] = "How do you do?";
var now = new Date();
var sec = now.getSeconds();
document.getElementsByName('srch')[0].placeholder=ar[sec % 20];
}
function command() {
var srchVar = document.getElementById("srch");
var srch = srchVar.value;
var t = srch;
var outputElement = document.getElementById('output');
if (srch == '') {
outputElement.innerHTML = "How can I help you, if you don't say anything?";
}
else if (srch.indexOf('about') != -1) {
outputElement.innerHTML = "Hello, I'm Aurum. I was designed by Omar Latreche to help people answer their questions. However, I also like to talk to people aswell as answer their questions.";
}
else if (srch.indexOf('time') != -1) {
outputElement.innerHTML = 'The current time according to your computer is' + ShowTime(new Date());
}
else {
if (confirm("I am sorry but for some reason I don't understand. You could either repeat that or would you like to search Google for that instead?") == true) {
window.open('https://www.google.co.uk/#q=' + srch, '_blank');
}
else { /* Nothing */ }
}
}
//Show time in 12hour format
var ShowTime = (function() {
function addZero(num) {
return (num >= 0 && num < 10) ? "0" + num : num + "";
}
return function(dt) {
var formatted = '';
if (dt) {
var hours24 = dt.getHours();
var hours = ((hours24 + 11) % 12) + 1;
formatted = [formatted, [addZero(hours), addZero(dt.getMinutes())].join(":"), hours24 > 11 ? "PM" : "AM"].join(" ");
}
return formatted;
};
})();
And the HTML:
<!DOCTYPE html>
<html>
<body onload="getWelcome(); getPlaceHolder();">
<div class="output" id="output">
An error has occoured. Please make sure you have JavaScript enabled in your browser.
</div>
<div class="cont">
<div class="ui-widget">
<div class="search-cont">
<input class="search-field" id="srch" name="srch" onkeypress="searchKeyPress(event);" placeholder="ask me anything" spellcheck="false"> <input class="refresh" onclick="refreshBtn()" title="Refresh the conversation" type="button"> <input class="go" onclick="goBtn()" type="button">
</div>
</div><br>
</div>
</body>
</html>
I really appreciate any help provided. Thanks, Omar.
PS. I apologies for the long paragraph but that is the only way I could think to explain what I need.
PPS. If you need any more information on my project just incase, the URL is http://omarlatreche.tk/aurum/
This is the function I came up with to check for number:
function checkNum() {
text = document.getElementById('srch').value;
valArr = document.getElementById('srch').value.split(' ');
for (i = 0; i < valArr.length; i++) {
if (isNaN(valArr[i])==false) {
alert("Number found");
}
}
}
Here is the JSFiddle demo
I called the function in the goBtn() function.
can you explain this line?
document.getElementById('output').innerHTML = [0].innerHTML=ar[sec % 20];
shouldn't it be
document.getElementById('output').innerHTML = ar[sec % 20];
Related
I have multiple variables that use arguments to calculate an answer, but it only seems to work when I have a single variable with arguments.
My HTML is:
<textarea id="given" placeholder="Given"></textarea>
<input type="text" id="result" placeholder="Result" list="resultAutoComplete"/>
<datalist id="resultAutoComplete">
<option value="v">(v) Speed</option>
<option value="ρ">(ρ) density</option>
<option value="Eₚ">(Eₚ) Potential energy</option>
</datalist>
<button type="button" onClick="calculateAnswer();">result</button>
<p><a id="Rho" onClick="RhoAdd();" style="cursor: pointer;">ρ</a></p>
<button id="Example" onClick="Examplefill();" style="cursor: pointer;">ρ</button>
<p>Answer: <b id="answer"></b></p>
<div style="background-color: #ACACAC; width: 100%;"><ins style="color: #ED141A; font-size: 20px; margin-left: 5px;" id="errorAlerts"></ins></div>
When I get rid of other variables: ress and rest it works.
Here's what worked
function calculateAnswer() {
var givenInput = document.getElementById('given').value;
var road_s = givenInput.match(/s=(.*)(;)/); //looks for S= (road)
var time_t = givenInput.match(/t=(.*)(;)/); //looks for t= (time)
var speed_v = givenInput.match(/v=(.*)(;)/); //looks for v= (speed)
var toFind = document.getElementById('result').value;
var resv = road_s[1] / time_t[1];
if (toFind === "v") {
document.getElementById('answer').innerHTML = resv;
document.getElementById('errorAlerts').innerHTML = "";
} else {
document.getElementById('errorAlerts').innerHTML = "ERROR... invalid requested result";
}
}
I need this to print out a answer using road_s[1], time_t[1] and speed_v[1], but when I add more variables using these arguments
var resv = road_s[1] / time_t[1];
var ress = speed_v[1] * time_t[1];
var rest = road_s[1] / speed_v[1];
the system doesn't print out anything
function calculateAnswer() {
var givenInput = document.getElementById('given').value;
var road_s = givenInput.match(/s=(.*)(;)/); //looks for S= (road)
var time_t = givenInput.match(/t=(.*)(;)/); //looks for t= (time)
var speed_v = givenInput.match(/v=(.*)(;)/); //looks for v= (speed)
var toFind = document.getElementById('result').value;
var resv = road_s[1] / time_t[1];
var ress = speed_v[1] * time_t[1];
var rest = road_s[1] / speed_v[1];
if (toFind === "v") {
document.getElementById('answer').innerHTML = resv;
document.getElementById('errorAlerts').innerHTML = "";
} else {
document.getElementById('errorAlerts').innerHTML = "ERROR... invalid requested result";
}
if (toFind === "s") {
document.getElementById('answer').innerHTML = ress;
document.getElementById('errorAlerts').innerHTML = "";
} else {
document.getElementById('errorAlerts').innerHTML = "ERROR... invalid requested result";
}
if (toFind === "t") {
document.getElementById('answer').innerHTML = rest;
document.getElementById('errorAlerts').innerHTML = "";
} else {
document.getElementById('errorAlerts').innerHTML = "ERROR... invalid requested result";
}
}
It's is very hard to explain because I'm not very familiar with arguments.
So, there are a few things going on here. First, when you match your regex (given the input you've commented), you will always have one of the three that doesn't match. Given the comment input, speed_v will be null, and would cause a fatal error in two of the three equations. At the first fatal error, the program would halt.
To fix this, I changed your match statements a little:
var road_s = givenInput.match(/s=(.*)(;)/) || [null, 0]; //looks for S= (road)
var time_t = givenInput.match(/t=(.*)(;)/) || [null, 0]; //looks for t= (time)
var speed_v = givenInput.match(/v=(.*)(;)/) || [null, 0]; //looks for v= (speed)
In each case, if match returns null, the || operator (logical or) kicks in, and creates a 'dummy array', containing [null, 0] - thus providing a value for the missing option, each time.
The second problem you encounter is in your if statement. In each branch, you say 'if the chosen option is thus-and-such, display the calculation. if not, show an error!' And that is happening for each of the various options.
A better approach may be to use a switch statement, allowing you to watch for each possible outcome:
switch(toFind){
case 'v':
document.getElementById('answer').innerHTML = resv;
document.getElementById('errorAlerts').innerHTML = "";
break;
case 's':
document.getElementById('answer').innerHTML = ress;
document.getElementById('errorAlerts').innerHTML = "";
break;
case 't':
document.getElementById('answer').innerHTML = rest;
document.getElementById('errorAlerts').innerHTML = "";
break;
default:
document.getElementById('errorAlerts').innerHTML = "ERROR... invalid requested result";
}
To see this as a working solution, take a look at this repl: https://repl.it/#TobiasParent/tooManyArgsSO
edit: I know this is a hacky solution, but let's face it - the HTML is hacky, the input is hacky, the whole thing has a slap-dash feel. Given that, this is a teachable moment. Learn about the switch/case branching mechanism, and try to understand why you were getting a fatal error in your calculations.
I'm trying to create a simple game where you have to answer the correct answer from a calculation.
I already have the function to generate random calculations, but i don't know how to compare it with the result which the user writted.
I tried to make the if, so when the user press the submit button, then the app will try to determine if that's the correct answer.
var numArray = ["10/2", "5x5", "12-22", "5-6", "20-70"];
var question = document.getElementById("textQuestion");
var answer = document.getElementById("textAnswer");
function rollDice() {
document.form[0].textQuestion.value = numArray[Math.floor(Math.random() * numArray.length)];
}
function equal() {
var dif = document.forms[0].textQuestion.value
if (dif != document.forms[0].textAnswer.value) {
life--;
}
}
<form>
<input type="textview" id="textQuestion">
<br>
<textarea id="textAnswer" form="post" placeholder="Answer"></textarea>
</form>
<input type="button" name="start" onclick="">
document.forms[0].textQuestion.value looking for an element with name=textQuestion, which doesn't exist. Use getElementById instead or add name attribute (needed to work with the input value on server-side).
function equal() {
if (document.getElementById('textQuestion').value != document.getElementById('textAnswer').value) {
life--; // life is undefined
}
}
// don't forget to call `equal` and other functions.
This is probably what you're looking for. I simply alert(true || false ) based on match between the random and the user input. Check the Snippet for functionality and comment accordingly.
var numArray = ["10/2", "5x5", "12-22", "5-6", "20-70"];
var questionElement = document.getElementById("textQuestion");
var answerElement = document.getElementById("textAnswer");
function rollDice() {
var question = numArray[Math.floor(Math.random() * numArray.length)];
questionElement.setAttribute("value", question);
}
//rolldice() so that the user can see the question to answer
rollDice();
function equal()
{
var dif = eval(questionElement.value); //get the random equation and evaluate the answer before comparing
var answer = Number(answerElement.value); //get the answer from unser input
var result = false; //set match to false initially
if(dif === answer){
result = true; //if match confirmed return true
}
//alert the match result
alert(result);
}
document.getElementById("start").addEventListener
(
"click",
function()
{
equal();
}
);
<input type="textview" id="textQuestion" value="">
<br>
<textarea id="textAnswer" form="post" placeholder="Answer"></textarea>
<input type="button" id="start" value="Start">
There's more I would fix and add for what you're trying to achieve.
First of you need a QA mechanism to store both the question and the correct answer. An object literal seems perfect for that case: {q: "", a:""}.
You need to store the current dice number, so you can reuse it when needed (see qa_curr variable)
Than you could check the user trimmed answer equals the QA.a
Example:
let life = 10,
qa_curr = 0;
const EL = sel => document.querySelector(sel),
el_question = EL("#question"),
el_answer = EL("#answer"),
el_check = EL("#check"),
el_lives = EL("#lives"),
qa = [{
q: "Calculate 10 / 2", // Question
a: "5", // Answer
}, {
q: "What's the result of 5 x 5",
a: "25"
}, {
q: "5 - 6",
a: "-1"
}, {
q: "Subtract 20 from 70",
a: "-50"
}];
function rollDice() {
qa_curr = ~~(Math.random() * qa.length);
el_question.textContent = qa[qa_curr].q;
el_lives.textContent = life;
}
function checkAnswer() {
const resp = el_answer.value.trim(),
is_equal = qa[qa_curr].a === el_answer.value;
let msg = "";
if (resp === '') return alert('Enter your answer!');
if (is_equal) {
msg += `CORRECT! ${qa[qa_curr].q} equals ${resp}`;
rollDice();
} else {
msg += `NOT CORRECT! ${qa[qa_curr].q} does not equals ${resp}`;
life--;
}
if (life) {
msg += `\nLives: ${life}`
} else {
msg += `\nGAME OVER. No more lifes left!`
}
// Show result msg
el_answer.value = '';
alert(msg);
}
el_check.addEventListener('click', checkAnswer);
// Start game
rollDice();
<span id="question"></span><br>
<input id="answer" placeholder="Your answer">
<input id="check" type="button" value="Check"> (Lives:<span id="lives"></span>)
The above still misses a logic to not repeat questions, at least not insequence :) but hopefully this will give you a good start.
I'm making a function to find the all movies made by the actor i search for, the movies are in a js file like so:
var filmlist = [
{"Title":"Killer's Kiss", "Actors":"Frank Silvera, Jamie Smith, Irene Kane, Jerry Jarrett"}
];
var a = document.getElementById("film");
function findActors() {
var x = document.getElementById("actor").value;
var y = document.getElementById("actorfilm");
a.innerHTML = "Movies with this actor: "
for (var i=0; i<filmlist.length; i++) {
if (x.indexOf(filmlist[i].Actors) !== -1) {
y.innerHTML = (filmlist[i].Title + "<br/>")
}
}
}
<textarea rows="2" cols="50" id="actor" placeholder="write actor name, and press the button"></textarea>
<button onclick="findActor()">ActorButton</button>
<p id="film"></p>
<p id="actorfilm"></p>
For some reason it wont show the actors, but it shows the first a.innerhtml
Im very new to javascript so any help is appreciated.
You are almost there, just that your if condition needs to be reversed.
if (filmlist[i].Actors.indexOf(x) )
You were checking the superset of actors within the value you have input, rather than doing it the other way round.
You can make it more precise by doing
var filteredFilms = filmlist.filter( s => s.Actors.indexOf(x) != -1 );
var output = filteredFilms.map( s => s.Title ).join( "<br/>" );
Demo
var filmlist = [{
"Title": "Killer's Kiss",
"Actors": "Frank Silvera, Jamie Smith, Irene Kane, Jerry Jarrett"
}];
var a = document.getElementById("film");
function findActors() {
var x = document.getElementById("actor").value;
var y = document.getElementById("actorfilm");
a.innerHTML = "Movies with this actor: "
var filteredFilms = filmlist.filter(s => s.Actors.indexOf(x) != -1);
y.innerHTML = filteredFilms.map(s => s.Title).join("<br/>");
}
<!-- find actor function -->
<textarea rows="2" cols="50" id="actor" placeholder="write
actor name, and press the button">Frank Silvera</textarea>
<button onclick="findActors()">ActorButton</button>
<p id="film"></p>
<p id="actorfilm"></p>
You are currently overwriting y.innerHTML with the last movie title. To append, to the innerHTML use:
y.innerHTML += (filmlist[i].Title + "<br/>")
There is an issue with your indexOf, mentioned in another answer and can be fixed with
if (filmlist[i].Actors.indexOf(x)) {
Lastly, your HTML is incorrectly referencing the js function and should instead be:
<button onclick="findActors()">ActorButton</button>
I'm trying to create a guessing game that if the user enters a number into an input field and click a button, a text shows up saying if the number is bigger or smaller than a random number that's been created by JavaScript. I seem to have figured out everything else, but I'm having a hard time getting the value that is entered into the input field.
I'd appreciate your help.
<div class="wrap" >
Project: Guessing Game
<input type="text" name="inputField" value="" id="inputField"/>
<button id="guess">Guess!</button>
<br>
<p id="result"></p>
</div>
<script type="text/javascript" charset="utf-8">
var $ = function(selector) {
return document.querySelector(selector);
};
var randomRange = function(min,max){
return Math.random(((Math.random()*(max-min))+min));
};
var randomNumber = randomRange(1,4);
var myButton = $("#guess");
var myNumber = $("#inputField").value;
var myResult = $("#result");
if ( myNumber > randomNumber) {
myButton.onclick = function () {
myResult.innerHTML += "Your number is bigger than the random number";
}
}
else if ( myNumber < randomNumber){
myButton.onclick = function () {
myResult.innerHTML += "Your number is smaller than the random number";
}
}
else if ( myNumber === randomNumber ){
myButton.onclick = function () {
myResult.innerHTML += "Your number matches the random number";
}
}
</script>
Your input is being read when there is no data, and when you click, you don't check if the data has changed. You should place the decision blocks to check the input inside the event handler, like this:
myButton.onclick = function () {
var myNumber = $("#inputField").value;
myNumber = parseInt(myNumber, 10);
if ( myNumber > randomNumber) {
myResult.innerHTML = "Your number is bigger than the random number";
} else if ( myNumber < randomNumber){
myResult.innerHTML = "Your number is smaller than the random number";
} else if ( myNumber === randomNumber ){
myResult.innerHTML = "Your number matches the random number";
}
}
var $ = function(selector) {
return document.querySelector(selector);
};
var randomRange = function(min,max){
return Math.round(((Math.random()*(max-min))+min));//notice here,Math.round
};
var randomNumber = randomRange(1,4);
var myButton = $("#guess");
var myNumber = $("#inputField");
var myResult = $("#result");
myButton.onclick = function(){
var val = parseInt(myNumber.value, 10);
if(val < randomNumber){
//smaller code
}else if(val > randomNumber){
//bigger code
}else{
//equal code
}
}
I have function that loops every 500ms, and collects date information:
var mlptoday = {};
var timer = setTimeout(today,500);
function today(){
var d = new Date()
mlptoday.date = checkTime(d.getDate()); //output: "27"
mlptoday.year = d.getFullYear(); //output: "2013"
mlptoday.month = checkTime(d.getMonth()+1); //output: "01"
}
function checkTime(i) { if (i<10){i="0" + i} return i }
In a different function, I would like to check if the date the user gives as input is either the same day, or after the given day.
An example input may be: 2013.01.27.
I use this snippet of code to achieve what I want:
var remTime = "2013.01.27"; //user input
var remTimeArray = remTime.split('.') //output: ["2013","01","27"]
if (
!(remTimeArray[0] >= parent.mlptoday.year &&
remTimeArray[1] >= parent.mlptoday.month) ||
!((remTimeArray[1] == parent.mlptoday.month) ? Boolean(remTimeArray[2]*1 >= parent.mlptoday.date) : true)
){
//the input date is in the past
}
As you could probably guess, this does not work. The conditional statement seems to fail me, because if I invert Boolean(...) with an !(...), it will never fire the error, otherwise it always will.
Here's a snippet, where it works at it should:
var mlptoday = {};
var timer = setTimeout(today,500);
function today(){
var d = new Date();
mlptoday.year = d.getFullYear(); //output: "2013"
mlptoday.month = checkTime(d.getMonth()+1); //output: "01"
mlptoday.date = checkTime(d.getDate()); //output: "27"
$('#values').html(JSON.stringify(mlptoday));
}
function checkTime(i) { if (i<10){i="0" + i} return i }
$(document).ready(function(){
$('form').submit(function(e){
e.preventDefault();
var remTime = $('input').val(); //user input
var remTimeArray = remTime.split('.') //output: ["2013","01","27"]
if (
!(remTimeArray[0] >= mlptoday.year &&
remTimeArray[1] >= mlptoday.month) ||
!((remTimeArray[1] == mlptoday.month) ? Boolean(remTimeArray[2]*1 >= mlptoday.date) : true)
){
$('#past').fadeIn('fast').delay(500).fadeOut('fast');
}
})
})
#past { display:none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form>
<input type="text" id="input" required autocomplete="off" placeholder="yyyy.mm.dd" pattern="^(19|20)\d\d[.](0[1-9]|1[012])[.](0[1-9]|[12][0-9]|3[01])$" required="" />
<button>Check</button>
</form>
<pre id="values"></pre>
<span id="past">the input date is in the past</span>
I need a better way to do this, and I don't want to use any date picker plugins.
I would compare the dates as integers to avoid complex logic.
var todayConcat = "" + parent.mlptoday.year + parent.mlptoday.month + parent.mlptoday.date;
var remTimeConcat = remTime.replace(/\./g, "");
if (remTimeConcat < todayConcat) {
//the input time is in the past
}
Just make sure the dates and months always have the leading zero.