Why javascript not run line by line - javascript

Below are html/javascript code, but when call function calc(), its output a <ol>
tag first, but bot run script orderly.
I have remove the settimeout() function to make it running sync.
Can some one give explain will be appreciated.
function $(id) {
return document.getElementById(id);
}
regex_field = $('regx');
content = $('content');
output = $('output');
flag_field = $('flag')
flag_field.addEventListener('input', function() {
calc();
});
content.addEventListener('input', function() {
calc();
});
regex_field.addEventListener('input', function() {
calc();
});
function calc() {
//setTimeout(function () {
var re = new RegExp(regex_field.value, flag_field.value)
console.log(re);
found = content.value.match(re);
if (found) {
$('output').innerHTML = "<ol>";
for (let i = 0; i < found.length; i++) {
$('output').innerHTML += '<li>' + found[i] + '</li>';
}
$('output').innerHTML += "</ol>";
} else {
$('output').innerHTML = "Nothing Found!";
}
// }, 500);
}
<html>
<head>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
</head>
<body>
<div class="row">
<div class="col-sm-6 form-inline">
RegExp
<input class="col-sm-4 form-control form-control-sm" type="text" id="regx" placeholder="Regex Input"> Flag
<input class="col-sm-1 form-control form-control-sm" type="text" id="flag">
<br>
<div>
<p>Input Content</p>
<textarea class="form-control col-sm-12" name="input" placeholder="Text" id="content" cols="30" rows="10"></textarea>
</div>
</div>
<div class="col-sm-6">
<p>Content get</p>
<div id="output"></div>
</div>
</div>
</body>
</html>
Output is like below. I don't understand why 'ol' tage go above the 'li' tag.
<div id="output">
<ol></ol> // <--- question here
<li>12</li>
<li>34</li>
</div>

When you do $('output').innerHTML = "<ol>"; it immediately adds the ol tag to #output. Since an <ol> without a closing </ol> is invalid, the DOM automatically closes it. So you get:
<div id="output">
<ol></ol>
</div>
Then, you do $('output').innerHTML += '<li>' + found[i] + '</li>';, so it adds that line to #output (which is also invalid, since an li can't belong to a div, but it doesn't know how to fix it):
<div id="output">
<ol></ol>
<li>12</li>
</div>
What you want to do it build up the innerHTML, then set it all at once, so more like:
if (found) {
var output = '';
output = "<ol>";
for (let i = 0; i < found.length; i++) {
output += '<li>' + found[i] + '</li>';
}
output += "</ol>";
} else {
output = "Nothing Found!";
}
$('output').innerHTML = output;

Related

WebChat how to set css color for sender/receiver

I am working on implementing a web chat and have come up with an issue that I hope is easily solvable.
How do I change the color for the sender/receiver to differenciate them?
I have tried to saving the colors into my db but the issue is how I can identify that I am the sender and the receivers color needs to be different.
This is how I have implemented my chat:
Chat.js
connection.on("SessionNotification", function (user, message) {
var msg = message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
var p = document.createElement("span");
var q = document.createElement("li");
p.setAttribute("class", "Sender");
q.setAttribute("class", "Message");
p.textContent = user + " - " + moment(datetime).format("DD-MM-YYYY HH:mm:ss");
q.textContent = msg;
document.getElementById("MessageList").appendChild(p);
document.getElementById("MessageList").appendChild(q);
});
Html
<script>
$(document).ready(function () {
$('#MessageList').stop().animate({
scrollTop: $('#MessageList')[0].scrollHeight
}, 2000);
var SessionId = document.getElementById("Id").value;
console.log(SessionId);
var form_data = {
"SessionId": SessionId
};
$.ajax({
url: "#Url.Action("GetHistory", #ViewContext.RouteData.Values["controller"].ToString())",
method: "POST",
data: JSON.stringify(form_data),
contentType: "application/json",
success: function (result) {
console.log(result);
var output = JSON.parse(result);
for (var i = 0; i < output.length; i++) {
var p = document.createElement("span");
var q = document.createElement("li");
p.setAttribute("class", "Sender");
q.setAttribute("class", "Message");
p.textContent = output[i].Name + " - " + moment(output[i].CreatedOn).format("DD-MM-YYYY HH:mm:ss");
q.textContent = output[i].Message;
document.getElementById("MessageList").appendChild(p);
document.getElementById("MessageList").appendChild(q);
}
},
error: function (error) {
console.log(error);
}
});
return false;
});
</script>
<div class="col-sm-12">
<h2>Session</h2>
<hr />
</div>
<div class="col-sm-12">
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<div id="MessageListContainer">
<ul id="MessageList">
</ul>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="form-group">
#Html.HiddenFor(m => m.Id)
#Html.HiddenFor(m => m.CurrentUser)
<input class="form-control col-sm-12" id="Message" type="text" />
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="form-group">
<div class="clearfix">
<div class="pull-right">
<input id="Send" type="button" value="Send" class="btn btn-primary" />
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-12">
<hr />
</div>
</div>
<script src="~/aspnet/signalr/dist/browser/signalr.js"></script>
<script src="~/js/chat.js"></script>
Your AJAX call that comes back as JSON appears to have a few fields like Name and CreatedOn. You can add an additional field server side for the SessionId, which you are injecting server-side anyway into your HTML. Then you can compare to see if the message's session matches yours. If so, then it is you and not the receiver. So you might have something like:
JS
// You set this earlier on
var SessionId = document.getElementById("Id").value;
// ........ OTHER CODE IN BETWEEN
for (var i = 0; i < output.length; i++) {
var p = document.createElement("span");
var q = document.createElement("li");
// If session ID matches current session (i.e. you) then add different class
if (output[i].SessionId === SessionId) {
// It is you
p.setAttribute("class", "Sender");
} else {
// It is other person
p.setAttribute("class", "Receiver");
}
q.setAttribute("class", "Message");
p.textContent = output[i].Name + " - " + moment(output[i].CreatedOn).format("DD-MM-YYYY HH:mm:ss");
q.textContent = output[i].Message;
document.getElementById("MessageList").appendChild(p);
document.getElementById("MessageList").appendChild(q);
}
CSS
.Sender {
color: blue;
}
.Receiver {
color: green;
}

jQuery .click() event isn't firing on-click

$("#backButton-1").click(function() {
$("#form-2").empty();
$("#form-1").show();
});
I'm having an issue getting this snippet to run. form-1 is hidden, backButton-1 is created after the end of form-2 and only after form-1 has been hidden. I want backButton-1 to empty out form-2 and unhide form-1 but the .click event isn't firing.
Here's the code:
$(document).ready(function() {
var playersName = '';
var gameName = '';
var playersNameArray = [];
$("#submit-1").click(function() {
playersName = $("#input_players").val();
gameName = $("#input_game").val();
$("#form-1").hide();
gameName = gameName.toLowerCase();
gameName = gameName.charAt(0).toUpperCase() + gameName.substr(1);
function makeArray(string) {
string = string.replace(/\s/g, '');
var array = string.split(",");
for (let i = 0; i < array.length; i++) {
array[i] = array[i].toLowerCase();
array[i] = array[i].charAt(0).toUpperCase() + array[i].substr(1);
}
playersNameArray = array;
}
makeArray(playersName);
function makeScores(array) {
$("#container-1").prepend("<p>Input " + gameName + " scores:</p>");
for (let i = 0; i < array.length; i++) {
var scoreDiv = document.createElement("div");
scoreDiv.className = "score";
scoreDiv.id = "score-" + (i + 1);
var scoreInput = document.createElement("input");
$(scoreInput).attr('type', 'text');
scoreInput.id = "scoreInput-" + (i + 1);
$("#form-2").append(scoreDiv);
$("#score-" + (i + 1)).append("<div class='scoreName'>" + array[i] + "</div>");
$("#score-" + (i + 1)).append(scoreInput);
}
$("#container-1").append(
$("<div class='submitButtonDiv' />").append(
$('<input type="submit" name="submit-2" value="Submit" id="submit-2" />')
),
$("<div class='backButtonDiv' />").append(
$('<input type="button" name="backButton-1" value="Back" id="backButton-1" />')
)
);
}
makeScores(playersNameArray);
});
$("#backButton-1").click(function() {
$("#form-2").empty();
$("#form-1").show();
});
$("#submit-2").click(function() {
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container-1">
<form action="/database.php" method="POST" id="form-1">
<div class="input">
<p>Enter player names, separated by commas:</p>
<input type="text" name="input_players" id="input_players">
</div>
<div class="input">
<p>Enter game name:</p>
<input type="text" name="input_game" placeholder="e.g. Smallworld" id="input_game">
</div>
<div class="submitButtonDiv">
<input type="submit" name="submit-1" value="Submit" id="submit-1">
</div>
</form>
<form action="/database.php" method="POST" id="form-2"></form>
</div>
You are saying the button is being created, which means that jQuery cannot add an event listener on load. Either create the listener together where you create the button, or use propagation.
// Create button, add to DOM
$("<div>New div</div>").appendTo("body")
.click(function() {
// Attach click event listener
alert("Works!");
});
// Or using propagation
$("body").on("click", "#test", function() {
alert("Works too!");
});
$("<div id='test'>New div</div>").appendTo("body");
Note that the second approach works irrespective of where you attach the event listener to body, be it before or after creating the new item.
In your case, I suggest:
$("#container-1").append(
$("<div class='submitButtonDiv' />").append(
$('<input type="submit" name="submit-2" value="Submit" id="submit-2" />')
),
$("<div class='backButtonDiv' />").append(
$('<input type="button" name="backButton-1" value="Back" id="backButton-1" />')
)
).on("click", "#backButton-1", function() {
$("#form-2").empty();
$("#form-1").show();
});
Try adding your links at the bottom
and add the following link in your head
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"> </script> <!-- <<<< This ONE-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div id="container-1">
<form action="/database.php" method="POST" id="form-1">
<div class="input">
<p>Enter player names, separated by commas:</p>
<input type="text" name="input**strong text**_players" id="input_players">
</div>
<div class="input">
<p>Enter game name:</p>
<input type="text" name="input_game" placeholder="e.g. Smallworld" id="input_game">
</div>
<div class="submitButtonDiv">
<input type="submit" name="submit-1" value="Submit" id="submit-1">
</div>
</form>
<form action="/database.php" method="POST" id="form-2"></form>
</div>
<script type="text/javascript" src="main.js"></script>
</body>

Writing single JS script for assigning ID's to output in HTML

I am creating a website that has a list of user inputs, however at a certain stage I want users to see a summarized page of all their inputs. If the input was not chosen it should not show as part of the summary (as in the script example below).
Here is my problem: there will be multiple user inputs and to write a JS script to achieve what I had done in an example script below will be lots of work and unfeasible. Is there a way the two JS scripts for the individual ID's can be combined into one as in the script below?
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div>
<label>For the first test</label>
<input type="text" placeholder="Enter Number" name="clientinfo" id="test1" required>
</div>
<div>
<label>For the second test</label>
<input type="text" placeholder="Enter Number" name="clientinfo" id="test2" required>
</div>
<button id="myBtn">Test</button>
<div style="color:blue;">
<p id="result1"></p>
</div>
<div style="color:red">
<p id="result2"></p>
</div>
<script>
function getUserName() {
var test1 = document.getElementById('test1').value;
var result1 = document.getElementById('result1');
if (test1.length > 0) {
result1.textContent = 'Test1: ' + test1;
} else {
null;
}
}
var myBtn = document.getElementById('myBtn');
myBtn.addEventListener('click', getUserName, false);
</script>
<script>
function getUserName() {
var test2 = document.getElementById('test2').value;
var result2 = document.getElementById('result2');
if (test2.length > 0) {
result2.textContent = 'Test2: ' + test2;
} else {
null;
}
}
var myBtn = document.getElementById('myBtn');
myBtn.addEventListener('click', getUserName, false);
</script>
</body>
</html>
P.s. I would also like to know if a user were to press the test button with an input, remove the input and press the test button again, that the first input would be removed?
You can get all inputs and loop throw the result and create an dom element which will contain the value of the input
and each created element will be added to lets say a result element
See code snippet
function getUserName() {
var inputList = document.getElementsByTagName("INPUT");
var res = document.getElementById("result");
res.innerHTML = "";
var indx = 1;
for (i = 0; i < inputList.length; i++) {
if (inputList[i].value != "") {
var ele = document.createElement("p");
ele.innerHTML ="test " + indx + " : " + inputList[i].value
res.appendChild(ele);
indx++;
}
}
}
var myBtn = document.getElementById('myBtn');
myBtn.addEventListener('click', getUserName, false);
<div>
<label>For the first test</label>
<input type="text" placeholder="Enter Number" name="clientinfo" id="test1" required>
</div>
<div>
<label>For the second test</label>
<input type="text" placeholder="Enter Number" name="clientinfo" id="test2" required>
</div>
<button id="myBtn">Test</button>
<div id="result">
</div>

Replicate user's input as typing effect in Javascript

I am trying to capture a sentence from a user's input and replicate it as a typing effect. I am using JavaScript to perform the task.
I am able to capture the input and display it with console.log(), but when I add the typing effect function, it doesn't seem to work.
My code are as follow. What's going wrong?
var getInput = document.getElementById("input");
getInput.onkeyup = function(e) {
if (e.keyCode == 13) {
var i = 0;
var text = input.value;
function typing() {
if (i < text.length) {
document.getElementById('output').innerHTML += text.charAt(i);
i++;
setTimeout(typeWriter, 200);
}
}
e.currentTarget.value = "";
}
}
<link href="https://fonts.googleapis.com/css?family=Francois+One" rel="stylesheet">
<div class="background"></div>
<div class="input"></div>
<div class="typing">
<div class="input-group">
<div class="form-group">
<label for="text">Please Type Here:</label>
<input type="text" class="form-control" id="input">
</div>
</div>
</div>
<div class="output" id="output">
</div>
You have defined the typing function, but haven't called it.
Plus, in the setTimeout, you've called typeWriter function which is undefined. You wanted calling typing instead:
var getInput = document.getElementById("input");
getInput.onkeyup = function(e) {
if (e.keyCode == 13) {
var i = 0;
var text = input.value;
function typing() {
if (i < text.length) {
document.getElementById('output').innerHTML += text.charAt(i);
i++;
setTimeout(typing, 200);
}
}
typing();
e.currentTarget.value = "";
}
}
<div class="background"></div>
<div class="input"></div>
<div class="typing">
<div class="input-group">
<div class="form-group">
<label for="text">Please Type Here:</label>
<input type="text" class="form-control" id="input">
</div>
</div>
</div>
<div class="output" id="output">
</div>
You can use the keyup event in Javascript and listen to that event and update your DOM element on each keyboard stroke.
window.onload = function() {
let myInputElement = document.querySelector(`#myInput`);
if (myInputElement) {
myInputElement.addEventListener('keyup', function(event) {
let myTextElement = document.querySelector(`#myText`);
myTextElement.innerText = myInputElement.value;
});
}
}
<html>
<head>
</head>
<body>
<input id="myInput" />
<br>
<hr>
<p id="myText"></p>
</body>

This else runs even if the if was true

What this program its supposed to do is first with a range input you put how many elements you want to guess then it will show a random element form a json list and you have to guess the valnce and then it will load annother one and you continue. OK when i run this code everything is normal until you click submit button two times. When i click the submit botton the first time its goes well but the second time the program runs the if in the line 41 but it also runs the code in the else and if you submit more times it will run the alerts more and more times.
I have tried doing it other ways like just putting all into a for but it still runing code i dont want to.
const $ = require('jquery');
let elementoActual;
let valorPositivoCorrecto;
let valorNegativoCorrecto;
let valorCuadroNegativo;
let valorCuadroPositivo;
// Button on click add the element
$(document).ready(function() {
$("#startButton").click(function() {
$(".hide").hide();
let questionHTML = '<div class="elementoQuimico"><img id="imgElemnt" src="" alt=""></div>' +
'<div class="valenciasElemento">' +
'<input type="text" class="valorPositivo" placeholder="Valencias positivas">' +
'<input type="text" class="valorNegativo" placeholder="Valencias negativas">' +
'</div>' +
'<button class="submitButtonElement">SUBMIT</button>';
$(".questions").append(questionHTML);
putAnElement();
}); //onclick ends
}) //ready ends
function putAnElement() {
let numb = $("#textInput").val();
let counter = 0;
$.getJSON("../../json/valencias.json", function(data) {
let numeroDeElemento = Math.floor(Math.random() * 3);
elementoActual = data[numeroDeElemento];
valorNegativoCorrecto = data[numeroDeElemento].valenciasNegativas;
valorPositivoCorrecto = data[numeroDeElemento].valenciasPositivas;
//$("#imgElemnt").attr( "src" , elementoActual.img);
$("#imgElemnt").attr("alt", elementoActual.name);
$("#imgElemnt").attr("width", "200px");
$("#imgElemnt").attr("height", "200px");
alert(numb);
$(".submitButtonElement").click(function() {
valorCuadroNegativo = $(".valorNegativo").val();
valorCuadroPositivo = $(".valorPositivo").val();
$(".valorNegativo").val("");
$(".valorPositivo").val("");
if (valorCuadroNegativo === valorNegativoCorrecto &&
valorCuadroPositivo === valorPositivoCorrecto) {
alert("correcto");
counter++;
alert(counter);
if (counter != numb){
putAnElement();
} else {
alert("ya");
}
} else {
alert("incorrecto");
counter++;
alert(counter);
if (counter != numb) {
putAnElement();
} else {
alert("ya");
}
}
});
}); //getJSON ends
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tabla periodica</title>
<link rel="stylesheet" href="../../css/periodic-table.css">
</head>
<body>
<div class="wrapper">
<div class="hide">
<h1>TABLA PERIODICA</h1>
<img src="../../img/tabla-valencias.png">
<div class="buttons">
<button id="startButton">EMPEZAR</button>
<form id="submit-tabla">
<label for="rangeInput"></label><input type="range" name="amountRange" id="rangeInput" min="10" max="30" value="20" oninput="this.form.amountInput.value=this.value" />
<label for="textInput"></label><input type="number" name="amountInput" id="textInput" min="10" max="30" value="20" oninput="this.form.amountRange.value=this.value" />
</form>
</div>
</div>
<div class="questions">
</div>
</div>
<footer>
2017 &COPY; Nestor and Diego
</footer>
<script src="chemistry.js"></script>
</body>
</html>
And here is the json
[
{
"name":"hidrogeno",
"valenciasNegativas":"-1",
"valenciasPositivas":"1",
"img":"img/Hidrogeno.svg"
},
{
"name":"litio",
"valenciasNegativas":"",
"valenciasPositivas":"1",
"img":"img/Litio.svg"
},
{
"name":"sodio",
"valenciasNegativas":"",
"valenciasPositivas":"1",
"img":"img/Sodio.svg"
}
]

Categories