I'm doing an exercise but I can't validate and send a form.
I have this HTML code, to which I cannot add or modify anything:
</head>
<body>
<h1>Card game</h1>
<p>
<label>Displays the name of the participant</label
><input type="text" name="name" />
</p>
<p>
<label>how many games do you want to play? </ tag
><input type="number" name="games" value="0" />
</p>
<button>PARTICIPATE!</button>
<script type="text/javascript" src="rockPaperScissors.js"></script>
</body>
I am trying to validate the form, which should turn the fields red when I hit the participate button and does not meet the validation conditions. Once the data has been corrected and the form has been validated, the fields must be deactivated so that they cannot be written again and remain visual.
I have done this but I don't get my goal:
function validateName() {
const name = document.getElementsByName("name");
const expression1 = /[A-Za-z]{3,}/;
name.click();
if (!expression1.test(name.value)) {
name.classList.add("RedBackground");
false return;
}
return true;
}
function validateGames() {
games.click();
const items = document.getElementsByName("items");
if (games.value <= 0) {
games.classList.add("RedBackground");
false return;
}
return true;
}
// Indicate who launches the events
document
.getElementsByTagName("button")[0]
.addEventListener("click", validateName);
document
.getElementsByTagName("button")[0]
.addEventListener("click", validateGames);
Issue
<input type="text" name="name" />
const name = document.getElementsByName("name");
getElementsByName returns a collection and not a single element.
Possible solution
To get the first element whose name attribute equals name, you have to either get the first index of the collection:
const name = document.getElementsByName("name")[0];
or querySelector which returns the first matching element.
const name = document.querySelector("[name=name]");
Example
document.querySelector("button").addEventListener("click", function(){
//REM: Is everything valid?
let tValid = true;
//REM: Validate "name" using "querySelector"
let tName = document.querySelector("[name=name]");
if(tName){
//REM: Put your logic here
tName.classList.add("RedBackground");
tValid = false
};
//REM: Validate "games" using "getElementsByName"
let tGames = document.getElementsByName("games")[0];
if(tGames){
//REM: Put your logic here
tGames.classList.add("BlueBackground");
tValid = false
};
return tValid
});
.RedBackground{
background-color: crimson
}
.BlueBackground{
background-color: cornflowerblue
}
<h1>Card game</h1>
<p>
<label>Displays the name of the participant</label>
<input type="text" name="name" />
</p>
<p>
<label>how many games do you want to play? </ tag>
<input type="number" name="games" value="0" />
</p>
<button>PARTICIPATE!</button>
I recommend, even if possible, not to reuse the keyword name as variable name.
Related
Want to change submit button color after email verification and checkbox marked. Added listeners on changes and they work well. But have no idea how to find out when this events are going to happen to launch function what is going to change submit button color.
```
https://jsfiddle.net/nvologdins/brfj2xk1/
```
Here is a basic example of how to do this.
I also changed the logic a bit to update the values if the user changes them again. - #Ultimater mentioned this also.
function setupButton() {
if (validEmail && validCheckbox) {
// add/show/enable submit button or simply change the color
button.style.color = "red";
} else {
// remove/hide/disable submit button revert the changes
button.style.color = "";
}
}
form.input.addEventListener('input', (event)=>{
validEmail = emailRegex.test(event.target.value);
setupButton();
})
form.checkbox.addEventListener('change', (event)=>{
validCheckbox = event.target.checked;
setupButton();
})
I would also suggest a different method to validate the form using the Constraint Validation API.
Every element has a validity check which can easily be accessed on the form element using formElement.checkValidity() and returns true/false if all (required) fields inside the form are filled with valid values.
<form oninput="this.querySelector('#submitButton').disabled = !this.checkValidity();" onsubmit="event.preventDefault(); console.log('Submit prevented but the form seems to be valid.'); return false;">
<fieldset>
<label for="newslettermail">E-Mail</label>
<!-- you could also define a more specific pattern on the email input since email would allow foo#bar as valid mail -->
<input type="email" id="newslettermail" required>
</fieldset>
<fieldset>
<input type="checkbox" id="newsletterAcceptTos" required>
<label for="newsletterAcceptTos">I accept the Terms of Service</label>
</fieldset>
<fieldset>
<label for="textFieldWithPattern">Enter <strong>foo</strong> or <strong>bar</strong></label>
<input type="text" id="textFieldWithPattern" pattern="^(foo|bar)$" required>
</fieldset>
<button type="submit" id="submitButton" disabled>Submit</button>
<button type="submit">Force submit (will show errors on invalid input)</button>
</form>
Using this, the browser for itself checks the values if they contain a valid value.
An input[type=email] with required flag must contain a valid mail address.
A checkbox with required flag, must be checked.
An input with required and a pattern must contain a value matching the regular expression from the pattern-attribute.
No need to create extra variables and listen on two form elements separately... You can check the whole thing and update accordingly only by listening to the form element
let form = document.querySelector('form');
let input = document.getElementById('input');
let checkbox = document.getElementById('checkbox');
let submit = document.getElementById('button');
const emailRegex = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
form.addEventListener('change', (event) => {
if (checkbox.checked && emailRegex.test(input.value)) {
submit.style.color = "red";
} else {
submit.style.color = "black"
}
})
//Update
input.addEventListener('input', () => {
const changeEvent = new Event('change');
form.dispatchEvent(changeEvent)
})
<form class="main__emailAndTerms emailAndTerms">
<div class="emailAndTerms__email">
<input type="text" id="input" placeholder="Type your email address here...">
<label class="emailAndTerms__terms">I agree to <span class="terms__link">terms of service</span>
<input type="checkbox" class="terms__checkbox" id="checkbox">
<span class="terms__checkbox_custom"></span>
</label>
<button type="submit" class="email__submitButton" id="button">Submit</button>
</div>
</form>
Note: I'm a total novice at any coding. I'm just a dumb amature graphic designer. I've only ever created a page that lets me copy the
the most common phrases I had to leave in notes all day. I struggled
with it.
I'm trying to create this page that lets input something into a text field, and it applies it to defined URLS attached to buttons, that will bring me to those pages. Since I struggle to describe it, please see this visual: https://i.stack.imgur.com/ZplRK.jpg
I've tried co-opting some scripts for similar problems, but with no luck. (See below for examples before I edited them ). I included them to see if I was on the right track whatsoever. I know I'm gonna have an issue with multiple functions, probably?
<script type="javascript">
function goToPage(var url = '')
{
var initial = "http://example.com";
var extension = "html";
window.location(initial+url+extension);
}
</script>
<form name="something" action="#">
Label <input type="text" name="url" value="" onchange="goToPage(this.value)">
</form>
<SCRIPT type="javascript">
function goToPage(var url = '')
{
var initial = "https://cms.example.com/client/viewcasedetails";
var extension = "";
window.location(initial+url+extension);
}
</SCRIPT>
<TITLE>Redirect 1</TITLE>
<BASE HREF="https://cms.example.com/client/viewcasedetails">
</HEAD>
<BODY>
<P>
<FORM name="jump" action="#">
CMS ID:
<INPUT type="text" name="url" value="" onSubmit="goToPage(this.value)">
<INPUT type="submit" value="GO">
That's where I at. I'm just tired of typing the same long URLs all day at work, and messing up more than half the time. I have no clue what the solution is - Javascript? HTML? CSS? Just trying to seek the DIY answer before looking on how to hire someone to make it. Which I have no clue how to do either but that's another question for later.
Thanks for helping / apologies for possibly super dumb questions.
You could do something like the following:
// grab the input element
const input = document.getElementById("cmsId");
// grab all links that need to be updated accordingly
// when value inside input element changes
const links = document.querySelectorAll("a");
// create a handler that listens for changes when
// you type some text into the input element
input.addEventListener("input", (event) => {
// grab value inside input elemenet
const value = event.target.value;
// iterate through all links and update
// the inner text + href attribute accordingly
// NOTE: `baseUrl` for each link is stored in a
// `data-*` attribute
links.forEach((link) => {
const baseUrl = link.dataset.url;
const url = baseUrl + value;
link.innerText = url;
link.href = url;
});
});
<!-- Use a simple input element here, no need for a form -->
<div>CMS ID: <input id="cmsId" type="text" /></div>
<div>
<!-- No need to create buttons, simple anchor elements will work just fine -->
<a
id="main"
href="#"
target="_blank"
data-url="https://cmss.company.com/client/viewclientdetails/"
>
https://cmss.company.com/client/viewclientdetails/
</a>
</div>
<div>
<a
id="notes"
href="#"
target="_blank"
data-url="https://cmss.company.com/client/viewnotes/"
>
https://cmss.company.com/client/viewnotes/
</a>
</div>
<div>
<a
id="docs"
href="#"
target="_blank"
data-url="https://cmss.company.com/client/documentsall/"
>
https://cmss.company.com/client/documentsall/
</a>
</div>
<div>
<a
id="activity"
href="#"
target="_blank"
data-url="https://cmss.company.com/client/viewactivityledger/"
>
https://cmss.company.com/client/viewactivityledger/
</a>
</div>
In your code you are working with only the "main" button as I can see (as it goes to viewclientdetails). You are missing a "/" sign after var initial. So, assuming that you can implement the same functionality of the main button to the other buttons, here's what you can do:
<script type="text/javascript">
function goToPage(var url = '')
{
var initial = "https://cms.example.com/client/viewcasedetails/"; //I added the slash
var extension = "";
window.location(initial+url+extension);
}
</script>
<TITLE>Redirect 1</TITLE>
<BASE HREF="https://cms.example.com/client/viewcasedetails">
</HEAD>
<BODY>
<P>
<FORM name="jump" action="#">
CMS ID:
<INPUT type="text" name="url" value="" onSubmit="goToPage(this.value)">
<INPUT type="submit" value="GO"> //you need 4 buttons here
You cannot have an input type="submit" here, since you will need four buttons. Submit works like a form submission. Add four buttons, then for each button's onClick property add the desired redirect url. You will need to get the value for the input field using an ID tag.
An example of what I am trying to say is given below:
<script type="text/javascript">
function onMainButtonClicked()
{
var cmsid= document.getElementById("cmsID").value;
var initial = "https://cms.example.com/client/viewcasedetails/"; //I added the slash
var extension = "";
window.location(initial+cmsid+extension);
}
function onNotesButtonClicked()
{
...
}
function onDocsButtonClicked()
{
...
}
function onActivityButtonClicked()
{
...
}
</script>
<TITLE>Redirect 1</TITLE>
<BASE HREF="https://cms.example.com/client/viewcasedetails">
</HEAD>
<BODY>
<P>
<FORM name="jump" action="#">
CMS ID:
<INPUT type="text" id="cmsID" name="url" value="">
<button onclick="onMainButtonClicked()">Main</button>
<button onclick="onNotesButtonClicked()">Notes</button>
<button onclick="onDocsButtonClicked()">Docs</button>
<button onclick="onActivityButtonClicked()">Activity</button>
There are much better ways to implement this, but this is a very simple implementation.
i created a form builder, however, i need to find a way to have the person add their own tracking codes when they publish the forms, these tracking codes go in the code.
<section class="tracking-codes">
<h2> Please enter all tracking codes in here: </h2>
<form>
<input type="text" id="code" placeholder="Facebook Pixel"> </input>
<button type="button" onclick="codes()"> Add Code </button
</form>
</section>
here is my js
function codes ()
{
var trackingCode = document.getElementById('code');
document.head.appendChild(trackingCode);
console.log(trackingCode);
}
at this point, it does append the id of code but only the part of
<input type="text" id="code" placeholder="Facebook Pixel">
and not the user input, how would i go about doing this?
I have also tried the .value at the end of making the var of trackingcodes but it doesnt work.
Instead of adding html to the head section, you should use a hidden field input. Add it like this:
function codes ()
{
var trackingCode = document.getElementById('code').value;
var element = document.createElement('input');
element.type = 'hidden';
element.id = 'tracking';
document.head.appendChild(element);
console.log(trackingCode);
}
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>Form</title>
<script>
function billingFunction()
{
var shippingName = document.getElementById("shippingName");
if(document.getElementById("same").checked )
{
document.getElementById("billingName").value= shippingName.value;
}
else
{
document.getElementById("billingName").removeAttribute("required");
}
}
</script>
</head>
<body>
<form>
<fieldset>
<legend>Shipping Information</legend>
<label for ="shippingName">Name:</label>
<input type = "text" name = "Name" id = "shippingName" required><br/>
</fieldset>
<input type="checkbox" id="same" name="same" onchange= "billingFunction()"/>
<label for = "same">Is the Billing Information the Same?</label>
<fieldset>
<legend>Billing Information</legend>
<label for ="billingName">Name:</label>
<input type = "text" name = "Name" id = "billingName" required><br/>
</fieldset>
<input type = "submit" value = "Verify"/>
</form>
</body>
</html>
Whenever the checkbox is checked, the code should automatically copy the values from first field into the second field. If the checkbox is unchecked, the second one should go blank. as per my code the first requirement is ok, but I couldn't make it blank when it is unchecked. Can anyone help plz.
Add document.getElementById("billingName").value = null; to the else clause.
Fiddle
Just set the value to an empty string in the else clause
function billingFunction() {
var shippingName = document.getElementById("shippingName");
var billingName = document.getElementById("billingName");
if(document.getElementById("same").checked ) {
billingName.value = shippingName.value;
} else {
billingName.removeAttribute("required");
billingName.value = "";
}
}
You only need to modify the else block
else{
document.getElementById("billingName").value="";
}
JSFIDDLE
EDIT
You have put the billing function inside header. You must be comming across reference error.
You can put this billing function inside window.onload or pu this script near closing body tag
window.onload= function(){
billingFunction;
}
function billingFunction(){ //Rest of code}
JSFIDDLE with window.onload
I have a form with a bunch of inputs. Sometimes the form will have 1 input and sometimes up to 10 inputs. When someone fills out each input I want a tag field at the bottom to be populated also. Right now I have it working but only with a set number of inputs. (3 at the moment).
Im trying to figure out how to make it work regardless of how many inputs there are on the page.
HTML
Input1 <input id="input1" name="input1" type="text" value="" />
<br/>
Input2 <input id="input2" name="input2" type="text" value="" />
<br/>
Input3 <input id="input3" name="input3" type="text" value="" />
<br/>
<p>List of inputed text</p>
<span id="allInputs"></span>
Jquery
$("#input1,#input2,#input3").change(function () {
var inputArray = [$("#input1").val(), $("#input2").val(), $("#input3").val()];
$("#allInputs").text(inputArray.join(' '));
});
A nice to have also would be putting them into another input instead of a span and adding a comma after each one except for the last one.
I know Im probably missing something very simple here.
In your example you are only allowing for 3 inputs as you have 3 input boxes, when any of those input boxes change your tags are then being transferred to the span.
Now it sounds like you wish to allow for multiple entries regardless of how many inputs. You could try something simple such as the below fiddle.
http://jsfiddle.net/K2g4z/
Html:
<div>
<strong>Enter your tag and click add</strong>
<br/>
<input type="text" id="tagEntry" />
<button id="tagAdd">Add</button>
</div>
<div>
<strong>Entered Tags</strong>
<br/>
<input type="text" id="tagsEntered" />
</div>
Javascript:
var tags = [];
$(function() {
$('#tagAdd').click(function(){
//get the tag value and trim the spaces
var tVal = $('#tagEntry').val().trim();
if(tVal == '')
return;
//reset the entry box
$('#tagEntry').val('');
//verify tag not already saved
for(var i=0;i<tags.length;i++)
if(tags[i] == tVal)
return;
//add the tag to the array
tags.push(tVal);
//set the tags entry box
$('#tagsEntered').val(tags.join(', '));
});
});
UPDATE:
The JSFiddle link http://jsfiddle.net/K2g4z/1/ now supports using multiple inputs of as many as you need. To achieve this instead of selecting on element ID we bind to a class name. Given the following Html.
<div>
<strong>Enter your tag and click add</strong>
<br/>
<strong>Tag 1</strong>
<input type="text" id="tagEntry" class="tagEntry" />
<br/>
<strong>Tag 2</strong>
<input type="text" class="tagEntry" />
<br/>
<strong>Tag 3</strong>
<input type="text" class="tagEntry" />
<br/>
<strong>Tag 4</strong>
<input type="text" class="tagEntry" />
<br/>
<strong>Tag 5</strong>
<input type="text" class="tagEntry" />
</div>
<div>
<strong>Entered Tags</strong>
<br/>
<input type="text" id="tagsEntered" />
</div>
All the tag input boxes have a class of tagEntry now this class will become our selector. With the following JS we can bind the blur event to every tag that has a class of tagEntry. This will now update the tags box every time any of the inputs changed.
var tags = [];
$(function() {
$('.tagEntry').blur(function(){
//get the tag value and trim the spaces
var tVal = $(this).val().trim();
if(tVal == '')
return;
//reset the entry box
$(this).val('');
//verify tag not already saved
for(var i=0;i<tags.length;i++)
if(tags[i] == tVal)
return;
//add the tag to the array
tags.push(tVal);
//set the tags entry box
$('#tagsEntered').val(tags.join(', '));
});
});
As you can see our handler binds to all the inputs, as any of the inputs receives the blur event the method of extracting the tags is executed.
$("#input1,#input2,#input3").change(function () {
var inputArray = [$("#input1").val(), $("#input2").val(), $("#input3").val()];
$("#masterinput").val(inputArray.join(' '));
});
You probably want to narrow the selector so it isn't selecting all text inputs on the page.
var inputs$ = $("input:text").change(function () {
var inputArray = [];
$.each(inputs$, function(i, v) {
inputArray.push($(v).val());
}
$("#allInputs").text(inputArray.join(' '));
});
Here you go:
var str = "";
$("input[type=text]").change(function () {
$("input[type=text]").each(function(){
str += $(this).val()+",";
};
});
$("#allInputs").html(str);