WebMatrix AJAX INSERT not working - ajax

i'm trying to add an entry into my database and update a table i have created using AJAX. I think i'm halfway there, i can send my form contents to the "partial" page, but thats where it gets stuck?
Here's my content page:
#{
Layout = "~/_SiteLayout.cshtml";
WebSecurity.RequireAuthenticatedUser();
var db = Database.Open("StayInFlorida");
var rPropertyId = Request.QueryString["PropertyID"];
var Roominfo = "SELECT * FROM RoomInfo WHERE PropertyID=#0";
var qRoominfo = db.Query(Roominfo, rPropertyId);
}
<h2>Current Rooms</h2>
<table id="room-table" class="table table-bordered">
<tr>
<th>Room Name</th>
<th>Room Type</th>
<th>Room Description</th>
</tr>
#foreach(var row in qRoominfo){
<tr>
<td>#row.RoomName</td>
<td>#row.RoomType</td>
<td>#row.RoomDescription</td>
</tr>
}
</table>
<form id="add-room-form" action="#Href("~/Partials/AddRoom")">
<div class="row">
<span class="label"><label for="title">Room Name:</label></span>
<input type="text" name="roomname" id="roomname" size="50" />
</div>
<div class="row">
<span class="label"><label for="title">Room Type:</label></span>
<input type="text" name="roomtype" id="roomtype" size="50" />
</div>
<div class="row">
<span class="label"><label for="title">Room Description:</label></span>
<input type="text" name="roomdescription" id="roomdescription" size="50" />
</div>
<input type="hidden" name="propertyid" value="#rPropertyId" />
<button class="btn btn-success" id="submitbutton">Submit</button>
</form>
<script type="text/javascript">
$(function(){
$('#submitbutton').click(function(){
$.ajax({
type: "POST",
url: "/Partials/AddRoom",
data: $("#add-room-form").serialize(),
dataType: "text/plain",
success: function (data) {
$('#room-table').html(data);
}
return false;
});
});
});
</script>
and here is the partial page which "should" insert the data into the database:
#{
var db = Database.Open("StayInFlorida");
var sql = "INSERT INTO RoomInfo (PropertyID, RoomName, RoomType, RoomDescription, LastModified) " +
"VALUES (#0, #1, #2, #3, GetDate())";
var propertyid = Request["propertyid"];
var roomname = Request["roomname"];
var roomtype = Request["roomtype"];
var roomdescription = Request["roomdescription"];
db.Execute(sql, propertyid, roomname, roomtype, roomdescription);
}
In theory, it should write the info to the database, and then refresh my table, so im guessing something isn't quite right with the javascript?

You cannot sent the data through an ajax call is because you cannot even start the request. You are using the function to trigger when a click is made. But there will be no click event.
Reason: There is no button with the ID for click event. See Click trigger issue section below.
Tip: To check whether there is any Request to the server or not, you should make use of this. In every browser when you press F12 you get Developer Tools opened. Make sure you are on network tab. You will be able to check any network request made to server through there. Ajax requests are also saved there as a log, there status and everything is present there. That will be a basic but a powerfull tool to help you out in understanding how Ajax requests are made.
There are certain issues in your code too.
Issue in the HTML: There is an error in your code, look at the submit button. Its having code as:
<button class="btn btn-success" type="submit" value="Submit"/>Submit</button>
Which should be:
<button class="btn btn-success" type="submit" value="Submit">Submit</button>
And then, I should change that too the following because the type="submit" will submit the form instead of creating an ajax request. I used your page in my website and just replaced the DataBase objects and replaced them with simple Response like Response.Write() and wrote the variables that I caught:
<button class="btn btn-success" id="submitbutton">Submit</button>
So the code that I changed the above one to is like this:
#{
if(IsPost){
var propertyid = "1";
var roomname = Request["roomname"];
var roomtype = Request["roomtype"];
var roomdescription = Request["roomdescription"];
var lastmodified = DateTime.Now;
// here you will write the data to database using Database.Execute
// Remember you should write the ajax response
// here as a result of Response.Write()
// However if you still want to load that page, its OK!
}
}
As mentioned earlier, you were write the propertyid as "'1'" I changed that to "1". But in case you want to execute as "'1'" its ok too.
Click trigger issue:
There were some other issues too. You were using:
$('#submitbutton').click(function(){
But there was no button with the ID submitbutton. So I changed the id of the button you were using there.
What I changed in your code:
What change I made in your code was I changed the POST request to GET. To have a look at what variables are being sent to server and what results I get. I had it easier to make use of this code as GET request was easily able to check then POST request.
If you still want to use POST request you should try to serialize() the form as JSON and send it to server. But GET will be easy.
Then I gave another field to the $.ajax section as:
data: 'roomname=' + $('#roomname').val() +
'roomtype=' + $('#roomtype').val() +
'roomdescription=' + $('#roomdescription').val(),
This will create a string of the data to be sent. And then it will be caught on that page. And I removed if(IsPost) too. I was able to get the result of the Response. So what you can do is to change the Response of the request and write is as:
$("#room-table").html(response);
And the table will be changed! This will remove the previous data in the table Or even whole of the table and update it with the data recieved from the Response. And then I was able to send the request to server, process the QueryString and then write a response and then using $('#idofelement').html(response) I wrote it in the specific area. You can try it as I did.
The full code that I used was:
One the main page I had this code:
#{
Layout = "~/_SiteLayout.cshtml";
}
<h2>Current Rooms</h2>
<div class="row">
<span class="label"><label for="title">Room Name:</label></span>
<input type="text" name="roomname" id="roomname" size="50" />
</div>
<div class="row">
<span class="label"><label for="title">Room Type:</label></span>
<input type="text" name="roomtype" id="roomtype" size="50" />
</div>
<div class="row">
<span class="label"><label for="title">Room Description:</label></span>
<input type="text" name="roomdescription" id="roomdescription" size="50" />
</div>
<button class="btn btn-success" id="submitbutton" value="Submit" >Submit</button>
<script type="text/javascript">
$(function(){
$('#submitbutton').click(function(){
$.ajax({
url: '/Partials',
data: 'roomname=' + $('#roomname').val() + 'roomtype=' +
$('#roomtype').val() + "roomdescription=" +
$('#roomdescription').val(),
dataType: 'text',
contentType: 'text/html',
success: function(response) {
$("#body").html(response);
},
error: function(data){
alert('Something went wrong');
}
});
});
});
</script>
I changed the page to partials only and used it. Here is the content for that page.
#{
var propertyid = "1";
var roomname = Request["roomname"];
var roomtype = Request["roomtype"];
var roomdescription = Request["roomdescription"];
var lastmodified = DateTime.Now;
Response.Write("Room name: " + roomname + "<br>Room Type: "
+ roomtype + "<br>Room Description: " + roomdescription +
"<br>Property: " + propertyid);
}
Now its upto you to use the Database variables here. Where I used Response.Write and other codes You can use the Database methods. And also you can add WebSecurity method.

The Database.Execute method requires the SQL to be executed to be passed in first. You don't appear to be passing it in at all. Also, I assume that PropertyId is an integer? If so, you should not surround it in quotes. In fact, you should try delimiting values that will be passed in via parameter at all. That's one of the benefits of using parameters. Try this:
#{
if(IsPost){
var db = Database.Open("StayInFlorida");
var sql = "INSERT INTO RoomInfo (PropertyID, RoomName, RoomType, RoomDescription, LastModified) " +
"VALUES (#0, #1, #2, #3, GetDate())";
var propertyid = 1;
var roomname = Request["roomname"];
var roomtype = Request["roomtype"];
var roomdescription = Request["roomdescription"];
db.Execute(sql, propertyid, roomname, roomtype, roomdescription);
}
}
You are hardcoding the Properytid at the moment. If you want that to be dynamic, add a hidden field to your AJAX form and set the value to rPropertyId:
<input type="hidden" name="propertyId" value="#rPropertyId" />
Then you can alter the 4th line in the snippet above:
var propertyId = Request["propertyId"];

Related

Updating .NET Charts using ajax.beginform

I'm using .NET Charts to create some dynamic charts from a table in a database, and each chart is a separate view, with a corresponding action in the controller.
Then they are displayed in a main view as images:
<img src="~/Controller/Chart1" class="centered" />
Now I want to be able to filter the charts by date, and I've added the parameters to the actions and a couple datepickers for a start date and an end date.
I'm trying to refresh the charts using Ajax, but I'm having trouble. Without Ajax, the filter works, but redirects to a page containing just the updated chart.
With Ajax, nothing happens, or rather, if I set the UpdateTargetId to a div it gets filled with text, like byte code or something.
This is what I'm using:
<div>
using (Ajax.BeginForm("Chart1", "controller",
new AjaxOptions
{
HttpMethod = "POST",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "Chart1"
}))
{
<p>
<input type="text" name="begindate" class="datefield" placeholder="Begin Date" />
<input type="text" name="enddate" class="datefield" placeholder="End Date" />
<input type="submit" value="Filter" />
</p>
<img src="~/controller/Chart1" class="centered" />
</div>
How can I fix this problem?
You need to pass the dates to your action method and let the action method uses these dates to generate a filtered data set which will be used to generate the chart.
You can simply use jQuery Ajax to do this.
<div>
<input type="text" name="begindate" class="datefield" placehold="Begin Date" />
<input type="text" name="enddate" class="datefield" placeholder="End Date" />
<input type="submit" id="btnFilter" value="Filter" />
<img src="~/controller/Chart1" id="chartImg" class="centered" />
</div>
Now when user clicks the form, pass the dates
$(function(){
$("#btnFilter").click(function(e){
e.preventDefault();
var d1 = $("input[name='begindate']").val();
var d2 = $("input[name='enddate']").val();
var url = "#Url.Action("Chart1", "YourControllerName")";
url += "?beginDate=" + d1 + "&endDate=" + d2;
$("#chartImg").attr("src", url);
});
});
Now of course your action method should accept the dates and return the data as needed:
public ActionResult Chart1(DateTime beginDate,DateTime endDate)
{
// Return the chart image
}
I am using the Url.Action action method to generate the correct path to the Chart1 action method. This code will work if your JavaScript code is inside a Razor view. If your code is inside an external js file, Use the approach mentioned in this post

Play framework write Action with Ok(...) that doesn't load new page

Play framework 2.4.x. A button is pressed on my home page that executes some code via Ajax, and returns its results beneath the button without loading a new page. The results wait for a user to input some text in a field and press "submit". Those results Look like this:
<li class="item">
<div>
<h3>Email: </h3>
<a>#email.tail.init</a>
<h3>Name: </h3>
<a>#name</a>
</div>
<div>
<h3>Linkedin: </h3>
<form class="linkedinForm" action="#routes.Application.createLinkedin" method="POST">
<input type="number" class="id" name="id" value="#id" readonly>
<input type="text" class="email" name="email" value="#email" />
<input type="text" class="emailsecondary" name="emailsecondary" value="" />
<input type="text" class="name" name="email" value="#name" />
<input type="text" class="linkedin" name="linkedin" value="" />
<input type="submit" value="submit" class="hideme"/>
</form>
</div>
<div>
<form action="#routes.Application.delete(id)" method="POST">
<input type="submit" value="delete" />
</form>
</div>
</li>
Along with some jquery that slides up a li after submission:
$(document).ready(function(){
$(".hideme").click(function(){
$(this).closest('li.item').slideUp();
});
});
However, since a form POST goes inside an Action that must a return an Ok(...) or Redirect(...) I can't get the page to not reload or redirect. Right now my Action looks like this (which doesn't compile):
newLinkedinForm.bindFromRequest.fold(
errors => {
Ok("didnt work" +errors)
},
linkedin => {
addLinkedin(linkedin.id, linkedin.url, linkedin.email, linkedin.emailsecondary, linkedin.name)
if (checkURL(linkedin.url)) {
linkedinParse ! Linkedin(linkedin.id, linkedin.url, linkedin.email, linkedin.emailsecondary, linkedin.name)
Ok(views.html.index)
}else{
Ok(views.html.index)
}
}
)
Is it possible to return Ok(...) without redirecting or reloading? If not how would you do a form POST while staying on the same page?
EDIT: Here is my attempt at handling form submission with jquery so far:
$(document).ready(function(){
$(".linkedinForm").submit(function( event ) {
var formData = {
'id' : $('input[name=id]').val(),
'name' : $('input[name=name]').val(),
'email' : $('input[name=email']).val(),
'emailsecondary' : $('input[name=emailsecondary]').val(),
'url' : $('input[name=url]').val()
};
jsRoutes.controllers.Application.createLinkedin.ajax({
type :'POST',
data : formData
})
.done(function(data) {
console.log(data);
});
.fail(function(data) {
console.log(data);
});
event.preventDefault();
};
});
This is an issue with the browser's behavior on form submission, not any of Play's doing. You can get around it by changing the behavior of the form when the user clicks submit.
You will first want to attach a listener to the form's submission. You can use jQuery for this. Then, in that handler, post the data yourself and call .preventDefault() on the event. Since your javascript is now in charge of the POST, you can process the data yourself and update your page's HTML rather than reloading the page.
What you need is use ajax to submit a form, check this: Submitting HTML form using Jquery AJAX
In your case, you can get the form object via var form = $(this), and then start a ajax with data from the form by form.serialize()
$.ajax({
type: form.attr('method'),
url: form.attr('action'),
data: form.serialize(),
success: function (data) {
alert('ok');
}
});
In order to accomplish this task, i had to use play's javascriptRouting
This question's answer helped a lot.
I'm not experienced with jquery so writing that correctly was difficult. For those that find this, here is my final jquery that worked:
$(document).ready(function(){
$("div#results").on("click", ".hideme", function(event) {
var $form = $(this).closest("form");
var id = $form.find("input[name='id']").val();
var name = $form.find("input[name='name']").val();
var email = $form.find("input[name='email']").val();
var emailsecondary = $form.find("input[name='emailsecondary']").val();
var url = $form.find("input[name='url']").val();
$.ajax(jsRoutes.controllers.Application.createLinkedin(id, name, email, emailsecondary, url))
.done(function(data) {
console.log(data);
$form.closest('li.item').slideUp()
})
.fail(function(data) {
console.log(data);
});
});
});
Note that my submit button was class="hideme", the div that gets filled with results from the DB was div#results and the forms were contained within li's that were class="item". So what this jquery is doing is attaching a listener to the static div that is always there:
<div id="results">
It waits for an element with class="hideme" to get clicked. When it gets clicked it grabs the data from the closest form element then sends that data to my controller via ajax. If the send is successful, it takes that form, looks for the closest li and does a .slideUp()
Hope this helps

Automate AJAXed forms with Jquery

I want to improve my website and figured out a good way to do it was by submitting forms via AJAX. But, I have so many forms that it would be inpractical to do $('#formx').submit(). I was wondering if there was a way to do this automatically by making an universal markup like;
<form class="ajax_form" meta-submit="ajax/pagename.php">
<input type="text" name="inputx" value="x_value">
<input type="text" name="inputy" value="y_value">
</form>
And have this submit to ajax/pagename.php, where it automatically includes inputx and inputy?
This would not only save me a lot of time but also a lot of lines of code to be written.
First question so I hope it's not a stupid one :)
Something like this should work for all forms. It uses jQuery - is this available in your project? This specific code chunk hasn't been tested per say, but I use this method all the time. It is a wonderful time saver. Notice I changed meta-submit to data-submit so that its value can be fetched using $('.elemenet_class').data('submit');
HTML
<!-- NOTE: All Form items must have a unique 'name' attribute -->
<form action="javascript:void(0);" class="ajax_form" data-submit="ajax/pagename.php">
<input type="text" name="inputx" value="x_value">
<input type="text" name="inputy" value="y_value">
<input type="submit" value="go" />
</form>
JavaScript
$('.ajax_form').submit(function(e){
var path = $(this).attr('data-submit'); //Path to Action
var data = $(this).serialize(); //Form Data
$.post(path, {data:data}, function(obj){
});
return false;
})
PHP
//DEBUGGING CODE
//var_dump($_POST);
//die(null);
$data = $_POST['data'];
$inputx = $data['inputx'];
$inputy = $data['inputy'];
you can create ajax fot text boxes so that it can update to database whenever change the focus from it.
<form id="ajax_form1">
<fieldset>
<input type="text" id="inputx" value="x_value" />
<input type="text" id="inputy" value="y_value" />
</fieldset>
</form>
<script>
$(document).ready(function()
{
$("form#ajax_form1").find(":input").change(function()
{
var field_name=$(this).attr("id");
var field_val=$(this).val();
var params ={ param1:field_name, param2:field_val };
$.ajax({ url: "ajax/pagename.php",
dataType: "json",
data: params,
success: setResult
});
});
});
</script>

jquery ajax multiple form submission

need a little help. My jQuery was going smooth today until I hit a wall. I am trying to have multiple forms (individual line items) editable on the fly via AJAX, with a text submission link or some kind of submit button. Problem is, I can get it to submit the form via the AJAX, but without any of the data from the form... i.e. hit submit, it sends the request, but no querystring. Can someone please help me identify what's missing?
Here is my jquery:
$('.submitLineChanges').click(function() {
var formID = $(this).closest('form').attr('ID')
datastring = $(formID).serialize();
$.ajax({
type:'POST',
url: 'update_ajax.asp',
data: datastring,
success: function(response) {
alert("Success " + id)
//$('#ContactForm').find('.form_result').html(response);
}//end ajax options
});//end ajax
return false;
});//end of click function
And my form:
<form id="line-item-<%= intRecID %>-form" class="submitLineForm">
<input type="hidden" name="UpdateLineItem" value="true" />
<span class="edit" id="edit-line-<%= intRecID %>" style="display: none;">
<span class="quantity"><input name="part_qty" id="part_qty_<%= intRecID %>" type="text" value="<%=FormatNumber(rs("quote_part_qty"),0)%>"></span>
<span class="partno"><input name="part_no" id="part_no_<%= intRecID %>" type="text" value="<%=rs("quote_part_id")%>"></span>
<span class="descrip"><Textarea name="part_descrip" type="text" id="descrip<%= intRecID %>" rows="3"><%=rs("quote_part_descrip")%></Textarea></span>
<span class="sellprice">$<input name="part_sale" id="part_sale_<%= intRecID %>" type="text" value="<%=FormatNumber(rs("quote_part_sale"),2)%>"></span>
<span class="margin" id="emargin_<%= intRecID %>"><%=margin%></span>
<span class="cost"><strong>Cost: </strong>$<input name="part_cost" id="part_cost_<%= intRecID %>" type="text" value="<%=FormatNumber(cost,2)%>"></span>
<span class="wt"><strong>Weight: </strong><input name="part_wt" id="part_wt_<%= intRecID %>" type="text" value="<%=FormatNumber(rs("quote_part_wt"),2)%>"></span>
<span class="update"><input type="button" value="Save Changes" class="submitLineChanges" /></span>
</span>
</form>
As you should be able to tell, I'm running this in ASP. The form is for each line item in a cart basically. Because of the nature of the page, I don't want to have a separate page to edit all the info. It seems this should work, but its likely I'm missing something through the tunnel vision I'm in now.
I should note, the form is for each line, I don't need it to submit all the forms, just the one.
Thanks
Change
datastring = $(formID).serialize();
to
var datastring = $('#' + formID).serialize();
You need to use a # prefix using the ID selector. Also - without the var keyword you polluting the global namespace for no reason.
Or even better ... you could replace
var formID = $(this).closest('form').attr('ID');
var datastring = $('#' + formID).serialize();
with
var datastring = $(this).closest('form').serialize();
Which finds the form and serialises it all in one go !!
Thanks to #MikeBrant for that suggestion.

ajax post no update in django template

I want to post some text in django with ajax,and save the input data,show the data in same page and no refresh,like twitter.
my js:
$('#SumbitButton').click(function(){
var data_1 = $('#data_1').val()
var data_2 = $('#data_2').val()
var data_3 = $('#data_3').val()
var data_4 = $('#data_4').val()
var user = $('#AuthorName').text()
var authorprotrait = $('#UserProprait').html()
if(data_1.length>0){
$.ajax({
type: 'POST',
url: '/post/',
data:{'data_1':data_1,'data_2':data_2,'data_3':data_3,'data_4':data_4},
async: false,
error: function(msg){alert('Fail')},
success: function(msg){
$('#TopicWrap').prepend("<div class='topic-all even'><div class='topic-left'><div class='topic-author'><div class='topic-author-protrait'>"+authorprotrait+"</div><div class='topic-author-nickname'>"+authorname+"</div></div></div><div class='topic-right'><div class='topic-meta'><span class='topic-datetime'></span></div><div class='topic-content-wrap'><div class='topic-content'>"+msg+"</div></div></div><div class='clearfix'></div></div>");
$('#data_1').val('');
$('#data_2').val('');
$('#data_3').val('');
$('#data_4').val('');
}
});
} else {
alert('The data_1's length error !'+data_1.length);
}
});
and the html:
<div id="TopicTextarea">
<div>
data1:<input tabindex="4" id="data_1" type="text" name="data1" value="" maxlength="6" placeholder=""/></br>
data2:<input tabindex="4" id="data_2" type="text" name="data2" value="" maxlength="8" placeholder=""/></br>
data3:<input tabindex="4" id="data_3" type="text" name="data3" value="" maxlength="10" placeholder=""/></br>
data4:<input tabindex="4" id="data_4" type="text" name="data4" value="" maxlength="10" placeholder=""/>
<div id="TopicFormControl">
<button type="button" id="SumbitButton" class="button orange">sumbit</button>
</div>
</div>
   <div class="clearfix"></div>
</div>
<div id="TopicWrap">
{% include 'topics.html'%}
</div>
and the views:
#login_required
def post(request):
assert(request.method=='POST' and request.is_ajax()==True)
data_1 = smart_unicode(request.POST['data_1'])
data_2 = smart_unicode(request.POST['data_2'])
data_3 = smart_unicode(request.POST['data_3'])
data_4 = smart_unicode(request.POST['data_4'])
data_obj = DataPool(user=request.user,data_1=data_1,data_2=data_2,data_3=data_3, data_4=data_4)
data_obj.save()
content = '"+data_3+"  "+data_4+" "+data_1+"("+data_2+")'
response = HttpResponse(cgi.escape(content))
return response
when I input the data and click the sumbit button,it can save the data ,but it can't show the data.what's wrong in my code?
thanks.
First, use something like Poster to test that your view is returning what you expect. Only then should you start building the AJAX part.
As for what's wrong... it's a bit difficult to say since you just write that it "can't show the data" instead of saying what it's actually doing. I suspect it has to do with this line in your view:
content = '"+data_3+"  "+data_4+" "+data_1+"("+data_2+")'
It's not really clear to me what you think this would do, but what it actually does is:
>>> '"+data_3+"  "+data_4+" "+data_1+"("+data_2+")'
'"+data_3+" \xe3\x80\x80"+data_4+"\xe3\x80\x80"+data_1+"("+data_2+")'
That is to say that it produces a string containing the substrings "data_3" (etc..) It does not include the submitted data.

Resources