Showing posts with label atlas. Show all posts
Showing posts with label atlas. Show all posts

Wednesday, March 28, 2012

Change in DragDropList in new release ?

Hello,

Back in Atlas Time (6 monthes ago), I used Garbin's great exemple for a drag and drop found here:
http://aspadvice.com/blogs/garbin/archive/2006/01/17/14730.aspx

Now, after updating to the latest releases of ASPnet Ajax, I cannot make it work.

I've changed the script reference call into:
<asp:ScriptReferenceName="Microsoft.Web.Resources.ScriptLibrary.PreviewScript.js"Assembly="Microsoft.Web.Preview"/>
<asp:ScriptReferenceName="Microsoft.Web.Resources.ScriptLibrary.PreviewDragDrop.js"Assembly="Microsoft.Web.Preview"/>

The drag function (using "draggableListItem" beaviour) works well but the drop ("dragDropList" beaviour) is bugged and I get the following javascript error :

'this._activeDragSource.get_dragDataType()' is null or is not an object

Has there been a change in dragDropList in the new release? I cannot see it listed in the documentation.

Thanks in advance

Hi,

I've modified the example and the following code is working for me:

<%@. Page %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" ><head id="Head1" runat="server"> <title>Widgets UI Example</title> <style type="text/css"> body { font-family:Verdana; font-size:11px; } .main { position:relative; width:710px; height:540px; margin:auto; } .list1 { position:absolute; left:0px; height:520px; width:340px; padding:10px 5px 10px 10px; } .list2 { position:absolute; right:0px; height:520px; width:340px; padding:10px 10px 10px 5px; } .item { background:#fff; margin-bottom:5px; background:#fff; } .itemContent { padding:5px; text-align:center; } .itemHandle { height:15px; background:#e5ecf9; overflow:hidden; border-top:solid 1px #3366cc; font-weight:bold; cursor:move; } .dropCue { border:dashed 1px #ff0000; margin-bottom:5px; } .emptyList{ font-weight:bold; text-align:center; } .centered { margin:auto; } .templates { visibility:hidden; } </style></head><body> <form id="form1" runat="server"> <asp:ScriptManager ID="scriptManager" runat="server"> <Scripts> <asp:ScriptReference Assembly="Microsoft.Web.Preview" Name="PreviewScript.js" /> <asp:ScriptReference Assembly="Microsoft.Web.Preview" Name="PreviewDragDrop.js" /> </Scripts> </asp:ScriptManager> <div class="main"><%-- Left Area --%> <div id="leftArea" class="list1"> <div id="content1" class="item"> <div id="content1Handle" class="itemHandle">Content 1</div> <div class="itemContent"> <asp:Login ID="myLogin" runat="server" CssClass="centered"></asp:Login> </div> </div> <div id="content2" class="item"> <div id="content2Handle" class="itemHandle">Content 2</div> <div class="itemContent"> <asp:TextBox ID="myTextBox" runat="server"></asp:TextBox> <asp:Button ID="myButton" runat="server" Text="ClickMe" /> </div> </div> </div><%-- Right Area --%> <div id="rightArea" class="list2"> <div id="content3" class="item"> <div id="content3Handle" class="itemHandle">Content 3</div> <div class="itemContent"> <asp:Calendar ID="myCalendar" runat="server" CssClass="centered"></asp:Calendar> </div> </div> </div><%-- Templates --%> <div class="templates"><%-- Drop Cue template --%> <div id="dropCueTemplate" class="dropCue"></div><%-- Empty template --%> <div id="emptyTemplate" class="emptyList">Drop content here.</div> </div> </div> </form> <script type="text/xml-script"> <page> <components><!-- Left Area --> <control id="leftArea"> <behaviors> <dragDropList dragDataType="HTML" acceptedDataTypes="'HTML'" dragMode="Move" direction="Vertical"> <dropCueTemplate> <template layoutElement="dropCueTemplate" /> </dropCueTemplate> <emptyTemplate> <template layoutElement="emptyTemplate" /> </emptyTemplate> </dragDropList> </behaviors> </control><!-- Right Area --> <control id="rightArea"> <behaviors> <dragDropList dragDataType="HTML" acceptedDataTypes="'HTML'" dragMode="Move" direction="Vertical"> <dropCueTemplate> <template layoutElement="dropCueTemplate" /> </dropCueTemplate> <emptyTemplate> <template layoutElement="emptyTemplate" /> </emptyTemplate> </dragDropList> </behaviors> </control><!-- Draggable items --> <control id="content1"> <behaviors> <draggableListItem handle="content1Handle" /> </behaviors> </control> <control id="content2"> <behaviors> <draggableListItem handle="content2Handle" /> </behaviors> </control> <control id="content3"> <behaviors> <draggableListItem handle="content3Handle" /> </behaviors> </control> </components> </page> </script></body></html>


Yes ! It works perfect.

Thank you very much Garbin ! Smile


It's a great example.

Many thanks

Any ideas how I could save the contents after dragging

Any help on how we can get the list contents after a drop event would be good

Thanks anyway


Mike


mike963:

Any ideas how I could save the contents after dragging

Any help on how we can get the list contents after a drop event would be good

That is what I would also like to know. Also could you please Garbin provide the same code without xmlscript but with Microsoft AJAX library?

Thanx


I've been able to use the following code to make elements draggable:

$create(Sys.Preview.UI.DraggableListItem, {'handle': $get('content1Handle')}, null, null, $get('content1'));

But I haven't been able to programatically attach dragDropList behaviors because I can't figure out how to get a reference to a template. I had it working in Atlas (see: http://forums.asp.net/thread/1411942.aspx) but I had problems updating the template manager to work with MS AJAX.


Not that this will help too much, but I've been attempting the same thing. I've been spending a lot of time trying to understand exactly what the differences are between how the xml-script is parsed and run vice the imperative methods that you (and I) are trying.

A few things of note...

First, I noticed that if you call Sys.Application.getComponents(), the .length property will reveal that the imperative method will show five components are present (one for each $create call if you're mod'ing garbin's example like I am). In the declarative version, there are 10. So, after some investigating it seems that the declarative model makes one component for each DragDropList and each DraggableListItem (each behavior) and another component for each control, as a Sys.UI.Control (rightArea, leftArea, content1, content2, content3). Not sure if that's relevant just yet, but I suspect it might be.

Second, dropCueTemplates are Sys.Preview.UI.Template objects, not 'Declarative Template' objects like in AlexL's previous work around.

I've made them imperatively, but that hasn't helped in part b/c I'm not sure I'm making all the initialization params right. Looking in the previewScript.debug.js file, it looks like there's four params expected, but when I reflect on the actual dropCueTemplate that is sitting in one of the list behavior objects, it looks liek only two of them are passed by the xml-script; those are the _layoutTemplate (to be expected; and it's the dropCueTemplate DomElement), and the _parentMarkupContext.

I tried passing the list behavior a dropCueTemplate by using both the $create(Sys.Preview.UI.Template and the =new Sys.Preview.UI.Template syntax, but I think it's coming down to not knowing how to build that parentMarkupContext right. I've also tried to build one of those to pass in, but so far no joy. $create says that it doesn't support the property and using the =new has no effect at all (no error, no success). I suspect that you have to call initialize to get it to do anything, but I'm not sure why it's throwing that 'not supported' error. The Sys.Preview.UI.Template.initialize() function just deals with really basic DOM manipulation (tests if the layoutelement has a parentnode, if so it removes it from its parent node...)

Well, anyway, I need to get back to work now. T hose are my thoughts, please post here if you guys find anything adn I'll do the same.

Paul


Sorry for the thread necromancy, bu thas anyone had any luck solving this yet? I'd *really* like to be able to handle the control via js instead of xml-script...

Paul


I am looking for an option to save the position of those dragged items. I tried including a floatingbehavior to the xml-script for that control and provided

move = "OnMove" attribute value. And on the OnMove i tried to Save Profile properties. It didn't work. Any suggestions ??


Just to mention I updated the code for Atlas RC1.

Source here :

http://blog.marjanenarnout.be/index.php?entry=entry070320-224307

Monday, March 26, 2012

Cell colors odd behaviour in DetailsView

I have a page with an Atlas updatePanel and a detailsview in editMode.

I also have a save button that is responsible for updating the detailsview and run a custom command (runChecks) that basically does the following:

- check if a textbox in the detailsview is within a specific range of values; if it is not, color the detailsview's cell in red;

Currently the SaveButton Command code is:

runChecks(); DetailsView1.UpdateItem(true);//DetailsView1.Dispose(); DetailsView1_DataBound(sender, e);

My problem is that if I change the value from "good" to "bad" and click the save button, the cell is not colored red. It only changes color if I refresh the page.

Oddly, if I change from "bad" to "good", I don't need the refresh for the color to be in its default value.

If the TextBox's autopostBack is set to true, the cell will become colored red after I change it to a "bad" value but the color dissappears when I click save. Again, it will reappear in red if I refresh the page.

Why is this happening and how can I prevent the red color from dissappear when I click save?

Thank you!

FYI, what the runChecks currently does is:

protected void runChecks() {bool valid =true; DemographicsCriteria criteria =new DemographicsCriteria(1,null,null); valid = valid && criteria.editCheck("Age", ((TextBox)DetailsView1.FindControl("ageTextBox")).Text, DetailsView1.Rows[2].Cells[1]); valid = valid && criteria.editCheck("Gender", ((RadioButtonList)DetailsView1.FindControl("genderRB")).SelectedValue, DetailsView1.Rows[3].Cells[1]);if (valid ==false) { warningLabel.Visible =true; }else { warningLabel.Visible =false; } }

where editCheck is:

public bool editCheck(string filter,string value, TableCell cell) { DataRow[] criteriaRow;switch (filter) {case"Age": {int valueInt = _code.convertStringToInt(value); criteriaRow = selectDemographicsCriteria(filter);if (((int)criteriaRow[0][_minimumVIndex]) >= valueInt || valueInt >= ((int)criteriaRow[0][_maximumVIndex])) { cell.BackColor = _errorColor;return false; }else {return true; } }break;case"Gender": {if (value !="M") { cell.BackColor = _errorColor;return false; }else {return true; } }break;default:return true;break; } }

Cause a JavaScript Function to run after update (update panel postback)

Hello,

I ran into a problem that im not sure if the Atlas framework addresses.

I need to fire off a javascript function (which is decided server side)on a postback. To do this I am going to be using a hidden input field.(since I already have one on the form I use to send information forserver use.) From the server side, I can place the function names intothe hidden input field. But I can't cause them to run, on each postback.

I suppose that is confusing, let me try something simpler.

1. I fire off a postback in javascript - This is done using the__dopostback() and the server side fires off its if statements and doesits functions based on what has been placed into my hidden input field.(this is all good so far) (if I had to I could use the body's on formload ability to fire off the javascript functions I desire, but thatwont work for the next step, and is really ugly)

2. I include Atlas to make my postback not refresh the whole page. This is done by using UpdatePanels.

3. On the server side I need to somehow tell it to run certainjavascript functions when that postback finishes loading. (so like onpartial page load)

How do I do step 3?<script type="text/javascript">
function AfterPostback()
{
alert("This is where we check the hidden input and run the functions.");
}

function PageRequestManagerPropertyChanged(sender, args)
{
if (args.get_propertyName() == "inPostBack")
{
if (!$object("_PageRequestManager").get_inPostBack())
AfterPostback();
}
}

function pageLoad()
{
$object("_PageRequestManager").propertyChanged.add(PageRequestManagerPropertyChanged);
}
</script
<div>
<atlas:ScriptManagerEnablePartialRendering="true" ID="ScriptManager1" runat="server">
</atlas:ScriptManager>
<atlas:UpdatePanel runat="server" Mode="Conditional" ID="UpdatePanel1">
<ContentTemplate>
<%= DateTime.Now.ToLongTimeString() %>
</ContentTemplate>
<Triggers>
<atlas:ControlEventTrigger ControlID="UpdateTime" EventName="Click"/>
</Triggers>
</atlas:UpdatePanel>
<asp:Button ID="UpdateTime" runat="server" Text="Update Time" />
</div
Thats the solution I rigged up.
Hi,

Thanks for posting your solution. It works very well and solves a whole bunch of missing stuff with AtlasPanels. One problem dough. I had to move the call to JS function pageLoad() to the end of the html file part instead of putting it to body onload event.
Another option for doing this is theUpdateProgressSignup extension.

Catching key press events. For example username control without postback

Hi atlas developers and implementers,

For example I have a textbox and I want that on every key press the written string will be controlled from database and it should say whether it is found on database or not. I'm using atlas 2.0. It is like username control without postback.

How can I do this..

Kind Regards,

Fatih U?AR.
Postglobal Ltd.
R&D ManagerHi,

basic example + bonus behavior:

<%@. Page Language="C#" %><%@. Import Namespace="System.Data" %><%@. Import Namespace="System.Web.Services" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><script runat="server"> private DataTable data = null; protected void Page_Load(object sender, EventArgs e) { BuildData(); } private void BuildData() { data = new DataTable(); data.Columns.Add(new DataColumn("Username", typeof(string))); data.Rows.Add("garbin"); data.Rows.Add("leoscorpio82"); } [WebMethod] public bool CheckForUsername(string username) { bool userExists = data.Select("Username = '" + username + "'").Length > 0; return userExists; }</script><html xmlns="http://www.w3.org/1999/xhtml" ><head runat="server"> <title>Untitled Page</title></head><body> <form id="form1" runat="server"> <atlas:ScriptManager ID="sm" runat="server"></atlas:ScriptManager> <div> <span>Username:</span> <asp:TextBox ID="txtUsername" runat="server"></asp:TextBox> </div> </form> <script type="text/javascript"> function txtUsername_Keypress(sender, e) { PageMethods.CheckForUsername($object('txtUsername').get_text(), onCheckComplete); } function onCheckComplete(result) { $object('txtUsername').get_style().backgroundColor = (result) ? '#ffffff' : '#ff0000'; } </script> <script type="text/xml-script"> <page> <components> <textBox id="txtUsername"> <behaviors> <keyUpBehavior keyup="txtUsername_Keypress" /> </behaviors> </textBox> </components> </page> </script> <script type="text/javascript"> // A behavior to handle the keyup event. Type.registerNamespace('AtlasExamples'); AtlasExamples.KeyUpBehavior = function() { AtlasExamples.KeyUpBehavior.initializeBase(this); // Private members. var _keyupHandler; // Events. this.keyup = this.createEvent(); // Initialize / Dispose. this.initialize = function() { AtlasExamples.KeyUpBehavior.callBaseMethod(this, 'initialize'); _keyupHandler = Function.createDelegate(this, keyupHandler); this.control.element.attachEvent('onkeyup', _keyupHandler); } this.dispose = function() { this.control.element.detachEvent('onkeyup', _keyupHandler); _keyupHandler = null; AtlasExamples.KeyUpBehavior.callBaseMethod(this, 'dispose'); } // Descriptor. this.getDescriptor = function() { var td = AtlasExamples.KeyUpBehavior.callBaseMethod(this, 'getDescriptor'); td.addEvent('keyup', true); return td; } // Event Handler. function keyupHandler() { //debug.trace(event.keyCode); this.keyup.invoke(this, Sys.EventArgs.Empty); } } AtlasExamples.KeyUpBehavior.registerClass('AtlasExamples.KeyUpBehavior', Sys.UI.Behavior); Sys.TypeDescriptor.addType('script', 'keyUpBehavior', AtlasExamples.KeyUpBehavior); </script></body></html>

hello ,

the answer is ok but where is the 'AtlasExamples' behavior

i'll be glad for you answer

kind regards,


Hi,

AtlasExamples is a namespace (defined with a call to Type.registerNamespace at the beginning of the Javascript code) while the behavior is the AtlasExamples.KeyUpBehavior class defined inside the Javascript code block (it inherits from the base Sys.UI.Behavior class).


hi garbin yes i know but i don't have the dll file of the namespace. so i can't get it work. I need necessary files.. I'll be glad if you send me the files tofatihu@.postglobal.com

regards,


Hi,

sorry, but what do you mean by "the dll of the namespace"?


I mean, I run the code you wrote but it didn't work, what should I do, it didn't validate

Hi,

ah, sorry, didn't notice that the code was written for CTPs :)

Here's the updated code:

<%@. Page Language="C#" %><%@. Import Namespace="System.Data" %><%@. Import Namespace="System.Web.Services" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><script runat="server"> private static DataTable data = null; protected void Page_Load(object sender, EventArgs e) { BuildData(); } private void BuildData() { data = new DataTable(); data.Columns.Add(new DataColumn("Username", typeof(string))); data.Rows.Add("garbin"); data.Rows.Add("leoscorpio82"); } [WebMethod] public static bool CheckForUsername(string username) { bool userExists = data.Select("Username = '" + username + "'").Length > 0; return userExists; }</script><html xmlns="http://www.w3.org/1999/xhtml" ><head id="Head1" runat="server"> <title>Untitled Page</title></head><body> <form id="form1" runat="server"> <asp:ScriptManager ID="TheScriptManager" runat="server"> <Scripts> <asp:ScriptReference Assembly="Microsoft.Web.Preview" Name="PreviewScript.js" /> </Scripts> </asp:ScriptManager> <div> <span>Username:</span> <asp:TextBox ID="txtUsername" runat="server"></asp:TextBox> </div> </form> <script type="text/javascript"><!-- function txtUsername_Keypress(sender, e) { PageMethods.CheckForUsername($get('txtUsername').value, onCheckComplete); } function onCheckComplete(result) { $get('txtUsername').style.backgroundColor = (result) ? '#ffffff' : '#ff0000'; } //--> </script> <script type="text/xml-script"> <page xmlns="http://schemas.microsoft.com/xml-script/2005" xmlns:cc="AtlasExamples"> <components> <textBox id="txtUsername"> <behaviors> <cc:keyUpBehavior keyUp="txtUsername_Keypress" /> </behaviors> </textBox> </components> </page> </script> <script type="text/javascript"> // A behavior to handle the keyup event. Type.registerNamespace('AtlasExamples'); AtlasExamples.KeyUpBehavior = function(element) { AtlasExamples.KeyUpBehavior.initializeBase(this, [element]); } AtlasExamples.KeyUpBehavior.prototype = { // Initialize / Dispose. initialize : function() { AtlasExamples.KeyUpBehavior.callBaseMethod(this, 'initialize'); $addHandlers(this.get_element(), {'keyup':this._onKeyUp}, this); }, dispose : function() { $clearHandlers(this.get_element()); AtlasExamples.KeyUpBehavior.callBaseMethod(this, 'dispose'); }, // Event Handler. _onKeyUp : function(evt) { this._raiseEvent('keyUp', Sys.EventArgs.Empty); }, // Event add_keyUp : function(handler) { this.get_events().addHandler('keyUp', handler); }, remove_keyUp : function(handler) { this.get_events().removeHandler('keyUp', handler); }, _raiseEvent : function(eventName, eventArgs) { var handler = this.get_events().getHandler(eventName); if (handler) { if (!eventArgs) { eventArgs = Sys.EventArgs.Empty; } handler(this, eventArgs); } } } // Descriptor. AtlasExamples.KeyUpBehavior.descriptor = { events: [{name: 'keyUp'}] } AtlasExamples.KeyUpBehavior.registerClass('AtlasExamples.KeyUpBehavior', Sys.UI.Behavior); </script></body></html>

Catching drop event in atlas drag and drop

Hi I want to drag a GridView cell and drop it on another GridView and adding a new row in second gridview based on the dragged element name. Is there any method by which I can capture the drop event .Have you tried using theReorderList Control?

Thanks Shepherd. But I want to use drag and drop between two GridView's. ReorderList does not work properly for this purpose. Moreover I tried to use ReorderList with DataSource and it gives me error while reordering. Can u help me regarding this. And I want to execute a Insert command on drop event.

Thanks.


@.Kanwar,

To my knowledge this is not supported yet. I've read requests for this functionality on the AJAX Control Toolkit Codeplex site, but I don't know of any official plans to add it. I assume that it is possible, and that you could build it yourself if you have time...you might also look into some third party controls like Telerik or Infragistics. I don't know if they have controls like this, but they are usually a little ahead of the curve feature-wise. I hope this is helpful.


Best Regards...


Thanks. I am trying to build Ajax template for this.
Best of luck to you.

CascadingDropDownProperties not recognised in AJAX

Hi,

I've been using CascadingDropDowns quite successfully in Atlas but have now hit a problem moving to ASP.NET AJAX.


I get a message saying "Element 'CascadingDropDownProperties' is not a known element. This can occur if there is a compilation error in the web site."

When I compile, I get an error message saying "'AjaxControlToolkit.CascadingDropDown' does not have a public property named 'CascadingDropDownProperties'".

In my VB code, I import the AjaxControlToolkit but I get a message saying "Type 'CascadingDropDownProperies' is not defined" and "'GetTargetProperties' is not a member of 'AjaxControlToolkit.CascadingDropDown'".

It almost seems as though CDD properties have been dropped, but that can't be right - can it?

I guess I must be missing something fundamental. Any ideas? I have pasted by code below and highlighted the offending lines...

-- Search.aspx --
<%@dotnet.itags.org. Page Language="VB" AutoEventWireup="true" CodeFile="Search.aspx.vb" MasterPageFile="~/MasterPage.master" Inherits="Search" Title="TiberPass: Property Search Page" %
<%@dotnet.itags.org. Register
Assembly="AjaxControlToolkit"
Namespace="AjaxControlToolkit"
TagPrefix="AjaxCTK"
%
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<AjaxCTK:CascadingDropDown ID="cdd" runat="server" >
<AjaxCTK:CascadingDropDownProperties
Category="Province"
PromptText="-- Any Province --"
ParentControlID="ddlRegion"
ServiceMethod="GetProvincesForRegion"
ServicePath="ListcountService.asmx"
TargetControlID="ddlProvince" />
<AjaxCTK:CascadingDropDownProperties
Category="Town"
ParentControlID="ddlProvince"
PromptText="-- Any Town --"
ServiceMethod="GetTownsForProvince"
ServicePath="ListcountService.asmx"
TargetControlID="ddlTown" />
<AjaxCTK:CascadingDropDownProperties
TargetControlID="ddlRegion"
Category="Region"
ServicePath="ListcountService.asmx"
ServiceMethod="GetRegions"
PromptText="-- Any Region --" />
</AjaxCTK:CascadingDropDown>
....


-- Search.aspx.vb --
Imports AjaxControlToolkit

Partial Class Search
Inherits SmartSessionPage

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

' Retrieve Atlas Cascading Dropdown settings from session variables
Dim properties AsCascadingDropDownProperties

' Region
properties = cdd.GetTargetProperties(ddlRegion)
If properties IsNot Nothing Then
If RegionID <> Nothing Then
properties.SelectedValue = RegionID
End If
End If

' Province
properties = cdd.GetTargetProperties(ddlProvince)
If properties IsNot Nothing Then
If ProvinceID <> Nothing Then
properties.SelectedValue = ProvinceID
End If
End If

' Town
properties = cdd.GetTargetProperties(ddlTown)
If properties IsNot Nothing Then
If TownID <> Nothing Then
properties.SelectedValue = TownID
End If
End If

End Sub

End Class

-- MasterPage.Master --
<%@dotnet.itags.org. Master Language="VB" %
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
<script runat="server"
</script
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Tiber Pass</title>
<link rel="stylesheet" type="text/css" href="http://links.10026.com/?link=css/main.css"/>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
</asp:contentplaceholder>
<asp:ScriptManager ID="ScriptManager1" runat="server" enablepartialrendering="true">
</asp:ScriptManager>
</div>
</form>
</body>
</html
-- Web.config --
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="microsoft.web" type="Microsoft.Web.Configuration.MicrosoftWebSectionGroup, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<sectionGroup name="scripting" type="Microsoft.Web.Configuration.ScriptingSectionGroup, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<sectionGroup name="webServices" type="Microsoft.Web.Configuration.ScriptingWebServicesSectionGroup, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<section name="jsonSerialization" type="Microsoft.Web.Configuration.ScriptingJsonSerializationSection, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false"/>
<section name="profileService" type="Microsoft.Web.Configuration.ScriptingProfileServiceSection, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false"/>
<section name="authenticationService" type="Microsoft.Web.Configuration.ScriptingAuthenticationServiceSection, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false"/>
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>
<system.web>
<pages>
<controls>
<add tagPrefix="asp" namespace="Microsoft.Web.UI" assembly="Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add tagPrefix="asp" namespace="Microsoft.Web.UI.Controls" assembly="Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add tagPrefix="asp" namespace="Microsoft.Web.Preview.UI" assembly="Microsoft.Web.Preview"/>
<add tagPrefix="asp" namespace="Microsoft.Web.Preview.UI.Controls" assembly="Microsoft.Web.Preview"/>
</controls>
<tagMapping>
<add tagType="System.Web.UI.WebControls.CompareValidator" mappedTagType="Microsoft.Web.UI.Compatibility.CompareValidator, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add tagType="System.Web.UI.WebControls.CustomValidator" mappedTagType="Microsoft.Web.UI.Compatibility.CustomValidator, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add tagType="System.Web.UI.WebControls.RangeValidator" mappedTagType="Microsoft.Web.UI.Compatibility.RangeValidator, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add tagType="System.Web.UI.WebControls.RegularExpressionValidator" mappedTagType="Microsoft.Web.UI.Compatibility.RegularExpressionValidator, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add tagType="System.Web.UI.WebControls.RequiredFieldValidator" mappedTagType="Microsoft.Web.UI.Compatibility.RequiredFieldValidator, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add tagType="System.Web.UI.WebControls.ValidationSummary" mappedTagType="Microsoft.Web.UI.Compatibility.ValidationSummary, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</tagMapping>
</pages>
<!--
Set compilation debug="true" to insert debugging
symbols into the compiled page. Because this
affects performance, set this value to true only
during development.
-->
<compilation debug="false">
<assemblies>
<add assembly="Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add assembly="System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/></assemblies>
</compilation>
<httpHandlers>
<remove verb="*" path="*.asmx"/>
<add verb="*" path="*.asmx" validate="false" type="Microsoft.Web.Script.Services.ScriptHandlerFactory, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add verb="GET" path="ScriptResource.axd" type="Microsoft.Web.Handlers.ScriptResourceHandler" validate="false"/>
</httpHandlers>
<httpModules>
<add name="WebResourceCompression" type="Microsoft.Web.Handlers.WebResourceCompressionModule, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="ScriptModule" type="Microsoft.Web.UI.ScriptModule, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</httpModules>
</system.web>
<microsoft.web>
<scripting>
<webServices>
<!-- Uncomment this line to customize maxJsonLength and add a custom converter -->
<!--
<jsonSerialization maxJsonLength="500">
<converters>
<add name="ConvertMe" type="Acme.SubAcme.ConvertMeTypeConverter"/>
</converters>
</jsonSerialization>
-->
<!-- Uncomment this line to enable the authentication service. Include requireSSL="true" if appropriate. -->
<!--
<authenticationService enabled="true" requireSSL = "true|false"/>
-->
<!-- Uncomment these lines to enable the profile service. To allow profile properties to be retrieved
and modified in ASP.NET AJAX applications, you need to add each property name to the setProperties and
getProperties attributes. -->
<!--
<profileService enabled="true"
readAccessProperties="propertyname1,propertyname2"
writeAccessProperties="propertyname1,propertyname2" />
-->
</webServices>
</scripting>
</microsoft.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules>
<add name="ScriptModule" preCondition="integratedMode" type="Microsoft.Web.UI.ScriptModule, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</modules>
<handlers>
<remove name="WebServiceHandlerFactory-ISAPI-2.0"/>
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="Microsoft.Web.Script.Services.ScriptHandlerFactory, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add verb="GET" path="ScriptResource.axd" type="Microsoft.Web.Handlers.ScriptResourceHandler" validate="false"/>
</handlers>
</system.webServer>
</configuration

Android:

Hi,

I've been using CascadingDropDowns quite successfully in Atlas but have now hit a problem moving to ASP.NET AJAX.


I get a message saying "Element 'CascadingDropDownProperties' is not a known element. This can occur if there is a compilation error in the web site."

When I compile, I get an error message saying "'AjaxControlToolkit.CascadingDropDown' does not have a public property named 'CascadingDropDownProperties'".

In my VB code, I import the AjaxControlToolkit but I get a message saying "Type 'CascadingDropDownProperies' is not defined" and "'GetTargetProperties' is not a member of 'AjaxControlToolkit.CascadingDropDown'".

It almost seems as though CDD properties have been dropped, but that can't be right - can it?

The properties have been moved for the new release of ASP.NET AJAX. There's more information in themigration guide for the toolkitand examples of how the new approach works in thesample page for the cascading dropdown control. I hope this helps!


Ah! That explains it. I thought I must have missed something pretty fundamental. Thanks for that.

I've been attempting to convert my code, but come across a problem when I try to use CascadingDropDownProperties and GetTargetProperties. I guess these don't exist any more but what do I use instead? Sorry if this seems basic, but I'm not very technical and am only using VB.NET reluctantly (I kind of hoped Atlas/Ajax would do it all for me, sigh). The examples are in C#.

I'm trying to set my drop down lists based on saved session variables. It was working OK in Atlas, but now I'm struggling. Any ideas? Here are the main parts of my code with the offending bits highlighted:

-- Search.aspx --
<AjaxCTK:CascadingDropDown
ID="cddProvince"
runat="server"
Category="Province"
PromptText="-- Any Province --"
ParentControlID="ddlRegion"
ServiceMethod="GetProvincesForRegion"
ServicePath="ListcountService.asmx"
TargetControlID="ddlProvince"
LoadingText="Loading Provinces..." />
<AjaxCTK:CascadingDropDown
ID="cddTown"
runat="server"
Category="Town"
ParentControlID="ddlProvince"
PromptText="-- Any Town --"
ServiceMethod="GetTownsForProvince"
ServicePath="ListcountService.asmx"
TargetControlID="ddlTown"
LoadingText="Loading Towns..." />
<AjaxCTK:CascadingDropDown
ID="cddRegion"
runat="server"
TargetControlID="ddlRegion"
Category="Region"
ServicePath="ListcountService.asmx"
ServiceMethod="GetRegions"
PromptText="-- Any Region --"
LoadingText="Loading Regions..." /
-- Search.aspx.vb --
Dim properties AsCascadingDropDownProperties

' Region
properties = cddRegion.GetTargetProperties(ddlRegion)
If properties IsNot Nothing Then
If RegionID <> Nothing Then
properties.SelectedValue = RegionID
properties = RegionID
End If
End If



Android:

Ah! That explains it. I thought I must have missed something pretty fundamental. Thanks for that.

I've been attempting to convert my code, but come across a problem when I try to use CascadingDropDownProperties and GetTargetProperties. I guess these don't exist any more but what do I use instead? Sorry if this seems basic, but I'm not very technical and am only using VB.NET reluctantly (I kind of hoped Atlas/Ajax would do it all for me, sigh). The examples are in C#.

I'm trying to set my drop down lists based on saved session variables. It was working OK in Atlas, but now I'm struggling. Any ideas? Here are the main parts of my code with the offending bits highlighted:


-- Search.aspx.vb --
Dim properties AsCascadingDropDownProperties

' Region
properties = cddRegion.GetTargetProperties(ddlRegion)
If properties IsNot Nothing Then
If RegionID <> Nothing Then
properties.SelectedValue = RegionID
properties = RegionID
End If
End If


I think they changed how you access the individual dropdownlists. You can now directly access them, so if you want to set the selectedValue of the ddlRegion control, do this:

cddRegion.SelectedValue = RegionID

I assume RegionID is stored somewhere in Session. It sounds like you're doing that.

One thing I would watch out for is the order you set the selectedValues for the cascading dropdowns. I haven't used the control yet, but I assume it might have problems if you don't assign a value to the parent dropdownlist, then the one under it, then the one under it, and so on.

Best of luck, let us know how it went!


That's great. It's much easier now.

You're right, I'm storing RegionID, etc. as session variables. The idea is that the drop downs will retain the user selections when they return to this page. I had it working fine before.

Now I have a new problem. For some reason the code I have written in my search page to populate the drop downs is not being executed. I have set up 3 drop downs with 3 associated CDDs. The dropdowns should call service methods like "GetRegions" and "GetProvincesForRegion", etc. within ListCountService.asmx, but it never gets that far. The drop downs come up with a Method Error 500. I've put a breakpoint in GetRegions, but it doesn't get activated. Maybe it's something in my header? Before, I had EnableEventValidation, EnableViewState and AutoEventWireup set to false. Now I just have AutoEventWireup set to true and don't mention the other two.

The code for Search.aspx hasn't changed since my last post and I haven't touched the code in ListCountService.asmx. Besides, no matter how good or bad the code is, it just isn't running!

I really appreciate your help on this.

Andrew


Check out Cranzy's post inthis thread andthis blog post by Shawn Burke. I hope this helps!

Fantastic! That's solved it and it's all working fine now. Thanks very much. I'm pretty sure I wouldn't have spotted that other post or blog entry without a nudge in the right direction.

Thanks again,

Andrew

Saturday, March 24, 2012

CascadingDropDown, FormView, ObjectDataSource, Optimistic Concurrency and Delete

Greetings,


We have recently upgraded a web site from "atlas" July 06 to use AJAX 1.0 (1.0.61025.0) and AjaxControlToolkit March 07 (1.0.10301.0). As you can imagine, we had to "tweak" a fair amount of code but in short, all is now working minus one major point.


We have a middle-tier DataAccessLayer that simply uses Microsoft's XSD's to connect to Oracle 9i and we make use of the Optimistic Concurrency feature. The front-end web with FormViews and Cascading dropdowns consumes the ObjectDataSource and works great on Insert and Update. But Deletes fail due to optimistic concurrency. It seems that only on deletes, the "Original_fieldname" values are NULL for any dropdown wired to a cascading control. However, "Original_fieldname" values are correct when UPDATE is clicked. Only when DELETE is clicked does the FormView fail to populate to original values and thereby the ObjectDataSource has NULL values as well.


Any ideas? Thanks!

Unfortunately, use of the CascadingDropDown isn't fully compatible with standard data-bound drop downs. The CascasdingDropDown expects to pick up it's data from the async web service call.

Off the top of my head, I'm not sure how those field values get populated, but I suspect it's part of the <%# Bind() %> functionality. The CascadingDropDown might be overwriting those values. You might be able to work around this by trapping the delete and filling in the value before the command is sent to the ObjectDataSource.


Thanks for the info. We used your suggestion in the ObjectDataSource_Deleting event and supplied all of the "original_xxx" InputParameters with values from a lookup to the record in question. Kind of a hack and somewhat defeats the purpose of optimistic concurrency, but it will do for now. Aside from that, the work your team has done on the toolkit is amazing. Keep it up!

CascadingDropDown with database - newbie question

Sorry if this seems a bit obvious but I'm a relative newcomer to ASP.NET, especially Atlas, and am a bit stuck.

I have an Access database with three tables: tblRegions, tblProvinces and tblTowns. I want to use these tables to drive 3 related dropdown lists. It's no problem achieving this with server-side controls, but I want the performance advantages of client-side processing - hence my interest in Atlas.

I've followed the examples and, after a bit of a struggle, managed to get a "hard-coded" version working (with the names of Regions, Provnces, etc. embedded in the code), but now I'm ready to data-enable it.

I've looked for examples and can't find anything that covers everything I need to do. All the examples seem to assume a fairly high level of coding experience - especially in C# - whereas I'm more used to dragging and dropping datasources and coding, when strictly necessary, in VB. Can anyone explain the exact steps I need to follow to achieve what I want using VB and, preferably, using an Access data source?

At the moment, my code is as follows:
---------- Default.aspx --------------
<%@dotnet.itags.org. Page Language="VB" EnableEventValidation="false" %>
<%@dotnet.itags.org. Register
Assembly="AtlasControlToolkit"
Namespace="AtlasControlToolkit"
TagPrefix="atlasToolkit" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server"><title>Test Page</title></head>
<body><form id="Form1" runat="server"><div>
<atlas:ScriptManager ID="ScriptManager1" runat="server" />
<table>
<tr>
<td align="right">Region: </td>
<td><asp:DropDownList ID="ddlRegion" runat="server"></asp:DropDownList></td>
</tr>
<tr>
<td align="right">Province: </td>
<td><asp:DropDownList ID="ddlProvince" runat="server"></asp:DropDownList></td>
</tr>
<tr>
<td align="right">Town: </td>
<td><asp:DropDownList ID="ddlTown" runat="server"></asp:DropDownList></td>
</tr>
</table>
<atlasToolkit:CascadingDropDown ID="cdd" runat="server">
<atlasToolkit:CascadingDropDownProperties
TargetControlID="DropDownList1"
Category="Region"
ServicePath="ListcountService.asmx"
ServiceMethod="GetRegions"
PromptText="-- Any Region --" />
<atlasToolkit:CascadingDropDownProperties
TargetControlID="ddlRegion"
Category="Region"
ServicePath="ListcountService.asmx"
ServiceMethod="GetRegions"
PromptText="-- Any Region --" />
<atlasToolkit:CascadingDropDownProperties
TargetControlID="ddlProvince"
ParentControlID="ddlRegion"
Category="Province"
ServicePath="ListcountService.asmx"
ServiceMethod="GetProvincesForRegion"
PromptText="-- Any Province --" />
<atlasToolkit:CascadingDropDownProperties
TargetControlID="ddlTown"
ParentControlID="ddlProvince"
Category="Town"
ServicePath="ListcountService.asmx"
ServiceMethod="GetTownsForProvince"
PromptText="-- Any Town --" />
</atlasToolkit:CascadingDropDown>
</div></form></body>
</html
----------- ListcountService.asmx ----------
<%@dotnet.itags.org. WebService Language="VB" Class="ListCountService1" %
Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports AtlasControlToolkit

<WebService(Namespace := "http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
Public Class ListCountService1
Inherits System.Web.Services.WebService

<WebMethod()> _
Public Function GetRegions(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
Return New CascadingDropDownNameValue() _
{New CascadingDropDownNameValue("Lazio", 1), _
New CascadingDropDownNameValue("Tuscanny", 2), _
New CascadingDropDownNameValue("Umbria", 3)}
End Function

<WebMethod()> _
Public Function GetProvincesForRegion(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
Dim kv As StringDictionary = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)
Dim RegionId As Integer
If (kv.ContainsKey("Region") And Int32.TryParse(kv("Region"), RegionId)) Then
If (RegionId = 1) Then
Return New CascadingDropDownNameValue() _
{New CascadingDropDownNameValue("Upper Lazio", 11), _
New CascadingDropDownNameValue("Middle Lazio", 12), _
New CascadingDropDownNameValue("Lower Lazio", 13)}
ElseIf (RegionId = 2) Then
Return New CascadingDropDownNameValue() _
{New CascadingDropDownNameValue("Upper Tuscanny", 21), _
New CascadingDropDownNameValue("Middle Tuscanny", 22), _
New CascadingDropDownNameValue("Lower Tuscanny", 23)}
End If
End If
Return New CascadingDropDownNameValue() {}
End Function

<WebMethod()> _
Public Function GetTownsForProvince(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
Dim kv As StringDictionary = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)
Dim ProvinceId As Integer
If (kv.ContainsKey("Province") And Int32.TryParse(kv("Province"), ProvinceId)) Then
If (ProvinceId = 11) Then
Return New CascadingDropDownNameValue() _
{New CascadingDropDownNameValue("Upper Lazio Town 1", 111), _
New CascadingDropDownNameValue("Upper Lazio Town 2", 112), _
New CascadingDropDownNameValue("Upper Lazio Town 3", 113)}
ElseIf (ProvinceId = 12) Then
Return New CascadingDropDownNameValue() _
{New CascadingDropDownNameValue("Middle Lazio Town 1", 121), _
New CascadingDropDownNameValue("Middle Lazio Town 2", 122), _
New CascadingDropDownNameValue("Middle Lazio Town 3", 123)}
End If
End If
Return New CascadingDropDownNameValue() {}
End Function
End Class
---------------------------

Thanks in advace for your help,
AndrewHave you already followed theUsing CascadingDropDown with a Database walkthrough that comes with the Toolkit?
Yes, but I don't understand the GetColorsForModel function, especially the code that reads:

CarsTableAdapters.ColorTableAdapter adapter =
newCarsTableAdapters.ColorTableAdapter();

Cars.ColorDataTable colorTable =
adapter.GetColorsForModel(modelId);

List<CascadingDropDownNameValue> values =
new List<CascadingDropDownNameValue>();

foreach (DataRow drin colorTable)
{
values.Add(newCascadingDropDownNameValue(
(string) dr["Color"],
dr["ColorID"].ToString()));

Maybe I'm naive, but when I used plain ASP.NET (with VWD 2005), I found it very easy to set up a dropdown list. I just dragged a datasource object from the toolbox, set it up by defining a few properties and then dragged a dropdown list next to it and linked it to the datasource by defining more properties. No coding necessary. Coming from that experince, I guess I'm a bit daunted by the amount of C# that comes up in the examples. I'm prepared to get my hands dirty if necessary, but I was hoping that the toolkit would hold my hand a bit. Any ideas?

The CascadingDropDown is more complex because it enables a richer scenario. The web service it calls has the ability to return any set of data based on any information. In the sample above, it's querying part of a database to return only the subset of data that's needed by the CDD that's about to populate. I believe that if you walk through the code above with the MSDN documentation, the purpose of each line should not be too difficult to understand. Once you understand how this example is working, if you have any suggestions for simplifying it from the point of view of someone who's just gone through the process, we'd certainly love to hear them!!

Thanks for your help!


Thanks for my help? I thought it was you helping me!

Anyway, it looks like I can't connect to the database table by dragging and dropping a DataSource object from the toolbox like- right? I need to make the connection in code. As a newbie used to ASP.NET and VWD2005, that's a bit daunting - especially since the example is in C# and I'm more used to VB.

Could you please point me to a code example (preferably in VB) that shows how to connect to an Access database table and put the results into an array?

Thanks in advance
OK here's an update. After much scrabbling around the MSDN documentation, and a lot of trial-and-error guesswork, I've finally managed to make some progress. This is the updated version of my GetRegions function:

Public Function GetRegions(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
Dim objAdapter As New System.Data.OleDb.OleDbDataAdapter _
("SELECT regID, regName FROM tlkpRegionList ORDER BY RegID", _
"Provider = Microsoft.Jet.OLEDB.4.0;" & _
"User ID = Admin;" & _
"Data Source=D:\WebSites\AtlasWebSite\App_Data\TiberPass.mdb")
Dim objDataSet As New System.Data.DataSet()
objAdapter.Fill(objDataSet)
Dim objTable As System.Data.DataTable
objTable = objDataSet.Tables(0)
With objTable
Dim intRow As Integer
For intRow = 0 To .Rows.Count - 1
Return New CascadingDropDownNameValue() _
{New CascadingDropDownNameValue(.Rows(intRow).ItemArray(1), .Rows(intRow).ItemArray(0))}
Next intRow
End With
Return New CascadingDropDownNameValue() {}
End Function

It succesfully gets a record from my database table. However, there are several problems:

1) I used the absolute path to connect to the Access database file. This won't port onto a web-server. Is there a way to use a relative path instead?

2) At this stage, I've only managed to retrieve one record. I want to loop through all the records in the table, but I don't know how to add additional entries to the CDD. Any clues?

3) Assuming I can solve the above problems, there's still a flaw when it comes to the other two CDDs. They are going to need logic (IF statements, etc.) so that they are populated with data depending on the user selection in the "upstream" CDDs. It seems that I'll need to make calls to the database (on the server) to achieve this. I feel it would be better if I could somehow make a single call to the database to get the contents of the three tables (into a DataSet?) for client-side processing. That would avoid repeated calls back to the server. Any idea how to achieve this?

Thanks again for your help,
Andrew

1: You can probably use relative paths. Someone who knows Access access can probably help here.

2: You want to build an array of CascadingDropDownNameValue objects, then return the array. Your code's set up for looping through the returned rows, but always returns just the first CascadingDropDownNameValue it creates.

3: Each CDD populates independently, so each associated web method should query the database to get the data it needs. That said, each call can use the information available to it about the values of the parent control(s) to filter that data. But there will be one web service call for each CDD when it needs to populate. If you want to cache things in your web methods such that you only ever need to make one database call, that's certainly something you can do.


I've solved point 1 (relative path) by replacing my code:
"Data Source=D:\WebSites\AtlasWebSite\App_Data\TiberPass.mdb")
with:
"Data Source=" & Server.MapPath(".") & "\App_Data\TiberPass.mdb")
I've yet to test this on a web server, but it works on my local machine.

Point 2 (returning an array of CascadingDropDownNameValue objects) is a bit more daunting.

Point 3 (caching table data) is something I can look into later. So...

Any advice on how to set up and return an array of CDD NameValue objects?

Hi Android,

The key bits you need are as follows:

Dim

valuesAs List(Of CascadingDropDownNameValue) =New List(Of CascadingDropDownNameValue)

For intRow = 0 To .Rows.Count - 1

values.Add(New CascadingDropDownNameValue(.Rows(intRow).ItemArray(1).ToString, .Rows(intRow).ItemArray(0)))

Next

Return

values.ToArray

Not sure I've copy and pasted your data in exactly right, but essentially when you add the CascadingDropDownNameValue pair, you need to put in the displayed text as a string then the hidden value (which doesn't have to be a string - and is obviously normally an Integer type ID field from your db).

Any probs, drop a reply.

Simon


Should've checked the preview, damn editor moved things onto next lines....... here's another try.

The key bits you need are as follows:

Dim valuesAs List(Of CascadingDropDownNameValue) =New List(Of CascadingDropDownNameValue)

For intRow = 0 To .Rows.Count - 1

values.Add(New CascadingDropDownNameValue(.Rows(intRow).ItemArray(1).ToString, .Rows(intRow).ItemArray(0)))

Next

Return values.ToArray

Simon


Thanks a lot Simon, that's exactly the help I needed.Big Smile After adding the lineImports System.Collections.GenericI now have the whole thing working. Thanks again.

I'm now interested in making it more efficient (addressing point (3)). At the moment, every time the user selects a dropdown value, the "downstream" dropdown(s) must be re-populated by a call to the appropriate webservice functions. That's fine but these functions make calls to the database. It seems to me that, since this is fairly static data (new towns don't appear every day) it would be better to make one call at the start and cache the results for later use. That would reduce the number of calls to the database and, presumably, improve performance.

I read in the MSDN documentation that the Data Adapter object (OleDbDataAdapter) can hold a "local" copy of a set of tables. Maybe I could populate this once and then fill my data sets from it when I need to. Trouble is, I'm not sure how to do this - including where to put the code so it's kept available to my functions. I guess I'm thinking of it a bit like a good 'ol global variable - but I guess that's not very object-oriented. Perhaps I need to create a class with Set and Get methods?

I've also notice that a lot of my logic is duplicated between the three webservice functions, e.g. setting up the connection to the database. That makes me think that it may be better to create a single parameterized function (or maybe the class mentioned above), that each function calls with a table name and which returns the CDD array to the calling function. I know the concepts, but my coding skills aren't really up to it.

Finally, I'm concerned about housekeeping, i.e. tidying up and closing objects that are no longer needed to free up resources.

It seems to me that, with a lot of help, I've managed to solve the main problems in getting this working. Maybe someone out there would be interested in addressing the issues I've mentioned above and creating an efficient and flexible object that accepts parameters, such as table names, and returns the appropriate arrays to populate the CDDs whilst hiding all the complexity from the developer. Come to think of it, it would be really great if such an object were part of the Atlas Control Toolkit. That way, novice developers could drag and drop it onto the work surface from the toolbox and set a few properties to get it working. That's my feedback to Microsoft. I like using ASP.NET and Visual Web Developer because I can achieve most of the common tasks without needing to write any code. Having created a set of CDDs in standard ASP.NET, I was dissappointed by the performance. So I had a look at Atlas - but I was suddenly thrown from the cosy drag-and-drop world I was used to into a world of C# code. I would have thought that this was a common enough requirement among web developers to be worth addressing.

Anyway, for anyone interested, my complete webservice code now reads:

<%@.WebServiceLanguage="VB"Class="ListCountService" %>

Imports System.Web

Imports System.Web.Services

Imports System.Web.Services.Protocols

Imports AtlasControlToolkit

Imports System.Collections.Generic

<WebService(Namespace:="http://tempuri.org/")> _

<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _

PublicClass ListCountService

Inherits System.Web.Services.WebService

<WebMethod()> _

PublicFunction GetRegions(ByVal knownCategoryValuesAsString,ByVal categoryAsString)As CascadingDropDownNameValue()

Dim objAdapterAsNew System.Data.OleDb.OleDbDataAdapter _

("SELECT regID, regName FROM tlkpRegionList ORDER BY regID", _

"Provider = Microsoft.Jet.OLEDB.4.0;" & _

"User ID = Admin;" & _

"Data Source=" & Server.MapPath(".") &"\App_Data\TiberPass.mdb")

Dim objDataSetAsNew System.Data.DataSet()

objAdapter.Fill(objDataSet)

Dim objTableAs System.Data.DataTable

objTable = objDataSet.Tables(0)

With objTable

Dim intRowAsInteger

Dim valuesAs List(Of CascadingDropDownNameValue) =New List(Of CascadingDropDownNameValue)

For intRow = 0To .Rows.Count - 1

values.Add(New CascadingDropDownNameValue(.Rows(intRow).ItemArray(1).ToString, .Rows(intRow).ItemArray(0)))

Next

Return values.ToArray

EndWith

ReturnNew CascadingDropDownNameValue() {}

EndFunction

<WebMethod()> _

PublicFunction GetProvincesForRegion(ByVal knownCategoryValuesAsString,ByVal categoryAsString)As CascadingDropDownNameValue()

Dim kvAs StringDictionary = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)

Dim RegionIdAsInteger

If (kv.ContainsKey("Region")And Int32.TryParse(kv("Region"), RegionId))Then

Dim objAdapterAsNew System.Data.OleDb.OleDbDataAdapter _

("SELECT provID, provName FROM tlkpProvinceList WHERE provRegion=" & RegionId &" ORDER BY provID", _

"Provider = Microsoft.Jet.OLEDB.4.0;" & _

"User ID = Admin;" & _

"Data Source=" & Server.MapPath(".") &"\App_Data\TiberPass.mdb")

Dim objDataSetAsNew System.Data.DataSet()

objAdapter.Fill(objDataSet)

Dim objTableAs System.Data.DataTable

objTable = objDataSet.Tables(0)

With objTable

Dim intRowAsInteger

Dim valuesAs List(Of CascadingDropDownNameValue) =New List(Of CascadingDropDownNameValue)

For intRow = 0To .Rows.Count - 1

values.Add(New CascadingDropDownNameValue(.Rows(intRow).ItemArray(1).ToString, .Rows(intRow).ItemArray(0)))

Next

Return values.ToArray

EndWith

EndIf

ReturnNew CascadingDropDownNameValue() {}

EndFunction

<WebMethod()> _

PublicFunction GetTownsForProvince(ByVal knownCategoryValuesAsString,ByVal categoryAsString)As CascadingDropDownNameValue()

Dim kvAs StringDictionary = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)

Dim ProvinceIdAsInteger

If (kv.ContainsKey("Province")And Int32.TryParse(kv("Province"), ProvinceId))Then

Dim objAdapterAsNew System.Data.OleDb.OleDbDataAdapter _

("SELECT townID, townName FROM tlkpTownList WHERE townProvince=" & ProvinceId &" ORDER BY townID", _

"Provider = Microsoft.Jet.OLEDB.4.0;" & _

"User ID = Admin;" & _

"Data Source=" & Server.MapPath(".") &"\App_Data\TiberPass.mdb")

Dim objDataSetAsNew System.Data.DataSet()

objAdapter.Fill(objDataSet)

Dim objTableAs System.Data.DataTable

objTable = objDataSet.Tables(0)

With objTable

Dim intRowAsInteger

Dim valuesAs List(Of CascadingDropDownNameValue) =New List(Of CascadingDropDownNameValue)

For intRow = 0To .Rows.Count - 1

values.Add(New CascadingDropDownNameValue(.Rows(intRow).ItemArray(1).ToString, .Rows(intRow).ItemArray(0)))

Next

Return values.ToArray

EndWith

EndIf

ReturnNew CascadingDropDownNameValue() {}

EndFunction

EndClass


I have now stumbled my way through creating my own first cascading dropdown (hooked into a database, and all in VB), and it is thanks largely to the posts here. I'm so happy I got it to work! For the sake of others trying to do this same thing, I will also post my code here, so that others may benefit. Also, if any experts out there see something inefficient in the code below, please let me know - I want this project to be as successful as possible! Thanks! - Matthew

In the aspx file that contains the dropdownlist:

<%

@.Register
Assembly="AtlasControlToolkit"Namespace="AtlasControlToolkit"TagPrefix="cc1" %>

That's at the top. Now, down in the area where we are using the drop down lists:

<cc1:CascadingDropDownID="CascadingDropDown1"runat="server">
<cc1:CascadingDropDownProperties
TargetControlID="DropDownList4"PromptText="Please select a product group name."ServicePath="ProductsService.asmx"ServiceMethod="GetProductGroups"Category="Group"/><cc1:CascadingDropDownProperties
TargetControlID="DropDownList5"PromptText="Please select a product code."ParentControlID="DropDownList4"ServicePath="ProductsService.asmx"ServiceMethod="GetCatalogCodesForGroup"Category="CatalogCode"/><cc1:CascadingDropDownProperties
TargetControlID="DropDownList6"PromptText="Please select a product description."ParentControlID="DropDownList5"ServicePath="ProductsService.asmx"ServiceMethod="GetProductsForCatalogCode"Category="Product"/>

</cc1:CascadingDropDown>

Now, I created theProductsService.asmxfile and put the follwing code in the .vb codebehind file:

Imports

System.Web

Imports

System.Web.Services

Imports

System.Web.Services.Protocols

Imports

System.Xml

Imports

System.Collections.Generic

Imports

AtlasControlToolkit

Imports

System.Data.SqlClient

<WebService(Namespace:=

"http://tempuri.org/")> _

<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _

<

Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _

Public

Class ProductsServiceInherits System.Web.Services.WebService

<WebMethod()> _

PublicFunction GetProductGroups(ByVal knownCategoryValuesAsString,ByVal categoryAsString)As CascadingDropDownNameValue()
'-- Declare the "List" of Name/Value pairs that we will build with our query to the databaseDim valuesAs List(Of CascadingDropDownNameValue) =New List(Of CascadingDropDownNameValue)Dim conAs SqlConnectionDim SQLcmdAs SqlCommandDim DataRAs SqlDataReaderDim strSQLAsString'-- Select all of the GroupNames from the database

strSQL =

"SELECT DISTINCT([GroupName]) FROM dbo_C_CatalogGroup ORDER BY GroupName"

con =

New SqlConnection(ConfigurationManager.ConnectionStrings.Item("CrosbyCertSQLConnectionString").ConnectionString)

con.Open()

SQLcmd =

New SqlCommand(strSQL, con)

DataR = SQLcmd.ExecuteReader()

While DataR.Read()

values.Add(

New CascadingDropDownNameValue(DataR("GroupName"), DataR("GroupName")))EndWhile

DataR.Close()

con.Close()

Return values.ToArray()EndFunction

<WebMethod()> _

Public

Function GetCatalogCodesForGroup(ByVal knownCategoryValuesAsString,ByVal categoryAsString)As CascadingDropDownNameValue()
Dim kvAs StringDictionary = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)If (kv.ContainsKey("Group"))Then
'-- Declare the "List" of Name/Value pairs that we will build with our query to the databaseDim valuesAs List(Of CascadingDropDownNameValue) =New List(Of CascadingDropDownNameValue)Dim conAs SqlConnectionDim SQLcmdAs SqlCommandDim DataRAs SqlDataReaderDim strSQLAsString'-- Select all of the CatalogCodes from the database

strSQL =

"SELECT [CatalogCode] FROM dbo_C_CatalogGroup WHERE [GroupName] = '" & kv("Group") &"' ORDER BY [CatalogCode]"

con =

New SqlConnection(ConfigurationManager.ConnectionStrings.Item("CrosbyCertSQLConnectionString").ConnectionString)

con.Open()

SQLcmd =

New SqlCommand(strSQL, con)

DataR = SQLcmd.ExecuteReader()

While DataR.Read()

values.Add(

New CascadingDropDownNameValue(DataR("CatalogCode"), DataR("CatalogCode")))EndWhile

DataR.Close()

con.Close()

Return values.ToArray()ExitFunctionEndIf'-- Return an empty list, otherwiseReturnNew CascadingDropDownNameValue() {}EndFunction

<WebMethod()> _

Public

Function GetProductsForCatalogCode(ByVal knownCategoryValuesAsString,ByVal categoryAsString)As CascadingDropDownNameValue()
Dim kvAs StringDictionary = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)If (kv.ContainsKey("CatalogCode"))Then
'-- Declare the "List" of Name/Value pairs that we will build with our query to the databaseDim valuesAs List(Of CascadingDropDownNameValue) =New List(Of CascadingDropDownNameValue)Dim conAs SqlConnectionDim SQLcmdAs SqlCommandDim DataRAs SqlDataReaderDim strSQLAsString'-- Select all of the Product Descriptions from the database

strSQL =

"SELECT [Description], [ProductCode] FROM dbo_C_Product WHERE [CatalogCode] = '" & kv("CatalogCode") &"' ORDER BY [ProductCode]"

con =

New SqlConnection(ConfigurationManager.ConnectionStrings.Item("CrosbyCertSQLConnectionString").ConnectionString)

con.Open()

SQLcmd =

New SqlCommand(strSQL, con)

DataR = SQLcmd.ExecuteReader()

While DataR.Read()

values.Add(

New CascadingDropDownNameValue(DataR("Description"), DataR("ProductCode")))EndWhile

DataR.Close()

con.Close()

Return values.ToArray()ExitFunctionEndIf'-- Return an empty list, otherwiseReturnNew CascadingDropDownNameValue() {}EndFunction

End

Class

Thank you very much for your example! It helped me out tramendously. I did have to modify your example some as I was using a SQL DataSet and TableAdapters. My tread is at:

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

Wednesday, March 21, 2012

CascadingDropDown require EventVlidation=false?

I turned on event validation (=true) of the Atlas Control Toolkit sample -> CascadingDropDown .

When I click the , Error message suggest turn event validation off.

Is this a must?

I saw some thread showing that they can add an attribute "SuppressEventValidation", but I can't see smart tag/ code hints in my version? Is it a new feature in later built of atlas?

Please advice how to keep EventValidated ?

This thread explains why I believe EnableEventValidation needs to be false:http://forums.asp.net/thread/1281139.aspx

Thanks for your kindly reference, It's really a time for me to choose between SECURITY , USABLITILY

I need to sacrifice security , choose usablitiliy

CascadingDropDown Problems......

Hello,

I am trying to create a vb.net 2005 web page using the Atlas cascadingdropdown control from the toolkit. Ideally I would like it to work like the sample demonstration at:

http://atlas.asp.net/atlastoolkit/CascadingDropDown/CascadingDropDown.aspx

But I can't seem toget it to work. Does someone have a working sample (vb or c#) of doing it the same way? By the same way I mean, when the page loads displaying multiple drop down lists with the first list populated and showing the watermark, and the rest of the dropdowns showing the watermark but disabled. When any item in the first drop down is selected, it should populate and enable the second drop down, etc.

When I code it, the first and second drop downs are disabled, enabled properly, but when I perform the callback from the first dropdown having changed, for some reason it is not recorded as changed within the code behind in tha application. What I have for my web page and code behind is (note that ddlCatalogItem is the first drop down, and ddlFrontImage is the second). Note that in the code behind in the procedure ddlCatalogItem_SelectedIndexChanged the value ddlCatalogItem.SelectedValue is not correct! Why?

<tr>

<tdstyle="width: 76px; text-align: right"class="formheading"valign="top">

Catalog Item

</td><tdstyle="width: 278px"valign="top"><asp:DropDownListID="ddlCatalogItem"runat="server"CssClass="formheading"AutoPostBack="True"OnSelectedIndexChanged="ddlCatalogItem_SelectedIndexChanged"></asp:DropDownList></td></tr><tr><tdstyle="width: 76px; text-align: right"class="formheading"valign="top">

Front Image

</td><tdstyle="width: 278px"valign="top"><atlas:UpdatePanelMode=ConditionalID="UpdatePanel1"runat="server"><ContentTemplate><asp:DropDownListID="ddlFrontImage"runat="server"CssClass="formheading"></asp:DropDownList></ContentTemplate><Triggers><atlas:ControlValueTriggerControlID="ddlCatalogItem"PropertyName="SelectedValue"/></Triggers></atlas:UpdatePanel></td></tr>

And in the code behind for that page I have:

ProtectedSub ddlCatalogItem_SelectedIndexChanged(ByVal senderAsObject,ByVal eAs System.EventArgs)

BindImageList(ddlCatalogItem.SelectedValue)

EndSubPrivateSub BindImageList(ByVal CatalogItemIDAsInteger)Dim sqlConn1AsNew SqlConnection()Dim drAs SqlDataReader

sqlConn1.ConnectionString =

"Data Source=PD-dev;Initial Catalog=Tapestry;Persist Security Info=True;User ID=sa;Password=s@dotnet.itags.org.w*"

sqlConn1.Open()

Dim oSQLAsNew SqlCommand("spReadFrontImageByCatalogItem", sqlConn1)

oSQL.CommandType = CommandType.StoredProcedure

' Add the parameters to the command object

oSQL.Parameters.Add(

"@dotnet.itags.org.CatalogItemID", SqlDbType.SmallInt, 0).Value = CatalogItemID' Run the stored procedureTryDim ImagesAsNew DataTable("Images")

Images.Columns.Add(

"Description", System.Type.GetType("System.String"))

Images.Columns.Add(

"ProductFamilyID", System.Type.GetType("System.String"))

dr = oSQL.ExecuteReader

Images.Load(dr)

ddlFrontImage.DataSource = Images

ddlFrontImage.DataTextField =

"Description"

ddlFrontImage.DataValueField =

"ProductFamilyID"

ddlFrontImage.DataBind()

Catch exAs SqlException

MsgBox(ex.Message, MsgBoxStyle.Critical,

"Error")EndTry

sqlConn1.Close()

EndSub

Thanks!

Jim

Hi jjr -

Looking at your code, I don't see the CascadingDropDown extender declared anywhere.

Take a look at the walk through on my blog and post again if you're still having troubles:

http://blogs.msdn.com/sburke/archive/2006/04/14/576421.aspx

Thanks,

Shawn


Hi Shawn,

When I take out my ddlCatalogSelectedIndexChanged function, and set up the extender, I only see a blank list from my webservice. The webservice functions are defined as shown below.. why won't those return anything to my drop down listboxes?

the web page extender definition

<atlasToolkit:CascadingDropDownID="CascadingDropDown1"runat="server"><atlasToolkit:CascadingDropDownPropertiesTargetControlID="ddlCatalogItem"Category="Item"PromptText="Select item to order"ServicePath="ListcountService.asmx"ServiceMethod="GetCatalogItems"/><atlasToolkit:CascadingDropDownPropertiesTargetControlID="ddlFrontImage"ParentControlID="ddlCatalogItem"PromptText="Select the front image"ServiceMethod="GetImages"ServicePath="ListcountService.asmx"Category="Image"/></atlasToolkit:CascadingDropDown>

the webservice code

:

<WebMethod()> _

PublicFunction GetImages(ByVal knownCatelogItemsAsString,ByVal ItemAsString)As CascadingDropDownNameValue()Dim kvAs StringDictionary = CascadingDropDown.ParseKnownCategoryValuesString(knownCatelogItems)Dim ItemIdAsIntegerIf (Not kv.ContainsKey("Item")OrNot Int32.TryParse(kv("Item"), ItemId))ThenThrowNew ArgumentException("Couldn't find Item.")EndIfDim sqlConn1AsNew SqlConnection()Dim drAs SqlDataReader

sqlConn1.ConnectionString =

"Data Source=PD-dev;Initial Catalog=Tapestry;Persist Security Info=True;User ID=sa;Password=s@.w*"

sqlConn1.Open()

Dim oSQLAsNew SqlCommand("spReadFrontImageByCatalogItem", sqlConn1)

oSQL.CommandType = CommandType.StoredProcedure

' Add the parameters to the command object

oSQL.Parameters.Add(

"@.CatalogItemID", SqlDbType.SmallInt, 0).Value = ItemId' Run the stored procedureTry

dr = oSQL.ExecuteReader

Catch exAs SqlExceptionEndTry

sqlConn1.Close()

Dim valuesAsNew List(Of CascadingDropDownNameValue)()Dim drowAs DataRowForEach drowIn dr

values.Add(

New CascadingDropDownNameValue(drow("Description"), drow("ProductFamilyID").ToString()))NextReturn values.ToArray()EndFunction

<WebMethod()> _

PublicFunction GetCatalogItems()As CascadingDropDownNameValue()Dim sqlConn1AsNew SqlConnection()Dim drAs SqlDataReader

sqlConn1.ConnectionString =

"Data Source=PD-dev;Initial Catalog=Tapestry;Persist Security Info=True;User ID=sa;Password=s@.w*"

sqlConn1.Open()

Dim oSQLAsNew SqlCommand("spGetAllCatalogItems", sqlConn1)

oSQL.CommandType = CommandType.StoredProcedure

' Run the stored procedureTry

dr = oSQL.ExecuteReader

Catch exAs SqlExceptionEndTry

sqlConn1.Close()

Dim valuesAsNew List(Of CascadingDropDownNameValue)()Dim drowAs DataRowForEach drowIn dr

values.Add(

New CascadingDropDownNameValue(drow("Description"), drow("ID")))NextReturn values.ToArray()EndFunction

Thanks!

Jim


My guess is because of this spelling typo. The way Atlas does it's webservice proxies, the names need to be exact.

Public Function GetImages(ByVal knownCatelogItemsAs String,ByVal ItemAs String)should bePublic Function GetImages(ByVal knownCategoryItemsAs String,ByVal categoryAs String)

Hi Jim,

I've played with the code you provided and tweaked it to work on my machine. I removed your data access code in the webservice and filled it with stubs. Here's the.aspx page:

<%@. Page Language="VB" %><%@. Register Assembly="AtlasControlToolkit" Namespace="AtlasControlToolkit" TagPrefix="atlasToolkit" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"><title>Test Page</title></head><body><form runat="server"><div> <atlas:ScriptManager ID="ScriptManager1" runat="server" /> <table> <tr> <td align="right">Catalog Item</td> <td><asp:DropDownList ID="ddlCatalogItem" runat="server"></asp:DropDownList></td> </tr> <tr> <td align="right">Front Image</td> <td><asp:DropDownList ID="ddlFrontImage" runat="server"></asp:DropDownList></td> </tr> </table> <atlasToolkit:CascadingDropDown ID="cdd" runat="server"> <atlasToolkit:CascadingDropDownProperties TargetControlID="ddlCatalogItem" Category="Item" ServicePath="ListcountService.asmx" ServiceMethod="GetCatalogItems" PromptText="Select item to order" /> <atlasToolkit:CascadingDropDownProperties TargetControlID="ddlFrontImage" ParentControlID="ddlCatalogItem" Category="Image" ServicePath="ListcountService.asmx" ServiceMethod="GetImages" PromptText="Select the front image" /> </atlasToolkit:CascadingDropDown></div></form></body></html>

And here's the code for the web service:

Imports System.Web.ServicesImports AtlasControlToolkit<WebService(Namespace:="http://tempuri.org/")> _<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _Public Class ListcountServiceInherits System.Web.Services.WebService <WebMethod()> _Public Function GetCatalogItems(ByVal knownCategoryValuesAs String,ByVal categoryAs String)As CascadingDropDownNameValue()Return New CascadingDropDownNameValue() _ {New CascadingDropDownNameValue("Fruit", 0),New CascadingDropDownNameValue("Vegetable", 1)}End Function <WebMethod()> _Public Function GetImages(ByVal knownCategoryValuesAs String,ByVal categoryAs String)As CascadingDropDownNameValue()Dim kvAs StringDictionary = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)Dim ItemIdAs Integer If (kv.ContainsKey("Item")And Int32.TryParse(kv("Item"), ItemId))Then If (ItemId = 0)Then Return New CascadingDropDownNameValue() _ {New CascadingDropDownNameValue("Apple", 2), _New CascadingDropDownNameValue("Pear", 3), _New CascadingDropDownNameValue("Banana", 4)}ElseIf (ItemId = 1)Then Return New CascadingDropDownNameValue() _ {New CascadingDropDownNameValue("Potato", 5), _New CascadingDropDownNameValue("Lettuce", 6), _New CascadingDropDownNameValue("Corn", 7)}End If End If Return New CascadingDropDownNameValue() {}End FunctionEnd Class

A couple of things to note:
- You need to implement the default constructor forCascadingDropDownNameValue as menionted in David's last post athttp://forums.asp.net/thread/1257783.aspx.
- Instead of throwing exceptions in your web services you should return an empty list if you have no data to fill. I believe it's the expectation made by theCascadingDropDownBehavior.

If this doesn't work or you have any other questions, just let us know.

Thanks,
Ted


I think I have most of it working now, but I am curious, how do I do the enabling / disabling of the second list box in the cascade? I would like the second listbox to be disabled on start of the web page, and then enabled only if the 'select' option is not chosen in the first listbox; and I cannot seem to figure out how to do that!

I do have the listboxes being filled properly and the first listbox successfully loads the second!

However, I do note that the webservice function to load the second list is called on page startup, at which time I have not yet selected anything, is there a way to buypass this extra call?

Thanks!

Jim


Hi Jim,

Are you throwing exceptions in your web service methods? I believe that throwing exceptions instead of returning an empty list causes behavior similar to what you're describing. If that's not the case though, feel free to post your code again and we can take a look.

Thanks,
Ted


Forget my last question, it all works now!

Now I am down to a very basic question, can I have it so when I change the selection in the first dropdownlist in the cascade, that it always resets the second dropdownlist in the cascaed to the first watermark item which is 'select...'?

How would I do that?

Thanks!

Jim


Hi Jim,

If I understand what you're asking, I think this should happen automatically. The working code I posted above does this on my machine. If you're experiencing different behavior, take a careful look to see if anything is different. If it all looks the same though, you can post your code and I'll take another look.

Thanks,
Ted

Ted,

In mine, if I select an item from the second dropdown, and then change the first dropdown, the second doesn't automatically change to select like I would expect... instead it stays on a different item... is that how it is supposed to work?

Jim


Hi Jim,

It is supposed to work exactly like you want it to. I'm not sure what you're doing different that has it acting funny. My guess would be that somehow your web services aren't working with the controls perfectly. Make sure your parameter names exactly match those in the sample. Shawn mentioned this above, but made a slight typo. Here's what they should look like (in C# and VB):

public AtlasControlToolkit.CascadingDropDownNameValue[] GetXXXXX(string knownCategoryValues,string category){}
Imports AtlasControlToolkitPublic Function GetXXXXX(ByVal knownCategoryValuesAs String,ByVal categoryAs String)As CascadingDropDownNameValue()End Function

If this doesn't help fix the problem, just keep posting with more details.

Thanks,
Ted


I'm not sure if the problem I'm having is similar or not, but I'm hoping someone can help me find a solution to my issue.

My webservices and atlas don't seem to want to play nicely together. My drop downs appear blank if I try to use web services to provide the data, but work fine if I use built in page methods.

Just to be sure, I copied the code for the vegetables mockup supplied here, and sure enough, if I used a webservice called listcountservice, my drop down was blank.

So I movd the code into my test page, and everything works fine. Just to be sure, my code works fine if I do the following:

<atlas:ScriptManagerID="ScriptManager1"runat="server"/><table><tr><tdalign="right">Catalog Item</td><td><asp:DropDownListID="ddlCatalogItem"runat="server"></asp:DropDownList></td></tr><tr><tdalign="right">Front Image</td><td><asp:DropDownListID="ddlFrontImage"runat="server"></asp:DropDownList></td></tr></table><atlasToolkit:CascadingDropDownID="cdd"runat="server"><atlasToolkit:CascadingDropDownPropertiesTargetControlID="ddlCatalogItem"Category="Item"ServiceMethod="GetCatalogItems"PromptText="Select item to order"/><atlasToolkit:CascadingDropDownPropertiesTargetControlID="ddlFrontImage"ParentControlID="ddlCatalogItem"Category="Image"ServiceMethod="GetImages"PromptText="Select the front image"/></atlasToolkit:CascadingDropDown>

and in the .vb

Imports

System.Web.Services

Imports

AtlasControlToolkit

Partial

Class spellvault_testInherits System.Web.UI.Page

<WebMethod()> _

PublicFunction GetCatalogItems(ByVal knownCategoryValuesAsString,ByVal categoryAsString)As CascadingDropDownNameValue()ReturnNew CascadingDropDownNameValue() _

{

New CascadingDropDownNameValue("Fruit", 0),New CascadingDropDownNameValue("Vegetable", 1)}EndFunction

<WebMethod()> _

PublicFunction GetImages(ByVal knownCategoryValuesAsString,ByVal categoryAsString)As CascadingDropDownNameValue()Dim kvAs StringDictionary = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues)Dim ItemIdAsIntegerIf (kv.ContainsKey("Item")And Int32.TryParse(kv("Item"), ItemId))ThenIf (ItemId = 0)ThenReturnNew CascadingDropDownNameValue() _

{

New CascadingDropDownNameValue("Apple", 2), _New CascadingDropDownNameValue("Pear", 3), _New CascadingDropDownNameValue("Banana", 4)}ElseIf (ItemId = 1)ThenReturnNew CascadingDropDownNameValue() _

{

New CascadingDropDownNameValue("Potato", 5), _New CascadingDropDownNameValue("Lettuce", 6), _New CascadingDropDownNameValue("Corn", 7)}EndIfEndIfReturnNew CascadingDropDownNameValue() {}EndFunction

End

Class

But not if I do it using the supplied web service. I'd appreciate it if anyone could give me a pointer towards where I'm apparantly misconfiguring my webservices or what not (I have tested and my web services do work fine by themselves, just not via the atlas extender)

Never mind. I eventually figured out that I needed some additional code

<

sectionname="webServices"type="Microsoft.Web.Configuration.WebServicesSection"requirePermission="false" />

and

<

webServicesenableBrowserAccess="true"/>

inside the microsoft.web section.

Thanks though!

CascadingDropDown persistent Values

Hi,i have 3 dropdownlist, using atlas cascadingdropdown. Every think works fine, but when i click in a button( this button only set the enable=true to all control in the page) occurs an postback, then when the page is load the dropdown loser the previos selected values..

the method to populate the dropdown are in the if(!Ispostback)...how can i fix that??

Try setting the SelectedValue property of the CDDs in the button handler.

hi, thanks for the reply but i have already tryied that and dont work...

bye,

marcos


Please reply with acomplete, self-contained sample page that demonstrates the problem so that we can investigate the specific behavior you're seeing. Thank you!

CascadingDropDown not working within EditItemTemplate in Ajax Beta

I had the cascading drop down working fine inside the EditItemTemplate in a gridview with the previous Atlas CTP release. But now it stopped working with Ajax Beta 1.0. Do I need to do something different to make it work again. I tried placing Gridview.Databind() in Page_Load, but that stopped the gridview from updating back to the database.

<EditItemTemplate>

<asp:DropDownListID="ddlBuEdit"runat="server"/>

<ajax:CascadingDropDownID="ccd1"runat="server"

TargetControlID="ddlBuEdit"

Category="BU"

LoadingText="Loading Data..."

PromptText="Select Business Unit"

ServicePath="getSelectionData.asmx"

SelectedValue='<%# Eval("BusinessUnit") %>'

ServiceMethod="getBU"/>

</EditItemTemplate>

Please see if this is relevant:http://forums.asp.net/thread/1441672.aspx.

CascadingDropDown List 1-dimensional array error

I'm trying to get the CascadingDropDown from the Atlas toolkit to work with a database. I receive this error at the lineReturn values.ToArray().

Error 1 Value of type '1-dimensional array of AtlasControlToolkit.CascadingDropDownNameValue' cannot be converted to 'AtlasControlToolkit.CascadingDropDownNameValue'

Here is the WebMethod.

<WebMethod()> _

PublicFunction GetMakes(ByVal knownCategoryValuesAsString,ByVal categoryAsString)As CascadingDropDownNameValue

Dim makeAdapterAs CarsTableAdapters.MakeTableAdapter =New CarsTableAdapters.MakeTableAdapter()

Dim makesAs Cars.MakeDataTable = makeAdapter.GetMakes()

Dim valuesAs List(Of CascadingDropDownNameValue) =New List(Of CascadingDropDownNameValue)()

ForEach drAs DataRowIn makes

Dim makeAsString =CStr(dr("Make"))

Dim makeIdAsInteger =CInt(dr("MakeID"))

values.Add(New CascadingDropDownNameValue(CStr(dr("Make")), dr("MakeID").ToString()))

Next dr

Return values.ToArray()

EndFunction

Any Ideas?

Rgds

Dave

Replace

PublicFunction GetMakes(ByVal knownCategoryValuesAsString,ByVal categoryAsString)As CascadingDropDownNameValue

With

PublicFunction GetMakes(ByVal knownCategoryValuesAsString,ByVal categoryAsString)As CascadingDropDownNameValue()

CascadingDropDownNameValue() is an array, butCascadingDropDownNameValue is not


Thanks lotusinriver. It works perfectly now.

Dave


You are very welcome.