Custom Validator in User Control not working

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

AJagadishAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

raterusCommented:
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
guru_samiCommented:
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
AJagadishAuthor Commented:
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
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

raterusCommented:
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
AJagadishAuthor Commented:
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
raterusCommented:
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
AJagadishAuthor Commented:
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
raterusCommented:
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
AJagadishAuthor Commented:
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
raterusCommented:
Yes, that was going to be my next suggestion, to see the complete code file
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
AJagadishAuthor Commented:
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
AJagadishAuthor Commented:
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
raterusCommented:
Great!, glad to hear you got it working.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
ASP.NET

From novice to tech pro — start learning today.