How to design a drop-down in button using css? - javascript

//id define
var id = function (name) {
return{
element : document.getElementById(name),
html : function (data) {
var ids = this.element;
if (data != undefined) {ids.innerHTML=data;}
else{return ids.innerHTML;}},
val : function (data) {
var ids = this.element;
if (data != undefined) {ids.value=data;}
else{return ids.value;}},
hide : function () {this.element.style.display="none";},
show : function () {this.element.style.display="block";},
clsremove : function (data) {this.element.classList.remove(data);},
clsadd : function (data) {this.element.classList.add(data);},
tex : function (data) { var latex = data.replace(/\^/g, "");
var latex_form = latex.replace(/([a-z])(\d+)/g,
function myFunction(tot,c1,c2) {var tag=(c1 =='^'?'sup':'sup');return c1+'<'+tag+'>'+c2+'</'+tag+'>';});
this.element.innerHTML= latex_form;
}
}
}
//class define
var cls = function (name) {
return{
element : document.getElementsByClassName(name),
html : function (data) {
var ids = this.element;
for (var i=0; i<ids.length; i++) {
if (data != undefined) {ids[i].innerHTML=data;}
else{return ids[i].innerHTML;}}},
val : function (data) {
var ids = this.element;
for (var i=0; i<ids.length; i++) {
if (data != undefined) {ids[i].value=data;}
else{return ids[i].value;}}},
hide : function () { var ids = this.element;for (var i=0; i<ids.length; i++) {ids[i].style.display="none";}},
show : function () {var ids = this.element;for (var i=0; i<ids.length; i++) {ids[i].style.display="block";}},
tex : function (data) { var latex = data.replace(/\^/g, "");
var latex_form = latex.replace(/([a-z])(\d+)/g,
function myFunction(tot,c1,c2) {var tag=(c1 =='^'?'sup':'sup');return c1+'<'+tag+'>'+c2+'</'+tag+'>';});
this.element.innerHTML= latex_form;
}
}
}
<!DOCTYPE html>
<html>
<head>
<script src="jfile/myquery.js"></script>
<script src="steps.js"></script>
</head>
<body>
<input id="myInput" type="text" value="20x+5k-10p-y=0">
<button onclick="checkFruit()">Check Fruit</button>
<p id="equ1"></p>
<p id="equ2"></p>
<p id="equ3"></p>
<p id="equ4"></p>
<p id="equ5"></p>
<p id="equ1p"></p>
<p id="equ2p"></p>
<p id="equ3p"></p>
<p id="equ4p"></p>
<p id="equ5p"></p>
<p id="xoneans1"></p>
<p id="xoneans2"></p>
<p id="xoneans3"></p>
<p id="xoneans4"></p>
<p id="xoneans5"></p>
<p id="xoneans6"></p>
<p id="xoneans7"></p>
<p id="xoneans8"></p>
<p id="xoneans9"></p>
<p id="xoneans10"></p>
<script>
function checkFruit() {
var reg =/([\-+])?\s*(\d+)?([a-zA-Z])\b/g;
var equation = id("myInput").val();
var spli= reg.exec(equation);
alert(spli);
var text;
var y= document.getElementById("myInput").value;
switch(y) {
case "20x+5k-10p-y=0":
ans = "First add both side for -20";
ans1= "Both side added by 10p";
ans2= "Next both side added by y";
ans3= "Divide by both side 5";
ans4= "Solution for k value";
document.getElementById("equ1").innerHTML = ans;
document.getElementById("equ2").innerHTML = ans1;
document.getElementById("equ3").innerHTML = ans2;
document.getElementById("equ4").innerHTML = ans3;
document.getElementById("equ5").innerHTML = ans4;
break;
case "20x+5k-10p-y=0p":
ans5p = "First add both side for -20";
ans6p= "Both side added by -5k";
ans7p= "Next both side added by y";
ans8p= "Divide by both side -10";
ans9p= "Solution for p value";
document.getElementById("equ1p").innerHTML = ans5p;
document.getElementById("equ2p").innerHTML = ans6p;
document.getElementById("equ3p").innerHTML = ans7p;
document.getElementById("equ4p").innerHTML = ans8p;
document.getElementById("equ5p").innerHTML = ans9p;
break;
case "20x+5k-10p-y=0x":
xone1 = "First add both side for -5";
xtwo2= "Both side added by 10p";
xthr3= "Next both side added by y";
xfour4= "Divide by both side 20";
xfive5= "Solution for x value";
document.getElementById("xoneans1").innerHTML = xone1;
document.getElementById("xoneans2").innerHTML = xtwo2;
document.getElementById("xoneans3").innerHTML = xthr3;
document.getElementById("xoneans4").innerHTML = xfour4;
document.getElementById("xoneans5").innerHTML = xfive5;
break;
case "20x+5k-10p-y=0y":
xone6 = "First add both side for -20";
xtwo7= "Both side added by -5k";
xthr8= "Next both side added by 10p";
xfour9= "Divide by both side -1";
xfive10= "Solution for y value";
document.getElementById("xoneans6").innerHTML = xone6;
document.getElementById("xoneans7").innerHTML = xtwo7;
document.getElementById("xoneans8").innerHTML = xthr8;
document.getElementById("xoneans9").innerHTML = xfour9;
document.getElementById("xoneans10").innerHTML = xfive10;
break;
// add the default keyword here
}
}
</script>
<p id="super"></p>
</body>
</html>
I have some code in the linear equation steps. How can I allow the user to open the drop-down list, and select a single letter, for which my code will then show the corresponding algorithm steps?
For example, I would like to display the menu
[x
y
z
p]
from that button, the user selects x, and my code should display the steps listed in the switch case for x.

Related

How to pass Range Values into an HTML sidebar to be ticked or selected then save selections using GAS?

As the sidebar is open, it displays the colors (color name and its HEX #, which are sitting in a sheet) and displays also a checkbox next to each color.
The user ticks the checkbox or selects the colors how many he/she wants all the way down, clicks on save and the list gets saved into an array...maybe PropertiesService.getDocumentProperties()
Here's the code I got for the sidebar and getting the colors from the range:
var ss = SpreadsheetApp.getActiveSpreadsheet();
function showSideBar() {
var ui = SpreadsheetApp.getUi();
var tmp = HtmlService.createTemplateFromFile('pickColor');
var html = tmp.evaluate();
html.setTitle('Escolha as cores');
ui.showSidebar(html);
}
function getColors() {
const colorListSheet = ss.getSheetByName('CadCores');
const colorList = colorListSheet.getRange(2,1,colorListSheet.getLastRow(),2).getValues();
return colorList;
}
Here's the html part, whose body I can't make it dynamic being a newbie. Listed Yellow as an example, but I suppose that having the checkbox, the color name and its hex would require it to be a table, correct?
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<input id="Yello" type="checkbox">
<label for="yellow">Yellow</label>
<br>
<br>
<button id='salvar-cores'>Salvar Cores</button>
<br>
<br>
<script>
let colorArray = 10;//But this would be the getColors' length, right?
function addColor(colors){
for (let i = 0; i < colorArray; i++){
$(i + 1).text(colors[i]);
}
};
google.script.run.withSuccessHandler(addColor).getColors();
</script>
</body>
</html>
Any direction is appreciated.
You can always put a ballot symbol into a select option and toggle on or off. Here is an example.
Code.gs:
function onOpen() {
try {
var menu = SpreadsheetApp.getUi().createMenu("Cad Colors");
menu.addItem("Get Colors", "showGetColors");
menu.addToUi();
}
catch(err) {
Logger.log(err);
}
}
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename)
.getContent();
}
function showGetColors() {
try {
var html = HtmlService.createTemplateFromFile("HTML_GetColors").evaluate();
SpreadsheetApp.getUi().showSidebar(html);
}
catch(err) {
SpreadsheetApp.getUi().alert(err);
}
}
function getColors() {
try {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName("CadColors");
return sh.getDataRange().getValues();
}
catch(err) {
Logger.log(err);
}
}
function setColors(checked) {
try {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName("CadColors");
sh.getRange(2,3,checked.length,1).setValues(checked);
}
catch(err) {
Logger.log(err);
}
}
Then if the HTML file:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<select id="colorSelect" onchange="colorOnChange()" ondblclick="colorDblClick()"></select>
<input type="button" onclick="colorSaveClick()" value="Save Colors">
<?!= include("JS_GetColors"); ?>
</body>
</html>
I've seperated out the javascript in a seperate file that is included into a HTML Template:
<script>
function colorOnChange() {
try {
var select = document.getElementById("colorSelect");
var option = select.options[select.selectedIndex];
var text = option.text;
text = text.charAt(0) === "☐" ? "☑" : "☐";
text = text.concat(option.text.slice(1));
option.text = text;
}
catch(err) {
alert(err);
}
}
function colorDblClick() {
try {
var select = document.getElementById("colorSelect");
var text = select.value;
var option = null;
text = text.charAt(0) === "☐" ? "☑" : "☐";
text = text.concat(select.value.slice(1));
for( var i=0; i<select.options.length; i++ ) {
option = select.options[i];
if( option.text.slice(1) === text.slice(1) ) {
option.text = text;
break;
}
}
select.value = text;
}
catch(err) {
alert(err);
}
}
function colorSaveClick() {
try {
var select = document.getElementById("colorSelect");
var checked = [];
for( var i=0; i<select.options.length; i++ ) {
// note that checked is an array of arrays
checked.push( select.options[i].text.charAt(0) === "☑" ? [true] : [false] );
}
google.script.run.setColors(checked);
}
catch(err) {
alert(err);
}
}
(function () {
try {
google.script.run.withSuccessHandler(
function (colors) {
try {
var option = null;
var text = null;
// omit first line
for( var i=1; i<colors.length; i++ ) {
option = document.createElement("OPTION");
text = document.createTextNode("☐ "+colors[i][0]+" "+colors[i][1]);
option.appendChild(text);
document.getElementById("colorSelect").appendChild(option);
}
}
catch(err) {
alert(err);
}
}
).getColors();
}
catch(err) {
alert(err);
}
}());
</script>
The only difficulty is handling the select.value. To toggle it you have to double click. Every other one you can select and toggle from the drop down. The status of the selections is returned to the spreadsheet using setColors().
My spreadsheet looks like this:
And the sidebar like this:
I think this could work for you
1. I got all the colors in a spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
function showSideBar() {
var ui = SpreadsheetApp.getUi();
var tmp = HtmlService.createTemplateFromFile('pickColor');
var html = tmp.evaluate();
html.setTitle('Escolha as cores');
ui.showSidebar(html);
}
function getColors() {
const colorListSheet = ss.getSheetByName('CadCores');
const colorList = colorListSheet.getRange(2,1,colorListSheet.getLastRow() -1,2).getValues();
return colorList;
}
function onOpen(){
showSideBar()
}
2. Render the colors in the DOM
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<div id='color-name'></div>
<br>
<button id='salvar-cores'>Salvar Cores</button>
<script>
function afterLoad(){
google.script.run.withSuccessHandler(afterDataReturned).getColors();
}
function afterDataReturned(arrayOfArrays){
const item = document.getElementById("color-name")
arrayOfArrays.forEach(function(row){
let input = document.createElement("input")
input.type = "checkbox"
input.id = row[0]
input.value = row[1]
item.appendChild(input)
let label = document.createElement("label")
label.setAttribute('for',row[0])
label.textContent = row[0]
item.appendChild(label)
})
}
document.addEventListener("DOMContentLoaded", afterLoad)
</script>
</body>
</html>
3. Add any other color you want in the sheet and refresh the menu, so it reloads the new colors

All buttons only affect one input instead of respective input

I am making a little project for my self. So basically its main function is to create a base counter for each game.
For example: If there are two players it should create three bases. (This is for the card game "smash up" if that helps you understand better.) But when the Buttons populate they all only effect the last input. I can not figure out how to make them effect their respective inputs.
The problem I am having is that every button I click only effects the last input.
<html>
<title> Base Maker </title>
<body>
<div>
<hl> Score Keeper </h1>
<hr>
<input type = "text" placeholder = "How many players?">
<button id = "enter" onclick = "baseMaker()">
Enter
</button>
</div>
<p></p>
</body>
</html>
var parent = document.querySelector("p");
var input = document.querySelector("input");
var enter = document.getElementById("enter");
function baseMaker()
{
for(var i = 0; i <= input.value; i++)
{
//base
var base = document.createElement("p");
base.textContent = "Base " + (i + 1) + ":";
//score
var score = document.createElement( "input");
score.setAttribute("id", "score" + i);
score.value = 20;
//upbutton
var upButton = document.createElement( "button");
upButton.textContent = "+";
upButton.setAttribute("id", "upButton" + i)
upButton.addEventListener('click', function() {
score.value++; });
//downbutton
var downButton = document.createElement( "button");
downButton.textContent = "-";
downButton.setAttribute("id", "downButton" + i)
downButton.addEventListener('click', function() {
score.value--; });
//populate data
parent.appendChild(base);
parent.appendChild(score);
parent.appendChild(upButton);
parent.appendChild(downButton);
}
input.value = "";
}
This is a common thing to run into especially when not using a framework in javascript.
I am not sure why this happens but when a function is defined directly in a loop, the closure for these created functions becomes whatever it is after the last iteration. I believe it is because the closure for each callback function is only "sealed up" (for lack of a better word) at the end of the loop-containing-function's execution which is after the last iteration. It's really beyond me, though.
There are some easy ways to avoid this behavior:
use bind to ensure a callback gets called with the correct input (used in solution at bottom)
create a function which creates a handler function for you and use that in the loop body
function createIncrementHandler(input, howMuch){
return () => input.valueAsNumber += howMuch;
}
/// then in your loop body:
downButton.addEventListener('click', createIncrementHandler(score, 1));
get the correct input by using the event parameter in the handler
downButton.addEventListener('click', (event) => event.target.valueAsNumber += 1);
make the entire body of the loop into a function, for example:
function createInputs(i) {
//base
var base = document.createElement("p");
base.textContent = "Base " + (i + 1) + ":";
//score
var score = document.createElement("input");
score.type = "number";
score.setAttribute("id", "score" + i);
score.value = 20;
//upbutton
var upButton = document.createElement( "button");
upButton.textContent = "+";
upButton.setAttribute("id", "upButton" + i)
upButton.addEventListener('click', function() {
score.value++; });
//downbutton
var downButton = document.createElement( "button");
downButton.textContent = "-";
downButton.setAttribute("id", "downButton" + i)
downButton.addEventListener('click', function() {
score.value--; });
//populate data
parent.appendChild(base);
parent.appendChild(score);
parent.appendChild(upButton);
parent.appendChild(downButton);
}
Here is a full example of one of the possible fixes.
<html>
<title> Base Maker </title>
<body>
<div>
<hl> Score Keeper </h1>
<hr>
<input type="text" placeholder="How many players?">
<button id="enter" onclick="baseMaker()">
Enter
</button>
</div>
<p></p>
<script>
var parent = document.querySelector("p");
var input = document.querySelector("input");
var enter = document.getElementById("enter");
function incrementInput(input, byHowMuch) {
input.valueAsNumber = input.valueAsNumber + byHowMuch;
}
function baseMaker() {
for (var i = 0; i <= input.value; i++) {
//base
var base = document.createElement("p");
base.textContent = "Base " + (i + 1) + ":";
//score
var score = document.createElement("input");
score.type = "number";
score.setAttribute("id", "score" + i);
score.value = 20;
//upbutton
var upButton = document.createElement("button");
upButton.textContent = "+";
upButton.setAttribute("id", "upButton" + i)
upButton.addEventListener('click', incrementInput.bind(null, score, 1));
//downbutton
var downButton = document.createElement("button");
downButton.textContent = "-";
downButton.setAttribute("id", "downButton" + i)
downButton.addEventListener('click', incrementInput.bind(null, score, -1));
//populate data
parent.appendChild(base);
parent.appendChild(score);
parent.appendChild(upButton);
parent.appendChild(downButton);
}
input.value = "";
}
</script>
</body>
</html>
I will do that this way :
const
AllBases = document.querySelector('#bases')
, bt_Start = document.querySelector('#game-go')
, bt_newGame = document.querySelector('#new-game')
, playerCount = document.querySelector("#play-start > input")
;
playerCount.value = ''
playerCount.focus()
playerCount.oninput = () =>
{
playerCount.value.trim()
bt_Start.disabled = (playerCount.value === '' || isNaN(playerCount.value))
playerCount.value = (bt_Start.disabled) ? ''
: (playerCount.valueAsNumber > playerCount.max) ? playerCount.max
: (playerCount.valueAsNumber < playerCount.min) ? playerCount.min
: playerCount.value
}
bt_newGame.onclick = () =>
{
playerCount.value = ''
playerCount.disabled = false
bt_Start.disabled = true
bt_newGame.disabled = true
AllBases.innerHTML = ''
playerCount.focus()
}
bt_Start.onclick = () =>
{
playerCount.disabled = true
bt_Start.disabled = true
bt_newGame.disabled = false
for(let i = 0; i <= playerCount.valueAsNumber; i++)
{
let base = document.createElement('p')
base.countValue = 20 // create a counter property on <p>
base.innerHTML = `Base ${i+1} : <span>${base.countValue}</span> <button>+</button> <button>−</button>\n`
AllBases.appendChild(base)
}
}
AllBases.onclick = ({target}) =>
{
if (!target.matches('button')) return // verify clicked element
let countElm = target.closest('p')
if (target.textContent==='+') countElm.countValue++
else countElm.countValue--
countElm.querySelector('span').textContent = countElm.countValue
}
#bases p span {
display : inline-block;
width : 6em;
border-bottom : 2px solid aqua;
padding-right : .2em;
text-align : right;
margin : 0 .3em;
}
#bases p button {
width : 2em;
margin : 0 .1em;
cursor : pointer;
}
<hr>
<hl> Score Keeper </h1>
<hr>
<div id="play-start" >
<input type="number" placeholder="How many players?" min="2" max="4">
<button id="game-go" disabled> Enter </button>
<button id="new-game" disabled> new </button>
</div>
<hr>
<div id="bases"></div>
If it helps, I can add more explanations

childNode.remove() doesn't seem to be working

I'm writing a google sheets add on that helps you track data as you play a game. In the sidebar, you can search for a monster in the game and after you hit the submit button the monster's stats, a list of what items they drop after a kill, and a link to the wiki is rendered on screen.
The problem I'm having is that when you search a new monster after having already searched for one, the old items from the drop section won't get removed. The other sections on stats and the wiki link will change, but instead of removing the old drop items, the new items just get added to the end of the list.
I've tried using parent.removeChild() and childNode.remove() and neither seem to do anything and I'm wondering if its because of how google apps script works.
Here is the html for the sidebar itself: note that include() is a custom function that google recommends you add to your script so you can import other files.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<?!= include('Info sidebar styles'); ?>
</head>
<body>
<form id="monsters">
<input class="monsterInput" type="text"placeholder="Monster Name" name="monsterName" />
<input class="monsterInput" type="text" placeholder="Monster Level" name="monsterLvl" />
<button id="submit">Search</button>
</form>
<div id="output">
</div>
<?!= include('sidebar script'); ?>
</body>
</html>
Here's the code for sidebar script:
<script>
if (document.readyState == 'loading') {
document.addEventListener('DOMContentLoaded', ready)
} else {
ready()
}
function ready(){
// create the divs that are later filled with info
var output = document.getElementById("output");
var stats = document.createElement("div");
stats.id = "statsDiv";
var drops = document.createElement("div");
drops.id = 'dropDiv';
var list = document.createElement("div");
list.id = "dropList";
var wiki = document.createElement("div");
wiki.id = "wiki";
output.appendChild(stats);
output.appendChild(drops);
output.appendChild(wiki);
var index = 0;
// the onSuccess for the onClick eventHandler. data is an object returned from the function call below
function onSuccess(data) {
console.log(`first index ${index}`);
// if the submit button has already been pushed and added the droplist to the DOM, increase the index
if(drops.getElementsByClassName("dropItem")[0]){
index++;
console.log(`second index ${index}`);
};
console.log(index);
// get the stats
var hitpoints = data.hitpoints;
var attackarray = data["attack_type"]
var attackTypes = '';
var attack1 = attackarray[0];
var attack2 = attackarray[1];
var attack3 = attackarray[2];
var attack4 = attackarray[3];
if(attackarray.length === 1){
attackTypes = attack1;
} else if (attackarray.length === 2){
attackTypes = `${attack1}, ${attack2}`;
} else if (attackarray.length === 3){
attackTypes = `${attack1}, ${attack2}, ${attack3}`;
} else if (attackarray.length === 4){
attackTypes = `${attack1}, ${attack2}, ${attack2}, ${attack4}`;
}
var attLvl = data["attack_level"];
var defLvl = data["defence_level"];
var magicLvl = data["magic_level"];
var rangeLvl = data["ranged_level"];
var maxHit = data["max_hit"];
var aggro = '';
if(data.aggressive){
aggro = "Yes";
} else {
aggro = "No";
}
var speed = data["attack_speed"];
// put the stats into html form
var statsInner =
`<h2> Stats </h2>
<ul id="statsList">
<li>Hitpoints: ${hitpoints}</li>
<li>Attack Level: ${attLvl}</li>
<li>Defense Level: ${defLvl}</li>
<li>Magic Level: ${magicLvl}</li>
<li>Ranged Level: ${rangeLvl}</li>
<li>Attack Style: ${attackTypes} </li>
<li>Attack Speed: ${speed}</li>
<li>Max Hit: ${maxHit} </li>
<li>Aggressive? ${aggro} </li>
</ul>`;
stats.innerHTML = statsInner;
drops.innerHTML = '<h2>Drops</h2>';
// Put the wiki url into HTML
var wikiURL = data["wiki_url"];
var wikiInner = `<p>For more info check out this monsters page on the wiki, <a href=${wikiURL}>here</a>.</p>`;
wiki.innerHTML = wikiInner;
// get the drop information and put it in html form. make the data-id attribute of each object equal the value of index
data.drops.forEach(function (item) {
var name = item.name;
var quant = item.quantity;
var members = '';
if(item.members){
members = "(m)";
}
var nameQM = `${name} (x${quant}) ${members}`;
var rarity = (item.rarity) * 100;
var rare = rarity.toFixed(2);
var nameNode = document.createElement("div");
var itemList =
`<p>${nameQM}</p>
<br>
<p> Rarity: ${rare} percent </p>`;
nameNode.innerHTML = itemList;
nameNode.className = "dropItem";
nameNode.dataset.id = index;
list.appendChild(nameNode);
})
drops.appendChild(list);
// if the drop item has a data-id that doesn't match the current index, remove it from the DOM.
var dropArray = list.getElementsByClassName("dropItem");
for(var i = 0; i < dropArray.length; i++){
var item = dropArray[i];
if(item.dataset.id != index){
item.remove();
}
}
}
//add the event listener to the submit button. getMonsterData makes an API call, parses the data, and returns an object filled with the data we add to the DOM through the success handler
document.getElementById("submit").addEventListener("click", function (e) {
e.preventDefault();
var parent = e.target.parentElement;
var monsterName = parent.elements[0].value;
var monsterlvl = parent.elements[1].value;
google.script.run.withSuccessHandler(onSuccess).getMonsterData(monsterName, monsterlvl);
});
}
</script>

result output disappears too quickly

the correct or wrong answer outputs and quickly disappears. How do I get the answer to remain on the screen. I want to keep the html and js files separate. What I want to do later is add other phrases to the program.
INDEX.HTML
<head> </head>
<body>
<form name="myForm">
<div id ="phrase"></div>
<input type = "text" id = "textinput">
<button id="myBtn">Click here</button>
<div id ="feedback"></div>
</form>
<script src = "phraseScrambler.js"></script>
</body>
</html>
PHRASESCRAMBLER.JS
var words = ['how', 'are', 'you', 'today?'];
var correctInput = "how are you today";
var userInput = 'how are you today?';
var newWords = words.slice(0);
shuffle(newWords);
question();
function question() {
var el = document.getElementById('phrase');
el.textContent = newWords.join(' ');
document.getElementById("myBtn").onclick = checkAnswer;}
function checkAnswer() {
var elMsg = document.getElementById('feedback');
if (document.myForm.textinput.value == correctInput) {
elMsg.textContent= "correct";}
else {
elMsg.textContent= "wrong answer";}}
function shuffle(newWords) {
var counter = newWords.length, temp, index;
while (counter > 0) {
index = Math.floor(Math.random() * counter);
counter--;
temp = newWords[counter];
newWords[counter] = newWords[index];
newWords[index] = temp;}
return newWords;}
First of all don't bind click event if you want to handle form submission, forms have dedicated event called onsubmit. When form is submitted default browser behavior is to navigate to form action (in your case reload the page). You need to prevent this by returning false from the onsubmit handler.
Corrected HTML will be (I gave an id to the form):
<form name="myForm" id="myForm"> ... </form>
And then event handling will look like (note return false; in checkAnswer function):
var words = ['how', 'are', 'you', 'today?'];
var correctInput = "how are you today";
var userInput = 'how are you today?';
var newWords = words.slice(0);
shuffle(newWords);
question();
function question() {
var el = document.getElementById('phrase');
el.textContent = newWords.join(' ');
document.getElementById("myForm").onsubmit = checkAnswer;
}
function checkAnswer() {
var elMsg = document.getElementById('feedback');
if (document.myForm.textinput.value == correctInput) {
elMsg.textContent = "correct";
} else {
elMsg.textContent = "wrong answer";
}
return false;
}
function shuffle(newWords) {
var counter = newWords.length,
temp, index;
while (counter > 0) {
index = Math.floor(Math.random() * counter);
counter--;
temp = newWords[counter];
newWords[counter] = newWords[index];
newWords[index] = temp;
}
return newWords;
}
<form name="myForm" id="myForm">
<div id ="phrase"></div>
<input type = "text" id = "textinput" />
<button>Click here</button>
<div id ="feedback"></div>
</form>

How to give Input tag attribute type button value at Runtime in Meteor JS

How to give Input tag Attribute type button value at Runtime in Meteor JS as shown below:
newButton = document.createElement('input');
newButton.value = ''; - Here value i need like as i.e , val ="{{btnValue}}"
I'm not familiar with Meteor JS, so please offer any suggestions.
Html Code I need like as below in Runtime JS:
// Manually Creating button
<input type="button" id="no" val ="{{btnValue}}">
My HTML Code :
<head>
<title>TICTACTOE App 1.3</title>
</head>
<body>
{{> uname}}
{{> main}}
{{> games }}
</body>
<template name="uname">
<h1>Welcome to TICTACTOE App</h1>
<p id="pname"><b>User Name :</b> <input type="text" id="uname" ></p>
</template>
<template name="main">
<p id="pno"><b>Layout Number :</b> <input type="text" id="no" ></p>
<div name="main"></div>
</template>
<template name="games">
{{#each game}}
<div>{{turn}} </div>
<div> {{wturn}}</div>
<div>{{bval}}</div>
{{/each}}
</template>
Meteor JS:
Counts = new Meteor.Collection('count');
TurnData= new Meteor.Collection('tdata');
BtnValues= new Meteor.Collection('btnvalues');
var x = "X";
var o = "O";
var Whoseturn = "";
var no;
var newButton;
var count = 0;
var IsWin = false;
var IsTurn = true;
var val = "";
var ButtonValue= "";
var btnval;
if (Meteor.isClient)
{
Template.main.helpers
({
btnValue: function()
{
return BtnValues.findOne();
}
});
Template.main.events
({
'click input' : function ()
{
// template data, if any, is available in 'this'
var name = document.getElementById('uname');
console.log(name.value);
var btnid = event.currentTarget.id;
ButtonValue = btnid;
btnval = document.getElementById(btnid);
console.log(btnid);
if(btnval.value == '' && btnid != "no" )
{
calculateTurn();
console.log(Whoseturn);
btnval.value = Whoseturn;
var myBtnData = BtnValues.findOne();
BtnValues.update( {_id: myBtnData._id},{ $set:{bval : btnval} });
}
}
});
Template.main.events
({
'keydown input#no' : function ()
{
// template data, if any, is available in 'this'
if (event.which == 13)
{
// 13 is the enter key event
console.log("You pressed enter key");
no = document.getElementById('no');
count = 0;
var myTurnData = Counts.findOne();
Counts.update( {_id: myTurnData._id},{ $set:{turn : count } });
if(no.value != '')
{
document.getElementById('pname').style.visibility = 'hidden';
document.getElementById('pno').style.visibility = 'hidden';
UI();
}
}
}
});
}
function UI()
{
console.log("*** UI() ***");
for(var i = 1 ; i <= no.value ; i++)
{
//var body=document.getElementsByTagName('body')[0];
var body = document.getElementsByName('main')[0];
for(var j = 1 ; j <= no.value ; j++)
{
newButton = document.createElement('input');
newButton.type = 'button';
newButton.id = 'btn'+i+j;
newButton.value = '';////Here value i need like as val ="{{btnValue}}
body.appendChild(newButton);
}
var newline = document.createElement('br');
body.appendChild(newline) ;
}
}
function calculateTurn()
{
var myTurnData = Counts.findOne();
count = myTurnData.turn;
console.log("count="+count);
count = count + 1;
console.log("updated count="+count);
Counts.update( {_id: myTurnData._id},{ $set:{turn : count } });
if(count <= 9)
{
var TData = TurnData.findOne();
IsTurn = true;
if(count % 2 == 0)
{
Whoseturn = o ;
TurnData.update( {_id: TData._id},{ $set:{wturn : Whoseturn } });
}
else
{
Whoseturn = x ;
TurnData.update( {_id: TData._id},{ $set:{wturn : Whoseturn } });
}
}
else
{
IsTurn = false;
console.log(" >= 9");
}
}
if (Meteor.isServer)
{
Meteor.startup(function ()
{
// code to run on server at startup
Counts.insert({turn : count});
TurnData.insert({wturn : Whoseturn});
BtnValues.insert({bval : val});
});
}

Categories