我刚刚开始为大学学位编写代码,虽然到目前为止我很喜欢它,但我忍不住觉得这门网络工程课程要求的内容比他们在实验室和讲座中教授的内容要先进得多。对于作业,我正在创建一个表单,供网站用户输入他们的第二手产品。它有一个下拉菜单,可以选择“自定义”,然后应该允许用户输入自定义类别,并将其成为下拉菜单中的一个选项。我几乎不知道如何做到这一点,我'我对 javascript 很陌生,并尝试制作某种最初隐藏的文本输入,并在用户选择自定义时弹出,但每当尝试单击该自定义字段上的 Enter 时,它都会尝试提交表单。如果有人可以编写函数来为我添加此字段,我将不胜感激。
<html lang="en">
<head>
<title>DOM Practice (Task 4.1)</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<h1>Submit your 2nd hand Product!</h1>
<form method="POST" action="../submit.php" onsubmit="return validateForm()" onreset="resetForm()">
<!-- form for submitting products-->
<fieldset class="form">
<fieldset class="fieldSet">
<legend>Enter your personal information</legend>
<label for="firstName">*First Name:</label>
<input type="text" id="firstName" required><br>
<label for="lastName">*Last Name:</label>
<input type="text" id="lastName" required><br>
<label for="pemail">*Email:</label>
<input type="email" id="pemail" required>
<br><!-- validate as valid email when entered -->
<label for="submitted">*Have you submitted a product before?</label>
<select name="submitted" id="submitted" required>
<option value="yes">
I have submitted a product before.
</option>
<option value="no" selected>
I have not submitted a product before.
</option>
</select>
</fieldset>
<fieldset class="fieldSet">
<legend>Enter the details of the product</legend>
<label for="productName">*Product name:</label><br>
<input type="text" id="productName" required><br>
<label for="description">*Product Description:</label><br>
<textarea name="description" required>*Please describe the product briefly here.</textarea><br>
<label for="priceInput">*Product Price:</label><br>
<input type="text" id="priceInput" onChange="displayPricing()" required><br>
<label for="priceOutput">Price Range:</label><br>
<input type="text" id="priceOutput" readonly><br>
<label for="picture">*Upload a picture of the product:</label><br>
<input type="file" id="picture" name="picture" onChange="testType()" required><br>
<label for="url">*Upload a URL of a webpage associated with the product:</label><br>
<input type="url" id="url" required><br>
<p>Price Matched?</p>
<label for="priceMatched">Yes</label>
<input type="radio" id="priceMatched" name="priceMatching" value="wasPriceMatched"><br>
<label for="notPriceMatched">No</label>
<input type="radio" id="notPriceMatched" name="priceMatching" value="notPriceMatched"><br>
<label for="easeOfDiy">*Ease of DIY:</label><br>
<input type="text" id="easeOfDiy" required onChange="validateEaseofDiy"><br>
<label for="toolsIncluded">*Tools Included:</label><br>
<select name="toolsIncluded" id="toolsIncluded" required>
<option value="toolsAreIncluded">Tools are Included</option>
<option value="toolsNotIncluded">Tools are not Included</option>
</select><br>
<label for="productCategory">*What category is this product?</label><br>
<select name="productCategory" id="productCategory" onChange="createNewCategory()" required>
<option value="kitchen">Kitchen</option>
<option value="gardening">Gardening</option>
<option value="custom">Custom</option>
</select><br>
<label for="checkedTerms">I have read the <a href="terms-and-conditions">terms and
conditions</a></label>
<input type="checkbox" id="checkedTerms" name="terms" value="haveCheckedTerms" required><br>
<fieldset class="searchTags"><!-- a box for adding search tags-->
<legend>Search Tags</legend>
<input type="text" name="custom_entry" id="custom_entry"><input type="button"
value="Enter a new search tag" onclick="addSearchTag()"></input>
</fieldset>
<fieldset id="Reviews"> <!-- a box for adding reviews-->
<legend>Reviews</legend>
<input type="button" value="New Review" onclick="addReview()" onChange="validateReview()">
</fieldset>
</fieldset>
<input type="submit" value="submit">
<input type="reset" value="Reset">
</fieldset>
<script type="text/javaScript">
createNewCategory()
{
}
function displayPricing() //validates valid numeric input, plus produces price category field based on price
{
var priceInput = document.getElementById('priceInput');
var priceDisplay = document.getElementById('priceOutput');
var pattern = /^-?\d+(\.\d+)?$/; //testing for number
if(!(pattern.test(priceInput.value))) //if not valid number
{
alert("Please enter a numeric value.");
priceInput.value = '';
return; //clear the input field
}
var price = parseFloat(priceInput.value); //turning text/string output to double
if(price < 0) //alert if less than 0
{
alert("Price cannot be below 0.");
priceInput.value = 0; //set to 0
}
if(price == 0) //if 0
{
priceDisplay.value = 'Free';
}
else if(price<25) //if under 25
{
priceDisplay.value = 'Cheap';
}
else if(price<=100) //if 25 to 100 inclusive
{
priceDisplay.value = 'Affordable';
}
else //anything over 100
{
priceDisplay.value = 'Expensive';
}
}
function testType() //function that validates file types
{
var picture = document.getElementById('picture'); //getting input file
const fileTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif']; //has to be one of these types
if(!(fileTypes.includes((picture.files[0]).type)))
{
alert('File type '+(picture.files[0]).type + ' is not a valid file type! Please upload a JPEG, JPG, PNG, or GIF for the product image.');
picture.value = ''; //clear
}
}
function validateEaseofDiy() //function to validate easeofDiy as Easy, Average, or Hard
{
var diyInput = document.getElementById('easeOfDiy'); //getting inputted ease of DIY
if((diyInput.value != "easy") && (diyInput.value != "average") && (diyInput.value != "hard")) //if input isnt easy, average, or hard
{
alert('Invalid ease of DIY. The entered difficulty must be \"easy\", \"average\", or \"hard\". The entered input is case sensitive!');
diyInput.value = ''; //clear entered ease of DIY
}
}
function addReview() //function that adds reviews with button click, was solution to zero to many selector.
{
var newReview = document.createElement('textarea');
var lineBreak = document.createElement('br');
var deleteButton = document.createElement("button");
deleteButton.textContent = "Delete";
var reviewsContainer = document.getElementById('Reviews');
deleteButton.onclick = function()
{
newReview.remove(); //needs to delete the text area and the delete button
deleteButton.remove();
lineBreak.remove();
}
newReview.placeholder = 'Enter Review Here';
newReview.className = 'review-input'; //use to style, and to delete upon reset
reviewsContainer.appendChild(lineBreak);
reviewsContainer.appendChild(newReview);
reviewsContainer.appendChild(deleteButton);
}
validateReview()
{
var pattern = /\d+(\.\d+)$/ // a regex to test 0.0-5 out of 5 stars
}
function addSearchTag() //function to add search tags
{
var customSearchTag = document.getElementById("custom_entry").value;
if(customSearchTag == '') //to ensure empty search tags arent added, important for when IDs are grabbed
{
alert('Added Search Tags cannot be empty'); //not sure why not alerting
customSearchTag = ''; //clear input
return; //exit method
}
var newSearchTag = document.createElement("input");
var tagContainer = document.createElement("div");
newSearchTag.type = 'text'; //creating new search tag
newSearchTag.name = 'searchTag';
newSearchTag.value = customSearchTag;
newSearchTag.id = customSearchTag;
newSearchTag.className = 'search-Tag-Input';
//creating delete button for new tag
var deleteButton = document.createElement("button");
deleteButton.textContent = "Delete";
deleteButton.onclick = function()
{
deleteSearchTag(tagContainer); //needs to delete the entire container
};
tagContainer.appendChild(newSearchTag); //appending all elements to one container, was necessary to remove delete button upon delete
tagContainer.appendChild(deleteButton);
tagContainer.appendChild(document.createElement("br"));
document.getElementById("custom_entry").insertAdjacentElement("beforebegin", tagContainer);
}
function deleteSearchTag(tagContainer) //function delete search tag
{
tagContainer.remove(); // Remove the entire container
}
function resetSearchTags() //deletes all search tags
{
var tagContainer = document.querySelectorAll('div');
tagContainer.forEach(function(container) {
container.remove(); // Remove the entire container
});
}
function resetReviews() //deletes all reviews
{
var reviewsContainer = document.getElementById('Reviews');
// Remove all review elements indivdually
var reviewInputs = reviewsContainer.querySelectorAll('.review-input');
reviewInputs.forEach(function(review) {
review.remove();
});
// Also remove any line breaks and delete buttons
var lineBreaks = reviewsContainer.querySelectorAll('br');
lineBreaks.forEach(function(lineBreak) {
lineBreak.remove();
});
var deleteButtons = reviewsContainer.querySelectorAll('button');
deleteButtons.forEach(function(button) {
button.remove();
});
}
function validateForm() //functions that runs mutliple validation functions on form submission
{
validateReview();
}
function resetForm() // function that runs resets form elements that dont reset normally upon reset button
{
resetReviews();
resetSearchTags();
}
</script>
</form>
</body>
接受挑战!
由于您没有提供任何工作片段,所以我自己制作了一个。
这只是一个关于它应该如何工作的示例。阅读评论,你应该明白它是如何工作的。
注意:此脚本不包含任何服务器端行为。
function IncludeCustom ( MySelectElement )
{
// Only open the dialog for product inclusion if the custom
// option was selected in the product selector.
if ( MySelectElement.value == 'CustomProduct' )
{
MyCustomProductDialog.open = true;
}
}
function SendData ( MyFormElement )
{
// Generate a validated form data object.
const MyFormData = new FormData(MyFormElement);
// Just showing the result that should be sent to the server.
{
console.log('Data that the server should receive:');
for ( const [ Field, Value ] of MyFormData )
{
console.log(`${Field} = ${Value}`);
}
}
}
function SaveCustomProduct ( MyFormElement )
{
// Generate a validated form data object.
const MyFormData = new FormData(MyFormElement);
// Get your form data from here
const ProductName = MyFormElement.querySelector('#CustomProductName').value;
// Create the new option tag.
const ProductOption = document.createElement('option');
// NOTE: You can send this data to your server to save in the database then
// update the information below from the result.
// Configure the new option tag.
ProductOption.innerText = ProductName;
ProductOption.value = JSON.stringify({name: ProductName});
ProductOption.selected = true;
// In the case above, the value becomes a JSON string with the needed data
// then when the other form is submited then the server should extract the
// data from the JSON string to save the custom product in the database.
// Append the option to the ProductDropDown.
ProductDropDown.appendChild(ProductOption);
}
<button onclick="MyFormDialog.open = true;">Open Dialog</button>
<dialog id="MyFormDialog" open>
<form method="dialog" onsubmit="SendData(this)">
<p>Select a product:</p>
<select name="TheProduct" id="ProductDropDown" onchange="IncludeCustom(this)">
<!-- default placeholder -->
<option selected disabled></option>
<!-- custom product -->
<option value="CustomProduct">Custom</option>
<!-- Sample of products for didactic purposes -->
<!-- Can be extracted from a database -->
<option value="1">My Product 1</option>
<option value="2">My Product 2</option>
<option value="3">My Product 3</option>
<option value="4">My Product 4</option>
<option value="5">My Product 5</option>
</select>
<button onclick="this.parentElement.submit()">Save</button>
</form>
</dialog>
<dialog id="MyCustomProductDialog">
<form method="dialog" onsubmit="SaveCustomProduct(this)">
<p>Custom Product Name:</p>
<input type="text" name="CustomProductName" id="CustomProductName" />
<button onclick="this.parentElement.submit()">Save</button>
</form>
</dialog>