views:

1403

answers:

14

I am using jQuery to try and trigger a method when a ASP.Net (2.0) dropdown list's change event is handled by jQuery. The problem is that the drop down list is located inside a gridview and even then only when a user has decided to edit a row within that gridview.

I think I have it picking up the object using a ASP code block but the problem with that is that when the page first loads the edit index of the row does not exist and it throws an error. Putting the block inside a IF statement also does not work.

$(document).ready(function() //when DOM is ready, run containing code
{
  <% if (grvTimeSheets.EditIndex > -1) {%>
      $(#<%=grvTimeSheets.Rows[grvTimeSheets.EditIndex].FindControl("ddlClients").ClientID %>).change(function() { 
           $(#<%= grvTimeSheets.ClientID %>).block({ message: null }
        }); 
}
);
 <% } %>

Is one attempt I made, I also tried putting the IF statement ASP code outside the JavaScript block. Doesn't work either.

Anyone with any ideas on how could I apply the jQuery event to the drop drop box? Ideally as concise as possible.

Thanks!

+2  A: 

A couple of things here.

  1. You need to wrap your selectors in quotes when you pass them to the $() function. The code snippet above generates something like $(#some-generated-id), which won't work.
  2. The closing curly brace for your server side if statement was outside the onready function. It needs to be nested at the same level as the opening if.

Try this one:

$(document).ready(function() //when DOM is ready, run containing code
{
  <% if (grvTimeSheets.EditIndex > -1) {%>
      var id = '#<%=grvTimeSheets.Rows[grvTimeSheets.EditIndex].FindControl("ddlClients").ClientID %>';
      $(id).change(function() { 
           $(id).block({ message: null }
        }); 
 <% } %>
}
);

If it doesn't work, go ahead and paste the generated javascript as well.

MrKurt
A: 

Thanks for the answer but Nope, Doesn't work :(. The JavaScript seems not to be outputted...Confusing....

<script type="text/javascript" src="jquery.js"></script>  
 <script type="text/javascript" src="jquery.tablesorter.js"></script> 
 <script type="text/javascript" src="jquery.blockUI.js"></script> 
 <script type="text/javascript">
$(document).ready(function() //when DOM is ready, run containing code
 {

 }
 );
</script>

Is the output. Even though this is the code:

<script type="text/javascript" src="jquery.js"></script>  
 <script type="text/javascript" src="jquery.tablesorter.js"></script> 
 <script type="text/javascript" src="jquery.blockUI.js"></script> 
 <script type="text/javascript">
$(document).ready(function() //when DOM is ready, run containing code
{<% if (grvTimeSheets.EditIndex > -1) {%>
  var id = '#<%=grvTimeSheets.Rows[grvTimeSheets.EditIndex].FindControl("ddlClients").ClientID %>';
  $(id).change(function() { 
       $(id).block({ message: null }
    }); 
 <% } %>
}
);
</script>

It was doing that before as well, driving me CRAZY

Damien
+1  A: 

I used the Page.ClientScript to register a script block to contain any id's I need to access with JQuery.

http://msdn.microsoft.com/en-us/library/system.web.ui.page.clientscript.aspx

Here is an example of my JavaScript in an external file: var myFancySelector = '#' + myControlId; selectedValue = $(myFancySelector).val();

myControlId is defined from the code behind and registerd in the ClientScriptBlock.

OutOFTouch
A: 

Sorry, Could you make that slightly clearer. I tried defining the entire thing is code behind like so:

DropDownList ddl (DropDownList)grvTimeSheets.Rows[grvTimeSheets.EditIndex].FindControl("ddlClients");
 if (ddl != null)
 {
     ClientScriptManager csm = Page.ClientScript;
     Type cstype = this.GetType();
     String csname1 = "PopupScript";

      string script = @"
      <script language='javascript' type='text/javascript'>
      $(#" + ddl.ClientID + ").change(function() { $(" + grvTimeSheets.ClientID + ").blockUI({ message: null }});} </script>";
            csm.RegisterStartupScript(cstype, csname1, script, true);

  }

Is that what you meant?

btw, above didnt work. No errors, just no events worked.

Damien
+1  A: 

Use this : cs.RegisterClientScriptBlock(cstype, csname, cstext2.ToString(), False)

False to not create the script tags since you are including them. The MSDN Documentation is wrong in how it explains the flag.

Also just put the client id's of your controls into separate variables from the code behind, not the JQuery code.

Then use the var's that contain the ids instead in JQuery Code.

OutOFTouch
A: 

for the key (csname) what is correct? I put PopupScript

Damien
A: 

The key can be anything you want, it should be unique though.

OutOFTouch
A: 

CHeers :D

I'll try more after weekend. This was code though:

DropDownList ddl = (DropDownList)grvTimeSheets.Rows[grvTimeSheets.EditIndex].FindControl("ddlClients");
        if (ddl != null)
        {
            ClientScriptManager csm = Page.ClientScript;
            Type cstype = this.GetType();
            String csname1 = "PopupScript";


            string script = @"
       <script language='javascript' type='text/javascript'>
       jQuery(#" + ddl.ClientID + ").change(function() { $(" + grvTimeSheets.ClientID + ").blockUI({ message: null }});} </script>";
            csm.RegisterStartupScript(cstype, csname1, script, false);
Damien
+1  A: 

Inside your script block that you create in the code behind:

string script = @"<script type=text/javascript> var myControlId = '" + ddl.ClientId  "';") + "</script>"

I didn't verify this syntax but it should be close. You can add the additional syntax for grvTimeSheets.ClientID in yourself. If you get this working then you might want to change it to build a JS array and stored the ClientId's that way then you only have one global JS variable that you need to work with.

OutOFTouch
+1  A: 

Another option is to just give the element you're looking for a class name that describes its behavior. Then your jquery code becomes really clear:

$(function() {
    $("select.yourMarkerClass").change(....);
});

IF there is no edit row, then this code does nothing. If there is an element that matches the selector, you'll get the new behavior added.

Ben Scheirman
+1  A: 

If you're not using the same ID elsewhere on the page, you can thwart ASP.Net's UniqueID with one of jQuery's advanced selectors:

$('[id$=ddlClients]')

this matches only the end of the id string rather than the whole. Bear in mind, if the control is present multiple times within different rows, this will match all instances.

See http://docs.jquery.com/Selectors for more examples.

Adam Lassek
A: 

I like the using the class selector way too Ben but I read it doesn't perform as fast as DOM access, is that true? Also each instance would have the same class no?

OutOFTouch
A: 

Because you have a dropdown in each row each dropdown will have a Unique ClientId so I suggest doing what Ben suggested and use the class selector since it is the simplest solution. Or you could create a javascript function on your edit click and then get the unique client id of your dropdown in that row that is being edited.

Sorry, I should have read your code closer.

OutOFTouch
A: 

Ok works, losing the functionality on postback...

Damien