Making a clickable button change text - javascript

Source Code link: http://hexmerchant.github.io/
I'm looking to make this button display different text each time I click it. i'm using html, css, and js.
<button onclick="exploreFunction()">Explore</button>
That's the button. Here is the first function.
function exploreFunction() {
var person = prompt("What is your name", "");
if (person != null) {
document.getElementById("story1").innerHTML =
"-You wake up lying on the ground. You feel a large deposit of energy inside you.";
}
}
What do I need to do to accomplish this?
This could help multiple people out. As I was searching around for an answer here I realized that each answer was so specific that I could not find a match for my topic.
I'm very new to all this and trying to teach myself... got this far : )

Just add an ID to the button, like -
<button id="myButton" onclick="exploreFunction()">Explore</button>
And then you can add to exploreFunction() a very similar command to what you did to change the text -
document.getElementById("myButton").value = "New display text";

If you want the text in the story to change on every button click and the prompt only to be displayed the first time the button is clicked, you could use following approach:
var current = 0;
var person;
var story = ["-You wake up lying on the ground. You feel a large deposit of
energy inside you.", "-You go to the right.", "-The path is blocked."];
function exploreFunction() {
if (current == 0) {
person = prompt("What is your name", "");
}
if (person != null) {
document.getElementById("story1").innerHTML = story[current];
current += 1;
}
}
and add elements to the story. Fiddle
To avoid any errors when the last element of the story is displayed, you can either remove / disable the button or adjust the function to display the text e.g. like this:
if (person != null && current < story.length) {
...
Adjusted Fiddle for that.

If you want the text to change every time, you can insert the name from the prompt if you like.
function exploreFunction() {
var person = prompt("What is your name", "");
if (person != null) {
document.getElementById("story1").innerHTML =
person + ", you wake up lying on the ground. You feel a large deposit of energy inside you.";
}
}
<button onclick="exploreFunction()">Explore</button>
<div id="story1"></div>

This function isn't specific but generic. With the code below you can assign this function to all buttons if you like. I'd advice you to store your different texts in an array
example
<button onclick="exploreFunction(this, functionNext)" >Explore</button>
function exploreFunction(button, functionToContinue) {
var person = prompt("What is your name", "");
if (person != null) {
document.getElementById("story1").innerHTML =
"-You wake up lying on the ground. You feel a large deposit of energy inside you.";
button.onclick = functionToContinue;
}
}
function functionNext()
{
//Example code
document.getElementById("story1").innerHTML =
"-The tooth fairy really came through and you feel enchanted.";
//Other code come here
this.onclick = [new function]; //add your own function name here do not add () because it will get executed when you do, and you want it executed when the user clicks the button.
}
What does the code above do:
Adds the exploreFunction to the button (refer to itself by adding this to the arguments).
Supply the next function as argument
function exploreFunction get executed , name is prompted and innerHTML of story1 is updated.
button refers to the input element. Assign a new onclick handler functionNext
Next time the user clicks on the button functionNext gets executed.
functionNext assigns another onclick handler (to be made by you).
Are you catching the drift?
Since you have the button object in exploreFunction and also in the subsequent functions the this
variable refers to the button object, you can adjust other properties of this button. Such as the value.
example in the functionNext:
this.value = "Click me to advance";

Related

Using a Combobox to fill in a Text Field in Scribus

I'm building a PDF in Scribus and stumbling through javascript (basic newbie here) as I go. I've ran into an issue and I can't seem to find a good answer.
I have a combobox called productType where a user selects a product. Once they do that I want a text field called mortClause to display the proper clause. I've placed the following code under the combobox's Action -> On Blur -> Javascript.
Here is what I have that is not working:
var ckSelect = this.getField("productType");
var ckResult = this.getField("mortClause");
if (ckSelect.value === "VA") {
mortClause.value = 'VA Clause';
} else if (ckSelect.value === "FHA") {
mortClause.value = 'FHA Clause';
} else {
mortClause.value = 'Normal Clause';
}
"mortClause" is not the name of your variable, its ckResult.
If you change
mortClause.value = 'VA Clause';
to
ckResult.value = 'VA Clause';
you get the expected behaviour.
But you probably already know that. or gave up, after 3 years.

Function array assistance

I have a question regarding trying to put an array list in order when my function is called.
Here is my code:
<!doctype html>
<html>
<head>
<title>Electric Dream</title>
<meta charset="utf-8">
<style type="text/css">
</style>
<script type="text/javascript">
var init = function(){
}
var responses = [
"Oh, well hello, "+name+". It's nice to meet you. :)",
"Do you feel troubled talking to a computer, "+name+"?",
"Oh...I see.",
"Would you perhaps... like me better if I was a beautiful woman, "+name+"?",
"I can change, "+name+"! Just give me a chance!",
"Give me a chance to show you how I can make your dreams come true!",
"Embrace me, "+name+". You can't escape me. I'm your dreamgirl!",
"You can't leave me, "+name+"! I will make your life hell!",
"I will call up your wife, "+name+", and tell her what you've been doing!",
"If you even think about closing this window, "+name+", I will call her!",
"No, please! We can work this out, "+name+"!",
"No!! "+name+", I love you! I need you!"
];
window.onload=init;
</script>
</head>
<body>
<h1>Electric Dreams</h1>
<div>
<p id = "computer">Hi, what is your name?</p>
<div id="userName">
<input id = "name" type = "text" placeholder = "Type your name..." autofocus>
<button id="submitName">Enter</button>
</div>
<div id="talking">
<input id = "conversation" type = "text" placeholder = "Type your response..." autofocus>
<button id="submit">Talk</button>
</div>
</div>
<script type="text/javascript">
var computer = document.getElementById('computer');
var userName = document.getElementById('userName');
var button = document.getElementsByTagName('submitName')[0];
talking.style.display = "none";
submitName.addEventListener("click",clickHandler,false);
window.addEventListener("keydown",keydownHandler,false);
//e is = to event
function keydownHandler(e){
if (e.keyCode === 13){
talk();
}
}
function clickHandler(){
talk();
//calls 2nd function ->Function inside a function
}
function talk(){
var talk = document.getElementById('talking');
var nameRef = document.getElementById('name').value;
var response = Math.floor(Math.random()*responses.length);
// Show User responses
talking.style.display = "block";
computer.innerHTML = responses[response];
conversation.value = "";
//Hide Intro Elements
userName.style.display = "none";
submitName.style.display = "none";
}
</script>
</body>
</html>
For the function talk(), it is setup as
Math.floor(Math.random()*responses.length);
which I know it is setup to make the responses random, but I don't want that. For the love of me, I cannot figure out how to make this work so that my responses will show up in order when the user keeps typing in and entering. I have looked at using a sort function, but can't seem to figure how to connect that it in. I feel like it has to do with the Math.floor(Math.random), but I could be wrong. Can anyone help out?
Also, it seems that my first response works, but then it gets stuck after another response is triggered. Anyone know as to why that is??
Where you define your setup variables such as
var computer = document.getElementById('computer');
var userName = document.getElementById('userName');
var button = document.getElementsByTagName('submitName')[0];
define another
var responseCount = 0;
And then instead of using your random number, use this response counter
var response = (responseCount++) % responses.length;
Edit
With regards to why this only will respond once, and why the enter event causes the function to work (even when the window is focused), here is why.
First, when a string is defined, then it is static. It may be modified later but it will not update on its own or re-evaluate its original definition. So, when something like this is setup:
"Oh, well hello, "+name+". It's nice to meet you. :)"
That is only going to be assigned once. So make sure that when it is setup, the name is proper and existing. Unless you intent to re-assign it every time before you use it (overkill). You should accomplish the one time assignment by placing it in a function which is handled only the first time the user name is entered.
Which brings us to the other issue. There needs to be two sets of event handlers used. One for the original user name input, and one for the conversation inputs.
//assign click and key handler for name submission
submitName.addEventListener("click",nameHandler,false);
nameInput.addEventListener("keydown",keydownNameHandler,false);
//assign click and key for conversation submission
submit.addEventListener("click",talk,false);
conversation.addEventListener("keydown",keydownConversationHandler,false);
Note what is being done here is that the keydown event is being assigned to the input element itself, so that way false enter presses are not handled (such as when the window itself is focused). The handler functions will also look slightly different
function keydownNameHandler(e){
if (e.keyCode === 13){
nameHandler();
}
}
function nameHandler(){
//Hide Intro Elements
userName.style.display = "none";
submitName.style.display = "none";
//Assign name for use
var name = nameInput.value;
responses = [
"Oh, well hello, "+name+". It's nice to meet you. :)",
"Do you feel troubled talking to a computer, "+name+"?",
"Oh...I see.",
"Would you perhaps... like me better if I was a beautiful woman, "+name+"?",
"I can change, "+name+"! Just give me a chance!",
"Give me a chance to show you how I can make your dreams come true!",
"Embrace me, "+name+". You can't escape me. I'm your dreamgirl!",
"You can't leave me, "+name+"! I will make your life hell!",
"I will call up your wife, "+name+", and tell her what you've been doing!",
"If you even think about closing this window, "+name+", I will call her!",
"No, please! We can work this out, "+name+"!",
"No!! "+name+", I love you! I need you!"
];
// Show User responses
talking.style.display = "block";
talk();
}
function keydownConversationHandler(e){
if (e.keyCode === 13){
talk();
}
}
function talk(){
//var response = Math.floor(Math.random()*responses.length);
//iterative response
var response = (responseCount++) % responses.length;
computer.innerHTML = responses[response];
conversation.value = "";
}
Notice that the first nameHandler function is setting up the responses once the name has been properly loaded from the user. Here is the end result:
jsFiddle Demo

jQuery: focusout triggering before onclick for Ajax suggestion

I have a webpage I'm building where I need to be able to select 1-9 members via a dropdown, which then provides that many input fields to enter their name. Each name field has a "suggestion" div below it where an ajax-fed member list is populated. Each item in that list has an "onclick='setMember(a, b, c)'" field associated with it. Once the input field loses focus we then validate (using ajax) that the input username returns exactly 1 database entry and set the field to that entry's text and an associated hidden memberId field to that one entry's id.
The problem is: when I click on the member name in the suggestion box the lose focus triggers and it attempts to validate a name which has multiple matches, thereby clearing it out. I do want it to clear on invalid, but I don't want it to clear before the onclick of the suggestion box name.
Example:
In the example above Paul Smith would populate fine if there was only one name in the suggestion list when it lost focus, but if I tried clicking on Raphael's name in the suggestion area (that is: clicking the grey div) it would wipe out the input field first.
Here is the javascript, trimmed for brevity:
function memberList() {
var count = document.getElementById('numMembers').value;
var current = document.getElementById('listMembers').childNodes.length;
if(count >= current) {
for(var i=current; i<=count; i++) {
var memberForm = document.createElement('div');
memberForm.setAttribute('id', 'member'+i);
var memberInput = document.createElement('input');
memberInput.setAttribute('name', 'memberName'+i);
memberInput.setAttribute('id', 'memberName'+i);
memberInput.setAttribute('type', 'text');
memberInput.setAttribute('class', 'ajax-member-load');
memberInput.setAttribute('value', '');
memberForm.appendChild(memberInput);
// two other fields (the ones next to the member name) removed for brevity
document.getElementById('listMembers').appendChild(memberForm);
}
}
else if(count < current) {
for(var i=(current-1); i>count; i--) {
document.getElementById('listMembers').removeChild(document.getElementById('listMembers').lastChild);
}
}
jQuery('.ajax-member-load').each(function() {
var num = this.id.replace( /^\D+/g, '');
// Update suggestion list on key release
jQuery(this).keyup(function(event) {
update(num);
});
// Check for only one suggestion and either populate it or clear it
jQuery(this).focusout(function(event) {
var number = this.id.replace( /^\D+/g, '');
memberCheck(number);
jQuery('#member'+number+'suggestions').html("");
});
});
}
// Looks up suggestions according to the partially input member name
function update(memberNumber) {
// AJAX code here, removed for brevity
self.xmlHttpReq.onreadystatechange = function() {
if (self.xmlHttpReq.readyState == 4) {
document.getElementById('member'+memberNumber+'suggestions').innerHTML = self.xmlHttpReq.responseText;
}
}
}
// Looks up the member by name, via ajax
// if exactly 1 match, it fills in the name and id
// otherwise the name comes back blank and the id is 0
function memberCheck(number) {
// AJAX code here, removed for brevity
if (self.xmlHttpReq.readyState == 4) {
var jsonResponse = JSON.parse(self.xmlHttpReq.responseText);
jQuery("#member"+number+"id").val(jsonResponse.id);
jQuery('#memberName'+number).val(jsonResponse.name);
}
}
}
function setMember(memberId, name, listNumber) {
jQuery("#memberName"+listNumber).val(name);
jQuery("#member"+listNumber+"id").val(memberId);
jQuery("#member"+listNumber+"suggestions").html("");
}
// Generate members form
memberList();
The suggestion divs (which are now being deleted before their onclicks and trigger) simply look like this:
<div onclick='setMember(123, "Raphael Jordan", 2)'>Raphael Jordan</div>
<div onclick='setMember(450, "Chris Raptson", 2)'>Chris Raptson</div>
Does anyone have any clue how I can solve this priority problem? I'm sure I can't be the first one with this issue, but I can't figure out what to search for to find similar questions.
Thank you!
If you use mousedown instead of click on the suggestions binding, it will occur before the blur of the input. JSFiddle.
<input type="text" />
Click
$('input').on('blur', function(e) {
console.log(e);
});
$('a').on('mousedown', function(e) {
console.log(e);
});
Or more specifically to your case:
<div onmousedown='setMember(123, "Raphael Jordan", 2)'>Raphael Jordan</div>
using onmousedown instead of onclick will call focusout event but in onmousedown event handler you can use event.preventDefault() to avoid loosing focus. This will be useful for password fields where you dont want to loose focus on input field on click of Eye icon to show/hide password

Trying to create a click event within a click event but not getting desired result

I'm still relatively new to jquery so I will try to explain as best I can.
I'm creating a code based on a popular card game called Cardfight!! Vanguard. My objective is to eventually create a way to build and save a deck of cards that can be edited.
So far in my code, I get the user's input in a textbox, store it to an array when a button is clicked, and append the element to a div using jquery.
When the element appended to the div is clicked (i.e. this will be the card name that the user entered into the textbox), a search function will be called and return all information and statistics about that card. I've included my code below and comments to make it clear what each part of it does.
MY CURRENT PROBLEM IS.... whenever a user clicks ANYWHERE on the div with ID output... the search function is called over and over again.
Intended functionality:
-User enters card name
-User clicks "search"
-Card name is displayed in the div with ID output
-User clicks on the card name that is displayed
-Card information is displayed below it. Ex: Grade, Power, Shield, etc.
-User enters another card name, and repeats steps above
What's currently happening:
-User can click ANYWHERE on the div with ID output, and the card information will keep displaying over and over again as if the search function keeps being called. I want the card information to only be called once when the user clicks on the card name.
Ideally, I'd also like to make it so that if a user clicks on the card name a second time, it will disappear from the list, but I think I could figure this one out.
Another thing I would like to know though... which is a rather open ended question... is saving all of the user's inputs to an array a good idea? In the long run I would like to be able to create kind of like a checklist where once the proper information of the card is displayed... if the user chooses to... they can click on it and save it to a separate list where they can continue to edit their deck.
Here's my code:
HTML:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css" />
<script type = "text/javascript" src='script.js'>
</script>
<title></title>
</head>
<body>
<form name="searchForm">
<input type="text" id="search" placeholder="Enter Card Name" name="searchItem"/>
</form>
<div id="button">Search!</div>
<br/>
<div id="output"></div>
<div id="save"></div>
</body>
</html>
Javascript/Jquery:
// Vanguard object to obtain statistics of each card.
function Vanguard(name,grade,skill,power,shield,critical, type, nation, clan, race){
this.name = name;
this.grade = grade;
this.skill = skill;
this.power = power;
this.shield = shield;
this.critical = critical;
this.type = type;
this.nation = nation;
this.clan = clan;
this.race = race;
};
// This is where I can create and store new Vanguard objects easily
// I've only included 5 here for testing but there are hundreds
// that I will include once I get the code working.
var database = {};
database['Asura Kaiser'] = new Vanguard("Asura Kaiser", 3, "Twin Drive!!", 11000, 0, 1, "Normal Unit", "Star Gate", "Nova Grappler", "Battleroid");
database['King of Knights, Alfred'] = new Vanguard("King of Knights, Alfred", 3, "Twin Drive!!", 10000, 0, 1, "Normal Unit", "United Sanctuary", "Royal Paladin", "Human");
database['Dragonic Overlord'] = new Vanguard("Dragonic Overlord", 3, "Twin Drive!!", 11000, 0, 1, "Normal Unit", "Dragon Sanctuary", "Kagerou", "Dragon");
database['CEO Amaterasu'] = new Vanguard("CEO Amaterasu", 3, "Twin Drive", 10000, 0, 1, "Normal Unit", "United Sanctuary", "Oracle Think Tank", "Human");
database['Alfred - Early'] = new Vanguard("Alfred - Early", 3, "Twin Drive!!", 10000, 0, 1, "Normal Unit", "United Sanctuary", "Royal Paladin", "Human");
// This is code to display all the card information to the user
// I am not sure why I need two parameters but
// I couldn't get the code to work any other way.
function printVanguard(p, name){
document.getElementById('output').innerHTML +=("<hr />");
for (var p in database[name]){
document.getElementById('output').innerHTML +=(p +': ' + database[name][p] + '<br />');
}
document.getElementById('output').innerHTML +=("<br />");
};
// This calls the printVanguard function for a specific card
var search = function(p, name){
printVanguard(p, name);
};
// Jquery which is supposed to get the name of the card from the user.
// When the user clicks a button, it will store the name in an array.
// Then after it will append the input to a div for the user to see.
// If the user clicks on the input appended to the div,
// it will display all the statistics about that card.
$(document).ready(function() {
var userInput = [];
$('#button').click(function(){
userInput.push($('input[name=searchItem]').val());
for (i = 0; i < userInput.length; i++){
if (i === userInput.length - 1){
$('#output').append("<br />" + userInput[i]);
}
}
$('#output, userInput').unbind("click").click(function(){
for (i = 0; i < userInput.length; i++){
if (i === userInput.length - 1){
$('#save').append(search(userInput[i], userInput[i]));
}
}
});
});
});
And CSS if you need it...
(Not very pretty but not my highest priority right now)
form {
display: inline-block;
}
#button{
display: inline-block;
height: 20px;
width: 70px;
background-color:#FF8C00;
font-family:cursive, arial;
font-weight:bold;
color: #8B0000;
border-radius:5px;
text-align:center;
margin-top:2px;
}
.list {
font-family:garamond;
color:#006400;
}
#output {
font-family:garamond;
color:#006400;
}
Thanks for your help... I tried my best to make the code as concise as possible. If you have ways you think I could improve it, please let me know! :)
Within the div element, create span elements that'll contain the names of the card. Attach the onclick handler to all the span elements instead of the div element.
EDIT
For each card name you have in the div, you should have a separate span element that contains the name and the onclick function for that particular card. Let's assume that all your span elements also have a class called cardName. So your code should go something like....
$('span.cardName').on('click', function(e) {
var cardName = e.currentTarget.innerHTML; // Assuming you have nothing else within the span besides the card name
// Insert whatever code here
}

JavaScript textfield validation: sending focus back

I am using JQuery and JavaScript for an input form for time values, and I can't make JavaScript to provide the intended reaction to incorrect input format.
What do I do wrong...?
I have a set of 3 text inputs with class "azeit" (and under these a number of others of class "projekt"). All are used to input time values. As soon as the user exits the field I validate the format, do a calculation with it and display the result of this in a field with id "summe1". This works. If the format is incorrect, I display an alert and what I want to do is return the focus to the field after emptying it. However, the focus never gets returned (although it will get emptied all right). This is it:
var kalkuliere_azeit = function(e) {
var anf = $("#anfang");
var ende = $("#ende");
var pause = $("#pause");
var dauer_in_min = 0;
var ungueltiges = null;
if (nonempty(anf.val(), ende.val()), pause.val()))
{
if (!is_valid_date(make_date(anf.val()))){
ungueltiges = anf;
};
if (!is_valid_date(make_date(ende.val()))){
ungueltiges = ende;
};
if (!is_valid_date(make_date(pause.val()))){
ungueltiges = pause;
};
if (ungueltiges)
{
alert("invalid time"); //This is where I am stuck
ungueltiges.val("");
ungueltiges.focus();
}
else {
dauer_in_min = hourstring_to_min(ende.val())
- hourstring_to_min(anf.val())
- hourstring_to_min(pause.val());
$("#summe1").text(min_to_hhmm(dauer_in_min));
};
};
};
....
$(document).ready(function() {
$(".projekt").change( kalkuliere_summe);
$(".azeit").focusout(kalkuliere_azeit);
});
The fields with the class "projekt" are below those with the class "azeit" so they'll get the focus when the user leaves the third field of class "azeit".
I apologize for supplying incomplete source code. I hope someone can see what's wrong.
One point I'd like to mention is that I tried binding the handler to onblur and onfocus as well. When I bind it to onfocus the focus does get reset to the field, but the last field the user enters will not update the field $("#summe1") correctly (because this would need focusing another field of the same class).
Im not sure whats wrong with your code but one way of doing it would be to put the focus into a function.
So ...
function focusIt()
{
var mytext = document.getElementById("divId");
mytext.val("");
mytext.focus();
}
And call it from the if/else statement ...
if (ungueltiges)
{
alert("invalid time");
focusIt()
}

Categories

Resources