So, im completely new to programming. All i know is extremely basic stuff like hello world. Basically, what i want to do is I want be able to pick random words out of a list. I'm not really sure how to do this. Im definitely not asking anyone to write the whole thing for me, I just need a starting point. Right now I'm pretty lost. Thanks in advance.
It does depend on how the list is "made".
If the list can be made by the programmer (thus static and not be altered by the user), you could do the following (copy and paste this into a .html file):
<html>
<button onclick="randomizeFunction()">Randomize!!</button>
<p>Random generated word is:</p>
<p id="randomWord"></p>
</html>
<script>
const myList = ["List item 1", "List item 2", "List item 3", "List item 4", "List item 5"];
randomizeFunction()
function randomizeFunction() {
document.getElementById("randomWord").innerHTML = myList[Math.floor(Math.random() * myList.length)]
}
</script>
Do note, this uses JavaScript as well! Most responsive websites are driven by it nowadays.
Javascript is the part between the script tags. For you to customize, change the items in const myList, between the [ ... ]. Make sure the [ ... ] stay and seperate items with a comma. Also, if you are to use words, make sure to quote them (making them strings), like I did.
By the way, most people don't mind to get their hands dirty and providing you with an example ('write the whole thing').
Keep going, programming is awesome!
You will need javascript for this rather than html.
I created a function for you, called Random Word Picker.
if you want to add javascript to a html page put it between these tags
<script> </script>
let theList = ["hello", "there", "john", "how", "are", "you", "doing"]
function randomWordPicker(aList){
let theListLength = theList.length / 10
let theAnswer = Math.floor( ( Math.random( ) * 10 ) * theListLength )
return aList[theAnswer]
}
let result = randomWordPicker(theList)
document.querySelector("h1").innerHTML = result
console.log(result)
this function will pick a random word from the list and then display it to a h1 tag and to the console.
Related
I've set up a webserver running on ESP8266 thats currently hosting 7 sites. The sites is written in plain HTML in each diffrent tab in the arduino ide. I have installed the library Pagebuilder to help with making everything look nice and run.
Except one thing. I have a button connected to my ESP8266 which by the time being imitates a sensor input. basicly when the button is pressed my integer "x" increments with 1. I also managed to make a string that replicates "x" and increments with the same value.
I also have a problem with Printing the IPadresse of the server, but thats not as important as the other.
My plan then was writing the string "score" (which contains x) into the HTML tab where it should be output. this obviously didnt work.
Things I've tried:
Splitting up the HTML code where I want the string to be printed and using client.println("");
This didnt work because the two libraries does not cooperate and WiFiClient does not find Pagebuilders server. (basicly, the client.println does nothing when I used it with Pagebuilder).
Reconstructing the HTML page as a literal really long string, and adding in the String with x like this: "html"+score+"html" and adding it into where the HTML page const char were. (basicly replacing the variable with the text that were in the variable).
This did neighter work because the argument "PageElement" from Pagebuilder does only expect one string, and errors out because theres an additional string inside the HTML string.
I've tried sending it as a post req. but this did not output the value either.
I have run out of Ideas to try.
//root page
#if defined(ARDUINO_ARCH_ESP8266)
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiClient.h>
#elif defined(ARDUINO_ARCH_ESP32)
#include <WiFi.h>
#include <WebServer.h>
#endif
#include "PageBuilder.h"
#include "currentGame.h" //tab 1
#if defined(ARDUINO_ARCH_ESP8266)
ESP8266WebServer Server;
ESP8266WebServer server;
#endif
int sensorPin = 2; // button input
int sensorValue = 0;
int x = 0; // the int x
String score=""; //the string x will be in
PageElement CURRENT_GAME_ELEMENT(htmlPage1);
PageBuilder CURRENT_GAME("/current-game", {CURRENT_GAME_ELEMENT}); // this //only showes on href /current-game
void button() {
sensorValue = analogRead(sensorPin); //read the voltage
score="Team 1: "+String((int)x+1); //"make" x a string
if (sensorValue <= 10) { // check if button is pressed
x++; // increment x
Serial.println(x);
Serial.println(score);
delay(100);
}
}
void setup() {
Serial.begin(115200);
pinMode(2, INPUT);
WiFi.softAP("SSID", "PASS");
delay(100);
CURRENT_GAME.insert(Server);
Server.begin();
}
void loop() {
Server.handleClient();
button();
}
// tab 1
const char htmlPage1[] PROGMEM = R"=====(
/*
alot of HTML, basicly the whole website...
..............................................
*/
<div class="jumbotron">
<div align="center">
<h1 class="display-4"> score </h1> // <--- this is where
//I want to print the
//string:
</div>
</div>
)=====";
what I want to do is getting the value of the string score displayed on the website. If I put "score" directly into the HTML, the word score will be displayed, not the value. I want the value displayed.
Edit:
I have figured out how to make the string(score) be printed in the HTML code, thus, I only have to convert the HTML code string back to a char. explanation is in comment below.
Edit 2: (-------------------------solution-------------------------)
Many thanks for the help I've gotten and sorry for being so ignorant, its just so hard being so close and that thing doesnt work. but anyways, What I did was following Pagebuilders example, and making another element to print in current game..
String test(PageArgument& args) {
return score;
}
const char html[] = "<div class=\"jumbotron\"><div align=\"center\"><h1 class=\"display-4\">{{NAME}}</h1></div></div>";
PageElement FRAMEWORK_PAGE_ELEMENT(htmlPage0);
PageBuilder FRAMEWORK_PAGE("/", {FRAMEWORK_PAGE_ELEMENT});
PageElement body_elem(html, { {"NAME", test} });
PageElement CURRENT_GAME_ELEMENT(htmlPage1);
PageBuilder CURRENT_GAME("/current-game", { CURRENT_GAME_ELEMENT, body_elem});
suprisingly easy when I first understood it.. Thanks again.
You could try building your string first, then converting it to a const char
like this: const char * c = str.c_str();
if you can't use a pointer you could try this:
string s = "yourHTML" + score + "moreHTML";
int n = s.length();
char char_array[n + 1];
strcpy(char_array, s.c_str());
additionally you could try the stringstream standard library
This sort of thing is often done using magic tags in your markup that are detected by the server code before it serves the HTML and filled in by executing some sort of callback or filling in a variable, or whatever.
So with this in mind and hoping for the best, I nipped over to: PageBuilder on github and looked to see if there was something similar here. Good news! In one of the examples:
const char html[] = "hello <b>{{NAME}}</b>, <br>Good {{DAYTIME}}.";
...
PageElement body_elem(html, { {"NAME", AsName}, {"DAYTIME", AsDayTime} });
Where {{NAME}} and {{DAYTIME}} are magic tokens. AsName and AsDayTime are functions to be called when the respective tag is encountered while the page is being served.
EDIT: in response to a request to explain differently, I'm not convinced I can do a better job of explaining the code than the example on the library's own github page, so I'll try a wordy description instead:
When you want to serve a webpage to a client, the code needs to know what you want to serve. In the simplest case, it's a static page: the same every time. You can just write the HTML, stick it in a string an be done.
whole_page = "<html>My fixed content</html>";
webserver.serve(whole_page);
But you want some dynamic element(s). As noted, you can do it in a few ways, such as serving some static HTML, then the dynamic bit, then some more static HTML. It seems you've not had much luck like this, and it's rather clunky anyway.
Or you can pre-build a new string out of the three bits and serve that in one chunk, but that's also pretty clunky.
(Aside: taking big strings and adding them together is likely to be slow and memory intensive, two things you really don't want on a little CPU like the ESP8266).
So instead, you allow 'magic' markers in the HTML, using a marker in place of the dynamic content, and serve that instead.
whole_page = "<html>My dynamic content. Value is {{my_value}}</html>";
webserver.serve(whole_page, ...);
The clever bit is that as the page is being served, the webserver is watching the text go by, and when it sees a magic tag, it stops and asks you to fill in the blank, then carries on as before.
Obviously, there is some processing overhead with watching for tags, and some programming overhead with telling it what tags to watch for and how to ask you for the data it needs.
I got advice from a friend who told me I should make a unique argument where I wanted the string(x) and then using some syntax to replace it. I also took inspiration from you Jelle..
what I did was make a unique argument "VAR_CURRENT_SCORE" put that into the HTML where I want the score output, then convert htmlPage1 from a char to a string, use string.replace() and replace "VAR_CURRENT_SCORE" with the string(x) score. this workes as I can see in the serial monitor output.
This is what I did:
//root page
String HTMLstring(htmlstringPage);
delay(100);
HTMLstring.replace("VAR_CURRENT_SCORE", score);
delay(50);
Serial.println("string:");
Serial.println(HTMLstring);
//tab 1 char htmlstringPage[] PROGMEM = R"=====(
<div class="jumbotron">
<div align="center">
<h1 class="display-4">VAR_CURRENT_SCORE</h1>
</div>
</div>
)=====";
However, I still have a small problem left which is converting the string back to char to post it to the website.
To convert the string back:
request->send_P(200, "text/html", HTMLstring.c_str());
I'm generating a table using xslt, but for this question I'll keep that side out of it, as it relates more to the actual generated structure of a html table.
What I do is make a vertical table as follows, which suits the layout needed for the data concerned that originated in a spreadsheet. Example is contrived for brevity, actual data fields contain lengthy strings and many more fields.
Title: something or rather bla bla
Description: very long desription
Field1: asdfasdfasdfsdfsd
Field2: asdfasfasdfasdfsdfjasdlfksdjaflk
Title: another title
Description: another description
Field1:
Field2: my previous field was blank but this one is not, anyways
etc.
The only way so far I found to generate such a html table is using repeating tags for every field and every record e.g.:
<tr><th>Title</th><td>something or rather bla bla</td></tr>
<tr><th>Description</th><td>very long desription</td></tr>
...
<tr><th>Title</th><td>another title</td></tr>
<tr><th>Description</th><td>another description</td></tr>
...
Of course this is semantically incorrect but produces correct visual layout. I need it to be semantically correct html, as that's the only sane way of later attaching a filtering javascript facility.
The following correct semantically produces an extremely wide table with a single set of field headers on the left:
<tr><th>Title</th><td>something or rather bla bla</td><td>another title</td></tr>
<tr><th>Description</th><td>very long desription</td><td>another description</td></tr>
...
So to summarise, need a html table (or other html structure) where it's one record under another (visually) with repeating field headers, but the field headers must not be repeated in actual code because that would wreck any record based filtering to be added later on.
Yo. Thanks for updating your question, and including some code. Typically you'd also post what you've tried to correct this issue - but I'm satisfied enough with this post.
Since you want the repeating headers in vertical layout (not something I've seen often, but I can understand the desire), you don't have to modify the HTML formatting, just use a bit more JavaScript to figure it out. I haven't gone through and checked to see if I'm doing things efficiently (I'm probably not, since there are so many loops), but in my testing the following can attach to a vertical table and filter using a couple variables to indicate how many rows there are in each entry.
Firstly, here's the HTML I'm testing this one with. Notice I have a div with the id of filters, and each of my filter inputs has a custom attribute named filter that matches the header of the rows they are supposed to filter:
<div id='filters'>
Title: <input filter='Title'><br>
Desc: <input filter='Description'>
</div>
<table>
<tr><th>Title</th><td>abcd</td></tr>
<tr><th>Description</th><td>efgh</td></tr>
<tr><th>Title</th><td>ijkl</td></tr>
<tr><th>Description</th><td>mnop</td></tr>
<tr><th>Title</th><td>ijkl</td></tr>
<tr><th>Description</th><td>mdep</td></tr>
<tr><th>Title</th><td>ijkl</td></tr>
<tr><th>Description</th><td>mnop</td></tr>
<tr><th>Title</th><td>ijkl</td></tr>
<tr><th>Description</th><td>mnop</td></tr>
</table>
Here are the variables I use at the start:
var filterTable = $('table');
var rowsPerEntry = 2;
var totalEntries = filterTable.find('tbody tr').size() / rowsPerEntry;
var currentEntryNumber = 1;
var currentRowInEntry = 0;
And this little loop will add a class for each entry (based on the rowsPerEntry as seen above) to group the rows together (this way all rows for an entry can be selected together with a class selector in jQuery):
filterTable.find('tbody tr').each(function(){
$(this).addClass('entry' + currentEntryNumber);
currentRowInEntry += 1;
if(currentRowInEntry == rowsPerEntry){
currentRowInEntry = 0;
currentEntryNumber += 1;
}
});
And the magic; on keyup for the filters run a loop through the total number of entries, then a nested loop through the filters to determine if that entry does not match either filter's input. If either field for the entry does not match the corresponding filter value, then we add the entry number to our hide array and move along. Once we've determined which entries should be hidden, we can show all of the entries, and hide the specific ones that should be hidden:
$('#filters input').keyup(function(){
var hide = [];
for(var i = 0; i < totalEntries; i++){
var entryNumber = i + 1;
if($.inArray(entryNumber, hide) == -1){
$('#filters input').each(function(){
var val = $(this).val().toLowerCase();
var fHeader = $(this).attr('filter');
var fRow = $('.entry' + entryNumber + ' th:contains(' + fHeader + ')').closest('tr');
if(fRow.find('td').text().toLowerCase().indexOf(val) == -1){
hide.push(entryNumber);
return false;
}
});
}
}
filterTable.find('tbody tr').show();
$.each(hide, function(k, v){
filterTable.find('.entry' + v).hide();
});
});
It's no masterpiece, but I hope it'll get you started down the right path.
Here's a fiddle too: https://jsfiddle.net/bzjyfejc/
Looking for an elegant and quick way to vary/rotate (rotate as in change value, not change orientation) the contents of an html Label (or textbox).
For example, on our website we would like a caption to sometimes say "Our Database Products are Great", other times have it populate with "Helping Small Businesses since 2004" etc. The chosen string can be randomly selected from a set list, but should vary every time the web page is reloaded (ok if the same one comes up more than once in a row).
What would be an easy way to accomplish this? Is there a quick way to do it without Java?
Java is the easy way.
add a div and then update it with text every few seconds.
var text = ["My text 1", "My text 2", "My text 3"];
var value = 0;
var elem = document.getElementById("div id");
setInterval(change, 1000);
function change() {
elem.innerHTML = text[counter];
value++;
if(value >= text.length) { value = 0; }
}
You can simply use JavaScript (if you can rely on your users having JavaScript). Add an id to the HTML element which will store the message, and add the following JavaScript code (replacing randommessage with you id) and adding any other messages to the messages array.
messages = ["Our Database Products are Great", "Helping Small Businesses since 2004", "Some other message"];
document.getElementById("randommessage").innerHTML = messages[Math.floor(Math.random()*messages.length)]
Live JSFiddle example
<html>
<head>
<script>
function myFunction() {
var cars = ["Saab", "Volvo", "BMW"];
var randomCar = cars[Math.floor(Math.random() * cars.length)];
alert(randomCar);
document.getElementById('randomName').innerHTML = randomCar;
}
</script>
</head>
<body onload="myFunction()">
<label id="randomName"></label>
</body>
</html>
I'm pretty new to MVC and I'm having a hard understanding how to get the values (basically the IDs) to checkboxes that I'm generating. Here are my checkboxes:
<div id='myCheckboxDiv'>
<input type="checkbox" onclick="checkAll(this)">Check All
#foreach (var form in #Model.DetailObject.DoaFormGroupDocuments)
{
<br>
var checkBoxId = "chk" + form.DocumentId;
#Html.CheckBox(checkBoxId, new { value = form.DocumentId, #checked = true });
#form.DocumentName;
}
</div>
Essentially what I want to do is get the ID to which ever checkbox is checked and save it in to a list after I click a save button at the bottom of the page.
I have run across something like this to handle everything but I'm not quite sure how to use it really...
var values = $('#myCheckboxDiv').find('input:checkbox:checked').map(function () {
// get the name ..
var nameOfSelectedItem = this.attr('name');
// skip the ‘chk’ part and give me the rest
return nameOfSelectedItem.substr(3);
}).get();
The only thing you need to think about is the value of the name attribute your checkbox(es) will have. The way you're handling it right now, your post body is going to have a fairly randomized collection of chkN-named parameters, where N is some number. The modelbinder will need something similarly named as a parameter to your action method in order to bind the posted values to something useful. That's a tall order for something that will be some what variable (the DocumentId values).
The best option would be to set up your checkboxes, instead, as a collection, which means giving them names chk[0], chk[1], etc. Then in your action you can accept a parameter like List<string> chk, and that will contain a list of all the values that were posted.
I'm reading XML and attaching values to objects in two seperate movieclips. Like this
Map01:
Marker01.name = hello there
Marker01.short = hel
Marker01.value = 12
Map02:
Marker02.name = hello there
Marker02.short = hel
Marker02.value = 99
Now I'm clicking on Marker01 in Map01 and get its name and value. I want to compare its value to that of Marker01 in Map02, using the name, or better yet .short because the names are long and use special characters/spaces. How do I do this? I've pretty much tried everything that seemed logical!
EDIT: sample code for clarification
var marker01:mc_marker = new mc_marker();
marker01.name="hello there";
marker01.short="abc";
marker01.val="99";
marker01.x=10;
marker01.y=10;
this.mc_map01.addChild(marker01);
var marker02:mc_marker = new mc_marker();
marker02.name="hello there";
marker02.short="abc";
marker02.val="20";
marker02.x=10;
marker02.y=10;
this.mc_map02.addChild(marker02);
marker01.addEventListener(MouseEvent.MOUSE_UP, showMarkerInfo);
marker02.addEventListener(MouseEvent.MOUSE_UP, showMarkerInfo);
function showMarkerInfo(event:MouseEvent):void {
txt_ms.text=event.target.short;
txt_mv.text=event.target.val;
if (event.target.short==mc_map02.marker02.short){
txt_mvi.text="here should be the marker02 value";
}
}
You have a typo there. Map02 use Marker1 things.
If its a typo in Stackoverflow,
this.getChildByName( "Marker01" ) will return you the movieclip, buy its name. take care though, as "name" is what it searches for. You used "hello there" when you should put Marker01 as the name. I would suggest you put a property called "data" and put the xml info in it so it doesn't conflict.
In the end you have:
if( this.getChildByName( "Marker01" ).data.value == this.getChildByName( "Marker02" ).data.value ).
I assume this is because you generate Marker0X at runtime and you can't declare some variables and use them directly.
Browny points if you make "data" a instance of a custom class where you can compare two "data". If you need more help, add a comment ^_^