Solved

Custom Validator in User Control not working

Posted on 2010-08-17
13
784 Views
Last Modified: 2012-05-10
Hello,

Currently I have created a user control which uploads photos and video. This user control is added to webpage.

Now the problem I am facing is this .. I have a custom validator in the user control which keeps track of the photos uploaded ( as shown in the code section ).

The MediaCount  is property in the usercontrol like this

 public  int MediaCount
    {
        get {
            if (ViewState["Controls_UploadMediaCount"] == null)
                return 0;
            else
                return (int)ViewState["Controls_UploadMediaCount"];
            }
        set {
                ViewState["Controls_UploadMediaCount"] = value;
            }
    }

which keeps a track of the total photos uplaoded.

But even When I upload  photos for what ever reason the custom validaor fires when I hit the submit button on the page.

 var mediacount = <%= MediaCount %>; in the MediaUploadedValidator dosent seem to pulling the latest value from public property.

Is there a better way to handle such a thing ?

Thanks,
Ashwin
function MediaUploadedValidator(source, args) {

        var mediacount = <%= MediaCount %>;

        if (mediacount == 0) 

         {

             args.IsValid = false; return;             

         }



        args.IsValid = true;

    }





<asp:CustomValidator Display="None" runat="server"ID="MediaUploadValidator" 

	                    ClientValidationFunction="MediaUploadedValidator"  

                        ErrorMessage="Please upload at least one media file.">

                    </asp:CustomValidator>

Open in new window

0
Comment
Question by:AJagadish
  • 6
  • 6
13 Comments
 
LVL 33

Expert Comment

by:raterus
Comment Utility
Instead of using <%= %> syntax (which I'd avoid like the plague!), your user control can register a startup script to set the mediacount variable.

You'd register this startup script anytime the user control is loaded.

--

However, what you have technically should work, do you have any AJAX, that might hinder a full postback, which is probably needed to update this mediacount variable?
0
 
LVL 41

Expert Comment

by:guru_sami
Comment Utility
Use ValidationGroup property to differentiate different sets of Validation controls on page.
e.g. here: http://quickstarts.asp.net/QuickStartv20/aspnet/doc/validation/default.aspx#validationgroups

0
 

Author Comment

by:AJagadish
Comment Utility
raterus :You are right ... here is the structure of the control I have built ( see code )


I am using Uplodify Control (http://www.uploadify.com/) to up load files
<input id="fileInput1" name="fileInput1" type="file" width="400" />

once the files are uploaded it fires the "onComplete" event in which I do a post back of the update panel like this

_doPostBack('<%= UpdatePanel1.ClientID  %>

which basically displays the images as thumbnails in a data list.

Now the count "MediaCount" is nothing but the count of the items in the Datalist which is set in the code behind
 
MediaCount = list.Count;  

Hoping for some help

Thanks,
Ashwin




<table class="norm"  border="0" cellspacing="0" cellpadding="0">

            <tr>
	            <td colspan=20 ></td>	          
	        </tr> 
	        
            <tr id="Tr1"  runat=server >
	          
	          <td >
	              <script type="text/javascript">
	                  // <![CDATA[
	                  var id = "55";
	                  var theString = "asdf";
	                  $(document).ready(function() {
	                      $('#fileInput1').uploadify({
	                          'uploader': '../uploadify/uploadify.swf',
	                          'script': '../Upload.ashx',
	                          'cancelImg': '../uploadify/cancel.png',
	                          'auto': true,
	                          'multi': true,
	                          'fileDesc': 'Image Files',
	                          'fileExt': '*.jpg;*.png;*.gif;*.bmp;*.jpeg;*.wmv;*.flv',
	                          'queueSizeLimit': 1,
	                          'sizeLimit': 40000000,
	                          'buttonText': 'Choose Files',
	                          'folder': '/uploads',
	                          'onComplete': function(event, queueID, fileObj, response, data) {

	                              if (response == "FileUploaded") {
	                                  __doPostBack('<%= UpdatePanel1.ClientID  %>', '');
	                              } else {
	                                  alert(response);
	                              }
	                          }
	                      });
	                  });
	                  // ]]></script>			    
			      <input id="fileInput1" name="fileInput1" type="file" width="400" />
			  </td>
	                  
	          <td width=25></td>
	          
	        </tr>   
             
            <tr>
	            <td colspan=2 height="25" >
	                <asp:HiddenField ID="hid_uploadedmediaCount" runat="server"  />
	            </td>	          
	        </tr> 
	        
	        <tr>
	            <td colspan=2 >
	            
	           <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
                <ContentTemplate>  
                     
                     <asp:DataList ID="MediaDataList" runat="server" RepeatColumns="5" CellPadding="5" 
                         onitemcommand="MediaDataList_ItemCommand" 
                         onitemdatabound="MediaDataList_ItemDataBound"  >
                        <ItemTemplate>                          
                             
                            <a id="thumb1"    runat=server  class="highslide" onclick="return hs.expand(this)">
	                               <asp:Image id="img1"  runat=server   BorderColor=Black BorderWidth=1 
	                                BorderStyle=Ridge  Width="40" Height="40"     class="thumbSelected"  ></asp:Image>
	                        </a>	
	                        <br />                        
                            <asp:LinkButton ID="lnkDelete" CausesValidation="false"  runat="server" CssClass="norm" Text="Delete"  ></asp:LinkButton>
                        </ItemTemplate>
                        <ItemStyle BorderColor="silver" BorderStyle="dotted" BorderWidth="3px" HorizontalAlign="Center"
                        VerticalAlign="Bottom" />
                   </asp:DataList>                           
                </ContentTemplate>
                
            </asp:UpdatePanel>
            </td>
	          
	        </tr>              
	    	
	        
	        <tr>
	             <td height="20" colspan="2" align=center >
	                <asp:Label ID="Label1" runat=server Visible=false></asp:Label>
	                <asp:CustomValidator Display="None" runat="server" ID="MediaUploadValidator" 
	                    ClientValidationFunction="MediaUploadedValidator"  
                        ErrorMessage="Please upload at least one media file.">
                    </asp:CustomValidator>  
	             </td>
	        </tr>      
        </table>

Open in new window

0
 
LVL 33

Expert Comment

by:raterus
Comment Utility
When you have a server side event after they upload a file, run this code.  I think it'll work.

ScriptManager.RegisterStartupScript(this, this.GetType(), "updateUploadCount", "mediaCount=" + MediaCount.ToString() + ";", true);

This will ensure the mediacount javascript variable is updated properly.
0
 

Author Comment

by:AJagadish
Comment Utility
raterus: This is what I did I created a function like this


   private void EmitCustomValidator(string count )
    {
        string customValidator = "function MediaUploadedValidator(source, args)"
              + "{"

                       + "alert(" + count + ");"
                       + "mediacount =" + count + ";"
                       + "if (mediacount == 0)"
                       + "{"

                       + "alert('Iargs.IsValid = false; return;');"
                       + "args.IsValid = false; return;"

                   
                       + "}"
                       + "args.IsValid = true;"
                 + "}";

        ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "CustValidator", customValidator + ";", true);
    }



And I am calling this function on page load like this

 if (!Page.IsPostBack)
        {
            EmitCustomValidator("0");
        }

and once when the Datalist is bound in the DisplayMedia() function which is called in the Page_Load function.

 EmitCustomValidator(list.Count.ToString());


So my page load looks like this


 protected void Page_Load(object sender, EventArgs e)
    {
         DisplayMedia();

        if (!Page.IsPostBack)
        {
            EmitCustomValidator("0");
        }

    }


  DisplayMedia(); only binds to the datalist when there are files to be bound in the particular folder it looks at .. so the first time the page is loaded the datalist is not bound because there are no files to be bound.


When I run this .. it still doesnt update the count .. it still displays 0 even after I upload files...

Does the RegisterClientScriptBlock need to be called on pre render event or some where else ?

Thanks
Ashwin

0
 
LVL 33

Expert Comment

by:raterus
Comment Utility
You don't need to re-emit the entire javascript after they upload something, you just need to register a startup script to update the javascript mediacount variable.

Look back at my last example, and put that code in the section that you were describing (below)

""and once when the Datalist is bound in the DisplayMedia() function which is called in the Page_Load function.""

(Put the code from my last post)
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:AJagadish
Comment Utility
Okay here is what I tried ..

This is the Javscript function I have in UploadMedia.ascx file

 <script type="text/jscript">

      function MediaUploadedValidator(source, args)
      {
          var mediacount = 0;
          alert(mediacount);
         
          if (mediacount == 0)
          {
              args.IsValid = false; return;
              alert('Inside mediacount.value == 0');
          }
          args.IsValid = true;
      }
</script>


The page load looks like this

    protected void Page_Load(object sender, EventArgs e)
    {
         DisplayMedia();
     }


In the DisplayMedia() function only when files are uploaded the datalist bound and after the datalist is bound I have added this

            ScriptManager.RegisterStartupScript(this, this.GetType(), "updateUploadCount", "mediacount=" + list.count.ToString() + ";", true);


But for what ever reason it dosent want to update the count .. it keeps displaying 0.

:(

Hoping for some help ...






0
 
LVL 33

Expert Comment

by:raterus
Comment Utility
Add an alert() script in the RegisterStartupScript to output the list.count value, and let me know if a) you see it popup and b) it has the value you are after.

Also, do you see any other javascript errors?
0
 

Author Comment

by:AJagadish
Comment Utility
I added this


            ScriptManager.RegisterStartupScript(this, this.GetType(), "updateUploadCount", "mediacount=" + list.Count.ToString()
                                                + "; alert('RegisterStartupScript Count='"+ list.Count.ToString() +"');", true);
     
I dont get any alert messages ... and there are no other javascript errors... and when i view source and search for "RegisterStartupScript Count" .. there is no trace of it either...

i can zip up the code and you can take a look at it if you dont mind ?


0
 
LVL 33

Accepted Solution

by:
raterus earned 500 total points
Comment Utility
Yes, that was going to be my next suggestion, to see the complete code file
0
 

Author Comment

by:AJagadish
Comment Utility
raterus: I have uploaded the whole website ... its a a temp website that i created for the purpose of testing.

Its created in VS2008.

The following are the important files to consider.

Controls/ UploadFiles.ascx   - Has the uplodify control
Pages/Test.aspx

The Test.aspx page has a question with a radiobutton list as an answer, if the user chooses Yes then the upload control is displayed. Where the user can select an image and upload it..

Now when I tried this

ScriptManager.RegisterStartupScript(this.UpdatePanel1, typeof(string), "alertScript", "alert('Error Message');", true);


It shows the alert ... the only thing I changed was

this --> this.UpdatePanel1
typeof(this) --> typeof(string)

But When I try

ScriptManager.RegisterStartupScript(this, this.GetType(), "updateUploadCount", "mediacount=" + list.Count.ToString() + "; alert('RegisterStartupScript Count='"+ list.Count.ToString() +"');", true);

It only displays the alert message but it dosent update the mediacount.

Please do let me know if you have trouble with this code.

Thanks a lot for all the help until now.

Ashwin

P.S: IMPORTANT: After unzipping the file please rename the file Upload.txt(Uploadify\Upload.txt) to Upload.ashx, i had to rename it to .txt extension as it would not allow me to upload a file with ashx extension.







Uploadify.zip
0
 

Author Comment

by:AJagadish
Comment Utility
Whooo hoooo !! I got it working !! :)  Thanks for all the help

This is the fucntion I used

   private void EmitCustomValidator(string count)
    {
        string customValidator = "function MediaUploadedValidator(source, args)"
              + "{"

                       + "alert(" + count + ");"
                       + "mediacount =" + count + ";"
                       + "if (mediacount == 0)"
                       + "{"

                       + "alert('Iargs.IsValid = false; return;');"
                       + "args.IsValid = false; return;"


                       + "}"
                       + "args.IsValid = true;"
                 + "}";

        ScriptManager.RegisterClientScriptBlock(this.UpdatePanel1, typeof(string), "CustValidator", customValidator + ";", true);
    }

I call this function on Page_Load() like this EmitCustomValidator("0");

and when the files are uploaded in the DisplayMedia() function like
EmitCustomValidator(list.count.tostring());

I also the removed the static Javasript function
  <script type="text/jscript">

      function MediaUploadedValidator(source, args)
      {
          var mediacount = 0;
          alert(mediacount);
         
          if (mediacount == 0)
          {
              args.IsValid = false; return;
              alert('Inside mediacount.value == 0');
          }
          args.IsValid = true;
      }
</script>

Since I was emitting the javascript from code behind.

The other change that worked was

using  this.UpdatePanel1, typeof(string)

instead of this,typeof(this)

        ScriptManager.RegisterClientScriptBlock(this.UpdatePanel1, typeof(string), "CustValidator", customValidator + ";", true);


Iam not sure if emttting the entire javasript function is the right apporach but it works for me. If you can think of doing it in a better way please do let me know.

Thanks for guiding me in the right direction ..

and the following link helped me too

http://fredrik.nsquared2.com/ViewPost.aspx?PostId=430

Thanks,
Ashwin




0
 
LVL 33

Expert Comment

by:raterus
Comment Utility
Great!, glad to hear you got it working.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Article by: DanRollins
This article describes a JavaScript program that creates a maze made of hexagonal cells.  In Part 2 (http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/A_7850-Hex-Maze-Part-2.html), we'll extend the program by adding a depth-…
Real-time is more about the business, not the technology. In day-to-day life, to make real-time decisions like buying or investing, business needs the latest information(e.g. Gold Rate/Stock Rate). Unlike traditional days, you need not wait for a fe…
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

744 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

12 Experts available now in Live!

Get 1:1 Help Now