Coding Conundrums

Icon

Justin Obney – Learning Through Doing

ASP.Net, JSON, and Web Services

Everyone knows that web2.0 is quickly becoming the new web standard. With CSS3, HTML5, and JavaScript becoming standards rather than just options, web developers are now beginning to build web apps that many never thought they would see in the browser.

Today I want to talk a little bit about AJAX in ASP.Net. First let me say that I am an ASP.Net web developer. I learned to make web apps in ASP.Net before I even knew what most of the controls corresponding HTML tags were. So once I began trying to use AJAX in my sites/apps, the first way I began to get data was through some response.write and code-behind hacks. I would do all  my processing in the code behind, format my HTML string I wanted to return, and use a jQuery $.get call to fetch the HTML the response.write would output.

I know it was ugly, but I was learning.

As my data needs began to get bigger and bigger, I had to find a more efficient way to do this. I had looked at JSON a little, and had seen how a lot of the jQuery Plugins I used would implement JavaScript objects to affectively manipulate data. As I began looking more into this, I quickly determined this was the way I needed to send my data across the wire.

Now how?

Because I had now had much experience with ASP.Net web services, I quickly turned to the old hack it up method again. This meant making my JSON objects and arrays of objects in a code-behind of a page, and sending them across as a string. This turned out to be a very frustrating way to handle this, and again I knew there had to be a better way. Digging a little more into I learned that if you use a web service, ASP.Net will greatly simplify the process. I will explain in a little more detail.

First lets start with the web service..

Begin by creating a new ASP.Net web service (ASMX) file. Open the code behind and add the following ScriptService attribute to allow ASP.Net to know how to handle the code.

1
2
Public Class QuickLookup
Inherits System.Web.Services.WebService End Class

Then i create a simple structure to send the data back. The real beauty is here because ASP.Net will automatically create JSON objects and return them.

1
2
3
4
5
6
7
Public Structure FormData
        Public property1 As String
        Public property2 As String
        Public property3 As Double
        Public property4 As Integer
        Public earned As Double
    End Structure

Because I am using a master page and don’t want to register this script with all pages that inherit from it, I will add a reference to the script in the code-behind of this single .aspx page. By doing this, ASP.Net will automatically create a proxy class for the object that can be accessed through the pages javascript.

1
2
3
4
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim sman As Web.UI.ScriptManager = ScriptManager.GetCurrent(Me)
        sman.Services.Add(New System.Web.UI.ServiceReference("PATH TO ASMX FILE"))
    End Sub

Next, add the function to the code behind of your web service file

1
2
3
4
5
6
7
8
9
10
    Public Function SearchCustomForms(ByVal FormName As String) As List(Of FormData)
        Dim searchResults As New List(Of FormData)
            Dim thisForm As New FormData
            thisForm.property1 = "Something"
            thisForm.property2  = "Something"
            thisForm.property3  = 5
            thisForm.property4  = "Something"
            searchResults.Add(thisForm)
        Return searchResults
    End Function

Then with a little jQuery magic, you can access the objects like so:

?View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
$(function() {
        $('#btnGetForms').click(function() {
            QuickLookup.SearchCustomForms($("#txtSearch").val(),Pass, Fail, null);
        });
    });
    function Pass(result, context) {
        alert(result[0].property1);
     };
    function Fail(result, context) {
        alert('Fail - ' + result);
    };

The Pass Fail function calls are REALLY important here. ASP.Net automatically creates this, so you must implement it. The Pass is the function that will be called on a successful AJAX call, the fail.. well you get the idea. The last null value is the context.. I am still learning this, so check back later for updates. As of now i am not using this parameter but need to include it to work. Any other parameters you need to send, like the value of the textbox I am sending, add to the beginning of the function call.
Well blog world. I have some work to get back to. As always, all comments or questions are welcome.

Some simple jQuery validation

Is this blog becoming solely about jQuery?

Nah, its just what I’m learning at the moment.

First let me say I realize there may be better ways to do some of these or plugins already built, but oh well. I am having fun learning to think better. I do see a small plug-in that will provide validation to come… I just need time. Also note that for now I have added all these functions to my standard jquery-1.3.2.min.js file, however will probably split them out into a validation.js file to couple with a validation.css soon.

Here are some functions I have been implementing. Keep in mind some are still incomplete, just having covered what I needed them for at the moment. If you have any suggestions please comment.

?View Code JAVASCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<code>/*Use the following one-line validations 
 
	$(function(){ValidateTxtbox($('#' + ''),$('#' + ''),'You must enter a Description')});
	$(function(){ValidateTxtboxType($('.ClassName'),$('.ClassName'),'You must enter a valid currency for Bid Value','currency')});
 
		-- Use ($('#' + '') an element by its ASP.Net ID
		-- Use ($('#HTML_ELEMENT_ID') an element by its ID  on HTML elements
		-- Use ($('.CONTROL_CLASS_NAME') to get the element by its class  (ASP.Net or HTML)
 
with below functions located in iN-dev jQuery file*/
 
    //This one is simply validating anything in the textbox except null
	function ValidateTxtbox(submitButton,txtBox,message){
		$(submitButton).click(function(){
            if($(txtBox).val() == ''){
                alert(message);
                return false;
            }
        })
	}
 
	//This function wants a type to validate by. Currently currency and email are valid parameters
	function ValidateTxtboxType(submitButton,txtBox,message,type){
		$(submitButton).click(function(){
            if($(txtBox).val() == '' || ValidateType($(txtBox).val(),type)){
                alert(message);
                return false;
            }
        })
	}
 
	//validating each type
	function ValidateType(data,type){
	    switch(type)
        {
        case 'currency':
            return isUSCurrency(data);
        break;
        case 'email':
            return validate(data);
        break;
        default:
            return false
        }
	}
 
//regex currency Valid values = #.##, $#.##, $####	INVALID: .##
function isUSCurrency (sString) {
	  return !(RegExp(/^\$?\d+(\.\d{2})?$/).test(String(sString).replace(/^\s+|\s+$/g, "")));
}
 
//Validates Emails
function validate(email) {
   var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
   var address = email
   if(reg.test(address) == false) {
      return false;
   }
}
 
    $(function(){
			//Gives 'highlight' class to input with current focus
            $("input, textarea").focus(function(){
                $(this).addClass('highlight');
            });
			//Removes 'highlight' class on blur
            $("input, textarea").blur(function(){
                $(this).removeClass('highlight');
            });
            //Gives all elements with class 'DeleteButton' a default "Delete Confirmation Dialog"
            $('.DeleteButton').click(function(){
                return confirm('Are you sure you want to delete this item?');
            });
    });<span style="font-family: Georgia; font-size: small;"><span style="line-height: 19px; white-space: normal;">
</span></span></code>

JQuery Checkbox Select All

Another "Gotcha"

Another "Gotcha"

Hello again world,

Today I was again able to implement a jQuery solution at work. The problem was a follows:

We had a asp:Gridview with selections for a report setup. In the gridview there was a asp:checkbox field that determined which entities the report would be run on. As  with most multiple checkbox selections we wanted a select all checkbox, so my first though was jQuery. However my first try at the script was doing nothing and I couldn’t see the problem.

The layout was:

1
2
<asp:CheckBox ID="CheckThis" runat="server" Text="Main" CssClass="ChkMain" />
<asp:CheckBox ID="CheckBox1" runat="server" Text="check me" CssClass="ChkChild" />
?View Code JAVASCRIPT
1
2
3
4
5
$(document).ready(function(){
	$('.ChkMain').click(function(){
		$('.ChkChild').attr('checked',$(this).attr('checked'));
	});
});

Everything appeared as it was correct but nothing would come back for the checked attribute of the elements jQuery selected. After alot of digging and using Chrome’s “inspect element” feature (which IMO totaly beat IE’s Developer Toolbar) And then i came upthis:

1
2
3
4
<span class="ChkMain">
<input id="ctl00_..._CheckThis" type="checkbox" name="ctl00$...1$CheckThis" />
<label for="ctl00_..._CheckThis"&gt;Main&lt;/label>
</span>
<span>
<input id=”ctl00_ContentPlaceHolder1_CheckThis” type=”checkbox” name=”ctl00$ContentPlaceHolder1$CheckThis” />
<label for=”ctl00_ContentPlaceHolder1_CheckThis”>Main</label>
</span>

It appears that the asp.Net Runtime Engine renders the elements in a <span> tag and puts the CssClass you assign on the <span> tag rather than on the <input> that is rendered. Naturally this would prevent jQuery from being able to evaluate the .attr(‘checked’) as there is no checked attribute on the <span> tag. After learning this behavior of the asp:Checkbox the solution became more apparent. Select the <input> elements that are children of the class set on the asp:Checkbox. This worked beautiful

1
2
<asp:CheckBox ID="CheckThis" runat="server" Text="Main" CssClass="ChkMain" />
<asp:CheckBox ID="CheckBox1" runat="server" Text="check me" CssClass="ChkChild" />
?View Code JAVASCRIPT
1
2
3
4
5
$(document).ready(function(){
	$('.ChkMain input').click(function(){
		$('.ChkChild input').attr('checked',$(this).attr('checked'));
	});
});

Donations Accepted Here

Bookmarks

Buy Me Something

Proven Portals: Best Practices for Planning, Designing, and Developing Enterprise Portals
Proven Portals: Best Practices for Planning, Designing, and Developing Enterprise Portals