Update Page With Values Before Continuing Loop - javascript

I've created some code that will round entered numbers either up or down, depending on if the whole number is even or odd. I've got that out of the way, however now I would like to place my code into a loop that will continuously prompt a user to enter another number until they enter a value like "x".
What I would like to happen is for the page to update with the calculated values before prompting the user again. I have not been able to figure how to do this yet, hence my question here.
Is there even a way to do this or am I going about it all wrong?
Javascript:
function main() {
var n = prompt("Enter A Number\nCan Be A Whole Number Or Decimal Number With One Decimal Place.\nOr Enter x To Exit.");
while (n != "x") {
var nn = 0
if (n.includes(".")) {
var n = parseFloat(n);
q = Math.trunc(n);
if (q % 5 == 0) {
if ((n % 1) >= 0.5) {
nn = (Math.ceil(n));
} else if ((n % 1) < 0.5) {
nn = (Math.floor(n));
}
} else {
if ((n % 1) <= 0.5) {
nn = (Math.floor(n));
} else if ((n % 1) > 0.5) {
nn = (Math.ceil(n));
}
}
document.getElementById("orgNum").innerHTML = "Original Number: " + n;
document.getElementById("roundNum").innerHTML = "Rounded Number: " + nn
setTimeout(main, 5000);
} else {
document.getElementById("orgNum").innerHTML = "Original Number: " + n;
document.getElementById("roundNum").innerHTML = "Rounded Number: Whole Number Was Entered."
setTimeout(main, 5000);
}
setTimeout(main, 5000);
var n = prompt("Enter Another Number\nCan Be A Whole Number Or Decimal Number With One Decimal Place.\nOr Enter x To Exit.")
}
}
HTML:
<div id="wrapper">
<div id="dataEntry">
<input type="button" id="subButton" value="Begin" onClick="main()">
</div>
<div id="dataPrint">
<p id="orgNum">Original Number: </p>
<p id="roundNum">Rounded Number: </p>
</div>
</div>
What am I missing here?
Any help would be greatly appreciated.

Javascript in the browser runs in a single thread along with the ui. Taking over that thread with a loop, as your code attempts to do, would block the ui from functioning, including allowing the user to enter text in the input.
Instead of your while loop, you need to use event listeners.
You could attach an onkeyup event listener to your input, which looks for the enter key (keycode 13), or put your input into a form and attach an onsubmit event listener to the form.
This event listener will look for an 'x' character in the input field: if it finds it, you're done (you could hide the input and/or put a message on the page indicating that no more input is required).
If you don't find the x, do your rounding and clear the input value. After you do the rounding/clear, the user will be able to enter another value, press enter, which triggers the event listener again, and so on until the 'x' is detected.
This link should help:
Element: keyup event

Related

How to use jquery to prevent a editable div reach over our restricting length

Let's said I have the following code:
<div id="editing" contenteditable onclick="document.execCommand('selectAll',false,null)">Put text here...</div>
In this case, I want to restrict my user, for example, can only put 200 characters in it (including space), how can I restrict it? I know I might achieve it with jquery but most example on webs checks it when they click a button, and as I redesign my code with this StackOverflow question as base, it checks it when the div is clicked but with that in mind you can't alert user when the types over 200 words.
So how can I continuously checking words user type in a contenteditable div and alert them when they reach the limit?
The input event is supported with contenteditable, then just stop the event if there is too much text like so:
var el = document.getElementById('editing');
var max = 20;
el.addEventListener('input', function(e) {
if (el.innerHTML.length > max) {
el.innerHTML = el.innerHTML.substr(0, max); // just in case
alert('Not allowed more than ' + max + ' characters');
}
});
<div id="editing" contenteditable onclick="document.execCommand('selectAll',false,null)">Put text here...</div>
However, just stay away from contenteditable events. they are bad
Here is simple pure js solution: if anything is there please comment i will update my answer.. :D
function check()
{
// get the HTML value.
var content = document.getElementById('editing').innerHTML;
//Edit : replace spaces from content (ideally you have to figure out how to remove the posible html tags that user might enter)
content = content.replace(/ /g," ");
console.log(content);
// validate value againts limit say 10 or any constant value.
if(content.length > 20)
{
// alert user.
alert('limit reached');
// flush extra characters from end.
document.getElementById('editing').innerHTML = content.slice(0,content.length-1);
return;
}
}
//Edit : if you want remove placeholder from annoying user you can flush it when user gets the focus on it say
function checkPlaceholder()
{
document.getElementById('editing').innerHTML = "";
}
<div id="editing" contenteditable onInput="check();" onfocus="checkPlaceholder();">Put text here...</div>
<div id="editing" contenteditable onkeypress = "if($(this).text().length >= 200) {return false; }"onclick="alert(document.execCommand('selectAll',false,null)">Put text here...</div>
You return false onkeypress when the character count is greater than or equal to 200
// Detect when you add a character to the div.
$('div#editing').on('keydown',function(e) {
// Check if you already have 200 characters (but allow 'backspace' and 'del' keys).
if (e.keyCode != 8 && e.keyCode != 46 && $(this).text().length >= 200) {
alert('The field is limited to 200 characters');
return false; // This will make the new character to be ignored.
}
});

How to add values from two buttons to single inputbox?

Assume that I have two buttons with the values 'abc' and 'efg' respectively, and an inputbox.
This is what I want to achieve :
When I click the button with the value 'abc' a single time, the value 'a' gets appended to the inputbox. If I press it two times immediately the value suddenly changes to 'b' instead of 'a', and when I do it three times it changes to 'c' instead of 'b'.
I should be able to type double 'a''s (or any of 'a', 'b', 'c') by waiting some time between button clicks on button 'abc'. For instance : I first click button 'abc', then 'a' gets into the inputbox, I wait for a short time and clicks one more time to get another 'a'.
I want the same functionality with all the buttons ('abc' and 'efg').
I have linked sample expected output image.
View this jsfiddle Code
<div ng-controller="MyCtrl">
<input type="text" ng-model="btnTxt[btnarr]">
<button ng-modle="btnarr" ng-Click="change()">abc</button>
</div>
Expected output:
Can anyone help me with this ?
I have tried one without using built-in timer functions, and checking it manually.
Solution at Pastebin : pastebin.com/vHF517FN
See if it's good enough for you. Btw, I didn't really refactor much, will do it if you are satisfied with this (I'm also new to js -_-).
EDIT
Refactored anyway.
Refactored Solution at Pastebin : pastebin.com/EnHz2EHK
EDIT 2
Added it to JSFiddle. However, I had to add everything to HTML part to make it work there, moving script to script part isn't working for me (wonder why).
Solution at JSFiddle
<script>
var prevClick = '!';
var prevClickTime;
var clicks = 0;
function buttonClick(letters) {
var input = document.getElementById("put");
var backLetterIndex = (clicks == 0) ? letters.length-1 : clicks - 1;
if(letters[backLetterIndex] == prevClick) {
var now = (new Date()).getTime();
if(now - prevClickTime < 500) {
var val = input.value;
input.value = val.slice(0, val.length - 1);
}
else
clicks = 0;
}
else
clicks = 0;
prevClickTime = (new Date()).getTime();
prevClick = letters[clicks];
clicks = (clicks + 1) % letters.length;
input.value = input.value + prevClick;
}
</script>
<input id="put" type="text"></input>
<button onClick="buttonClick('abc');">abc</button>
<button onClick="buttonClick('defg');">defg</button>
I get it, you want to do phone keyboard.
I am not sure what exactly is your question so here I wrote complete example
http://jsfiddle.net/daybda4h/5/
Bacically, I wrote click event listener with timer if click comes within 200ms after another click I count up.
clicks++;
if(timer) {
clearTimeout(timer);
}
timer = setTimeout(function () {
timer = null;
updateInput(clicks, evt.target);
clicks = 0;
}, timeout);
Then, when no more clicks are comming, I take the final number of clicks, take data attribute of a button that says what letters does it control, and take the letter number according to num of clicks.
to add value to input, you simply take input value and add the same value + some custom string.
function updateInput(cl, btn) {
var input = document.getElementById("test");
var letters = btn.getAttribute("data-letters").split("");
input.value = input.value + letters[cl-1];
}
Hope this resolves your problem :)

Getting Text out of HTML into Javascript as a Function with Input Changing IDs

I am trying to create an if/else statement that checks the text of a button that the user presses. If there is no text in that button, it continues the function, if there is pre-existing text then it gives an alert stating that there is already an entry there.
Essentially, the user clicks a button and the code checks to see if that button is empty or not. However, since the button's ID is constantly changing, I don't know how to tell the code to check the pressed button. I feel that using 'this' is part of the solution to this problem, but I am too new to JavaScript to use it correctly.
This is my entire JavaScript code, off it works fine except for the two lines that have comments in them. I am trying to make the variable "inSquare" to equal the text from the button that triggered the function. Then it goes on to check the text of the variable, but currently all it does is fail the if and head straight to the else.
var turnNumber = 9;
var whoseTurn;
var inSquare;
function currentTurn(id) {
inSquare = this.innerHTML; /*This Line*/
if (inSquare === "") { /*This Line*/
if (whoseTurn === 0) {
id.innerHTML = "X";
turnNumber -= 1;
whoseTurn = turnNumber % 2;
} else {
id.innerHTML = "O";
turnNumber -= 1;
whoseTurn = turnNumber % 2;
}
} else {
window.alert("Something is already in that square!");
}
}
Also, here is an example of what the HTML buttons look like. (There are nine total, but they are all formatted the same).
<button id="topLeft" onclick="currentTurn(this)"></button>
<button id="topMid" onclick="currentTurn(this)"></button>
<button id="topRight" onclick="currentTurn(this)"></button>
inSquare = this.innerHTML; should be inSquare = id.innerHTML;
this in your function refers to the window object, but you want to refer to the element you passed, which you provided as the id argument of the function.

disable textarea by height not characters

So many times we want to limit how much a user can write, but here I have a special sized box that it has to fit in, so I want to disable adding more characters if it would surpass a specific height. here is what I did:
var over;
$('textarea').keypress(function(e){
var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
var t = $(this).val();
jQuery('<div/>', {
style: "visibility:hidden",
text: t,
id: "test"
}).appendTo('body');
var h = $('#test').height();
if(h >= 100){
over = true;
}
else{
over = false;
}
if(over){
//code goes here
}
$('#test').remove();
});
I got the limiting code (what goes where I have the "code goes here" comment) from here and it ALMOST works.
There is only one problem:
if somebody copies and pastes, it can place multiple characters and therefore still go over the limit.
How can I fix this issue?
jsfiddle
Another somewhat hacky solution could be to check scroll on key up. If scroll exists, delete the last character while scroll exists:
function restrictScroll(e){
if(e.target.clientHeight<e.target.scrollHeight){
while(e.target.clientHeight<e.target.scrollHeight){
e.target.value = e.target.value.substring(0, e.target.value.length-1);
}
}
};
document.getElementById("textareaid").addEventListener('keyup', restrictScroll);
This would work as you type and if you paste blocks of text. Large text blocks may take a little longer to loop through though. In which case you may want to split on "\n" and remove lines first, then characters.
jsfiddle
If you want your function to fire whenever the text in your field changes, you can bind it to the input and propertychange events, as per this answer:
https://stackoverflow.com/a/5494697/20578
Like this:
$('#descrip').on('input propertychange', function(e){
This will make sure your code fires when e.g. the user pastes in content using the mouse.
As for stopping them from entering content that would go over the limit, I think you have to keep track of what content they've entered yourself, and then revert their last edit if it infringed your criteria.
Note that e.g. Twitter doesn't stop the user from entering more characters if they've gone over the limit - they just tell the user they're over the limit, and tell them when they're back under. That might be the most usable design.
You may try this:
$('#descrip').bind('paste',function(e) {
var el = $(this);
setTimeout(function() {
//Get text after pasting
var text = $(el).val();
//wath yu want to do
}, 100);
};
Jsfiddle
The solution is taken from here and here. It works by binding to the paste event. Since paste event is fired before the text is pasted, you need to use a setTimeout to catch the text after pasting. There is still some rough edges (i.e. if you select text and press backspace, it does not update).
Still, Spudley comment has some valid points, that you may want to consider.
Edit:
Note on the jsfiddle: It allow you to go over the limit when pasting, but once over the limits, you cannot paste (or type) more text until you go under the limit again.
Must be taken into account that, since you are limiting the text length by the size it ocuppies after rendering (wich have it own issues as pointed by Spudley), and not a defined lenth, you can know if a text fits or not, but not know how much of the text is inside the limits, and how much is out of them.
You may consider reseting textbox value to its previous value if pasted text makes imput go over the limit, like in this one.
However, for cutting down the text after pasting so as non-fitting text is left out, but the rest of the pasted text is allowed, you need an entirely different approach. You may try iterating over the text until you find how much of the new text is enough.
By the way, line feeds and seems to cause your original script to behave weirdly.
I've been able to get the program working:
var over = false;
var num = 0;
var valid_entry = "";
$('#descrip').keyup(function(e){
var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
var t = $(this).val();
getMaxRow(t,key,this);
});
function getMaxRow(t,key,obj) {
jQuery('<div/>', {
"class": "hide",
text: t,
id: "test"
}).appendTo('body');
var h = $('#test').height();
$('#test').remove();
if(h >= 100){
num += 1;
if(num == 1){
var div = '<div id="message">You have run out of room</div>'
$('body').append(div);
}
over = true;
}
else{
over = false;
valid_entry = t;
if(num >= 1){
$('#message').remove();
num = 0;
}
}
if( over ) {
//Do this for copy and paste event:
while ( over ) {
//Try using a substring here
t = t.substr(0,(t.length-1));
over = getMaxRow(t,key,obj);
}
}
$(obj).val(valid_entry);
return over;
}

jQuery submit form IF

Hey guys,
I have this great scripts someone on stack overflow helped me out with, except the one major function I need is missing.
This is a game where the user picks a number (by entering that number in a text field) then hits a play button. After they hit the play button a series of numbers will appear, they then have to click on the number that matches their number.
The query script I'm using counts how many times they hit the number and how many times they missed the number. Take a look at the script in action here. link text
now what I need it to do, is send the score (hits and misses ) to a database after 3 misses, so I can keep high score. Any ideas? Here's the script.
var hitCount = 0,
missCount = 0;
function IsNumeric(n) {
return !isNaN(n);
}
$("#getit").click(function() {
var li = [],
intervals = 0,
n = parseInt($('#MyNumber').val());
if (IsNumeric(n)) {
setInterval(function() {
li[intervals++ % li.length].text(Math.random() > .1 ? Math.floor(Math.random() * (10 + n) + (n / 2)) : n).attr('class', '');
}, <?php echo $time ?>);
}
$('#randomnumber').empty();
for (var i = 0; i < 5; i++) {
li.push($('<li />').click(function() {
var $this = $(this);
if (!$this.hasClass('clicked')) {
if (parseInt($this.text(), 10) === n) {
$this.addClass('correct');
$('#hitcount').text(++hitCount);
} else {
$this.addClass('wrong');
$('#misscount').text(++missCount);
}
}
$this.addClass('clicked');
}).appendTo('#randomnumber'));
}
return false;
});
I've updated your problem here.
After updating the status Check for the missCount if it is greater than or equal to 3 then stop the play(clear the interval and unbind the event), then save the value using an ajax request.
I've changed the event handling to use event delegation instead of direct click event on the <li> elements. Event delegation is better in cases where there are lot of elements to which we have to bind a particular event.
I updated your fiddle with the solution. Check http://jsfiddle.net/DHPQT/2/.
I marked all the new stuff with a comment in the form of
//new ....
The main thing to do is checking after
$('#misscount').text(++missCount);
if missCount is 3 and if yes stop the game and send something

Categories

Resources