DRY-ing JS code and hiding input on address bar? - javascript

I've got a script which would pass input of the user onto the completed.html page but here are two problems:
All of the user inputs are displayed on the address bar, i want to hide it but i dont want to use the POST method which will ruin the purpose of my JS script. Is there any way i can hide those inputs without changing the method even if i have to change the JS script?
My JS code is really repetitious, it's repeated 4 times and i want to know a better way of writing it without copy and pasting all over?
index.html
<div id="container">
<header>
<h1>Registration Form</h1>
<hr>
</header>
<article>
<form action="completed.html" method="GET">
<label for="FirstName"><b>First Name:</b></label>
<input name="FirstName" type="text" placeholder="John" required>
<label for="LastName"><b>Last Name:</b></label>
<input name="LastName" type="text" placeholder="Doe" required>
<label for="email"><b>Email:</b></label>
<input name="email" type="text" placeholder="example#mail.com" required>
<label for="password"><b>Password:</b></label>
<input name="password" type="password" placeholder="Password here." required>
<p></p>
<input type="submit" value="Submit">
</form>
</article>
<footer>
Copyright # 2017 Name
</footer>
</div>
completed.html
<div id="container">
<header>
<h1>Registration Completed!</h1>
<hr>
</header>
<article>
<div id="info" style="float: left;">
<p>Thank you for registering on our site! An verification email has been seen to your email address! To make sure we got everything right, we would like you to review the infomation you've put in.</p>
<div id="fn">
Your First Name is:
</div>
<div id="ln">
Your Last Name is:
</div>
<div id="em">
Your email is:
</div>
<div id="pw">
Your password is:
</div>
</div>
</article>
<footer>
Copyright # 2017 Name
</footer>
</div>
<script>
function processForm() {
var ary = location.search.substring(1).split("&");
var fnpart = ary[0].split("=");
frn = unescape(fnpart[1]);
document.getElementById("fn").innerHTML = "<b>Your First Name is:</b>" + "<br>" + frn;
var lnpart = ary[1].split("=");
lsn = unescape(lnpart[1]);
document.getElementById("ln").innerHTML = "<b>Your Last Name is:</b>" + "<br>" + lsn;
var empart = ary[2].split("=");
ema = unescape(empart[1]);
document.getElementById("em").innerHTML = "<b>Your Email is:</b>" + "<br>" + ema;
var pwpart = ary[3].split("=");
psw = unescape(pwpart[1]);
document.getElementById("pw").innerHTML = "<b>Your First Name is:</b>" + "<br>" + psw;
}
processForm();
</script>

You can try with a pattern like below, using the loop index to match the position in the short names/ long names :
But the password shouldn't be visible in the location like it is now !
var names = [['fn', 'First Name'],
['ln', 'Last Name'],
['em', 'Email'],
['pw', 'Password']
]
for (ind in ary){
var part = unescape(ary[ind].split("=")[1]);
document.getElementById(names[ind][0]).innerHTML = "<b>Your "+ names[ind][1] + " is:</b> <br>" + part;
}

To accomplish goal no. 1, you do not need to use attribute action on form. Also you can replace submit button with <input type="button"> and handle click event and call processForm() function.
To be able to call that function, you need to move processForm() declaration into index.html. so you only need one file. You do not need to read any data from query string. Just read input value from DOM element

Related

Use html form input to build URL that the page directs to upon submitting using JavaScript

I am attempting to take user input from an html form and then form a URL from that input that the user is directed to upon submitting the form. Currently, I have the following html form:
<form>
<br />
<div class="form-group">
<label for="cityInput">City</label>
<input type="text" class="form-control" id="cityInput" name="cityInput">
</div>
<div class="form-group">
<label for="stateCodeInput">State Code</label>
<input type="text" class="form-control" id="stateCodeInput" name="stateCodeInput">
</div>
<button type="submit" class="btn btn-primary" name="submitLocation "id="submitLocation" onclick="costOfLivingURL()">Submit</button>
</form>
Then I have the following JavaScript function that is setting values that will make the URL, as well as building the URL:
async function costOfLivingURL() {
let searchedCity = await getCity();
let searchedStateCode = await getStateCode();
var currentCity = document.getElementById('cityInput').value.trim();
var currentStateCode = document.getElementById('stateCodeInput').value.trim();
window.location.href = "https://www.bestplaces.net/cost-of-living/" + currentCity + "-" + currentStateCode + "/" + searchedCity + "-" + searchedStateCode + "/50000";
}
However, when I click on the button, nothing is happening at all.
I am not sure if my redirection is incorrect and I am also not sure if this is the correct way to use input data. If anyone can help me with this, I would greatly appreciate it!

How do I use elements with sequential but different names into an array?

I'm not sure if the title is accurate. I am still getting familiar with jQuery/JavaScript so please feel free to correct my grammar/terms.
Problem: I have a form page that I need to read and validate the user supplied data when the user clicks send. The data I am having trouble with is contact data. The form by default lists two contacts. There is a button which allows the user to add one new contact at a time dynamically to the page. So, my code might need to validate tens or hundreds of contacts on this page. I cannot change the code/format of the form. I can only add Javascript/jQuery to validate the data.
Each contact is set up within a repeat wrapper like this:
<div class="ff-sec-repeat-wrapper">
<div class="ff-item-row">
<div class="ff-col-1 ff-label-col">LABELS&STUFF</div>
<div class="ff-col-2 ff-field-col">
<input type="textbox"
id="Membership_Application__c.Contact.A_1_.FirstName"
placeholder=""
name="Membership_Application__c.Contact.A_1_.FirstName"
vatt="STRING"
class="ff-input-type ff-type-text"
data-maxlengthmessage="Maximum 40 characters"
maxlength="40"
value=""
data-requiredmessage="required"
data-isupsert="false"
data-ishidden="false"
data-vatt="STRING">
</div>
</div>
<div class="ff-item-row">
<div class="ff-col-1 ff-label-col">LAST_NAME_STUFF_SAME_FORMAT_AS ABOVE</div>
<div class="ff-col-2 ff-label-col">...</div>
</div>
<div class="ff-item-row">
<div class="ff-col-1 ff-label-col">EMAIL_STUFF_SAME_FORMAT_AS_ABOVE</div>
<div class="ff-col-2 ff-field-col">
<input type="textbox"
id="Membership_Application__c.Contact.A_1_.Email"
placeholder=""
name="Membership_Application__c.Contact.A_1_.Email"
vatt="EMAIL"
class="ff-input-type ff-type-text"
data-maxlengthmessage="Maximum 80 characters"
maxlength="80"
value=""
data-requiredmessage="required"
data-isupsert="false"
data-ishidden="false"
data-vatt="EMAIL">
</div>
</div>
</div>
<div class="ff-sec-repeat-wrapper">
<div class="ff-item-row">
<div class="ff-col-1 ff-label-col">LABELS&STUFF</div>
<div class="ff-col-2 ff-field-col">
<input type="textbox"
id="Membership_Application__c.Contact.A_2_.FirstName"
placeholder=""
name="Membership_Application__c.Contact.A_2_.FirstName"
vatt="STRING"
class="ff-input-type ff-type-text"
data-maxlengthmessage="Maximum 40 characters"
maxlength="40"
value=""
data-requiredmessage="required"
data-isupsert="false"
data-ishidden="false"
data-vatt="STRING">
</div>
</div>
<div class="ff-item-row">
<div class="ff-col-1 ff-label-col">LAST_NAME_STUFF_SAME_FORMAT_AS ABOVE</div>
<div class="ff-col-2 ff-label-col">...</div>
</div>
<div class="ff-item-row">
<div class="ff-col-1 ff-label-col">EMAIL_STUFF_SAME_FORMAT_AS_ABOVE</div>
<div class="ff-col-2 ff-field-col">
<input type="textbox"
id="Membership_Application__c.Contact.A_2_.Email"
placeholder=""
name="Membership_Application__c.Contact.A_2_.Email"
vatt="EMAIL"
class="ff-input-type ff-type-text"
data-maxlengthmessage="Maximum 80 characters"
maxlength="80"
value=""
data-requiredmessage="required"
data-isupsert="false"
data-ishidden="false"
data-vatt="EMAIL">
</div>
</div>
</div>
Above is the basic setup. Each repeat wrapper contains multiple rows with different contact's data. There are many fields for each contact, such as LastName, EmailAddress, ContactRole, etc. But I suspect that once I understand how to access one, the others will essentially be accessed the same way.
Importantly (I believe): Each new contact id is sequentially iterated with a Alpha_Number_ combination. So, above, the first contact's FirstName id is Application__c.Contact.A_1_.FirstName, while the eigth contact's would be Application__c.Contact.A_8_.FirstName. This number changes for all other contact fields like LastName and EmailAddress.
At a minimum, how can I retrieve all of the contacts' email addresses into an array? This will allow me to do things like check for duplicate email address and match the supplied email addresses to other data I can already retrieve.
So, you're trying to figure out how to validate something like the following, without manually writing validation for "contact 1, contact 2, ..., contact 8", etc?
Using querySelectorAll will be your friend here. We can use it to grab all of your repeat wrappers and add them to an array, and then you can loop through that array to validate.
Here's a simple example. For demonstration purposes, it will kick out the phony name and add the two valid names to an object. Of course, you'll replace this with your own validation and whatever you do from there. I think effectively what you're looking is a way to loop through an indeterminate amount of fields; which
querySelectorAll
and a simple loop:
for( i = START; i <= NUM_OF_ITEMS; i++ ){
Will make simple work of. Check out the following snippet:
// Run this code when #myform is submitted
document.querySelector('#myform').addEventListener("submit", function(e){
e.preventDefault(); // Prevent page load for demo purposes
var object = {},
valid = 0;
// Grab an array of all the repeat-wrapper fields
var fields = document.querySelectorAll('.ff-sec-repeat-wrapper');
// Loop through that array, it will stop when total # of `repeat-wrappers` has been reached
for( i = 1; i <= fields.length; i++ ){
// The "magic" here is the '+ i +', which is replaced with the current iteration number
// Since i will never be greater than fields.length, it will only run as much as long as needed
FirstName = document.getElementById('Membership_Application__c.Contact.A_'+ i +'_.FirstName').value;
LastName = document.getElementById('Membership_Application__c.Contact.A_'+ i +'_.LastName').value;
//Example Fields:
//Email = document.getElementById('Membership_Application__c.Contact.A_'+ i +'_.Email').value;
//SomeField = document.getElementById('Membership_Application__c.Contact.A_'+ i +'_.SomeField').value;
contact = []; // For demo purposes we're making an associative array of valid contacts
// Put your validation here
// Demo validation will only kick out the fake name "Foo Bar"
if( FirstName != 'Foo' ) contact.push( FirstName );
if( LastName != 'Bar' ) contact.push( LastName );
// If contact is valid, add it to our object
if( contact.length > 0 ) object[valid++] = contact;
}
console.log( object ); // Will contain 0:John, 1:Jane - having skipped `Foo` for not meeting out validation
});
<form id="myform">
<div class="ff-sec-repeat-wrapper">
<div class="ff-item-row">
<div class="ff-col-2 ff-field-col">First
<input type="text" id="Membership_Application__c.Contact.A_1_.FirstName" value="John"/>
</div>
<div class="ff-col-2 ff-field-col">Last
<input type="text" id="Membership_Application__c.Contact.A_1_.LastName" value="Doe" />
</div>
</div>
</div>
<div class="ff-sec-repeat-wrapper">
<div class="ff-item-row">
<div class="ff-col-2 ff-field-col">First
<input type="text" id="Membership_Application__c.Contact.A_2_.FirstName" value="Foo" />
</div>
<div class="ff-col-2 ff-field-col">Last
<input type="text" id="Membership_Application__c.Contact.A_2_.LastName" value="Bar" />
</div>
</div>
</div>
<div class="ff-sec-repeat-wrapper">
<div class="ff-item-row">
<div class="ff-col-2 ff-field-col">First
<input type="text" id="Membership_Application__c.Contact.A_3_.FirstName" value="Jane" />
</div>
<div class="ff-col-2 ff-field-col">Last
<input type="text" id="Membership_Application__c.Contact.A_3_.LastName" value="Smith" />
</div>
</div>
</div>
<input type="submit" />
</form>

Save html form as html file with submitted values

First I'd like to say I read the answers to similar questions including this how to save the content of html form as .html page but that did not solve my problem.
I'm building a reporting system that allows users to use templates to create reports. These templates are html forms and can be developed my any external application or manually. What my application does is, it imports these templates and presents them to the user when he is creating his reports and I want to save the submitted report as as an html file with all the values the user selected, be it text fields or checkboxes.
The above answer suggests using $('#myForm').html(). What this does is get the html of the form but does not include any values entered by the user. How can I achieve this?
Update
I'd like to say this templates are developed by an external application and could have any structure depending on what the user is reporting. So I don't know of any id or name attribute of any of the form inputs used by the creator of the form. The only think I know of is that all the forms are always in a
<div id="reportTemplate"></div>
so that's the only thing I can access with javascript.
Javascript
function CreateHtml(){
var field1 = $("#field1").val();
var field2 = $("#field2").val();
var fieldn = $("#fieldn").val();
var form = $("#myForm").clone();
$(form).find("#field1").val(field1);
$(form).find("#field2").val(field2);
$(form).find("#fieldn").val(fieldn);
$('#btn_download').attr('download', 'sampleFile.html');
$('#btn_download').attr('href', 'data:text/html,' + form);
$('#btn_download').show();
}
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div>
<input placeholder="field1" id="field1" type="text" />
<br/>
<input placeholder="field2" id="field2" type="text" />
<br/>
<button type="button" onclick="CreateHtml();">Submit</button>
<br>
<a href="" id="btn_download" hidden>Download</a>
</div>
You can wrap the html content in a variable and export it using anchor tag like below.
function CreateHtml() {
var htmlContent = "";
htmlContent = "<h1>Name - " + $('#name').val() + "</h1><br>" +
"<p>Email - " + $('#email').val() + "</p>";
$('#btn_download').attr('download', 'sampleFile.html');
$('#btn_download').attr('href', 'data:text/html,' + htmlContent);
$('#btn_download').show();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div>
<input placeholder="Name" id="name" type="text" />
<br/>
<input placeholder="Email" id="email" type="text" />
<br/>
<button type="button" onclick="CreateHtml();">Submit</button>
<br>
<a href="" id="btn_download" hidden>Download</a>
</div>
Updated:
function CreateHtml() {
var htmlContent = TraverseThroughReport();
$('#btn_download').attr('download', 'sampleFile.html');
$('#btn_download').attr('href', 'data:text/html,' + htmlContent);
$('#btn_download').show();
}
function TraverseThroughReport() {
var elements = document.getElementById("report").elements;
var htmlContent = "";
for (var i = 0, element; element = elements[i++];) {
if (element.type === "text")
//console.log("it's an empty textfield")
htmlContent = "<h1>" + element.value + "</h1>";
}
//You can add as many conditions for placeholder etc to detect the form element type
return htmlContent;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div id="report">
<input placeholder="Name" id="name" type="text" />
<br/>
<input placeholder="Email" id="email" type="text" />
<br/>
<button type="button" onclick="CreateHtml();">Submit</button>
<br>
<a href="" id="btn_download" hidden>Download</a>
</div>
If I had asked my question properly or searched for existing questions using "innerHtml with form values" instead of "how to save html for as files" I would have been taken to this link jquery get all form elements: input, textarea & select with already good answers of which this particular one worked for me
$('input:text, input:hidden, input:password').each(function() {
var v=this.value;
$(this).attr("magicmagic_value",v).removeAttr("value").val(v);
});
$('input:checkbox,input:radio').each(function() {
var v=this.checked;
if(v) $(this).attr("magicmagic_checked","checked");
$(this).removeAttr("checked");
if(v) this.checked=true;
});
$('select option').each(function() {
var v=this.selected;
if(v) $(this).attr("magicmagic_selected","selected");
$(this).removeAttr("selected");
if(v) this.selected=true;
});
$('textarea').each(function() {
$(this).html(this.value);
});
var magic=$('form').html().replace(/magicmagic_/g,"");
$('[magicmagic_value]').removeAttr('magicmagic_value');
$('[magicmagic_checked]').attr("checked","checked").
removeAttr('magicmagic_checked');
$('[magicmagic_selected]').attr("selected","selected").
removeAttr('magicmagic_selected');
alert(magic);

Simple jQuery code doesn't work (dealing with Objects)

All right. So I'm coding after A LOOONG TIME, and I just went on to codecademy to get a bit refreshed with javascript. So I learnt something I didn't know before : OOP.
Help. I tried something. Will include the JSfiddle. But I don't know why, it doesn't work.
Nevermind my Idiocy, I will complete the code as soon as I know what the problem in the prev code was. I have alot to do in that. I also want to learn PHP to make a kind of phone directory!
I have also NOT included the CSS, but that hardly matters.
What the code should do, is that everytime a user fills up the form and clicks submit, it should append the values in a '#results' div. Not doing anything. Help?
Also, nevermind the two password fields. I will write the code for validating the form once I am clear with this problem.
THANK YOU IN ADVANCE.
JSFIDDLE : http://jsfiddle.net/Ns66V/1/
HTML -- >
<html>
<head>
<link rel="stylesheet" href='style.css'>
<script type="type/javascript" src='jquery.js'></script>
<script type="type/javascript" src='js.js'></script>
<title>Form JS</title>
</head>
<body>
<div class='container'>
<h1>Create an ID! It's absolutely <strong>FREE!</strong></H1>
<div id='form'><form action='get'>
<input name='fname' type='text' placeholder='First Name'><br>
<input name='lname' type='text' placeholder='Last Name'><br>
<input name='email' type='email' placeholder='Email Address'><br>
<input name='passw' type='password' placeholder='Password'>
<input name='Again' id='last' type='password' placeholder='Again!'><br>
<select name='gender'>
<option value='male'>Male</option>
<option value='female'>Female</option>
<option value='other'>Other</option>
</select>
<div id='submit'><strong>SUBMIT IT!</strong></div>
</form>
</div>
<div class='results'>
<div class='vals' id='intro'>
<div class='srn item'>#</div>
<div class='bigitem item'>FULL NAME</div>
<div class='bigitem item'>EMAIL ADDRESS</div>
<div class='gender item'>Gender</div>
</div>
<div class='vals'>
<div class='srn item'>#</div>
<div class='bigitem item'>FULL NAME</div>
<div class='bigitem item'>EMAIL ADDRESS</div>
<div class='gender item'>Gender</div>
</div>
</div>
</div>
</body>
</html>
JS (JQuery) -->
$(document).ready(function(){
function Person(fname,lname,email,passw,gend){
this.fname = fname;
this.lname = lname;
this.email = email;
this.passw = passw;
this.gend = gend;
};
var numPeople = 0; //Setting the number of people var.
$('#submit').click(function(){
var fname = $('input[name=fname]').val(), //SETS VALUES OF ALL THE INPUTS
lname = $('input[name=lname]').val(), //SETS VALUES OF ALL THE INPUTS
email = $('input[name=email]').val(), //SETS VALUES OF ALL THE INPUTS
passw = $('input[name=passw]').val(), //SETS VALUES OF ALL THE INPUTS
gend = $('select[name=gender]').val(); //SETS VALUES OF ALL THE INPUTS
var People = new Array(); //Definin
numPeople++;
People[numPeople] = new Person(fname,lname,email,passw,gend);
$('.results').append(People[numPeople].fname + People[numPeople].lname + People[numPeople].email + People[numPeople].passw + People[numPeople].gend);
}); //#SUBMIT.CLICK() END
});
OOP isn't entirely needed in this case. The problems is that you need to use #results, and you need to close your button along with other tags.
HTML
<button id='submit' type='button'><strong>SUBMIT IT!</strong></button>
JS
$('#results').append(...);
Here is a Fiddle example, added a <br /> at the end.
Also get and post are for a forms method attribute. action is where the form sends the data. So you probably want:
<form method="get"></form>
Check http://jsfiddle.net/Ns66V/4/
The button tag was not closed and the content was appended to the button and
$('#submit').click(function()
should be replaced with
$('#submit').on('click', function()
Now seems to work.
Of course you should improve how you append the content though - use html tags to separate each information.

Put javascript data into a form

I have the following javascript code:
game.bind('gameover', function(seconds) {
setTimeout(function() {
var rank = game.getRank(seconds);
scorecard.find('.time').text(seconds + ' sec');
scorecard.find('.rank').text(rank[0]);
scorecard.find('.byline').text(rank[1]);
...more code
In the following div this data is displayed (so the js script is working):
<div class="inner">
<h3>Nice job! Your time:</h3>
<h1 class="wobble time"><!-- 15 seconds --></h1>
<h2 class="rank"><!-- Friendly Mallard --></h2>
<h3 class="byline"><!-- (That's pretty good) --></h3>
</div>
Now I want to put the results also in a form so I can post it to the a database (mysql). So I've added a form and put it in the same div:
<form id="form" action="updatescore.php" method="post">
<input type="text" id="time" name="time" value="" />
<input type="text" id="rank" name="rank" value="" />
<input type="text" id="byline" name="byline" value="" />
</form>
Now in the JS I've copied the lines (e.g. scorecard.find('.time').text(seconds + ' sec');) and changed it to look for the id, so . becomes # and passed it in the js like:
scorecard.find('.time').text(seconds + ' sec');
scorecard.find('#time').text(seconds + ' sec');
etc
So this should work I think, but the form inputs stay empty. What am I doing wrong?
Kind regards,
Maurice
If you are just looking to move js variables into your database via updatescore.php you don't need to use a form at all! You can do it with AJAX.
var scoreData = {
time : time,
rank : rank[0],
byline : rank[1]
};
$.post('updatescore.php', scoreData); //done!
Use val() instead of text() for setting the values

Categories