I am currently working on a Nodejs Project and I am trying to grab the information inputted into a form to redisplay in the form after a failed submit occurs. However, I am confused as to how exactly to perform this. From researching around, I've learned that accomplishing this through an Ajax request would be my best option. I have looked at other posts as well as Googled around but have had no luck. Would anyone be able to assist me? This is the link to the project repo: https://github.com/halsheik/RecipeWarehouse.git. I have also posted any relevant code that may or may not be updated in this repo.
$(document).ready(function(){
$("#createRecipeForm").submit(function(e) {
$.ajax({
type: "POST",
url: "/recipes/createRecipe",
data: $(this).serialize(), // serializes form input
success: function(data){
console.log(data);
},
error: function(data){
console.log(data);
}
});
console.log(data);
});
});
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Homemade</title>
<!-- Required program scripts -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script>
<!-- Style Sheets-->
<link rel="stylesheet" href="/styles/navBarStyle.css">
<link rel="stylesheet" href="/styles/myRecipesStyle.css">
<link rel="stylesheet" href="/styles/createRecipeStyle.css">
</head>
<body>
<!-- Background image -->
<img id="background" src="/images/foodBackground.jpg" alt="">
<div id="newRecipeContainer">
<div id="closeButtonContainer">
<div id="backButton"><a id="back" href="/recipes/myRecipes">← My Recipes</a></div>
</div>
<form id="createRecipeForm" action="/recipes/createRecipe" method="POST" enctype="multipart/form-data">
<label id="formSubHeading">Create Your Homemade Recipe</label>
<div id="recipeNameContainer">
<label id="recipeNameLabel">Title</label>
<input id="recipeNameInput" type="text" name="recipeName">
</div>
<div id="recipeImage">
<label id="recipeImageLabel">Add An Image of Your Meal</label>
<input id="recipeImageInput" type="file" accept="image/*" name="recipeImage"/>
<label id="recipeImageInputLabel" for="recipeImageInput" name="recipeImage">Choose A File</label>
</div>
<div id="recipeDescription">
<label id="recipeDescriptionLabel">Description</label>
<textarea id="recipeDescriptionInput" name="recipeDescription" cols="30" rows="10" maxlength="2000"></textarea>
</div>
<div class="ingredientsContainer">
<label id="ingredientsLabel">Ingredients</label>
<button id="addIngredientButton" type="button" @click="addIngredientForm">Add Another Ingredient</button>
<div class="allIngredients" v-for="(ingredient, ingredientIndex) in ingredients">
<label class="ingredientLabel">{{ ingredientIndex + 1 }}.)</label>
<input class="ingredientInput" type="text" name="ingredients" v-model="ingredient.ingredient">
<button class="deleteIngredientButton" type="button" v-if="ingredientIndex > 0" @click="deleteIngredientForm(ingredientIndex)">X</button>
</div>
</div>
<div class="directionsContainer">
<label id="directionsLabel">Directions</label>
<button id="addDirectionButton" type="button" @click="addDirectionForm">Add Another Direction</button>
<div class="allDirections" v-for="(direction, directionIndex) in directions">
<label class="directionLabel">{{ directionIndex + 1 }}.)</label>
<input class="directionInput"type="text" name="directions" v-model="direction.direction">
<button class="deleteDirectionButton" type="button" v-if="directionIndex > 0" @click="deleteDirectionForm(directionIndex)">X</button>
</div>
</div>
<div id="createRecipeButtonContainer">
<button id="createRecipeButton" type="submit">Create Recipe</button>
</div>
</form>
</div>
</body>
<script src="/controls/newRecipeControl.js"></script>
</html>
Again, thanks for any help.
EDIT 1:
EDIT 2: My current code. I console.log in order to check that the form info is being received. Before moving it into the form submit call, it would not receive any of the form data. Currently, it does not redisplay the form info upon failed submissions.
$(document).ready(function(){
$("#createRecipeForm").submit(function(e) {
const data = {
title: $('#recipeNameInput').val(), // this syntax is for grabbing input data from jquery
image: $('imageNameInput').val(), // where the # sign indicates an id is being used to grab the value
description: $('#recipeDescriptionInput').val(),
ingredients: $('#ingredientInput').val(),
directions: $('#directionInput').val(), // in the cases of ingredients and directions, you are using Vue's `v-model` but I am going to assume you have text id's of `ingredientInput` and `directionInput` for them respectively
};
console.log(data);
localStorage.setItem('data', JSON.stringify(data)); // data is assumed to be an array or an object
$.ajax({
type: "POST",
url: "/recipes/createRecipe",
data: $(this).serialize(), // serializes form input
success: function(data){
localStorage.removeItem('data') // clear the data from localStorage as it won't be necessary again
// do another thing
},
error: function(data){
// throw or return error message
}
});
});
if (localStorage.getItem('data') !== null) { // The getItem(key) method must return the current value associated with the given key. If the given key does not exist in the list associated with the object then this method must return null.
const data = JSON.parse(localStorage.getItem('data')); // parse the retrieve JSON object from localStorage. Data should be exactly the way you put it earlier
$('#recipeNameInput').val(data.title); // grab the title form input and populate it with the data.title value.
$('#imageNameInput').val(data.image);
$('#recipeDescriptionInput').val(data.description);
$('#ingredientInput').val(data.ingredients);
$('#directionInput').val(data.directions);
}
});