I'm trying to create a simple web page in JavaScript, HTML, and CSS. The web page generates 5 div elements. Each div element includes a random number, text input, and submit button. My code below does that.
The user then should be able to enter the random number into the text input box and click the submit button. The script should check if they entered the correct answer or not.
I'm not sure if this is possible? I understand how to write the code for just a single form on the page but this example is using 5 forms on a single page that are dynamically generated. Any help would greatly be appreciated.
<html>
<head>
<style type="text/css">
#test {
width:250px;
padding:10px;
border:5px solid gray;
margin:10px;
}
</style>
</head>
<body>
<script>
for (i = 0; i < 5; i++) {
document.write('<div id="test">');
var ranNum = Math.floor(Math.random()*10);
document.write(ranNum);
document.write("<p>Enter the number above:</p>");
document.write("<form id=\"form1\" name=\"form1\" method=\"post\" action=\"\"><input type=\"text\" name=\"answer\" id=\"answer\" /><input type=\"submit\" name=\"button\" id=\"button\" value=\"Submit\" /></form>");
document.write('</div>');
}
</script>
</body>
</html>
You don't even interact with the server to check if it was the correct answer.
So, yes, you can easily do that.
Use jquery, make those numbers properties to a global object, properties named after #id of your inputs, so when user clicks, just compare the value of input with the property of your global object with the same name.
eg:
window.myObject = {}
myObject.div1 = // your code for random number
myObject.div2 = // again, code for random number
And so on, even better put your random number code into a function and call
it for each property.
then just set the divs values as properties:
$("div.div1").append("<span class='value'>" + myObject.div1 + "</span>");
Or maybe even you could create a loop to do it so you don't need to type it for all divs.
After that, test your inputs:
$("div.div1").find("submit").click(function(){
// here you collect the data from your form, lazy to type
// and test it for equality with coresponding myObject.div1
// or with the value in <span class="value>
//e.g.
if ($(this).parent().find(".mytextinput").val() == $(this).parent().find("span.value").val())
{ //do something} else {//do something else }
});
Of course, this presumes you can use jquery.
as has been pointed out in the comments, make sure id's are always unique. I wouldn't use ajax for something this simple, you can check the values client side. See below for a working solution.
for (i = 0; i < 5; i++) {
document.write('<div id="div-' + i + '">');
var ranNum = Math.floor(Math.random()*10);
document.write(ranNum);
document.write("<p>Enter the number above:</p>");
document.write("<form id=\"form-" + i + "\" name=\"form-" + i + "\"><input type=\"text\" name=\"answer\" id=\"answer-" + i + "\" /><input type=\"submit\" name=\"button\" id=\"button-" + i + "\" value=\"Submit\" onclick=\"checkAnswer(this); return false;\"/></form>");
document.write('</div>');
}
function checkAnswer(element) {
var thisAnswer=element.form.parentElement.textContent.substring(0,1);
var answerGiven=element.form.children[0].value;
if (thisAnswer==answerGiven) {
alert("correct!");
} else {
alert("wrong!");
}
}
Related
I have an old asp page that had a small image that could be clicked to change some selected text in a form text input box to italics using javascript. This was working fine for many years, but a user just informed me that it no longer seems to be working. In looking around for a solution, it seems the createRange() function is no longer supported by many current browsers, causing the browser to throw an error, and getSelection() should now be used instead.
The old script is listed below.
<script type="text/javascript">
var j; // this is the currently selected form element i.e., line number
function getelement_num(k) {
j = k;
return;
}
function format_sel(v) {
var str = document.selection.createRange().text;
document.form1.strMessage.focus();
var sel = document.selection.createRange();
sel.text = "[" + v + "]" + str + "[/" + v + "]";
return;
}
</script>
I have modified the format_sel function as follows:
function format_sel(v) {
var str = window.getSelection().toString;
document.FrontPage_Form2.elements[j].focus();
var sel = window.getSelection().toString;
sel.text = "<" + v + ">" + str + "</" + v + ">";
return;
}
So, the getSelection() seems to be working fine. If I alert(sel), it returns the selected text. However, the sel.text portion is not replacing the selected text in the input field of the form.
My question is, how should I modify the code above so that the selected text in the form input field will be replaced with the modified text as found in sel.text?
Pertinent HTML code (with only 1 of 9 form fields shown for brevity):
<a title="Select text in fields below and then click this button to add Italics" href="#" onclick="format_sel('i');" ><img alt="Select text in fields below and then click this button to add Italics" border="0" src="images/italic.gif" width="21" height="19" align="middle" class="style33" /></a>
<input name="Title" id="Title" type="text" placeholder="Add Title" style="border: 1px solid #B5DB38; width: 250px" onfocus="lastFocus=this; getelement_num('0');" onselect="storeCaret(this);" onclick="storeCaret(this);" onkeyup="storeCaret(this);" /></td>
I should note that I also have code that will insert special characters into the form as well, which is what the storeCaret code is for. That seems to work fine.
Many thanks for the assistance.
There seem to be two types of problem with this code.
The first one is that if you want to get the string value of the selection, you should use toString() instead of toString. Using the latter will give you a reference to the function toString instead of the returned value. I don't know what your alert function is calling, but it doesn't seem correct.
The second problem is that your sel variable is currently a function, and even if you did it correctly (using toString()) you would get a string which has no .text attribute. What you should be calling there is actually
var sel = window.getSelection();
So that you get a reference to the Html Element, which does have the .text attribute.
Ok, in searching around a little bit, I found some code that seems to work. I modified it slightly for my own purposes (see below), but the original code by Er. Anurag Jain can be found here: https://stackoverflow.com/a/11170137/2121627.
Many thanks as well to #user2121627 for their suggestions on amending and testing the code.
<script type="text/javascript">
var j; // this is the currently selected form element i.e, line number
function getelement_num(k) {
j = k;
return;
}
function format_sel(v) {
var elem = document.FrontPage_Form2.elements[j];
var start = elem.selectionStart;
var end = elem.selectionEnd;
var len = elem.value.length;
var sel_txt = elem.value.substring(start, end);
if (sel_txt != "") {
document.FrontPage_Form2.elements[j].focus();
var replace = "<" + v + ">" + sel_txt + "</" + v + ">";
elem.value = elem.value.substring(0, start) + replace + elem.value.substring(end, len);
}
}
</script>
Here is a jsfiddle for those interested: https://jsfiddle.net/jwfetz/kzcywvnh/42/
What I have is a page which is gathering a large list of data via jQuery. I am trying to limit the amount of results shown to a variable, and change the results shown on the list to create a false-page effect. Everything works via the same JS function, and relies on 1 variable to make everything work. Simple. I've removed all of the extra code to simplify everything
function myFunction() { var page = 1; console.log(page); }
I am looking for a way to call on this function, but change the variable 'page' from within html. Something along the lines of:
2
I have been looking on google (and still am) I just can't seem to find what I am looking for. I'm trying to avoid multiple pages/refreshing as this element is going to be used for a larger project on the same page.
UPDATE: I managed to pass the intended values through to a JS function like so...
function myFunction(page) { console.log(page); }
...and...
<input type='button' onclick='myFunction(value)' value='input page number'>
This seems the simplest way of doing what I need, what do you think?
Thanks for your help btw guys.
To do this you will need to move the page variable to be a parameter of myFunction
function myFunction(page) { console.log(page); }
Then you can just pass in whatever page number you would like
2
Sure, you can add the data-url attribute to your markup and select on the .link class to fetch the data-url attribute for each element thats part of that class.
I'm trying to avoid multiple pages/refreshing as this element is going
to be used for a larger project on the same page.
Sounds like you also want an AJAX solution.
$(document).ready( function()
{
//Add this on your call.html page
$(".link").click(function()
{
//location of test JSON file
var root = 'https://jsonplaceholder.typicode.com';
//your custom attribute acting as your 'variable'
var page = $(this).attr('data-url');
console.log("page = " + page);
//remove any previous html from the modal
$(".modal-content").empty();
//send a request to the server to retrieve your pages
$.ajax(
{
method: "GET",
//this should be updated with location of file
url: root + '/posts/' + page,
//if server request to get page was successful
success: function(result)
{
console.log(result);
var res = result;
var content = "<div class='panel-default'><div class='panel-heading'><h3 class='panel-title'>" + res.title + "</h3></div><i><div class='panel-body'>''" + res.body + "''</i></div><p><u> Master Yoda, (2017)</u></p><p class='page'> Page: " + page + "</p></div>";
$(".modal-content").html(content);
},
//otherwise do this
error: function(result)
{
$(".modal-content").html("<div class='error'><span><b> Failed to retrieve data </b></span><p> try again later </p></div>");
}
});
});
});
.error
{
border: 2px dotted red;
margin: 5px;
}
a
{
font-size: 20px;
}
.page
{
text-align: left;
padding: 0 15px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/js/bootstrap.min.js"></script>
<a class="link" data-url="1" data-toggle="modal" data-target="#Modal" href="test.html">Show Page 1</a>
<br />
<a class="link" data-url="2" data-toggle="modal" data-target="#Modal" href="">Show Page 2</a>
<div id="Modal" class="modal fade text-center">
<div class="modal-dialog">
<div class="modal-content">
</div>
</div>
</div>
I seem to have figured out how to do this. I wanted to stray from using lots of libraries in the project and just wanted to keep things simple, using the above answers for guidance (and a little more digging), basically my end goal was to use jQuery to obtain a long list of data, and format this data into a multiple page list (for which I used a table for formatting purposes). Let's say it's a list of names. The JSON results output as:
[{"first_name":"Bob"},{"last_name":"Jones"}] // (key, value)
But when I passed this through to the HTML Table it was just displaying 1000s of results in a single list, and formatting the list was a pain. This was my solution:
<script>
var pageNum = ""; // define Page Number variable for later.
var resLimit = 35; // variable to specify the number of results per page
function updateList () {
$.getJSON(" Location of JSON results ", function(data) {
var pageCount = Math.round(data.length/resLimit); // calculate number of pages
var auto_id = ((pageNum-1)*resLimit) // use variables to give each result an id
var newListData = ""; // define this for use later
then define and pass "new list data" to HTML Table:
var newListData = "";
$.each(data.slice(auto_id, (pageNum*resLimit)), function(key, value) {
auto_id++;
newListData += '<tr>';
newListData += '<td class="id">' + audo_id + '</td>';
newListData += '<td class="id">' + value.first_name + '</td>';
newListData += '<td class="id">' + value.last_name + '</td>';
newListData += '</tr>';
});
$('# ID of table, data will replace existing rows ').html(newListData);
At this point if you set the value of pageNum to 1 you should see the first 35 results on the list, all with auto-incremented ID numbers. If you change it to 2 and refresh the page you should see the next 35, with the ID numbers following on from the first page.
Next I needed to create a button for each of the pages:
$('# ID of table, data will replace existing rows ').html(newListData);
function createButtons() {
var buttonArray = "";
for(i=0, x=pageCount; i<x; i++) {
buttonArray += '<input type="button" onclick="changePage('
+ (i + 1) + ')" value="' + (i + 1) + '">';
}
$('# ID of Span tags for button container ').html(buttonArray); }
createButtons();
}); }
</script>
Then create changePage() and a function to refresh the data in the list automatically without messing things up
<script>
var pageNum = "";
function changePage(page) {
if (pageNum < 1) { pageNum = 1; } // set pageNum when the page loads
if (page > 0) { pageNum = page; } // overwrite pageNum when 'page' variable is defined
updateList(); }
changePage(); // initialise to prevent delayed display on page load
// refresh function:
function refreshData() {
changePage(0); // define 'page' as 0 so that pageNum is not overwritten
window.setTimeout(refreshData, 5000); } // loop this function every 5 seconds to
refreshData(); //-- keep this list populated with current data.
And that should just about do it! At least it's working for me but I might have missed something (hopefully not lol). Hope this helps someone theres quite a few things involved in this that could be extrapolated and used elsewhere :)
thanks for help everyone.
I am trying to create code that when you press a button, it will change the value of a variable and replace some text.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<p id="unitts">You have 0 unitts</p>
<script type="text/javascript">
var unitt = 0;
function unittIncrease() {
var unittPrev = unitt;
unitt++;
document.getElementById(unitts).innerHTML.replace("You have " + unittPrev.toString() + " unitts.", "You have " + unitt.toString() + " unitts.");
}
</script>
<button id="unittIncrease" onclick="unittIncrease();">Digitize Unitt</button>
</body>
</html>
When I press the button, nothing happens to the text.
I don't know why this does not work.
Please help me!
EDIT: I am only 11 years old,
please don't throw your wizard
code at me.
maybe you should remove your button system and add a while loop that
automatically add a unit but waits one second with a setInterval
function
I think you should write the js code like this
document.getElementById('unitts').innerHTML = "You have"....
Instead of:
document.getElementById(unitts).innerHTML.replace("...")
Your JavaScript should be (note the unitts wrapped in quotes and the full stop removed):
document.getElementById('unitts').innerHTML = "You have " + unitt + " unitts";
Instead of:
document.getElementById(unitts).innerHTML.replace("You have " + unittPrev.toString() + " unitts.", "You have " + unitt.toString() + " unitts.");
In the latter, it is looking for the non-existent variable unitts instead of the string 'unitts'. Also, you are looking for the text You have x unitts. which cannot be found because in your HTML, it is just You have x unitts without the full stop.
Edit
See this plnkr.
Apart from the issues that the other answer mentions, by calling .replace method on the .innerHTML property of the element, the content of it doesn't change. You should reset the property by using the returned value of the method call:
el.innerHTML = el.innerHTML.replace(...);
Also, as you are trying to increase a number, instead of replacing all the characters, you can just replace the numeric part:
var unitts = document.getElementById('unitts');
function unittIncrease() {
unitts.textContent = unitts.textContent.replace(/\d+/, function(n) {
return +n + 1;
});
}
https://jsfiddle.net/h6odbosg/
I'm creating my html tags on my Javascript because of some logic, but the expected result is not being displayed. I'm trying to get all checked checkboxes and display their names. I can pull the names and the checked checkboxes. But it is no rendering correctly. Here is my code:
var amenities = <%= #amenities_json.html_safe %>;
var appendAmenitiesAndFeatures= "<p class='p-tab-title3'>Amenities</p><table class='table-amenities-and-features'><tbody><tr>";
for(var i=0; i<amenitiesChecked.length;i++)
{
$.each(amenities, function(index, amenity){
if(amenity.id == amenitiesChecked[i])
{
appendAmenitiesAndFeatures += "<td><p class='p-tab-subtitle2><span> </span>" + amenity.name + "</p></td>";
}
});
}
appendAmenitiesAndFeatures += "</tr></tbody></table>";
$("#dv-amenities-and-features").html(appendAmenitiesAndFeatures);
When I check 3 checkboxes and alert their names, I can see the string of html tags being build properly. I can see 3 sets of tds in my alert. But when the page is being rendered. It only displays one. I really don't know why. I'm appending to a div and build my table using .html. Any ideas?
hum.... You miss a '
replace your line with this:
appendAmenitiesAndFeatures += "<td><p class='p-tab-subtitle2'><span> </span>" + amenity.name + "</p></td>";
Noob question alert! So, I've got this script, which loops through an array and adds a <br> tag to the end of each array item. But i dont know the proper way of displaying this output on my page. Currently, when it loads the <br> tags show up on screen, whereas I want them to render as line-breaks. It is outputting into a <textarea> if that makes a difference. Thanks a bunch.
var outputLinkText = document.getElementById('outputLinkText');
var outputStageOne = "";
for (var i = 0; i < arrayOne.length; i++) {
outputStageOne += (arrayOne[i] + "<br>");
}
if ( 'textContent' in timePlace ) {
outputLinkText.textContent = outputStageOne;
}
else {
outputLinkText.innerText = outputStageOne;
}
<textarea> tags don't support <br> tags (or any other HTML tags) within their contents. They only hold plain text.
You need to add "\n" as the separator instead.
(Strictly, it should be "\r\n" but a "\n" on its own is usually sufficient)
Yes the textarea is a difference, try this :
"\r\n" instead of "<br>"