Solved

Preventing databind when page is invalid

Posted on 2006-06-13
5
430 Views
Last Modified: 2008-02-01
I have a page set up as follows:

A TextBox that accepts a value, which will be used as a parameter in the ObjectDataSource
A CustomValidator on that textbox (it checks to make sure the string represents a date)
A GridView, with an associated ObjectDataSource, having a SelectParameter set to the TextBox.

My problem is that the GridView rebinds on every postback, causing a problem if the textbox is invalid, the database will throw an exception.  Ideally, I would like the page to simply display the form again, with the old GridView data, and an error message from the Validators.  I thought this would be built in, because why would anybody want to use an invalid control as the source of a parameter.

If I'm confusing you, I can post snippets of my code to help clarify.
0
Comment
Question by:marker126
  • 4
5 Comments
 
LVL 7

Expert Comment

by:kGenius
Comment Utility
First you can read this post on 4guysfromrolla: http://aspnet.4guysfromrolla.com/demos/IsPrime.Client.aspx

You should check "if (Page.IsValid) { }" before you do you're databind...

Hope this help,
you can always post the code if you want more help.

kGenius
0
 

Author Comment

by:marker126
Comment Utility
Maybe I should clarify my situation:

I'm using ASP.NET 2.0, and the GridView is set at design-time to use the ObjectDataSource.  I have written no code to actually control the binding of the GridView, it has all been done for me (which is one of my biggest complaints about 2.0, a great deal of the details have been hidden)

<asp:TextBox ID="txtBeginDate" runat="server" CausesValidation="True"></asp:TextBox>

<asp:CustomValidator ID="valBeginDate" runat="server"
   ControlToValidate="txtBeginDate"></asp:CustomValidator>

<asp:GridView ID="gvData" runat="server" AutoGenerateColumns="True"></asp:GridView>

<asp:ObjectDataSource ID="dsData" runat="server"
      OldValuesParameterFormatString="original_{0}"
      SelectMethod="GetData"
      TypeName="dsOrders.OrdersTableAdapter">
   <SelectParameters>
      <asp:ControlParameter ControlID="txtBeginDate" Name="BeginDate" PropertyName="Text"
            Type="DateTime" />
   </SelectParameters>
</asp:ObjectDataSource>

So when txtBeginDate/valBeginDate is invalid, I want to prevent the GridView/ObjectDataSource from using the textbox to bind data.
0
 
LVL 7

Expert Comment

by:kGenius
Comment Utility
You could write a javascript with a function called ValidateDate(sender, args) { }

This function must return args.IsValid=false; when the date is not valid.

ie
<SCRIPT LANGUAGE="javascript" >
function ValidateDate(sender, args) {

  bValidDate= //check date here returns boolean;

  if (bValidDate) {
    args.IsValid=true;
    return;
  } else {
    args.IsValid=false;
    return;
  }
}
</SCRIPT>


Add an extra attribute to the customvalidator
<asp:CustomValidator ID="valBeginDate" runat="server" ClientValidationFunction="ValidateDate"
   ControlToValidate="txtBeginDate"></asp:CustomValidator>

That should do...
When the function rejects the arguments as invalid no postback will occur. And no databinding or what so ever that happens server-sided.

kGenius
 
 
0
 
LVL 7

Accepted Solution

by:
kGenius earned 500 total points
Comment Utility
I did some homework for you:

create This Customvalidator: <asp:CustomValidator ID="valBeginDate" runat="server" ClientValidationFunction="ValidateDate" ControlToValidate="txtBeginDate"></asp:CustomValidator>


Add this javascript to your header: (this one checks if a date is in mm/dd/yyyy format)
This works perfect with me...


<script language="javascript">

// Declaring valid date character, minimum year and maximum year
var dtCh= "/";
var minYear=1900;
var maxYear=2100;

function isInteger(s){
      var i;
    for (i = 0; i < s.length; i++){  
        // Check that current character is number.
        var c = s.charAt(i);
        if (((c < "0") || (c > "9"))) return false;
    }
    // All characters are numbers.
    return true;
}

function stripCharsInBag(s, bag){
      var i;
    var returnString = "";
    // Search through string's characters one by one.
    // If character is not in bag, append to returnString.
    for (i = 0; i < s.length; i++){  
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }
    return returnString;
}

function daysInFebruary (year){
      // February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 );
}
function DaysArray(n) {
      for (var i = 1; i <= n; i++) {
            this[i] = 31
            if (i==4 || i==6 || i==9 || i==11) {this[i] = 30}
            if (i==2) {this[i] = 29}
   }
   return this
}

function isDate(dtStr){
      var daysInMonth = DaysArray(12)
      var pos1=dtStr.indexOf(dtCh)
      var pos2=dtStr.indexOf(dtCh,pos1+1)
      var strMonth=dtStr.substring(0,pos1)
      var strDay=dtStr.substring(pos1+1,pos2)
      var strYear=dtStr.substring(pos2+1)
      strYr=strYear
      if (strDay.charAt(0)=="0" && strDay.length>1) strDay=strDay.substring(1)
      if (strMonth.charAt(0)=="0" && strMonth.length>1) strMonth=strMonth.substring(1)
      for (var i = 1; i <= 3; i++) {
            if (strYr.charAt(0)=="0" && strYr.length>1) strYr=strYr.substring(1)
      }
      month=parseInt(strMonth)
      day=parseInt(strDay)
      year=parseInt(strYr)
      if (pos1==-1 || pos2==-1){
            return false
      }
      if (strMonth.length<1 || month<1 || month>12){
            return false
      }
      if (strDay.length<1 || day<1 || day>31 || (month==2 && day>daysInFebruary(year)) || day > daysInMonth[month]){
            return false
      }
      if (strYear.length != 4 || year==0 || year<minYear || year>maxYear){
            return false
      }
      if (dtStr.indexOf(dtCh,pos2+1)!=-1 || isInteger(stripCharsInBag(dtStr, dtCh))==false){
            return false
      }
return true
}

function ValidateDate(sender, args){
alert(args.Value);
      if (isDate(args.Value)==false){
            args.IsValid=false;
            return;
      }
    args.IsValid=true;
            return;
 }
</script>
0
 
LVL 7

Expert Comment

by:kGenius
Comment Utility
just one last correction you should remove "alert(args.Value);" in the javascript (in ValidateDate function).
That one was for testing
kGenius
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Sometimes in DotNetNuke module development you want to swap controls within the same module definition.  In doing this DNN (somewhat annoyingly) swaps the Skin and Container definitions to the default admin selections.  To get around this you need t…
ASP.Net to Oracle Connectivity Recently I had to develop an ASP.NET application connecting to an Oracle database.As I am doing it first time ,I had to solve several problems. This article will help to such developers  to develop an ASP.NET client…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now