Get the value from a clicked button - javascript

I am creating a keyboard on my screen. Right now I am getting back the value of each letter when clicked through the function getLetter, but I need to grab that value and use it instead of prompt()[0]. So I want my input to be the actual letter ("A" or "B" or...). The problem is that I am not being able to put that value in the input variable. How do I do this?
abc = ['A','B','C','D','E','F','G','H','I','J','K','L','M',
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
$('#letters').text('');
for (i = 0; i < 26; i++) {
var div = $('<div>').css( 'cursor', 'pointer' );
div.html(abc[i]);
div.on('click', getLetter);
var newDiv = $('#letters').append(div);
}
$('body').append(newDiv);
function getLetter() {
$(this).text();
this.innerHTML = ' ';
this.style.cursor = 'default';
this.onclick = null;
}
while(!game.isOver()) {
var input = prompt()[0];
game.guess(input);
$('p').text(game.render());
}

You can move the contents of the while loop into the getLetter() function, and remove the while loop because it is useless now: you don't want to do anything until the user clicks a button.
function getLetter() {
var input=$(this).text();
this.innerHTML = ' ';
this.style.cursor = 'default';
this.onclick = null;
game.guess(input);
$('p').text(game.render());
}

Related

Javascript to change innerHTML function not working

I'm building an interface that consists of 9 cells in table. When a person mouses over a cell, I want other cells to become visible, and change the text content of some of the cells. I can do that just fine if I create individual functions to change the content of each cell, but that's crazy.
I want a single function to change the text depending on the cells involved. I created a function that can take n arguments, and loops through making changes based on the arguments passed in to the function. It doesn't work.
Code for the function is below. If I call it, onMouseOver="changebox('div3')", the argument makes it to the function when I mouse over the cell. If I uncomment the document.write(cell) statement, in this instance, it prints div3 to the screen. So... why isn't it making any changes to the content of the div3 cell?
function changebox() {
for (var i = 0; i < arguments.length; i++) {
var cell = document.getElementById(arguments[i]).id;
var text = "";
if (cell == 'div3') {
text = "Reduced Travel";
} else if (cell == 'div4') {
text = "Reduced Cost";
}
//document.write(cell)
cell.innerHTML = text;
}
}
In your code cell is a string which holds the id of the object. Update the code as follows
function changebox() {
for (var i = 0; i < arguments.length; i++) {
var cell = document.getElementById(arguments[i]),
text = "";
if (cell.id == 'div3') {
text = "Reduced Travel";
} else if (cell.id == 'div4') {
text = "Reduced Cost";
}
//document.write(cell)
cell.innerHTML = text;
}
}
UPDATE :
You can reduce the code as #Tushar suggested.
No need of iterating over arguments(assuming there are only two elements, but can be modified for more elements).
function changebox() {
// As arguments is not real array, need to use call
// Check if div is present in the arguments array
var div3Index = [].indexOf.call(arguments, 'div3') > -1,
div4Index = [].indexOf.call(arguments, 'div4') > -1;
// If present then update the innerHTML of it accordingly
if (div3Index) {
document.getElementById('div3').innerHTML = 'Reduced Travel';
} else if (div4Index) {
document.getElementById('div4').innerHTML = 'Reduced Cost';
}
}
function changebox() {
var args = [].slice.call(arguments);
args.map(document.getElementById.bind(document)).forEach(setElement);
}
function setElement(ele) {
if (ele.id === 'div3') {
ele.innerHTML = "Reduced Travel";
} else if (ele.id === 'div4') {
ele.innerHTML = "Reduced Cost";
}
}
this make your function easy to be tested
As your assigning the cell variable the id of the element and changing the innerHTML of cell which is not valid .
var changeText = function() {
console.log("in change text");
for(var i= 0; i<arguments.length; i++) {
var elem = document.getElementById(arguments[i]);
var cell = document.getElementById(arguments[i]).id;
var text = "";
console.log(cell)
if (cell === "div-1") {
text = cell+" was selected!!";
} else if(cell === "div-3") {
text = cell+" was selected!!";
} else {
text = cell+" was selected";
}
elem.innerHTML = text;
}
}
This would properly change the text of div mouseovered!!

How to remember a position in a texarea?

I just want to remember always the last position in a textarea, but I fail always.
I've got this code:
//This function catch the position
(function ($, undefined) {
$.fn.getCursorPosition = function() {
var el = $(this).get(0);
var pos = 0;
if('selectionStart' in el) {
pos = el.selectionStart;
} else if('selection' in document) {
el.focus();
var Sel = document.selection.createRange();
var SelLength = document.selection.createRange().text.length;
Sel.moveStart('character', -el.value.length);
pos = Sel.text.length - SelLength;
}
return pos;
}
})(jQuery);
//Insert the text by clicking an icon
function insertar(texto) {
var div = $('textarea');
var text = div.val();
var pos = div.getCursorPosition();
text = text.substring(0,pos) + " " + texto + text.substring(pos);
div.val(text);
}
$('#icon').click(function(evt){ insertar(':icon:'); });
Well, if I write this:
"hello hello"
And I want to add this with the function:
"hi hi hello hello"
It give me this:
"hi hello hello hi."
I think the second time I execute the function, this forget the position and add the text at the end of the text.
PD: I'm adding text clicking on an image. I'm trying to do a quick reply fieldset for a forum.
Anyone knows where the problem is?
Here is my demo where you can see it: http://jsfiddle.net/ko295zpw/6/
One option would be to set a bool that determines whether or not you need to re-find the cursor position, then reset the bool to true every time the textarea is clicked and set it to false after you've found the position the first time after the user has clicked on the textarea. You'd need to move the declarations of both var pos and the bool to a scope outside the insertar function. So:
var encontrarPos = true;
var pos = 0;
function insertar(texto) {
var div = $('textarea');
var text = div.val();
if (encontrarPos) pos = div.getCursorPosition();
encontrarPos = false;
console.log(pos);
text = text.substring(0,pos) + texto + " " + text.substring(pos);
div.val(text);
}
$('textarea').click(function() {
encontrarPos = true;
});
And here's the updated Fiddle

Determine radio button not selected anymore

I wrote a javascript function that change the style of a div (here a TR tag) when I select a radio button in form (called by onchange event).
function handleCheck(myRadio) {
var vak = 'vak' + myRadio.name + 'x' + myRadio.value;
var col = document.getElementById(vak);
col.style.backgroundColor = "black";
col.style.color = "white";
}
However, often when you select option X another option is deselected while you can select only one value at the time in the same. This option is not triggered by the onchange event. Is there a way to determine that a radio button is not checked any more?
You will have to clear previously assigned classes. Take a look at this example:
function handleCheck(myRadio) {
clear(myRadio.className);
var vak = 'vak' + myRadio.name + 'x' + myRadio.value;
var col = document.getElementById(vak);
col.className += ' selected';
}
function clear(className) {
var tr = document.querySelectorAll('tr.vak' + className);
for (var i = 0; i < tr.length; i++) {
tr[i].className = 'vak' + className;
}
}
Demo: http://jsfiddle.net/abh7guv5/
If I understood correctly what you are trying to achieve, simply read document.getElementById("myRadio").checked - it will be true or false
well, if I understand you correctly, you have a function that applies some styles whenever you check a radio button, but you also would like to remove styles from elements, that corresponds to already unchecked buttons. If yes, you can store your previous checked item in a variable, then you might want something like:
var previousElement = null;
function handleCheck(myRadio) {
var vak = 'vak' + myRadio.name + 'x' + myRadio.value;
var col = document.getElementById(vak);
col.style.backgroundColor = "black";
col.style.color = "white";
if(previousElement!==null&&previousElement!==col){
previousElement.style.color = ""; // or whatever you want
}
previousElement = col;
}

Add clicked words to string 2

I have the following solution that adds clicked words to a <input> field string.
However, I would like to change the javascript to allow me to:
Keep text that I manually add to the <input> field. At the moment it is overwritten.
Exclude full stops from text transferred from <p> to <input>
HTML
<p id="target_para">
Here's an example of the thing you wanted to be made clickable.
</p>
<input type="text" id="display" />
JS
(function () {
"use strict";
var para, targets, display, words, clickHandler, updateList, i, j, cur;
display = document.getElementById("display");
para = document.getElementById("target_para");
// Wrap every word in a span element
para.innerHTML = '<span>' + para.innerText.replace(/ /g,'</span><span> ') + '</span>';
// Updated target
targets = para.getElementsByTagName("span");
words = [];
// Handler for clicking a clickable element
clickHandler = function () {
var text = this.innerText || this.textContent,
idx = words.indexOf(text);
if (words.indexOf(text) < 0) {
// If not already in list, add it
words.push(text);
} else {
// Otherwise remove it
words.splice(idx, 1);
}
updateList();
};
// Update display of word list
updateList = function () {
while (display.firstChild) {
display.removeChild(display.firstChild);
}
// Set the input box value
display.value = words.join(",");
};
// Bind event handlers to clickable elements
for (i = 0, j = targets.length; i < j; i++) {
cur = targets[i];
cur.addEventListener("click", clickHandler, false);
}
}());
I would do it this way
(function() {
"use strict";
var input = document.getElementById('display');
var paragraph = document.getElementById('target_para');
paragraph.innerHTML = paragraph.innerHTML.replace(/([^\ ]+)/g, "<span>$1</span>");
paragraph.addEventListener('click', function(e) {
if ('span' !== e.target.nodeName.toLowerCase()) {
return false;
}
input.value += ' ' + e.target.innerHTML;
}, false);
})();
Here's a fiddle: http://jsfiddle.net/HAxCw/
As a word separator for the input I used a space but you can change it to whatever you want. It's this line of code
input.value += ' ' + e.target.innerHTML;

Register a click except on a certain element

I have a javasccript function that shows or hides "spans" when I click an input to show hints when a user fills out forms:
function prepareInputsForHints() {
var inputs = document.getElementsByTagName("input");
for (var i=0; i<inputs.length; i++){
// test to see if the hint span exists first
if (inputs[i].parentNode.getElementsByTagName("span")[0]) {
// the span exists! on focus, show the hint
inputs[i].onfocus = function () {
this.parentNode.getElementsByTagName("span")[0].style.display = "inline";
}
// when the cursor moves away from the field, hide the hint
inputs[i].onblur = function () {
this.parentNode.getElementsByTagName("span")[0].style.display = "none";
}
}
}
}
My problem is that when I try to add a link to the hints text, the user cannot click it because it registers first with the onblur event and the hint dissapears, so I would like to know how to modify this function so that it does not hide when I click the hint.
You can use a boolean var to test if the user is with mouse over your hint, then if onblur and not mouseOver you hide your hint.
Something like this inside your loop:
var inputs = document.getElementsByTagName("input");
for (var i=0; i<inputs.length; i++){
(function(i) {
// Let the code cleaner :)
var span = inputs[i].nextElementSibling;
span.onmouseover = function() { this.isOver = true; }
span.onmouseout = function() { this.isOver = false; if(!inputs[i].isFocus) inputs[i].onblur(); }
// the span exists! on focus, show the hint
inputs[i].onfocus = function () {
this.isFocus = true;
span.style.display = "inline";
}
// when the cursor moves away from the field, hide the hint
inputs[i].onblur = function () {
this.isFocus = false;
if(!span.isOver) span.style.display = "none";
}
})(i);
}
I put a self executing function just to keep the var i scope, you don't have troubles onmouseout function.
EDIT: Updated the example
Your code for get the next span will not work, so I changed to nextElementSibling, because the example you put in the jsfiddler.
This is the new working code:
$(function(prepareInputsForHints) {
var inputs = document.getElementsByTagName("input");
for (var i=0; i<inputs.length; i++){
(function(i) {
// Let the code cleane
var span = inputs[i].nextElementSibling;
if(span instanceof HTMLSpanElement) {
if(span.className == "hint") {
span.onmouseover = function() { this.isOver = true; }
span.onmouseout = function() { this.isOver = false; if(!inputs[i].isFocus) inputs[i].onblur(); }
// the span exists! on focus, show the hint
inputs[i].onfocus = function () {
this.isFocus = true;
span.style.display = "inline";
}
// when the cursor moves away from the field, hide the hint
inputs[i].onblur = function () {
this.isFocus = false;
if(!span.isOver) span.style.display = "none";
}
}
}
})(i);
}
});

Categories