Add a new item into the table and database and have it immediately sortable, pageable, etc without any postback
This is a continuation of my
'REAL' AJAX with Asp.Net (not Asp.Net AJAX)
series posts for those of us trying to stop relying on Asp.Net 'AJAX'.
This is probably the hardest part about a full CRUD (Create, Read, Update, Delete) system, but as we have already covered 'RUD', it's time to hit the 'C'.
First of all, we have to break down what will be happening, both on the client-side, and the server side, then it will be easier to dissect.
- User pulls up a 'New Entry' dialogue (client)
- User enters information and it is validated (client*)
- Valid information is sent to the server (client)
- Server attempts to add in new item (server)
- Server spits back status update (server)
- status update is displayed (client)
- item is added into the visible table (client)
- input fields are cleared and the input dialogue is hidden (client)
The * above denotes that while in this example we are doing only client-side validation, it is in your best interest to add in some server side as well
(keep in mind that this example will not work without javascript, so it is not robust and does not 'gracefully' degrade).
As you can see, most of the heavy lifting here is done on the client side, with the server doing just a couple things.
set up the entry dialogue
First I am adding a couple divs which will be clicked to open the dialogue:
insert.aspx
<div class="button triggerNew">New Entry</div>
In the CSS, you can see that these will render like buttons:
demo.css
.button
{
width: 100px;
font-weight: bold;
border: outset 2px blue;
padding: 1px;
text-align: center;
color: Blue;
}
.button:hover
{
border-style: inset;
cursor: pointer;
padding: 2px 0 0 2px;
}
To go with the whole ajax feel, I am setting up the entry in a modal popup;
you probably noticed the class 'triggerNew' which isn't really a css class, but it will be used to by jQuery to hook into any elements that have that class and tie them to the modal.
To do that first we must include the
jquery.jqModal plugin (which IMO is the best modal plugin as it is minimalist and customizable as well as easy to use)
in our masterpage.
demo.master
<script type="text/javascript" src="js/jquery.jqModal.js"></script>
As for the modal popup, here is the markup:
<div class="jqmWindow" id="new">
<h3 class="modal_header">
<div class="working">working...</div>
<a href="#" class="x jqmClose">X</a>
Add New Entry
</h3>
<div class="pad">
<div class="left">
<h4>
<asp:RequiredFieldValidator ID="rfvFirst" ControlToValidate="txtFirst" CssClass="right"
ErrorMessage="required" runat="server" ValidationGroup="new" />
First Name
</h4>
<input type="text" ID="txtFirst" runat="server" />
</div>
<div class="left">
<h4>
<asp:RequiredFieldValidator ID="rfvLasst" ControlToValidate="txtLast" CssClass="right"
ErrorMessage="required" runat="server" ValidationGroup="new" />
Last Name
</h4>
<input type="text" ID="txtLast" runat="server" />
</div>
<div class="left">
<h4>
<asp:RegularExpressionValidator ID="regAge" ControlToValidate="txtAge" CssClass="right"
ErrorMessage="1-3 digits" runat="server"
Display="dynamic" ValidationGroup="new" />
<asp:RequiredFieldValidator ID="rfvAge" ControlToValidate="txtAge" CssClass="right"
ErrorMessage="required" runat="server"
Display="dynamic" ValidationGroup="new" />
Age
</h4>
<input type="text" ID="txtAge" runat="server" />
</div>
<div class="summary">
<div id="submit" class="button">Submit</div>
</div>
</div>
</div>
Now there is a lot going on there.
First of all, I used the Asp.Net validators as we are most familiar with them, and
they play nicely with jQuery.
Also, I am not using
asp:TextBoxes at all, I am sticking with the basic
input boxes.
But, because I am using the Asp.Net Validators, I still need to include
runat="server" with each
input that I Validate;
this also means that they will get weird Asp.Net IDs and not the exact ones I
assign them.
All I am doing here is making sure all the fields have values, and that age is a diget with 1-3 digits (yes, someone can be 999 in this system...).
In addition, the css class 'jqmClose' class is included in a link: this will automatically be assigned to close the modal window by jqModal.
I also put an additional 'working' element in there so the user can see that dialogue while the program is running its magic.
But as it stands now, we can't even see that popup, get the validators to fire or submit any sort of data.
Here comes the jQuery.
work the jQuery magic
Here is the script, it is explained in the comments:
//assign all 'triggerNew' elements to open the modal dialogue
$('#new').jqm({ trigger: false }).jqmAddTrigger($('.triggerNew'));
//attach this event to the clicking of the 'submit' div
$("#submit").click(function() {
//will not do anything if the validators don't check out
//Page_ClientValidate('ValidationGroup') is an Asp.Net generated function
if (!Page_ClientValidate('new')) { return false; }
else {
// get the values from the textboxes into an array
// notice that this is using .ClientID to get the strange Asp.Net ID assigned to it
var vals = [
$("#<%= txtFirst.ClientID %>"),
$("#<%= txtLast.ClientID %>"),
$("#<%= txtAge.ClientID %>")
];
// do the ajax post
$.post(
//function is at
"ajax_functions/insert.aspx",
//send the values frorm the vals object
{ first: vals[0].val(), last: vals[1].val(), age: vals[2].val() },
function(data) {
//output the return data
$("#report").html(data);
// the class 'success' was sent back if it worked...
var success = (data.toString().substring(12, 19) == "success");
//add the new data into the table so the user can see it if it was successful
if (success) {
oTable.fnAddData([
vals[0].val(),
vals[1].val(),
vals[2].val(),
' '
]);
//clear the textboxes
$(vals).each(function() { $(this).val('') });
}
//hide the modal now that it's done
$('#new').jqmHide();
}
);
}
});
Note that this will not allowed items added since the last postback to be deleted/edited, that is why the last cell simpy gets an ' '.
Keep in mind that it is possible, just beyond the scope of this tutorial.
Also, in a ghetto form of error reporting, I passed the css class which will
either be 'error' on error, or 'success' otherwise. We can use that to
decide whether or not to post the new data into the table and to clear the
inputs. This will catch any errors that we did not already account for.
Really all that remains is the server-side part, we need to make the page that is called: "ajax_functions/insert.aspx" to handle the inputs passed.
server-side functions
Notice this time that we used a $.post() method, which sends the stated values and returns something - in this case, we are having it return a chunk of html which will tell us what happened with the server, and it will be pushed into the 'report' div.
Here is our server operations:
ajax_functions/insert.aspx.cs
using System;
public partial class ajax_functions_insert : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
demoDataContext db = new demoDataContext();
try
{
// get all the new values
string first = Request.Form[0];
string last = Request.Form[1];
int age = Convert.ToInt32(Request.Form[2]);
//make a new person
person p = new person()
{
first_name = first,
last_name = last,
age = age
};
//insert them into the db
db.persons.InsertOnSubmit(p);
db.SubmitChanges();
//if it was all successful
Response.Write("<div class='success'>" + first + " " + last + " [" + age + "] inserted</div>");
}
// this will catch all the errors and output an error message if caught
catch (Exception ex)
{
Response.Write("<div class='success'>Error: " + ex.Message +"</div>");
}
}
}
As usual, this is the easy part. Now you have a full working CRUD system, with some pretty good error catching as such with absolutely no postbacks!
Ajax is fun and can be quite useful, I hope these tutorials helped make it a little more accessible to some Asp.Net devs, I know I learned a lot making them.
« Deleting