ajax call with html form won't work properly - javascript

I'm stuck.
It's like the script doesn't have any function at all.
<script>
$("#continue").click(function () {
$.ajax({
type: "POST",
url: "dbc.php?check=First",
data: {full_name : $('#full_name').val()
usr_email : $('#usr_email').val()},
success: function(msg){
if(msg==1){
$("#First_1").hide();
$("#Next_2").toggle();
}else{
alert(msg)
}
}
});
return false;
});
</script>
<form action="index.php?page=checkin" method="post" name="regForm">
<div id="First_1">
<table width="100%" cellpadding="0" cellspacing="0">
<tr>
<td>
<table cellpadding="0" cellspacing="5">
<tr>
<td style="padding: 5px;">
Fullständiga namn:
</td>
<td>
<input name="full_name" type="text" id="full_name" class="required">
</td>
</tr>
<tr>
<td style="padding: 5px;">
Email:
</td>
<td>
<input name="usr_email" type="text" id="usr_email" class="required email">
</td>
</tr>
<tr>
<td style="padding: 5px;">
Sex:
</td>
<td>
<select name="sex">
<option value="male">Kille</option>
<option value="female">Tjej</option>
</select>
</td>
</tr>
<td>
<input type="submit" id="continue" value="Continue">
</td>
</table>
</td>
</tr>
</table>
</div>
With this when i press continue it should send ajax call, but it doesn't. When i press Continue it just takes me to the form´s action="index.php?page=checkin", even if theres return false; on click(in the script)? I even tried to change the form line and inserted onsubmit="return false;" but then nothing happens at all when i click on the button.

The problem is it's doing the default action, because none of your jQuery code is running :) When your code runs, the id="continue" element isn't there yet, so $("#continue") doesn't find anything to bind a click handler to. It's an easy fix, wrap your code in a document.ready call, like this:
$(function() {
$("#continue").click(function () {
$.ajax({
type: "POST",
url: "dbc.php?check=First",
data: {full_name : $('#full_name').val()
usr_email : $('#usr_email').val()},
success: function(msg){
if(msg==1){
$("#First_1").hide();
$("#Next_2").toggle();
}else{
alert(msg)
}
}
});
return false;
});
});
By doing this it'll wait until the DOM is ready, and your elements are there to find/bind to. Also instead of attaching to the #continue button's click event, it's usually better to attach to the form's submit handler, so it's caught there, so instead of this:
$("#continue").click(function () {
You would do this:
$("form[name='regForm']").submit(function() {
With everything else staying the same.

Sounds to me like a typo and it looks like in your data field.
I would suggest doing
data: "value1="+$("#val1").val()+"&value2="+$("#val2").val()
Also a good way to debug javascript is to open up chrome's console or in firefox use firebugs console and when you perform the action it will usually inform you of a problem or lack thereof.
One last note: I would suggest using json in your return from php, this way you can provide user with a more catered message. For example, lets say your form doesnt validate server side (you are validating server side right?) you can return to client a nice message explaining to them waht did not validate. How to do this?
$.ajax({
type: "POST",
url: "dbc.php",
data: "val1="+$(#val1).val()+"&val2="+$(#val2).val(),
success: function(json){
if(json.error){
//notify user of error message
$(#statusDiv).(json.message);
}else{
//perform success
}
}
});
And on the server side to use something such as
echo json_encode(array("error"=>1, "message"=>"<insert validation problems here>"));
This will on success function have access via json.error, or json.message.

In your new code on phpbin you need a comma after the line:
data: "full_name="+$("#full_name").val()+"&usr_email="+$("#usr_email").val(), // <-- COMMA HERE
Or, in your old code (which is nicer since you don't have to deal with concatenating the data url yourself), you were missing a comma also, between the two lines:
data: {full_name : $('#full_name').val(), // <-- COMMA HERE
usr_email : $('#usr_email').val()},
ALSO, you need a semicolon after this line:
alert(msg); // <-- SEMICOLON HERE
;)

Related

jQuery Ajax Post keep adding username and password on the URL

I am using the Login Dialog as mentioned here on jQWidgets which I think is not the problem I am having and hence it shouldn't matter if someone has used it before or not for answering my question:
When testing the login functionality by putting login credentials, the username and password keep getting added on the URL of the page which I don't want. I am not sure why it's happening. Am I doing something wrong with the jQuery Ajax Post Webservice call?
Say for example, my home page URL of the webapp is : https://example.com/home.html
After entering loging credentials, it gets added to the URL for some reason like this:
https://example.com/home.html?username=myname&password=mypassword
Here is my HTML:
<!-- Login HTML Begins -->
<div id="wrap">
<div id="window" caption="Login">
<div>
<form >
<table>
<tr>
<td>Username:</td>
<td><input style="width: 150px;" type="text" name="user" id = "username" /></td>
</tr>
<tr>
<td>Password:</td>
<td><input style="width: 150px;" type="password" name="password" id = "password" /></td>
</tr>
<tr>
<td colspan="2" align="right" valign="bottom">
<input type="submit" id="submit" value="Login" />
</td>
</tr>
</table>
</form>
</div>
</div>
<!-- Login HTML ends -->
Here is my Javascript Code:
<script type="text/javascript">
$(document).ready(function () {
$('#window').jqxWindow({ theme: "shinyblack", width: 250, height: 130, isModal: true });
$('#submit').jqxButton({ theme: "shinyblack" });
var loginUrl = "https://example.com:8443/Webservice/loginCheck"
$( "#submit" ).click(function() {
var userName = $("#username").val();
var passWord = $("#password").val();
var ajaxRequest = jQuery.ajax({
//beforeSend: TODO: show spinner!
data: {
username: userName,
passWord: passWord
},
dataType: "json",
method: "POST",
url: loginUrl
})
.done(function (data_, textStatus_, jqXHR_) {
// Validate the web service and retrieve the status.
if (typeof (data_) === "undefined" || data_ === null) { alert("Invalid data returned from LoginCheck Web Service"); return false; }
if (isEmpty(data_.webservice_status) || isEmpty(data_.webservice_status.status)) { alert("Invalid Web Service Status for LoginCheck Webservice!"); return false; }
if (data_.webservice_status.status != "SUCCESS") { alert(data_.webservice_status.message);
return false; }
})
.fail(function (jqXHR_, textStatus_, errorThrown_) {
alert("Hitting the Fail function : Error in LoginCheck webservice: " + errorThrown_);
return false;
});
}
});
</script>
The default protocol used by forms are GET so you need to override it using POST protocol
so you need something like this:
<form action="url" method="post">
..
..
..
</form>
also the embedded click function you should prevent some default by putting this code :
$("#submit").click(function(e){
e.preventDefault();
<!-- your statement !>
...
})
also the butto type :
<button type="button" id="submit"></button>
or
<input type="button" id="submit">
The way you've set it up, you're submitting the form data in the traditional way rather than via AJAX.
One option is to add:
$('form').on('submit',function(event){
event.preventDefault();
});
(A common error is to try to prevent form submission in a click handler attached to the submit button. There are a number of ways to submit a form and the submit button is only one of them.)
Another option is to just remove the form element.
Your form may be sending a get request, because you haven't prevented the default functionality of a form button. Try adding these two lines to your click handler:
$( "#submit" ).click(function(event) {
event.preventDefault();
event.stopPropagation();
}

How to manipulate and redirect google form action without having that shown to the user with javascript and/or jquery

i have a google form that i toke embedded into my site and change the css, so it can post to google sheets.
<form action="https://docs.google.com/forms/d/FormID/formResponse" method="POST" target="_self" onsubmit="" role="form">
<table>
<thead>
<tr>
<th>Friends name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="form-group">
<input type="text" name="entry.ID" value="" id="entry_ID" class="form-control" dir="auto" aria-label="Name " title="">
</div>
</td>
<div>
<input type="submit" name="submit" value="Submit" id="button-submit" class="btn btn-primary btn-block">
</div>
</form>`
Now if you notice the button is an input here, what i want to do is to keep the form posting normaly to google sheets, without showing any of that to the user, i want to redirect the user to either a different page of success message or some jquery action that says that the posting worked.
i hope i was specific enough, google was of no help, and i could not find anything similar to this,
ps: i deleted most of the irrelevant code and inputs.
You can't keep it posting normally and hijack the response from the server. But you can post the data using AJAX and handle the reponse:
$( "form" ).on( "submit", function( event ) {
var $t = $( this ),
params = $t.serialize(),
url = $t.prop('action');
event.preventDefault();
$.post( url , params )
.done(function() {
console.log( "success" );
window.location.href = "success.html");
})
.fail(function() {
console.log( "error" );
window.location.href = "error.html");
});
});

Post Dynamic Inputs that are Appended with jQuery

I have found multiple questions that are the same, these include:
dynamically inserted form inputs aren't posted
jQuery not posting all inputs of a form after the .append()
Most problems are caused by opening the form within a table / div or some other problem with the HTML. I don't believe I have either of these problems; I suspect my javascript needs to be tweaked.
I am using jQuery as so:
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
</head>
When the add link is clicked a new table row is appended to tbody.newRow
When clicking .remove, you are asked for confirmation. Upon confirmation the row is removed.
The form is submitted via ajax when input.Value loses focus.
jQuery:
$(document).ready(function() {
$(".add").on('click', function() {
$("tbody.newRow").append(
'<tr><td><input type="text" name="NewJobLeviesId[]" class="JobLeviesId" /><input type="text" name="NewValue[]" class="Value" /><input type="text" name="MasterId[]" class="Values" /><input type="text" name="LUPChoiceId[]" class="Values" /><input type="text" name="SortOrder[]" class="Values" /></td><td class="removeSelection">Remove</td></tr>'
);
});
$("tbody").on('click', '.remove', function() {
$(this).parent().append($(
'<div class="confirmation">YesNo</div>'
))
$(this).remove();
});
$("tbody").on('click', '.removeConfirm', function() {
$(this).parent().parent().parent().remove();
});
$("tbody").on('click', '.removeCancel', function() {
$(this).parent().parent().append(
'Remove');
$(this).parent().remove();
});
var formTwo = $('.ajaxTwo'); // contact form
// form submit event
$(".Value").blur(function() {
$.ajax({
type: 'POST', // form submit method get/post
dataType: 'html', // request type html/json/xml
data: formTwo.serialize(), // serialize form data
success: function(data) {
url: 'functions.php'; // form action url
},
error: function(e) {
console.log(e)
}
});
});
});
The html form. The ajax works wonderfully with the existing row that is not added dynamically. The add row is located in the table footer looking pretty. The form is posted as an array.
<form class="ajaxTwo" method="post">
<table>
<tbody class="newRow">
<tr>
<td>
<input type="text" name="NewJobLeviesId[]" class="JobLeviesId" />
<input type="text" name="NewValue[]" class="Value" />
<input type="text" name="MasterId[]" class="Values" />
<input type="text" name="LUPChoiceId[]" class="Values" />
<input type="text" name="SortOrder[]" class="Values" />
</td>
<td class="removeSelection">
Remove
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>
Add Row
</td>
</tr>
</tfoot>
</table>
</form>
Finally the php. Each row is inserted into my database table with a PDO prepared statement.
if(isset($_SERVER['HTTP_X_REQUESTED_WITH'])){
if(isset($_POST['NewJobLeviesId'])) {
for($i=0; $i<count($_POST['NewJobLeviesId']); $i++) {
$NewJobLeviesId = $_POST['NewJobLeviesId'][$i];
$NewValue = $_POST['NewValue'][$i];
$MasterId = $_POST['MasterId'][$i];
$LUPChoiceId = $_POST['LUPChoiceId'][$i];
$SortOrder = $_POST['SortOrder'][$i];
$sql = "INSERT INTO joblevies (JobLeviesId,Value,MasterId,LUPChoiceId,SortOrder) VALUES (:JobLeviesId,:Value,:MasterId,:LUPChoiceId,:SortOrder)";
$q = $db->prepare($sql);
$q->execute(array(':JobLeviesId'=>($NewJobLeviesId),':Value'=>($NewValue),':MasterId'=>($MasterId),':LUPChoiceId'=>($LUPChoiceId),':SortOrder'=>($SortOrder)));
}
}
}
Again, this works wonderfully well. Only the dynamically added inputs have a problem. What am I missing?
The dynamically created dom elements don't have any of the events that you attach on $(document).ready(... because they didn't yet exist when you were attaching events. So the $('.Value').blur(... stuff is only attached to the first form, and not any future ones. So attach the event every time you create a new row, so maybe something like this:
First, delegate the binding action to its own function
function attachSubmitEvent() {
// form submit event
//remove old events first
$(".Value").off();
$(".Value").blur(function () {
var formTwo = $('.ajaxTwo'); // contact form
$.ajax({
type: 'POST', // form submit method get/post
dataType: 'html', // request type html/json/xml
data: formTwo.serialize(), // serialize form data
success: function (data) {
url: 'functions.php'; // form action url
},
error: function (e) {
console.log(e)
}
});
});
}
then in your document.ready, call that function
attachSubmitEvent();
then, to make sure they are also attached to the new elements, call it again when creating new elements
$(".add").on('click', function () {
$("tbody.newRow").append('<tr><td><input type="text" name="NewJobLeviesId[]" class="JobLeviesId" /><input type="text" name="NewValue[]" class="Value" /><input type="text" name="MasterId[]" class="Values" /><input type="text" name="LUPChoiceId[]" class="Values" /><input type="text" name="SortOrder[]" class="Values" /></td><td class="removeSelection">Remove</td></tr>');
attachSubmitEvent(); //now everyone has the event attached.
});
For your form submit event, try:
$("tbody").on('focusout', '.Value', function() {
...
});
You could also use blur in this event handler, but the documentation recommends using focusout for clarity (See 'Additional Notes' section of jQuery on() method documentation: http://api.jquery.com/on/)

Is it possible to construct a link, navigate to it and print the response in C# programmatically? How?

I have a webpage written in C#/Razor. I am printing all the values from a database on this page like so :
<div style="min-height: 150px; font-size: 1.25em">
<div style="margin-bottom: .5em">
<table>
<thead>
<tr>
<th>Name</th>
<th>Branch</th>
<th>Phone No.</th>
<th>Extension</th>
<th>Email</th>
</tr>
</thead>
<tbody>
#foreach (var prod in Model)
{
<tr>
<td>#prod.FullName</td>
<td>#prod.Branch</td>
<td>#prod.PhoneNo</td>
<td>#prod.Extension</td>
<td>#prod.Email</td>
#if (User.IsInRole(#"Admins") || User.Identity.Name == prod.DomainAC)
{
<td>edit</td>
}
else
{
<td>User => #User.ToString()</td>
}
<td>
<input type="checkbox" name="message" value="#prod.PhoneNo">Message<br>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
This works fine to display their info. What I would like to do now is a small bit more difficult.
Below this, I have a form with a username, password and message. Using this form, I would like to have the behaviour that on submit, it will take the values in the input boxes of the form and the above C#, construct a link, navigate to the link and print the response of the server
So I have :
#{if (IsPost)
{
//handle and print response
}
else
{
<form method="post" action="">
Username:<br />
<input type="text" name="u" /><br />
Password<br />
<input type="text" name="p" /><br />
<br />
Password<br />
<textarea name="m" cols="25" rows="5">
Enter your comments here...
</textarea><br>
<br />
<input type="submit" value="Submit" class="submit" />//when this is clicked, construct url and navigate to it.
</form>
}
}
The URL I want to construct from this form is :
http://webaddress.com/web/d.php?u=<Username entered by user>&p=<Password entered by user>&s=<List of Phone Numbers from the C# above where the checkbox is selected, comma separated>&m=<Comment submitted by user>
So, if my name is "John", Password is "Password1", Comment is "Test" and I have selected one checkbox for a user with the phone number "12345678", the URL I will navigate to is :
http://webaddress.com/web/d.php?u=John&p=Password1&s=12345678&m=Test
Ideally I would like to print the response of the webpage in a <div> while still on the same parent web page rather than going to a new one if this is possible.
I have no idea where to begin with this, how to do it or even if this is possible. Can anyone help me please ?
UPDATE :
Trying this JQuery which does not alert me so I cannot debug :
<script>
$("#thebutton").click(function() {
var form = $(document.getElementById('FormID'));
var urlToConstruct = 'http://webaddress.com/web/d.php';
urlToConstruct += '?u=' + form.find('#u').val();
urlToConstruct += '&p=' + form.find('#p').val();
('#employeeTable tbody tr').has(':checkbox:checked').find('td:eq(2)').each(function() {
urlToConstruct.append($(this).text());
alert(urlToConstruct);
})
});
</script>
$("#SubmitButtonID").click(function() {
var form = $(document.getElementById('FormID');
var urlToConstruct = 'http://webaddress.com/web/d.php';
urlToConstruct += '?u=' + form.find('#iDoFInputControl1').val();
urlToConstruct += '&p=' + form.find('#iDoFInputControl2').val();
form.submit();
});
this example uses jQuery, a javascript library (jquery.com), i'm using getElementById to find your form, faster then the native jQuery() selector. This example assumes all your controls are inside your form (but if they are not it wouldn't be a train smash, just cant use (jQuery obj).find).
.val() gets the value, and it should work for checkboxes too, but if it doesn't, a quick google search for getting values from checkboxes using jquery will return loads of results.
p.s. I've written that code mostly freehand, not checked it in a browser to make sure that it is completely correct.
Update... to answer your follow up question...
If you are using mvc (assumed as you using razor), inside your controller you can use Request.Params["urlParameter"] or Request.Form["controlID"] to access what you've received from the browser. Then once you've got those values, you should place them inside the 'ViewBag' (ViewBag.yourVariableHere="val") for them to be accessible in your view via #ViewBag.yourVariableHere, or you can include the required data in your model which can also be accessed in your view

jquery remove causes mvc3 post to fail

I have an HTML table with dynamically generated rows (using MVC3's EditorFor). Users fill in the data in the table (row by row), then submit the form to the server (via MVC3 HTML form). Users can delete a row by pushing a button that calls $(tableRow).remove() on the TR element, and then calls an async server method that removes the row from the database.
I've found that if I have say 5 rows in my table and I delete the third one then submit, the server method receives rows 1 and 2, but looses the other rows (the original 4th and 5th rows).
I've tried searching online as to why the postback would receive the first two rows and miss the last two, but all the answers I could find revolved around JQuery posts, which I'm not using.
Any help or direction would be great, please let me know if I need to clarify anything.
EDIT: adding code from my project that applies to the question. if you need more code for context, let me know and I'll add it.
//////////////// VIEW ////////////////
// model info and initialization logic
#using (Html.BeginForm("EditTimesheet", "ControllerName", FormMethod.Post, new { enctype = "multipart/form-data", id = "editTimesheet" }))
{
#Html.ValidationSummary(true)
<fieldset>
<table width="100%">
<tr>
<td colspan="14" align="right">
// lots of code
</td>
</tr>
#Html.EditorFor(m => m.Rows)
<tr>
<td colspan="14" align="right">
// lots of code
</td>
</tr>
// closing statements
//////////////// EditorFor ////////////////
// model info and initialization logic
<tr class="timesheet-row">
<td>
<a href='#'>
<img src='#Url.Content("~/Content/Images/delete.gif")'
width='17' height='17' style='border: 0;'
onclick="DeleteRow(this, #Model.RowId)" />
</a>
</td>
// other td's
</tr>
//////////////// JS file ////////////////
function DeleteRow(box, rowId)
{
$(box).closest(".timesheet-row").remove();
// HACK: despicable, detestable HACK!
var url = deleteRowUrl;
url += '?rowId=' + rowId;
var ajaxData = {
type: "POST",
url: url,
dataType: "json",
contentType: "application/json; charset=utf-8",
data: null,
success: null,
error: function (error) {
alert("There was an error posting the data to the server: " + error.responseText);
}
};
$.ajax(ajaxData);
}
When you delete a row you are creating holes in the indexes of the names in the collection and the default model binder stops working because you no longer respect the expected format.
So instead of having the following sequential values:
<input type="text" name="Items[0].Id" value="1" />
<input type="text" name="Items[1].Id" value="2" />
<input type="text" name="Items[2].Id" value="3" />
<input type="text" name="Items[3].Id" value="4" />
<input type="text" name="Items[4].Id" value="5" />
if you delete the third row with $(tableRow).remove() on the TR element you end up with:
<input type="text" name="Items[0].Id" value="1" />
<input type="text" name="Items[1].Id" value="2" />
<input type="text" name="Items[3].Id" value="4" />
<input type="text" name="Items[4].Id" value="5" />
See the problem?
Here's an article which illustrates how to solve this problem by using a custom helper called Html.BeginCollectionItem and which uses GUIDs in the names of the input fields for the collection instead of integer indexes. Also checkout Phil Haacks article about the syntax that the default model binder expects your fields to be named. There's a section towards the end which is called Non-Sequential Indices in which he covers how this could be done.
Sounds like part of your form is being deleted.
Inspect the DOM
find your form
delete a row and see what changes

Categories