I want to create a text input form on a static page and convert that to an email body using the mailto option. For example, the following with take the input from the text box
<form action="/action_page.php">
First name:<br>
<input type="text" name="firstname" value="Mickey"><br>
Last name:<br>
<input type="text" name="lastname" value="Mouse"><br><br>
<input type="submit" value="Submit">
</form>
and in the email body will display as
Hello ABC,
The details are:
First Name: Mickey
Last Name: Mouse
Thanks,
XYZ
I've taken the time to round up a few answers for you. I hope that you take the time to read through each of the links provided.
First you want to get your form data as an object:
const formToJSON = elements => [].reduce.call(elements, (data, element) => {
data[element.name] = element.value;
return data;
}, {});
I've used destructuring assignment to set defaults for some constants to use in the mailto:
const {
recipientName = "ABC", recipientAddress = "abc#123.yes",
subject = "Some mailz for youz", senderName = "XYZ",
firstname = "first", lastname = "last"
} = formToJSON(document.querySelectorAll("form input:not([type='submit'])"))
We also need some linebreaks in our email body:
const lineBreak = "%0D%0A"
And finally template literals to construct our href for mailto:
const mailTo = `mailto:${recipientAddress}?subject=${subject}&body=Hello ABC,${lineBreak}
I am your father.${lineBreak}${lineBreak}
The details are:${lineBreak}${lineBreak}
First Name: ${firstname}${lineBreak}
Last Name: ${lastname}${lineBreak}${lineBreak}
Thanks,${lineBreak}
${senderName}`
Here's the snippet so you can see it all working together:
const formToJSON = elements => [].reduce.call(elements, (data, element) => {
data[element.name] = element.value;
return data;
}, {});
const {
recipientName = "ABC", recipientAddress = "abc#123.yes",
subject = "Some mailz for youz", senderName = "XYZ",
firstname = "first", lastname = "last"
} = formToJSON(document.querySelectorAll("form input:not([type='submit'])"))
const lineBreak = "%0D%0A"
const mailTo = `mailto:${recipientAddress}?subject=${subject}&body=Hello ABC,${lineBreak}
I am your father.${lineBreak}${lineBreak}
The details are:${lineBreak}${lineBreak}
First Name: ${firstname}${lineBreak}
Last Name: ${lastname}${lineBreak}${lineBreak}
Thanks,${lineBreak}
${senderName}`
const link = document.createElement("a")
link.textContent = "Send some mailz yaaaal"
link.href = mailTo
document.body.appendChild(link)
<form action="/action_page.php">
First name:<br>
<input type="text" name="firstname" value="Mickey"><br>
Last name:<br>
<input type="text" name="lastname" value="Mouse"><br><br>
<input type="submit" value="Submit">
</form>
Related
I need to display some numbers, strings from a class named Student, but i can't figure it out how i can change the id from children element. I have to use JavaScript.
what i tried to do:
class Student{
static count = 0;
constructor(nume, prenume, data_nasterii, foaie_matricola){
this.IdClasa = ++Student.count;
//definirea atributelor
this.nume = nume;
this.prenume = prenume;
this.data_nasterii = data_nasterii;
this.foaie_matricola = foaie_matricola;
}
afiseazaVarsta(){
}
afiseazaNotele(){
}
calculeazaMedia(){
}
adaugaNota(nota_noua){
}
}
var Stud = [new Student("Name", "Name1", "2000.01.01", "0123123"),
new Student("Green", "Blue", "2022/12.12", "321321")];
function afisareStudenti(){
let i = 0; let bol = false;
for(let x=1; x<=Student.count; x++) {
console.log(document.getElementById("AfisareStudenti"+x)==null);
if(document.getElementById("AfisareStudenti"+x)==null)
{
i = x;
bol = true;
break;
} else {
bol = false;
}
}
if((i<=Student.count)&&(bol==true)){
for(i; i<=Student.count; i++) {
console.log("i="+i);
var div = document.querySelector('#AfisareStudenti1');
var divClone = div.cloneNode(true);
console.log(divClone);
divClone.id = 'AfisareStudenti'+(i);
div.after(divClone);
var NumeStud = document.getElementById("NumeStudent"+(i-1));
var PrenumeStud = document.getElementById("PrenumeStudent"+(i-1));
var dataNastStud = document.getElementById("intData"+(i-1));
var FoaiaMatStud = document.getElementById("FoaiaMatStud"+(i-1));
NumeStud.id = "NumeStudent"+(i);
PrenumeStud.id = "PrenumeStud"+(i);
dataNastStud.id = "intData"+(i);
FoaiaMatStud.id = "FoaiaMatStud"+(i);
}
}
}
and this is the html file(the div that i want to clone):
<!--AFISARE-->
<div id="AfisareStudenti1">
<h2> Afisare Student 1</h2>
<label>Ce student doriti sa modificati? </label>
<form>
<label>Nume:</label><br>
<input type="text" id="NumeStudent1"><br>
<label>Prenume:</label><br>
<input type="text" id="PrenumeStudent1"><br>
<label>Data Nasterii:</label><br>
<input type="date" id="intData1"><br>
<label>Foaie matricola:</label><br>
<input type="text" id="FoaiaMatStud1"><br><br>
<input class="butoane" type="submit" value="Afisare"
onclick="afisareMeniuAfisStudenti()">
</form>
</div>
the class is saved in a dynamic array (could be n object of the class) so i have to make somehow to display the information dynamic. My version changes the id from all elements with the same id (every incrementation of i, the idnumber from id is incremented also). I tried to create that div with document.createElement but is impossible(at least for me) xD . I started coding in javascript 2 days ago, so please take it slow on me :(
I think i found the problem, but it doesn't solve it. (i need to put (i-1) when calling for getting the ids). (Newbie mistake)
Having commented ...
"I have the feeling that if provided with the broader picture the audience could be of much more help since the OP could be provided back with leaner/cleaner and better maintainable approaches."
... I nevertheless hereby lately provide a template-based approach which, besides supporting the OP's id based querying of student-items, is also easier to read and to maintain.
The code provided within the example-code's main function does not just implement the usage of the template-based node-creation via template literals and DOMParser.parseFromString but also prevents the default behavior of each student-form's submit-button by making use of event-delegation.
function createStudentElement(studentId) {
const markup =
`<div class="student-item" id="AfisareStudenti${ studentId }">
<h2> Afisare Student ${ studentId }</h2>
<label>Ce student doriti sa modificati? </label>
<form>
<label>Nume:</label><br>
<input type="text" id="NumeStudent${ studentId }"><br>
<label>Prenume:</label><br>
<input type="text" id="PrenumeStudent${ studentId }"><br>
<label>Data Nasterii:</label><br>
<input type="date" id="intData${ studentId }"><br>
<label>Foaie matricola:</label><br>
<input type="text" id="FoaiaMatStud${ studentId }"><br><br>
<input
class="butoane" type="submit" value="Afisare"
onclick="afisareMeniuAfisStudenti(${ studentId })"
>
</form>
</div>`;
const doc = (new DOMParser).parseFromString(markup, 'text/html');
return doc.body.removeChild(doc.body.firstElementChild);
}
// the button click handler.
function afisareMeniuAfisStudenti(studentId) {
console.log({ studentId })
}
function main() {
const itemsRoot = document.querySelector('.student-items');
// - prevent any form-submit by making use of event-delegation.
itemsRoot.addEventListener('submit', evt => evt.preventDefault());
// - just for demonstration purpose ...
// ... create student-items from a list of student IDs.
[1, 2, 3, 4, 5].forEach(studentId =>
itemsRoot.appendChild(
createStudentElement(studentId)
)
);
}
main();
.as-console-wrapper { left: auto!important; width: 50%; min-height: 100%; }
<div class="student-items"></div>
Tom's answer above is what you want for the element id problem that you asked about.
For your code in particular, you are going to have a couple other problems:
Because the final input is type="submit", its going to reload the page by default when it is clicked. The name of the "onclick" function also needs to match the function you defined (afisareStudenti).
You have:
<input class="butoane" type="submit" value="Afisare" onclick="afisareMeniuAfisStudenti()">
Change this to:
<input class="butoane" type="submit" value="Afisare" onclick="afisareStudenti(event)">
Now, when you click that button, it will call the afisareStudenti function and pass in the "event". So if you change:
function afisareStudenti(){
let i = 0; let bol = false;
to:
function afisareStudenti(event){
event.preventDefault()
let i = 0; let bol = false;
This will correctly call your function, and prevent the "default" action of that submit button from reloading the page.
To change the id attribute of children elements, you could use Element.querySelector() on divClone.
Because if you use Document.querySelector() or Document.getElementById() you will get the first element that matches your selector (i.e.children of div#AfisareStudenti1).
let i = 2;
var div = document.querySelector('#AfisareStudenti1');
var divClone = div.cloneNode(true);
divClone.id = 'AfisareStudenti'+(i);
divClone.querySelector("h2").innerText = "Afisare Student " + i;
var NumeStud = divClone.querySelector("#NumeStudent1");
var PrenumeStud = divClone.querySelector("#PrenumeStudent1");
var dataNastStud = divClone.querySelector("#intData1");
var FoaiaMatStud = divClone.querySelector("#FoaiaMatStud1");
NumeStud.id = "NumeStudent"+(i);
PrenumeStud.id = "PrenumeStud"+(i);
dataNastStud.id = "intData"+(i);
FoaiaMatStud.id = "FoaiaMatStud"+(i);
div.after(divClone);
<div id="AfisareStudenti1">
<h2> Afisare Student 1</h2>
<label>Ce student doriti sa modificati? </label>
<form>
<label>Nume:</label><br>
<input type="text" id="NumeStudent1" /><br>
<label>Prenume:</label><br>
<input type="text" id="PrenumeStudent1" /><br>
<label>Data Nasterii:</label><br>
<input type="date" id="intData1" /><br>
<label>Foaie matricola:</label><br>
<input type="text" id="FoaiaMatStud1" /><br><br>
<input class="butoane" type="submit" value="Afisare" onclick="afisareMeniuAfisStudenti()" />
</form>
</div>
I want to make a form that contains a filed. Value of field will replace a string between double bracket in the template. here example :
first, I type value in field with id "username".
second, the string between <textarea></textarea> with double bracket {{username}} (which is It has been around since it was loaded) will replace by value that I type in first form.
I try the same thing like this but it's not work with my case.
Here's a way how you could do it:
const textarea = document.querySelector('textarea');
const inputs = [...document.querySelectorAll('input[id]')];
const template = textarea.value;
function update() {
textarea.value = inputs.reduce((acc, i) => acc.replace(new RegExp(`\\{\\{\\s*${i.id}\\s*\\}\\}`, 'g'), i.value), template);
}
inputs.forEach(e => e.addEventListener('input', update));
update();
<label for="username">Username:</label>
<input id="username" />
<br />
<label for="age">Age:</label>
<input id="age" />
<br /><br />
<textarea readonly="readonly">user: {{username}} age: {{age}}</textarea>
Alternatively,
Split template from the result, this way you can define the template and update the username or any other fields without needing to go through it and fix after you entered first char which is what will happen if the template is ever predefined.
// define fields
let fields = {
'username': document.querySelector('input[name="username"]'),
'when': document.querySelector('input[name="when"]')
}
// working textareas
const template = document.querySelector('textarea[name="template"]');
const textarea = document.querySelector('textarea[name="template-rendered"]');
// get fields values and render into textarea value
function renderTemplate() {
let vars = {}
for (let field in fields)
if (fields[field].value) vars[field] = fields[field].value
textarea.value = template.value.replace(/\{{[ ]{0,}([\w\_-]{1,})[ ]{0,}}}/gi, function(...match) {
return typeof vars[match[1]] !== 'undefined' ? vars[match[1]] : `{{ ${match[1]} }}`
})
}
// template update event
template.addEventListener('input', renderTemplate);
// attach input events
for (let field in fields)
fields[field].addEventListener('input', renderTemplate);
div {
margin-bottom: 10px;
}
textarea {
height: 50px;
width: 100%
}
<div>
<label for="username">Username:</label>
<input name="username" />
</div>
<div>
<label for="when">When:</label>
<input id="when" name="when" />
</div>
<div>
<label for="username">Template:</label>
<textarea id="template" name="template">Hello {{ username }}, how are you {{ when }}?</textarea>
</div>
<div>
<label for="result">Result:</label>
<textarea id="result" name="template-rendered"></textarea>
</div>
after a few tries finally.
function myFunction(value) {
String.prototype.replaceAt = function(index,index2, replacement,awal) {
return this.substr(awal.length-index, index+2) + replacement + this.substr(index2);
}
var p=document.getElementById("p");
var str = p.value;
var index1 = str.indexOf("{{");
var index2 = str.indexOf("}}");
var awalan=str.split('{{')[0];
p.value=(str.replaceAt(index1,index2, value,awalan));
}
<input onInput="myFunction(this.value)"/>
<br>
<br>
<Textarea id="p">my name is {{username}} im living on earth.</textarea>
I am having a problem with regex and some if statements . I have classic form with "name" , "lastName" and "email".
I am using simple validation with these if statements
function addTask(e) {
const filter = /^([a-zA-Z0-9_\-\.]+)#([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/;
const filterName = /[a-zA-Z]/
if (!filter.test(email2.value)) {
alert('please enter valid mail')
}
if (!filterName.test(lastName.value)) {
showError('Please check your last name');
}
if (!filterName.test(yourName.value)) {
showError('Please check your name');
} else {
save(yourName.value, lastName.value, email2.value, text.value);
const div = document.createElement('div');
div.className = "testimonial";
const div2 = document.createElement('div');
div2.className = "pic";
div.appendChild(div2);
const img = document.createElement('img');
img.src = "tormund.png";
div2.appendChild(img);
const p = document.createElement('p');
p.className = "description";
p.appendChild(document.createTextNode(text.value));
div.appendChild(p);
const h3 = document.createElement('h3');
h3.className = "title";
h3.appendChild(document.createTextNode(yourName.value));
div.appendChild(h3);
cards.appendChild(div);
}
e.preventDefault();
}
<input id="name" type="text" name="field1" placeholder="Name*" >
<input id="lastName" type="text" name="field2" placeholder="Last name*">
<input id="emailRev" type="email" name="field3" placeholder="Email *">
name and email if statements works perfectly ,they wont go straight to "else statement" and they stop running the function right away, but when it comes to last name, code continues directly to "else" and execute my card creation.
Also to mention, regex should be only text for both input fields. Does anyone knows where i get this wrong?
How I can get value from input and store it to the object?
When button is clicked value from the input - should to be stored in the object.
Thank you a lot in advance
var testObject = { 'name': nameOfbook.value,
'author': nameOfauthor.value,
'year': year.value
};
console.log(testObject);
<input type="text" id="nameOfbook" required="" placeholder="Book name" />
<input type="text" id="nameOfauthor" required="" placeholder="Athor name" />
<input type="text" id="year" required="" placeholder="Add year" />
<button id="addder" type="button">StoreEmail</button>
Here's a working JSfiddle for you.
The relevant JS code is here. Using the id tags on your html elements, I got all of the elements and stored them into variables. Next, I added an event listener on your button, and on click, I push the relevant value of each element into your testObject.
var testObject = [];
const button = document.getElementById("addder");
const name = document.getElementById("nameOfbook");
const author = document.getElementById("nameOfauthor");
const year = document.getElementById("year");
button.addEventListener("click", function() {
testObject.push({
name: name.value,
author: author.value,
year: year.value
})
console.log(testObject)
})
https://jsfiddle.net/991jqomq/
Here's how I did it
HTML:
<form id="new-post">
<label for="post-title">Title:</label>
<input id="post-title" type="text" />
<label for="post-body">Body:</label>
<textarea id="post-body"></textarea>
<button>Post</button>
</form>
JS:
document.getElementById("new-post").addEventListener("submit", function(e) {
e.preventDefault()
const postTitle = document.getElementById("post-title").value
const postBody = document.getElementById("post-body").value
const data = {
title: postTitle,
body: postBody
}
console.log(data)
})
This includes a sample code from a previous question "IndexedDB Fuzzy Search".
How can I bound the cursor result to a input box to create a auto-complete effect and fill multiple input boxes of a form with the different values from the objectStore when a result is chosen? I would like to do this without any libraries.
The HTML input boxes.
<input name="name" id="name"> //search by name, when a name is selected the last name and age are automatically attached to the other input boxes
<input name="lastname" id="lastname">
<input name="age" id="age">
The Javascript.
var result = [];
db.transaction(['table'], IDBTransaction.READ_ONLY)
.objectStore('table')
.openCursor(
IDBKeyRange.bound(searchTerm, searchTerm + '\uffff'),
IDBCursor.PREV)
.onsuccess = function (e) {
e || (e = event);
var cursor = e.target.result;
if (cursor) {
result.push([cursor.value.column1, cursor.value.sortcolumn]);
cursor.continue();
} else {
if (result.length) {
result.sort(function (a, b) {
return a[1] - b[2];
});
}
// Process code here
}
};
Well, in your case you might only want the first result that cursor return, so you just need to check is there a result returned, something like this:
<input name="name" id="name">
<input name="lastname" id="lastname">
<input name="age" id="age">
<script>
document.getElementById('name').oninput = function () {
var searchTerm = this.value;
var result = [];
db.transaction(['table'], IDBTransaction.READ_ONLY)
.objectStore('table')
.openCursor(
IDBKeyRange.bound(searchTerm, searchTerm + '\uffff'), // The important part
IDBCursor.PREV)
.onsuccess = function (e) {
e || (e = event);
var cursor = e.target.result;
if (cursor) {
// Here I assume that your table with 'lastname' and 'age'
// Return result to "lastname" input
document.getElementById('lastname').value = cursor.value.lastname;
// Return result to "age" input
document.getElementById('lastname').value = cursor.value.age;
}
};
}
</script>
Ok, so I know it's bad form to post links here as answers, but I did an article on this at HTML5Rocks. It's too long for me to cut and paste in here, but I think it's exactly what you want. http://www.html5rocks.com/en/tutorials/indexeddb/uidatabinding/