HTML post method vs AngularJS - html

I want to use AngularJS in my application, and at the initial stage I followed plain HTML for front view and for the back end potion I used a servlet and an ejb class where I organized SQL querys following CURD application method and that works really fine. Then I applied AngularJS that includes an Ajax call inside the $scope method. Once I create an Ajax method named "btnadd()", but now I cannot pass a value because the page directs to a servlet. Can any one help me to
<html ng-app="helloApp">
</head>
<body>
<div ng-controller="demoApp">
<form name="frm" method="post" action="Srvlet">
<input type="submit" name="btnadd" value="Add" ng-click="btnadd()"/>
My method in the JS file:
$scope.btnadd = function() {
$.ajax({
url: 'Srvlet',
type: "POST",
data: {
datepicker: $scope.newcontact.datepicker,
eId: $scope.newcontact.eId,
name: $scope.newcontact.name, `enter code here`
cmp: $scope.newcontact.cmp
},
success: function(data, textStatus, jqXHR) {
console.log(data);
$scope.$apply(function(){
$scope.newcontact.addRecordResult = data.addRecordResult;
});
},
error: function(jqXHR, textStatus, errorThrown) {
console.log('Error : ' + jqXHR.responseText);
}
}); if($scope.newcontact.eId == null) {
$scope.newcontact.eId = departmentID++;
$scope.Departments.push($scope.newcontact);
} else {
for(i in $scope.Departments) {
if($scope.Departments[i].eId == $scope.newcontact.eId) {
$scope.Departments[i] = $scope.newcontact;
}
}
}
$scope.newcontact = {};
};

Hello and welcome on stackoverflow
I assume that the method btnadd() is attached to a submit button in which case it will proceed to the action. There is few possible solutions i.e. change submit button to standard button that wont send form but will call the method or/and add onsubmit="return false;" to form which will prevent form from sending
Although why don't you use an angularjs $httpinstead of jQuery?
https://docs.angularjs.org/api/ng/service/$http

Related

Trouble Keeping Form Inputs Saved After Failed Submission in Nodejs Express Project Using Ajax

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:
Errors from using jquery code
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);
}
});
EDIT 3:
You could use localStorage to set form details before the request is made and then clear the request if the request is successful or get the data if the request fails.
Try this
$(document).ready(function(){
// You have form inputs of title, image, description, ingredients, directions
// Grabbing the input from the form will be something like this
const data = {
title: $('#recipeNameInput').val(), // this syntax is for grabbing input data from jquery
image: $('#recipeNameInput').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
}
localStorage.setItem('data', JSON.stringify(data)) // data is assumed to be an array or an object
$("#createRecipeForm").submit(function(e) {
$.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
}
});
});
});
You can find out more about getting form field values using jQuery here
Then, onLoad of the form, you check if there is data in localStorage.
$( document ).ready(function() {
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
data = {
title: ....., //all fields will be populated with data from the previous attempt
image: .....,
description: ....,
ingredients: ....,
directions: .....
}
$('#recipeNameInput').val(data.title) // grab the title form input and populate it with the data.title value.
// Do the same with the rest of the form inputs
} else {
// continue to fresh form in a situation where the previous form request were successful
}
});
You can find out more about populating form fields using jQuery here

MVC 5 prevent page refresh on form submit

yBrowser: IE9
Technologies: MVC5
I am mainly using Angular for everything on my page. (Single Page App).
But because I am working with IE9, I can't use FileAPI.. So, I decided to go with MVC's Form Actions to get HttpPostedFileBase in my controller methods to handle fileupload.
Html Code: (Is present in a modal)
#using (Html.BeginForm("UploadTempFileToServer", "Attachment", FormMethod.Post, new { enctype = "multipart/form-data", id = "attachmentForm" }))
{
<div>
<span id="addFiles" class="btn btn-success fileinput-button" ng-class="{disabled: disabled}" onclick="$('#fileUpload').click();">
<span>Add files...</span>
</span>
<input id="fileUpload" type="file" name="files" class="fileInput" onchange="angular.element(this).scope().fileAdded(this)" />
</div>
<div>
<span class="control-label bold">{{currentFilePath}}</span>
<input name="fileUniqueName" value="{{fileUniqueName}}" />
<input id="attachmentSubmit" type="submit" value="Upload File" />
</div>
}
MVC Controller:
public void UploadTempFileToServer(IEnumerable<HttpPostedFileBase> files, string fileUniqueName)
{
var folderPath = fileStorageFolder;
foreach (var file in files)
{
if (file.ContentLength > 0)
{
file.SaveAs(folderPath + fileUniqueName);
}
}
}
Question #1: Does anyone know of a way to send the HttpPostedFileBase data to the controller, without using form's submit action?
I don't mind using Jquery if need be. I have tried hijacking the form's submit action and that didn't work.
I tried sending the file control's data using non submit button event, but no luck there either.
If not:
Question #2 How do I prevent the page from going to /Attachment/UploadTempFileToServer after the execution of submit is completed?
To answer #2 (and assuming you're using jQuery):
$(document).on('submit', '#attachmentForm', function(event){
event.preventDefault();
// everything else you want to do on submit
});
For #1, unfortunately, unless a browser supports XMLHttpRequest2 objects (which I don't believe IE9 does), you can't send file data via ajax. There are plugins that let you submit the form to a hidden iframe, though. I think Mike Alsup's Form plugin has that ability: http://malsup.com/jquery/form/#file-upload
So, after much research and attempts. This is my solution:
Using https://github.com/blueimp/jQuery-File-Upload/wiki
HTML:
Earlier I was using a hidden file upload control and triggering its click via a span. But because of security issues a file input which is opened by javascript can't be submitted by javascript too.
<div class="col-md-7">
<div class="fileupload-buttonbar">
<label class="upload-button">
<span class="btn btn-success btnHover">
<i class="glyphicon glyphicon-plus"></i>
<span>Add files...</span>
<input id="fileUpload" type="file" name="files"/>
</span>
</label>
</div>
</div>
Javascript:
$('#fileUpload').fileupload({
autoUpload: true,
url: '/Attachment/UploadTempFileToServer/',
dataType: 'json',
add: function (e, data) {
var fileName = data.files[0].name;
var ext = fileName.substr(fileName.lastIndexOf('.'), fileName.length);
var attachment = {
AttachmentName: fileName,
Extension: ext
}
var fileUniqueName = id + ext;
//Sending the custom attribute to C#
data.formData = {
fileUniqueName: fileUniqueName
}
data.submit().success(function (submitData, jqXhr) {
attachment.Path = submitData.path;
//Add the attachment to the list of attached files to show in the table.
$scope.attachmentControl.files.push(attachment);
//Since this is not a direct angular event.. Apply needs to be called for this to be bound to the view.
$scope.$apply();
}).error(function (errorData, textStatus, errorThrown) {
});
},
fail: function (data, textStatus, errorThrown) {
}
});
C#:
public virtual ActionResult UploadTempFileToServer(string fileUniqueName)
{
//Getting these values from the web.config.
var folderPath = fileStorageServer + fileStorageFolder + "\\" + tempFileFolder + "\\";
var httpPostedFileBase = this.Request.Files[0];
if (httpPostedFileBase != null)
{
httpPostedFileBase.SaveAs(folderPath + fileUniqueName);
}
return Json(new
{
path = folderPath + fileUniqueName
},
"text/html"
);
}

Prevent HTML form action from being displayed on browser, or redirect to another page after the action being executed

Alright let's put it this way: How can I "redirect" a user to another page, "MyPage.php" after submitting a form that looks like this:
<form action="http://www.example.com/APageICanNotEdit.php" method="POST">
<input type="submit" name="send" value="Go" />
</form>
Please note that, I don't have control over the URL provided in the action attribute. It's an external source. Which means, I cannot edit the "APageICanNotEdit.php" file.
Here is what I want:
User will click on submit button (Labeled as Go)
action="http://www.example.com/APageICanNotEdit.php" - this action
must be performed, if possible, without displaying the contents of it.
I want the user to reach "MyPage.php" safely after
"APageICanNotEdit.php" is executed.
I need a solution without changing the URL in action, cause that
defeats the purpose.
use an hidden parameter like
<input type="hidden" name="action" value="1" />
Your form will look like this:
<form action="http://www.example.com/form-manager.php" method="POST">
</form>
Yout form manager will look like this:
if ($_POST['action'] == "1")
require_once('ThePHPFileIDoNotWantToBeLoadedOnBrowser.php");
Seeing your comment, you can do it with an AJAX call:
$(document).on('submit' , 'form[action="http://www.example.com/ThePHPFileIDoNotWantToBeLoadedOnBrowser.php"]' , function(e){
var formData = $(this).serialize(); // if you need any of the vars
$.ajax({
url:'someOtherURL.php',
type:'POST',
datatype:'json',
data: formData,
success : function(data){
for(var i = 0; i < data.length; i++){
console.log(data);
}
},
error : function(s , i , error){
console.log(error);
}
});
return true; // keep normal behavior
});

How to send form field value to a REST service using JSON or AJAX

I have a form field (email signup) on the site, and the email provider wants me to submit it to their REST web service and get a response. I've never used JSON or AJAX before so floundering!
The HTML:
<form>
<input type="hidden" name="gid" value="12345678">
<input type="hidden" name="user.CustomAttribute.NewsletterPopUp" value="Global">
<input type="hidden" name="user.CustomAttribute.NewsletterOptIn" value="True">" value="True">
<input type="text" name="uemail" class="email_input_field" value="please enter your email" size="30" maxlength="64" onFocus="clearText(this)">
<input type="submit" name="signup" value="signup" class="email_submit_button">
</form>
Currently, using Javascript and using window.location to visit the URL (which creates the action instead of posting it) they want it converted to a form post action with XML response. What happens now:
$(".email_submit_button").click(function(){
var uemail = $('.email_input_field').val();
window.location = "http://example.com/automated/action.jsp?action=register&errorPage=/automated/action.jsp&gid=12345678&uemail="+uemail+"&user.CustomAttribute.NewsletterPopUp=Global&user.CustomAttribute.NewsletterOptIn=True";
return false;
}
});
I see you'r using jQuery so you can use the $.post to post to the server like this:
var url = "http://example.com/automated/action.jsp"
var data ={
"gid": form.gid,
"action": register,
"uemail": form.uemail,
"errorPage": "/automated/action.jsp",
"user.CustomAttribute.NewsletterOptIn": user.CustomAttribute.NewsletterOptIn,
"user.CustomAttribute.NewsletterPopUp": user.CustomAttribute.NewsletterPopUp
};
var success_func = function(data){
//do what you want with the returned data
};
$.post(url, data, success_func);
Documentation for $.post.
Or you can use the pure longer Ajax version it's mentioned in the documentation of the $.post.
EDIT:
I forget you can't do xhttpresuext to a different domain you need to use JSONP, here's a link to another SO post explaining everything by detail
Hope this help.
$(".email_submit_button").submit(function(e) {
// stop form from submitting
e.preventDefault();
// Grab all values
var uemail = $('.email_input_field').val();
// make a POST ajax call
$.ajax({
type: "POST",
url: "YOUR URL", // set your URL here
data: {
uemail: uemail // send along this data (can add more data separated by comma)
},
beforeSend: function ( xhr ) {
// maybe tell the user that the request is being processed
$("#status").show().html("<img src='images/preloader.gif' width='32' height='32' alt='processing...'>");
}
}).done(function( response ) {
// do something with the received data/response
//$("#status").html(response);
});
});
Not sure if ".email_submit_button" is the class given to the submit button or the form.. you need to use the id or class given to the form and not the submit button.. hope this helps

Prevent Ajax.BeginForm from HTML encoding output

#using (Ajax.BeginForm("Create", "Comment",
new AjaxOptions
{
UpdateTargetId = "newComment",
OnSuccess = "function() { alert('finished " + ViewData.Model.Id + "'); }",
}))
{
...
}
outputs the following markup:
<form action="/Comment/Create" data-ajax="true" data-ajax-mode="replace"
data-ajax-success="function() { alert('finished 34'); }"
data-ajax-update="#newComment34" id="form1" method="post">
As you can see, it has HTML encoded my javascript. How do I prevent this?
EDIT: I have multiple AJAX forms on my page so the onsuccess function needs to know which one called it. In my code, you can see I am trying to pass state to this function. If OnSuccess can only take a function name (and not state), then how can I achieve this?
Personally I would use a standard Html.BeginForm helper with HTML5 data-* attributes that I will AJAXify myself:
#using (Html.BeginForm(
"Create",
"Comment",
FormMethod.Post,
new { data_id = Model.Id }
))
{
...
}
which outputs:
<form action="/Comment/Create" data-id="some id here" method="post">
...
</form>
and then in a separate javascript file I would subscribe for the .submit event:
$(function() {
$('form').submit(function() {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
dataId: $(this).data('id'), // <- pass the data-id HTML5 attribute
success: handleSuccess
});
return false;
});
});
function handleSuccess(result) {
$('#newComment').html(result);
// fetch the data-id of the form that trigerred the AJAX request
var id = this.dataId;
// TODO: do something with this id
}
I prefer this technique compared to the Ajax.* helpers as it gives me all the control I might need. Another advantage is that we get a clear separation between script and markup making the code nice and tidy.
Don't.
The HTML encoding is correct behavior, and the attribute value (as seen from Javascript code) will not be encoded.
I believe that It's because MVC interprets the OnSuccess (and other vars) as the name of a Javascript function and not a bit of Script.
Make a helper function that performs the script you want to act on the submit.