Showing posts with label code. Show all posts
Showing posts with label code. Show all posts

Wednesday, March 28, 2012

Changing Background color of grid row when row checkbox selected

What option should I choose:

1) Write java script for this

2) Write server code and have grid in UpdatePanel

?

Not clear what the best guidline would be. I am already using update panel for that grid.

I guess the best solution should be if I have defined this background color in CSS.. I guess I could use java script to change the class name dynamicly and have that class defined in CSS. Not sure how to do it...


Here's some sample code I use in my custom ajaxed gridview control...

May or not work for you but should give you some idea..

 protectedvirtualvoid GridView_RowDataBound(Object s,GridViewRowEventArgs e)

{

if (e.Row.RowType ==DataControlRowType.DataRow )

{

//Note: Here is where we change the button submit so that

//our IPostBackHandler can properly handle AJAX requests.

int editID = (int)DataBinder.Eval(e.Row.DataItem,"id");

e.Row.Attributes.Add("onMouseOver","SetNewColor(this);");

e.Row.Attributes.Add("onMouseOut","SetOldColor(this);");

e.Row.Attributes.Add("onDblClick", Page.ClientScript.GetPostBackEventReference(this, e.Row.RowIndex.ToString()));

e.Row.Attributes.Add("onKeyDown","if( event.keyCode == 13 ) " + Page.ClientScript.GetPostBackEventReference(this,"KEYDOWN" +"$" + e.Row.DataItemIndex.ToString()));

Here is the code for adding it to the script manager on the prerender() phase

protected override void OnPreRender(EventArgs e) {string script = @." var _oldColor; function SetNewColor(source) { _oldColor = source.style.backgroundColor; source.style.backgroundColor = '#00ff00';} function SetOldColor(source) { source.style.backgroundColor = _oldColor; }"; ScriptManager.RegisterClientScriptBlock(this,typeof(Page),"ToggleScript", script,true);

Here is the aspx / ascx .Net code to use if you do not wanna do the PreRender event...

<script language="javascript" type="text/javascript"> var _oldColor; function SetNewColor(source) { _oldColor = source.style.backgroundColor; source.style.backgroundColor = '#00ff00';} function SetOldColor(source) { source.style.backgroundColor = _oldColor; } </script>

That should set you on the right direction....at least...


I have tried your aproach, I have created very similar code, but in my code I want to change ackground colour when the checkbox is chcked... It changes the color, but than it does not reverse it back to the old color... Any idea?

function highLight(CheckBoxObj){

var _oldColor;

if (CheckBoxObj.checked ==true) {

_oldColor = CheckBoxObj.parentElement.parentElement.style.backgroundColor;

CheckBoxObj.parentElement.parentElement.style.backgroundColor ='#D6DEEC';

//'#88AAFF';

}

else

{

CheckBoxObj.parentElement.parentElement.style.backgroundColor = _oldColor;

}


OK, I almost figured this out. My _OldColor variable needs to be global, outside of the function of course. OK, it seems to be working for one chcekbox at the time, but when multiple checkboxes are selected it doe not work. My guess would be I need to put the saved value to the array, but not sure how to do it...

var _oldColor;

function highLight(CheckBoxObj){

if (CheckBoxObj.checked ==true) {

_oldColor = CheckBoxObj.parentElement.parentElement.style.backgroundColor;

CheckBoxObj.parentElement.parentElement.style.backgroundColor ='#D6DEEC';

//'#88AAFF';

}

else

{

CheckBoxObj.parentElement.parentElement.style.backgroundColor = _oldColor;

}


In fact I suspect you may have the same problem happening in yourcode as you also do not put it (old color) into an array...

I was merely interested in just showing it highlighted for editing not necessarily for the checkboxes although that would be a nice feature to incorporate...

here some SAMPLE CODE to bite your teeth into - its out of the ajaxtoolkit... shows how to at least work with the arrays:

disableTab :function()

var i = 0;

var tagElements;

var tagElementsInPopUp =new Array();

this._saveTabIndexes.clear();

//Save all popup's tag in tagElementsInPopUp

for (var j = 0; j <this._tagWithTabIndex.length; j++) {

tagElements =this._foregroundElement.getElementsByTagName(this._tagWithTabIndex[j]);

for (var k = 0 ; k < tagElements.length; k++) {

tagElementsInPopUp[i] = tagElements[k];

i++;

}

}

Its from the ModalBehavior.js if you need to examine it a bit more...


Also some of the checkboxes can be initially checked as I keep track of those checked if user changes the pages... I used some code for this, I found on the web...

Thank you very much, the problem is how to get an index of the curren checkbox in the function (I am new to js):

function highLight(CheckBoxObj){

//var theBox=(spanChk.type=="checkbox")?spanChk:spanChk.children.item[0];

//xState=theBox.checked;

//elm=theBox.form.elements;

//for(i=0;i<elm.length;i++)

//if(elm[i].type=="checkbox" && elm[i].id!=theBox.id)

//{

////elm[i].click();

//if(elm[i].checked!=xState)

//elm[i].click();

if (CheckBoxObj.checked ==true) {

_oldColor = CheckBoxObj.parentElement.parentElement.style.backgroundColor;

CheckBoxObj.parentElement.parentElement.style.backgroundColor ='#D6DEEC';

//'#88AAFF';

}

else

{

CheckBoxObj.parentElement.parentElement.style.backgroundColor = _oldColor;

}

This is my checkbox declaration (onclick works somehow, even not recognized by VS editor...):

<ItemTemplate>

<asp:CheckBoxid="chkActive"onclick="javascript:highLight(this);"runat="server"></asp:CheckBox>

</ItemTemplate>

Change WatermarkText in VB code behind

I would like to be able to change the WatermarkText in my VB.NET code.

<atlasToolkit:TextBoxWatermarkExtender ID="txtWMEAddress1" runat="server">
<atlasToolkit:TextBoxWatermarkProperties TargetControlID="txtAddress1" WatermarkText="test" WatermarkCssClass="WaterMark" />
</atlasToolkit:TextBoxWatermarkExtender>

Your help is appreciated.

Thank you

it's really as easy as saying:

txtWMEAddress1.WatermarkText =

"Text from code behind"


I tried that before I put up the original posting.

There is no direct property of a TextBoxWatermarkExtender called"WatermarkText".

There is a separate tag called TextBoxWatermarkProperties, but does not have an ID or a runat to access it from the code behind.

The syntax should be (I think) txtWMEFirstName.<access TextBoxWatermarkProperties>.WatermarkText = "My text"

<atlasToolkit:TextBoxWatermarkExtender ID="txtWMEFirstName" runat="server">
<atlasToolkit:TextBoxWatermarkProperties TargetControlID="txtFirstName" WatermarkText="First Name" WatermarkCssClass="WaterMark" />
</atlasToolkit:TextBoxWatermarkExtender>

How should I be doing this?

Thank you very much.


Your code seem to be using pre-beta code of ASP.NET Ajax. Is there any reason why you are still using that version. In the current version of ASP.NET Ajax there is no separate TextBoxWatermarkProperties, instead TextBoxWatermarkExtender has the WaterMarkText property.

Change Themes using Ajax

Hi,

I am changing themes dynamically when i am clicking image button. i write a code to change the theme at Page_PreInit().

I need to reload the page to take effect. so i used response.redirect(SamePage.aspx). hope response.redirect is not supported on update panel.

i need to change themes using Ajax( without postback).

Thanks in Advance.

I don't think you can change the theme directly using ajax; but what you can do is change the href on your link tag(s) to give you new stylesheets.


Hi,

I think you dont need to Redirect to the same page to change the theme.

Just put

if(Page.IsPostBack)

GridView1.SkinID ="newskinID" in the Page.PreInit event.

Thanks,

Regards

Aruna


Hi,

My previous reply was to change the Skin of a particular control.

If you want to change the theme u can put this code

if (Page.IsPostBack)

this.Page.Theme ="NewSkinFile"

in the Page.PreInit Event Handler

Regards,

Aruna


Aruna,

Thanks for your response.

This is my code.

protectedvoid Page_PreInit(object sender,EventArgs e)

{

if (Request.Cookies["theme"] !=null)

{

this.Theme = Request.Cookies["theme"].Value.ToString();

}

else

{

this.Theme ="Black";

}

}

protectedvoid ImgGreen_Click(object sender,ImageClickEventArgs e)

{

HttpCookie cook=newHttpCookie("theme");

cook.Value=((ImageButton)sender).CommandName;

cook.Expires =DateTime.MaxValue;

Response.AppendCookie(cook);

string[] path = Request.Path.Split(char.Parse("/"));

Response.Redirect(path[path.Length-1].ToString() );

}

when i click image button, i stored theme name in a cookie. based on a cookie i am loading theme.

Page_PreInit() method never fire after image button click until the page reload ( Page_PreInit() will fire first).

so, i redirected to same page.

It is immediately taking theme.

Actually my problem is the page is get postback even i am using update panel.

you got my point.


Paul,

Thanks.

I referred two sites. Live.com and msn india. they are changing page themes without postback. so, i tried.

If you will get resource, post here.

once again thanks paul.


Hi Nanda,

Have u set the commandName of Image Button to the name of the Theme, as you mentioned cook.Value=((ImageButton)sender).CommandName you are trying to put the name of Command in the cookie.

Regards,

Aruna


Aruna,

I am using 4 themes in my project. so, i put 4 imagebutton in my page. all 4 buttons are sharing one methodImgGreen_Click(). so, based on the command name, i am trapping which button is clicking by the user ( i assigned theme name as command name for all four button.)

Thanks.


As I said before, you can't do it the way you're trying to do it. The ASP.Net 'theme' is a pretty rigid thing, and it's set during the Init cycle, which does not fire if you're using and updatepanel (see the documentation on page lifecycle).

If you want to change the look and feel of your site without postback, the way to do it is to build a CSS-based design, and then swap stylesheets from the client.


Dear,

You have redirected to the same page that's y ur page is posted back.

The major problem in your code is PreInit Fires before the button click event, so u cant modify the theme on click of the button by using this code as preinit fires first so it takes the theme of previous click.


Hi,

Hope u have solved ur problem.

If not then let me know I have a solution of ur problem.

Regards,

Aruna


Is that it ? Is CSS-based design the only way to achieve themes without postbacks ?

Aruna, do you have an alternate solution ?

Thanks

Jai

Change Event not fired when changed once or more then restored to its original value.

Hi.


I am trying to ATLAS-ize an existing application with lots of Master Detail controls.

As I don't want to write a heap of new code I am using UpdatePanels rather than writing web services even though my situation is similar to the one in the CascadingDropDown example (http://atlas.asp.net/atlastoolkit/CascadingDropDown/CascadingDropDown.aspx)


The problem I have though is that if I change the master listbox selected value (say from 0 to 1) then the Update Panel refreshes fine.

If I change it back from 1 to 0 the SelectedIndexChanged event does not fire leaving a load of incompatible info in the details listbox

I'm assuming that this is because when the page was first loaded the value was 0 so it does not recognize that a change has occurred.

I'd be grateful for advice on the optimum solution to this.

Ah Problem Semi Solved!


The first thing I was doing "wrong" was that my page overrides Load and Save PageStateFromPersistenceMedium and stores it in a DB and just passes the GUID back and forth in a hidden field. This obviously means the ViewState updates never made it into my page.

I would appreciate some advice on things I can override to get this functionality back however as some of the ViewState is pretty huge but required without a lot of extra coding. Is their any way I can replicate what is happening automatically with __VIEWSTATE to my own custom hidden input (hdnViewStateId) (i.e. get it automatically submitted on a call back, get it passed back in the XML envelope and automatically update the value with the new one)

The other thing I was doing wrong was that I'd left in an old school Response.Write in my page which knackered up the XML sent! (By the way is there any way I could have switched on any error logging which would have alerted me to this last issue?)


Ah Problem Semi Solved!


The first thing I was doing "wrong" was that my page overrides Load and Save PageStateFromPersistenceMedium and stores it in a DB and just passes the GUID back and forth in a hidden field. This obviously means the ViewState updates never made it into my page.

I would appreciate some advice on things I can override to get this functionality back however as some of the ViewState is pretty huge but required without a lot of extra coding. Is their any way I can replicate what is happening automatically with __VIEWSTATE to my own custom hidden input (hdnViewStateId) (i.e. get it automatically submitted on a call back, get it passed back in the XML envelope and automatically update the value with the new one)

The other thing I was doing wrong was that I'd left in an old school Response.Write in my page which knackered up the XML sent! (By the way is there any way I could have switched on any error logging which would have alerted me to this last issue?)


Your drop down list is set to do a autopostback, correct? This would translate to a partial postback given that it's within the update panel.

Given that you've turned off the standard viewstate mechanism provided by ASP.Net, the "change" isn't going to be noticed 'cause the runtime can't compare what "was" (in the viewstate) with what "is" (in the form post). However, you can...

Take a look at this Fiddler trace of a site I quickly built using the update panel to do what you're doing with a drop down list (this is taken when the drop-down list auto posts back to the server):

POST /public/testsites/atlaswebsite3/Default.aspx HTTP/1.1
Accept: */*
Accept-Language: en-us
Referer:http://www.ben-rush.net/public/testsites/atlaswebsite3/
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
delta: true
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)
Host:www.ben-rush.net
Content-Length: 305
Proxy-Connection: Keep-Alive
Pragma: no-cache

ScriptManager1=myupdatepanel&__EVENTTARGET=DropDownList1&__EVENTARGUMENT=&__LASTFOCUS=&__VIEWSTATE=%2FwEPDwUKLTgwNzIyNjA5NA9kFgICAw9kFgICAw9kFgJmD2QWAgIDDxBkZBYBZmRkrJaJXj2KU%2FOTLiUUKLu7RDDJunM%3D&DropDownList1=2&__EVENTVALIDATION=%2FwEWBALyq5BnAp3kj%2BUKApKLpYsGApOLpYsGRIPIbgqWzDqL6Q8VoLqfhZnR%2BlM%3D&

You could grep out of the form post the object that created the postbck (__EVENTTARGET), and what its postback value is (DropDownList1=2). You could store the state of the last selected item value in whatever mechanism you choose and do your own compare, even in your custom page_load.

Thanks. I reckon that's probably the way to go.

I was contemplating (but probably wouldn't have actually done) a pretty horrible solution as I was playing with adding my own

__VIEWSTATE

hidden input with the GUID and it almost works if I strip out the extra "," that I get on the form post from the redundant ASP.NET added control of the same name!

I still hadn't sussed out how to change the XML envelope to reflect that change though..


When you say "change the XML envellop to reflect that change" you're talking about changing the XML response from the server that contains all the delta bits for the clientside framework, right (the XML that directs the client code to do its DHTML tricks to update the content within the UpdatePanel)?

So, before we go any further - your problem is that you can now detect when the change is made, but the atlas server code still doesn't and, therefore, doesn't include the right junk in the XML response back to the client to update the doodads in your UpdatePanel control?


Yes that's correct.

BTW: I've had a look at your blog and I suspect you're going to tell me that you know how to do this.

I'm a bit torn on the best way of doing this as.

I reckon__EVENTTARGET is probably the more robust way of doing it even though I lose a lot of the benefits of the ASP.NET module (I need to figure out how to store and retrieve the initial values of controls without using view state and raise the change events myself)

If I try and hijack the __VIEWSTATE control for my own purposes then a lot of the code is written for me already but my solution could break if a new version of ATLAS or update to ASP.NET comes out!


Actually Ben.

I've tried your suggestion and it's trickier than I thought it would be.

The problem is that when I select the original value in the Master ListBox nothing is sent back to the browser!

I assume that this is some sort of optimisation to only send back the things which are different and (as far as ASP.NET knows from looking at the old ViewState) it doesn't have to send anything back as they are the same.

It looks like I am going to need to integrate it with ViewState somehow. For the time being I've commented out my overrides and am sending all ViewState to the Client to get it working.

However I would be extremely grateful for suggestions of ways to get around this issue and get the benefits of both ServerSide ViewState Storage and ATLAS.


...let me dink around a bit with some stuff on my side here and try to duplicate what you're running into more accurately. This has got me curious about several things going on...


Can you visit this page and tell me how accurately this matches your situation:http://www.ben-rush.net/public/testsites/atlaswebsite3/.

I have a textbox and a listbox, the textbox updates its content to the selected index of the listbox when the selectedindex changes. The viewstate for the listbox is off. I don't believe that the listbox requires viewstate for identification of changes because the "change" will only occur when the index is changed; therefore a form post that includes the listbox as an eventtarget will be seen as a selectedindexchanged event. I could be wrong, but I seem to remember this being the case (I did some viewstate optimizations for a shopping cart system a long, long time ago).

Regardless, look at these two fiddler dumps, one during change from index 0 -> 1 (value 1->2), the other from 1->0 (value 2->1). Both show the value of the listbox.

POST /public/testsites/atlaswebsite3/Default.aspx HTTP/1.1
Accept: */*
Accept-Language: en-us
Referer:http://www.ben-rush.net/public/testsites/atlaswebsite3/
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
delta: true
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)
Host:www.ben-rush.net
Content-Length: 288
Proxy-Connection: Keep-Alive
Pragma: no-cache

ScriptManager1=myupdatepanel&__EVENTTARGET=ListBox1&__EVENTARGUMENT=&__LASTFOCUS=&__VIEWSTATE=%2FwEPDwUJNTA5MjUzOTYxZGTFj5uiiDfrPSUZQz6IYXNKpb8xOQ%3D%3D&ListBox1=2&TextBox1=0&__EVENTVALIDATION=%2FwEWBwKJvNCXBgK9ueOMCQKy1sniBQKz1sniBQKw1sniBQKx1sniBQLs0bLrBlpXNeow%2BdPC39h7%2F1FxYfamkoLm&

And the other...

POST /public/testsites/atlaswebsite3/Default.aspx HTTP/1.1
Accept: */*
Accept-Language: en-us
Referer:http://www.ben-rush.net/public/testsites/atlaswebsite3/
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
delta: true
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)
Host:www.ben-rush.net
Content-Length: 288
Proxy-Connection: Keep-Alive
Pragma: no-cache

ScriptManager1=myupdatepanel&__EVENTTARGET=ListBox1&__EVENTARGUMENT=&__LASTFOCUS=&__VIEWSTATE=%2FwEPDwUJNTA5MjUzOTYxZGTFj5uiiDfrPSUZQz6IYXNKpb8xOQ%3D%3D&ListBox1=1&TextBox1=1&__EVENTVALIDATION=%2FwEWBwKJvNCXBgK9ueOMCQKy1sniBQKz1sniBQKw1sniBQKx1sniBQLs0bLrBlpXNeow%2BdPC39h7%2F1FxYfamkoLm&


I should probably mention that I have a trigger in the UpdatePanel as well.

I suspect that it may be a trigger optimisation causing the issue (for the same reason as previously described it can't realise that there is a change to process so returns an empty envelope)

<Triggers>

<atlas:ControlEventTriggerControlID="drpMasterListBox"EventName="SelectedIndexChanged"/></Triggers>

Well yes that is definitely working.

Do you have a trigger?

Is your UpdatePanel set to the same options as mine or is anything different?

(I haveMode="Conditional"RenderMode="inline")

In any event I'm thinking of doing it without update panels now and using a custom extender.

I was hoping that UpdatePanels would be a quick and dirty solution but I'm not progressing as fast as I wanted to and I suspect I may hit yet more obstacles because my UpdatePanel is in a UserControl which I was planning to embed in another UpdatePanel at Page Level.


No, I don't have a trigger. I changed my rendering modes to what you have, and it didn't change things (I wouldn't expect that it would). You can visit the same page URL I gave you earlier to confirm.

If you have a control in your update panel that does a postback automatically (say, the listbox control with its autopostback option on), then you have no need for a trigger. Triggers will only be useful for controls that don't postback automatically. I haven't researched triggers much, but if they're anything like binding objects then the control they're bound to needs to be AJAX savvy anyway.

Try turning off the trigger, I guess - and see what that does.


MartinSmithh:

The first thing I was doing "wrong" was that my page overrides Load and Save PageStateFromPersistenceMedium and stores it in a DB and just passes the GUID back and forth in a hidden field. This obviously means the ViewState updates never made it into my page.

well, though i haven't tried it, i think it's safe to assume that your field will allways be maintained if you add it to the page by using the registerhiddenfield of the clientscriptmanager api.

Monday, March 26, 2012

CascadingDropDowns from bad to worse...

I was getting a [Method Error 500] on a DropDown and was combing through the posts trying to find a solution. I stripped my code down to two simple DropDowns with CascadingDropDown controls attached to them. I was able to get the top level control to populate correctly but was still getting the Eror 500 on my child DropDown. One of the posts I saw suggested making my Web Service methods Shared (I'm using VB). I tried that and now my original DropDown stopped populating at. The Web Service code isn't being reached at all. I tried removing the Shared designation from my methods but the problem has not gone away. I have cleared my IE cache and completely recreated the project. Still, I can't get a single DropDown to populate usnig a Cascading DropDown and a WebService.Here's my aspx markup:

Here's the code in my WebService: _ _ _ _Public Class Locations Inherits System.Web.Services.WebService Private Shared ConnString As String = ConfigurationManager.ConnectionStrings("Inventory").ToString() Private Shared SqlCN As New SqlConnection(ConnString) _ _ Public Shared Function GetLocations() As CascadingDropDownNameValue() Try Dim Ds As DataSet = GetLocationDs() Ds.Tables(0).DefaultView.Sort = "Text ASC" Dim Values As New List(Of CascadingDropDownNameValue) For Each Dr As DataRow In Ds.Tables(0).DefaultView.Table.Rows Values.Add(New CascadingDropDownNameValue(Dr("Text").ToString(), Dr("Value").ToString())) Next Return Values.ToArray() Catch ex As Exception Dim newEx As Exception = ex Return Nothing End Try End Function Private Shared Function GetLocationDs() As DataSet Try Dim SqlCmd As SqlCommand = SqlCN.CreateCommand() Dim PTextColumn As New SqlParameter() Dim PValueColumn As New SqlParameter() Dim PTableName As New SqlParameter() Dim SqlDA As SqlDataAdapter = New SqlDataAdapter() Dim DropDownDS As DataSet = New DataSet() Dim I As Integer = 0 With PTextColumn .DbType = DbType.String .ParameterName = "@dotnet.itags.org.TextColumn" .Value = "Location" End With With PValueColumn .DbType = DbType.String .ParameterName = "@dotnet.itags.org.ValueColumn" .Value = "Location" End With With PTableName .DbType = DbType.String .ParameterName = "@dotnet.itags.org.TableName" .Value = "HE_Locations" End With With SqlCmd .CommandType = CommandType.StoredProcedure .CommandText = "usp_GetDropDownValues" .Parameters.Add(PTextColumn) .Parameters.Add(PValueColumn) .Parameters.Add(PTableName) End With SqlDA.SelectCommand = SqlCmd If SqlCN.State <> ConnectionState.Closed Then SqlCN.Close() End If SqlCN.Open() SqlDA.Fill(DropDownDS, "Values") Return DropDownDS Catch ex As Exception Throw New DataException("GetDropDownValues failed.", ex) Return Nothing Finally SqlCN.Close() End Try End FunctionEnd ClassIf anyone has any ideas, I would sure like to hear them. I'm about ready to pull out my AJAX manual and roll my own. I have lost a whole day on this. Even if I get my original DropDown working I still have the ubiquitous Method Error 500 to deal with.Btw, the code in my Catch block was simply a place to put a breakpoint for debugging so I could read exception mesage if there was one. There wasn't.Thanks!

Well, that didn't come out very well, did it?

Actually, nevermind. For some reason, after using the I.E. Devloper Toolbar, scripting in I.E. was disabled. I also figured out my Method Error 500 problem. I realize now that the parameters in the method signature have to match the example exactly - even the case. I assumed that wouldn't matter since I'm using VB.

Thanks.

CascadingDropDownProperties - Creating an extra Category/Value through code

I need to add an initial "filter" to my CascadingDropDown Lists.

How do I create a Property, and assign a value and category to it through code?

Thank you,

Bryan

I'm afraid I don't understand - could you please rephrase the question?

Saturday, March 24, 2012

CascadingDropDownList - Am i being a complete tool?

Hey,

Trying to get my head round these CascadingDropDownLists but i am continually returned with a [Method Error 500] error.

This is my code for 'Default.aspx'


<%@dotnet.itags.org. Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %
<%@dotnet.itags.org. Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />

<asp:DropDownList ID="DropDownList1" runat="server"></asp:DropDownList>

<ajaxToolkit:CascadingDropDown ID="CascadingDropDown1" runat="server"
Category="Author"
TargetControlID="DropDownList1"
ServiceMethod="FillMe"
ServicePath="WebService.asmx"
PromptText="Please select a category"
>
</ajaxToolkit:CascadingDropDown>
</form>
</body>
</html>

And my webservice, WebService.asmx, is as follows:

using System;using System.Configuration;using System.Web;using System.Collections;using System.Collections.Generic;using System.Collections.Specialized;using System.Web.Services;using System.Web.Services.Protocols;using AjaxControlToolkit;using System.Data;using System.Data.SqlClient;/// <summary>/// Summary description for WebService/// </summary>[WebService(Namespace ="http://tempuri.org/")][WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]public class WebService : System.Web.Services.WebService { [System.Web.Services.WebMethod] [System.Web.Script.Services.ScriptMethod] public static CascadingDropDownNameValue[] FillMe(string knownCategoryValues, string category) { string connString = ConfigurationManager.ConnectionStrings["tenderlistDB"].ConnectionString; SqlConnection conn = new SqlConnection(connString); DataTable dt = new DataTable(); string Sql = "SELECT [ID], [Name] FROM tblCategories WHERE ParentID=@dotnet.itags.org.ParentID ORDER BY [Name] ASC"; try { conn.Open(); SqlCommand comm = new SqlCommand(Sql, conn); comm.Parameters.AddWithValue("@dotnet.itags.org.ParentID", "0"); SqlDataAdapter adapt = new SqlDataAdapter(comm); adapt.Fill(dt); } finally { conn.Close(); } List<CascadingDropDownNameValue> values = new List<CascadingDropDownNameValue>(); for (int i = 0; i < dt.Rows.Count; i++) { CascadingDropDownNameValue CCD = new CascadingDropDownNameValue(); CCD.name = dt.Rows[i]["Name"].ToString(); CCD.value = dt.Rows[i]["ID"].ToString(); values.Add(CCD); }return values.ToArray(); }}

Anyone have an idea as to why it's just not working?

Cheers,

Sean


Most likely you have an exception being thrown in your WebMethod. Set a breakpoint in it and use the site in Debug mode. Step through the WebMethod and see if you are getting an exception. This is usually the case for me. The other thing I have seen is too much information being returned, but I think that is another error number. The Execption will not be returned by the Web Service, so AJAX throws a 500 error up at you.


Thanks for getting back to me.

I've never really used the debug function, but i stuck some breakpoints in the code and hit F5, and it all ran ok.

If i run it in debug mode, instead of Error method 500, i get an Error Method 12031...Could that be anything?

In terms of the SQL, it returns 12 rows when run through Sql Query Analyzer.

Appreciate your help!


Been thinking about this a little over lunch. Have you marked your Web Service and Web methods with AJAX attributes?

The Class should have this attribute:

<System.Web.Script.Services.ScriptService()> _

The Web Method this one:

<System.Web.Script.Services.ScriptMethod()> _

So a method would resemble the following:

<WebMethod()> _

<System.Web.Script.Services.ScriptMethod()> _

PublicFunction GetMarkets(ByVal knownCategoryValuesAsString, _

ByVal categoryAsString)As AjaxControlToolkit.CascadingDropDownNameValue()

Dim kvAs StringDictionary = _

AjaxControlToolkit.CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)

Dim RegionIdAsInteger

IfNot kv.ContainsKey("Region")OrElseNot Int32.TryParse(kv("Region"), RegionId)Then

ReturnNothing

EndIf

Dim lcAsNew LocMarketController

Dim itemListAs LocMarketList = lc.GetLocMarketByRegion(RegionId)

Dim valueAsNew List(Of AjaxControlToolkit.CascadingDropDownNameValue)

ForEach itemAs LocMarketInfoIn itemList

value.Add(New AjaxControlToolkit.CascadingDropDownNameValue(item.Market, item.MarketId))

Next

Return value.ToArray

EndFunction


Hey,

Tried that but still no joy. Starting to get frustrating now hehe, anyone else got any ideas?

Cheers for the help!


Hey,


Just to let you all know i got it working...i rewrote it this morning when i got into work and its all working fine...not sure why though, i have a feeling I wasn't passing through the correct parameters, so when the


'StringDictionary kv = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);'

line was hit, the method would break!

Thanks for all the help.

CascadingDropDownList - Adding KnownCategoryValues through code

I am using several Cascading Drop Down Lists.

Is there a way that I can add values to the knownCategoryValues and category parameters that get passed to the webmethods?

For example:

[

WebMethod(EnableSession =true)]
publicCascadingDropDownNameValue[] GetSkill(
string knownCategoryValues,
string category)
{
int SubSystem_ID =int.Parse(Session["PageSubSystem"].ToString());
StringDictionary kv =CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);

int Location_ID;
if (!kv.ContainsKey("Location") || !int.TryParse(kv["Location"],out Location_ID))
{
returnnull;
}

Sorry for the badly formatted code, but the Code Entry thing is not working.

Anyway, how would I add a "Key" of Location to the parameters? Would this have to be in the WebService, or can I add it from the web page?

Any help on this would be greatly appreciated!

Try to take a look at the following link about how to useAjax:CascadingDropDown with a Database for reference.
http://ajax.alpascual.com/Walkthrough/CCDWithDB.aspx
Wish this can help you.

CascadingDropDown selectindexchanged problem with iframe

Hi community,

i implement the CascadingDropDown code into my application and it works correct. So where is the problem ? :)
in my programm i have two aspx sites one with dropdownlist and an iframe(where the Piechart is displayed),
and a second for Piechart Drawing.
The iframe is in the updatepanel and the ImageUrl is empty
What i add to the selectindexchanged Event is a db connect with handels with the dropdownlist choise

Added Code selectindexchanged Event from the first site

Session("bezeichner") = bezeichner
Session("anzahl") = anzahl
Session("i") = i
iframe.ImageUrl = "Piechart.aspx"

Code from the second site

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

Dim bezeichner = Session("bezeichner")
Dim anzahl = Session("anzahl")
Dim i = Session("i")
Dim count = Session("count")
CreatePie(bezeichner, anzahl, i, count)

End Sub

Now i choose a item from the CascadingDropDown: the db connect process starts, the Sessionvariable gets filled and the PieChart is drawing in the iframe..
After that, i select a different item from the CascadingDropDown and "nothing" happens...to the iframe

But the Label1.Text(joe's tutorial) shows me the correct result.

So whats wrong ?

Thanks for any help!

Simon A.

Hi Simon,

I made a sample according to your description, and it worked fine.

Please try it and compare with yours:

Default.aspx

<%@. Page Language="C#" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><script runat="server"> protected void Page_Load(object sender, EventArgs e) { Label1.Text = DateTime.Now.ToString(); Label2.Text = DateTime.Now.ToString(); } protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e) { Session["index"] = DropDownList1.SelectedIndex; }</script><html xmlns="http://www.w3.org/1999/xhtml"><head id="Head1" runat="server"> <title>Hover Sample</title></head><body> <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager><div> <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label><asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged" Width="188px"> <asp:ListItem>1</asp:ListItem> <asp:ListItem>2</asp:ListItem> <asp:ListItem>3</asp:ListItem> </asp:DropDownList> <asp:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:Label ID="Label2" runat="server" Text="Label"></asp:Label> <iframe id="iframe1" runat="server" src="Default2.aspx"></iframe> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="DropDownList1" /> </Triggers> </asp:UpdatePanel> </div> </form></body></html>

Default2.aspx

<%@. Page Language="C#" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><script runat="server"> protected void Page_Load(object sender, EventArgs e) { Response.Write(Session["index"].ToString()); // draw the pie based on the value of Session["index"] here }</script><html xmlns="http://www.w3.org/1999/xhtml" ><head runat="server"> <title>Untitled Page</title></head><body> <form id="form1" runat="server"> <div> </div> </form></body></html>

HiRaymond,

Big thanks for your help, it works fine now!

best regards,

Simon A.

CascadingDropDown SelectedValue Attribute in GridView giving Error

I have a CascadingDropDown inside of an GridView EditItemTemplate. Code is below. I need the SelectedValue of the CascadingDropDown to come from the database when then user Edit's the row. I tried addingSelectedValue='<%# Bind("sentity") %>' but I get this error:

Parser Error Message:The CascadingDropDownProperties control with a two-way databinding to field sentity must have an ID.

Source Error:

Line 67: Line 68: <atlasToolkit:CascadingDropDown ID="CascadingDropDown2" runat="server">Line 69: <atlasToolkit:CascadingDropDownPropertiesLine 70: TargetControlID="ddlEditEntity" Line 71: Category="Entity"

<asp:TemplateFieldHeaderText="Entity">

<EditItemTemplate><asp:DropDownListID="ddlEditEntity"runat="server"CssClass="dropDownList"/><atlasToolkit:CascadingDropDownID="CascadingDropDown2"runat="server"><atlasToolkit:CascadingDropDownPropertiesTargetControlID="ddlEditEntity"Category="Entity"PromptText="<-- Selected an Entity -->"ServicePath="webservices/ws_Timetracking.asmx"ServiceMethod="GetEntitesText"SelectedValue='<%# Bind("sentity") %>'/><atlasToolkit:CascadingDropDownPropertiesTargetControlID="ddlEditProperty"ParentControlID="ddlEditEntity"PromptText="<-- Select a Property -->"ServiceMethod="GetPropsForEntitytext"ServicePath="webservices/ws_Timetracking.asmx"Category="Property"/></atlasToolkit:CascadingDropDown></EditItemTemplate><ItemStyleHorizontalAlign="Left"Width="20%"/><HeaderStyleHorizontalAlign="Left"/><ItemTemplate><asp:LabelID="lblEntity"runat="server"Text='<%# Bind("sentity") %>'></asp:Label></ItemTemplate></asp:TemplateField>As you've noted, the Toolkit controls don't support data binding yet. (Though we have plans to do so soon!) For the time being, I believe you can override your page's OnDataBind method and set the SelectedValue in code. I think Shawn's posted an example of this to the forum. If that's not enough to get you going, reply back and I'll post a sample.

David, I tried setting the selectedValue for the dropdownlist in theGridView1_RowUpdating method, but it seems to not be working.

GridViewRow row = GridView1.Rows[e.RowIndex];
DataKey datakey = GridView1.DataKeys[e.RowIndex];
// Get hmy for updating the database
int hmy =Convert.ToInt32(datakey.Value.ToString());

if (row !=null)
{
DropDownList ddlEditEntity = row.FindControl("ddlEditEntity")asDropDownList;
DropDownList ddlEditProperty = row.FindControl("ddlEditProperty")asDropDownList;
TextBox txtEditDescription = row.FindControl("txtEditDescription")asTextBox;
TextBox txtEditHours = row.FindControl("txtEditHours")asTextBox;ddlEditEntity.SelectedValue = "Chastain Center (8755)"; // this doesn't seem to be workingstring entity = ddlEditEntity.SelectedItem.Value;string property = ddlEditProperty.SelectedItem.Value;string description = txtEditDescription.Text;decimal hours =Convert.ToDecimal(txtEditHours.Text);int retval =Queries.UpdateEntity(hmy, entity, property, description, hours);

GridView1.EditIndex = -1;

GetTimeByUser(ddlYear.SelectedValue +

"/" + ddlMonth.SelectedValue);

}


Well, we added databinding support in the 60731 release of the Toolkit. :) Would you mind trying that approach again with the updated Toolkit? Failing that, let me know and I'll have a look. For real this time. :) Thanks!


When upgrading to the latest do all I need to do is swap out the dll, correct?


Yes, but you'll need to swap out the Microsoft.Web.Atlas.DLL as well (if you're not already using the July CTP).


Thanks David I will try this approach today. One final question. Is it necessary to swap out the Script Library as well? Do you guys update the JavaScript code to reflect changes in the dll?

I swapped out my dll's as followed:

AtlasControlToolkit.dll (version 1.0.60731.0)

Microsoft.AtlasControlExtender.dll (version 1.0.60726.0)

Microsoft.Web.Atlas.dll (version 2.0.50727.60725)

And did the following and still get the error:

The CascadingDropDownProperties control with a two-way databinding to field sentity must have an ID.

<asp:TemplateFieldHeaderText="Entity"><EditItemTemplate><asp:HiddenFieldID="hdnEditEntity"runat="server"Value='<%# Bind("sentity") %>'/><asp:DropDownListID="ddlEditEntity"runat="server"CssClass="dropDownList"/><atlasToolkit:CascadingDropDownID="CascadingDropDown2"runat="server"><atlasToolkit:CascadingDropDownPropertiesTargetControlID="ddlEditEntity"

SelectedValue='<%# Bind("sentity") %>'

Category="Entity"PromptText="<-- Selected an Entity -->"ServicePath="webservices/ws_Timetracking.asmx"ServiceMethod="GetEntitesText"/><atlasToolkit:CascadingDropDownPropertiesTargetControlID="ddlEditProperty"ParentControlID="ddlEditEntity"PromptText="<-- Select a Property -->"ServiceMethod="GetPropsForEntitytext"ServicePath="webservices/ws_Timetracking.asmx"Category="Property"/></atlasToolkit:CascadingDropDown></EditItemTemplate>

joee, I've looked into this for some time and discussed the issue with Shawn as well. Unfortunately for your scenario, we're only able to use one-way databinding (i.e., Eval) in Extender Properties declarations. If you want to handle the CascadingDropDown's SelectedValue that comes back from the client, you'll need to do so in code (at least for the time being - fortunately it shouldn't be very much code!). At a very high level, in order to support two-way databinding, ASP.NET looks for a real Control (hence the error you get about needing an ID) and the Extender Properties objects aren't currently Controls themselves.

Sorry for the trouble; I hope this explanation at least makes things clearer.


Hello

I have a CascadingDropDown in a page and need to set its selectedValue based on the values in the querystring. I tried to use the DataBinding event to set the values, but looks like the event is not being raised.

protected void CascadingDropDown1_DataBinding(object sender, EventArgs e)
{
ddMake.SelectedValue = Request.QueryString["make"];
ddModel.SelectedValue = Request.QueryString["model"];
}

Any ideas?

Thanks for the report! I've just fixed this problem for the next Toolkit release with change 3420 in CodePlex:

Method override ExtenderControlBase.OnDataBinding didn't call base.OnDataBinding, so event handlers hooked up to an extender's .DataBinding event weren't getting fired - this change fixes that problem by calling the base class implementation as it should.

If you're able to use the sources from CodePlex, this should work now. Sorry for the trouble!


Thanks David. I guess change 3431 will address my issue as well. Pardon my ignorance, but how do I work off the source code? Do I just need to build and swap out the Web.Atlas and AtlasControlToolkit.dll?
Yes, just download the sources from CodePlex, extract the files somewhere, build the project, and then use the resulting AtlasControlToolkit.dll instead of the one you were formerly using.

So what is the status now regarding to ways binding, e.g. binding a dropdown's selectedvalue to an item in detailsview ?

Wednesday, March 21, 2012

CascadingDropDown Not Cascading

I have wired 2 dropdownlists to the cascadingdropdown controls. My page code looks like this:

1<asp:DropDownList ID="StateDropDownList" runat="server" />2<ajax:CascadingDropDown ID="StateDropDownListCascadingDropDown" runat="server" Enabled="True" Category="StateName"3 PromptText="Select a state" ServiceMethod="GetDropDownStates" ServicePath="~/Site_Services/Datasets.asmx"4 TargetControlID="StateDropDownList" />56<asp:DropDownList ID="CountyDropDownList" runat="server" />7<ajax:CascadingDropDown ID="CountyDropDownListCascadingDropDown" runat="server" Enabled="True" Category="County"8 PromptText="Select a county" ServiceMethod="GetDropDownCounties" ServicePath="~/Site_Services/Datasets.asmx"9 ParentControlID="StateDropDownList" TargetControlID="CountyDropDownList" />

I've simplified the second web method to try anything to get the 2nd dropdownlist to work and no matter what, it still doesn't work. Here is the simplified method:

1 [System.Web.Services.WebMethod]2 [System.Web.Script.Services.ScriptMethod]3public CascadingDropDownNameValue[] GetDropDownCounties(string knownCategoryValues,string category)4 {5 List<CascadingDropDownNameValue> values =new List<CascadingDropDownNameValue>();6 values.Add(new CascadingDropDownNameValue("Test","Test"));7return values.ToArray();8 }

Here's what is posted:

The server returns no response. Any ideas?

j_gaylord:

5List values =new List();

Are you referring a generic List<> collection?

I got an article on Cascading dropdownlist athttp://www.aspalliance.com/1183 . Check it

Thanks


Yes. The code didn't print out properly as the Code screen in the forums ommited my < and >. I updated the code above. You'd think that it would work regardless because no matter what the values are, a value is being added to the collection. However, that's not the case.


any ideas?

nudge


Two things I would check are:

1. The webservice is decorated with [System.Web.Script.Services.ScriptService] attribute.
2. The correct web.config file and the AjaxControlToolkit.dll binary.

Thanks


Both of them are correct. I already have one drop down working. Its just the second one who's parent is the first is not.


j_gaylord:

Both of them are correct. I already have one drop down working. Its just the second one who's parent is the first is not.

In such case, the second dropdown should also fill, as the method [GetDropDownCounties] you wrote has nothing to do with the parent dropdownvalue. I have tested your code and its working fine for me. You messed up something for sure.

Thanks


Thanks for the positive insight. Any further suggestions?Wink

CascadingDropDown method error 500

Hi,

I've created a new project following the video found here :http://www.asp.net/learn/ajax-videos/video-77.aspx

My code is the same as in the demo, but when I run the website, I have the "method error 500" in each dropdownlist instead of the makes, models and colors...

Does anyone know what this error code means ?

Thanks for your help.

Hi Dpin,

10.5 Server Error 5xx
Response status codes beginning with the digit "5" indicate cases in which the server is aware that it has erred or is incapable of performing the request. Except when responding to a HEAD request, the server should include an entity containing an explanation of the error situation, and whether it is a temporary or permanent condition. User agents should display any included entity to the user. These response codes are applicable to any request method.

10.5.1 500 Internal Server Error
The server encountered an unexpected condition which prevented it from fulfilling the request.

To resovle the kind of problem, we suggest that you should first check whether your WebService works fine or not. Then check the Control settings. If all these are ok, but your application doesn't work properly. Please add break points to your WebService and debug it step-by-step. Here is theuseful information. Please pay special attention to my last reply.

I hope this help.

Best regards,

Jonathan

CascadingDropDown Method error 500

I have a couple of CascadingDropDown controls on an ASP.NET page and am filling them from a code behind function that makes a call to a SQL Server 2005 database. My problem is that sometimes I receive a 'Method error 500' when filling the second dropdownlist based on a parent control. I am concatenating three fields together and I can mix and match 2 of them, but when I use all three, I consistently get the error.

Example "Select StoreCode + ' ' + City + ' ' State as Name From Table".

Is there a data size limit with using this control?

Also, I am able to bind the same data to a dropdownlist not used in AJAX.

Thanks in Advanced,

Marc


I am encountering a similar problem with some CascadingDropDowns that help define someone's location. Whn I gt tothe City level, sometimes I get a 'Method Error 500' and sometimes I do not.

Your question "Is there a data size limit with using this control?" got me experimenting, and my results suggested that indeed there was a correlation between the error and the amount of data being returned.

So I installed IEInspector and fond that indeed, requests that return a lot of data are creating a problem. This is one of the responses I am getting:

{"Message":"Maximum length exceeded.","StackTrace":" at System.Web.Script.Services.RestHandler.InvokeMethod(HttpContext context, WebServiceMethodData methodData, IDictionary`2 rawParams)\r\n
at System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData)","ExceptionType":"System.InvalidOperationException"}
 
My next step is to use Reflctr to look at the code for System.Web.Script.Services.RestHandler.InvokeMethod and see what I discover.
 
Thanks for the data length suggestion!
 

Ken, thanks for the investigative work. Can you please keep me updated as to what you find?

I too will continue to debug this issue and will report any findings to this thread.

Thanks in advance,

Marc


Eureka!

Stepping thru the AJAX source code was tiring but informative.

In any event, here is my solution (if your underlying issue is different, YMMV).

I was hitting a size limit in the JSON conversion stuff, which fortunately can be customized without recompiling the code.

When returning custom objects (like the arrays returned by the CascadingDropDown web methods), the objects are serialized using object names, including their namespace. While my collections were only a few thousand items in length, the unfortunate choice of the long-winded namespace 'AjaxControlToolkit' and class name 'CascadingDropDownNameValue' results in ridiculous object bloat and blows out the default JSON string size by adding the long object name to every single object.

For example, a single City in my array of around 4000 of them is being returned like this:

"__type":"AjaxControlToolkit.CascadingDropDownNameValue","name":"Abanda","value":"2728903","isDefaultValue":false},{"

IMHO it would be much more efficient (and give us programmers less gray hairs!) if shorter names were used, like:

"__type":"AjaxCT.CDDNV","n":"Abanda","v":"2728903","def":false},{"

Or even better, instead of returning an array of objects, return a single object (thus avoiding the namespace.classname overhead in each array element) that contains a string with the data in it. That is exactly what I did in my earlier implementation using Michael Schwartz's AJAX.NET and my own custom code.

In any event, adding the following to my Web.Config solved my issues (so far):

<

system.web.extensions>
<scripting>
<webServices>
<jsonSerializationmaxJsonLength="5000000" />
</webServices>
</scripting>
</system.web.extensions>This link describes Web.Config settings for AJAX:

http://ajax.asp.net/docs/ConfiguringASPNETAJAX.aspx#microsoftweb

This forum thread was also helpful:

http://forums.asp.net/thread/1634922.aspx