What's the best way to implement user controls that require AJAX callbacks?
I want to accomplish a few things:
Have events done in the browser (eg, drag and drop) trigger an AJAX notification that can raise a control event, which causes code on the page using the control to do whatever it needs to do (eg, change a value in a database).
Have partial updates (NOT using an updatepanel) that can do things like populate an auto-complete dropdown underneath a textbox.
Implement a single user control that is generic enough to be reused on several pages
Avoid having to implement logic on the page itself that passes events back to the control, because that is repetitive and hard to maintain
I'm using jQuery for most of the client side stuff, but for the actual AJAX calls I don't really care if it's jQuery or the ASP AJAX libraries.
Effectively what would be perfect is PageMethods on the user control, that would be easily callable from client-side script. Unfortunately, as far as I'm aware, pagemethods do not work on user controls.
I'll use an autocomplete control as an example:
I should be able to put the autocomplete control on the page, and then in the page code, have eg:
Public Sub HandleLookup(ByVal input As String, ByRef list As List(Of String) Handles MyControl.LookupEntries
list = New List(Of String)
' Query database for list of items..
For Each item as String in FullItemList
If item.StartsWith(input) then list.Add(item)
Next
Return list
End Sub
And do nothing else .. the rest of the code should be in the usercontrol.
Note, the controls I'm trying to make are much more specific than eg, autocomplete. They do not exist in any 3rd party libraries and I really need to be able to make them myself.
Look into implementing ICallbackEventHandler in your Page -- it's a simple way to make a call back to a page function from JavaScript.
Here's a good tutorial:
http://www.ajaxprojects.com/ajax/tutorialdetails.php?itemid=119
You might want to check out; Ra-Ajax UserControl Sample and combine that knowledge with Ra-Ajax Drag and Drop
Click the "Show code" C# icon to the left to see the usage of the code...
Related
I am creating a web user control for a simple poll. I am currently registering it on the page and then referencing it via tagprefix.
The form for the poll is in basic html (no server controls) and is in the front-end of the web control. How can I change the look of the user control depending on the settings passed into it? Is this possible without using server controls?
Update
Can I change the html layout of a user control? If so could someone post some examples. Please note I do not use asp.net form controls, so none of that please :)
You might be able to also use jQuery to replace existing css setting in your code. Create properties on for your user control, and then pass settings in the classes. Then use jQuery to replace them. This however requires jQuery to be linked to your page (or within your control) and you'd have to write the CSS classes out to the jQuery code (using server controls, but you could use the literal control so there's no excess code).
Personally I'd go with the option of using server controls instead of straight up HTML, you'd get alot more flexibility, and then passing through the settings would be pretty straightforward, put something like this in your controls backend code:
Private _TextBoxCssClass As String
Public Property TextBoxCssClass() As String
Get
Return _TextBoxCssClass
End Get
Set(ByVal value As String)
_TextBoxCssClass = value
txtBox1.CssClass = value
txtBox2.CssClass = value
End Set
End Property
You most likely want to have a property or event in the control that changes the css. It may end up best to add some server controls or javascript / jquery to make it easier.
If its only the styles you want to change, then you can expose a property to set the style attribuites of the respective control inside your User Control. If you want to control the whole HTML layout of the control then Custom Control is the viable option.
I am developing an ASP.NET web application that incorporates google maps. I have an ASP.NET listbox on my page which contains a list of items. When the user selects one of the items, I'd like to show this item on the map. The main complication lies in the fact that google maps uses javascript to control it and the listbox is a server control.
I can think of two ways to do this. The first would involve the listbox calling a javascript function when the user selects a new item. I can then write this function to perform the necessary map operations. Unfortunately, the OnSelectedIndexChanged property of the listbox doesn't seem to support javascript functions.
The second involves wrapping an UpdatePanel around the listbox and getting the listbox to perform a postback. In the SelectedIndexChanged event in VB/C#, I would the need to somehow make a call to a javascript function which would then update the map.
Which solution can I use?
Thanks
--Amr
In your codebehind (in your pageload) just add a javascript handler to the OnChange attribute that points to your javascript function. Eg:
lbYourListBox.Attributes.Add("onChange", "UpdateYourMap();");
You could also add this to your control using inline javascript as well but I prefer to do it in the codebehind so that the framework can handle matching up the names.
You could simply embed javascript into your page, avoidig relying on ASP with it. Put the code into your document body:
<script language="javascript">
body.onload=function(){
var lb=document.getElementById("yourlistboxid");
lb.onChange = function(){
// put your handling code here
}
}
</script>
to demo the other approach, here's a rough guide:
void listbox_SelectedIndexChanged( ... ) {
string js = string.Format("callToMapsFunction({0});", listbox.SelectedValue);
string scriptKey = "mapscript";
ScriptManager.RegisterStartupScript( listbox, typeof(ListBox), scriptKey
, js, true);
}
RegisterStartupScript runs whatever javascript you give it after the partial postback completes. you don't necessarily have to pass the listbox value- just whatever data you want to provide to the maps api. the first 3 items are for preventing the script from registering a bunch of times (as far as I know). the true at the end tells the scriptmanager to automagically add opening and closing tags around your js code.
I need to develop a page which has 2 dropdownlist.
Options of dropdownlist 2 are based on selection of dropdownlist 1.
I have 2 methods to change the dropdownlist 2. What will you choose?
1:
Postback when users select dropdownlist 1 and change dropdownlist 2.
Pros:
Can use the postback feature, can use the asp.net validator
Cons:
Need to communicate with server (more traffic)
Users will see the page loading in the status bar.
2:
Get all the data (not very much data) in a JSON object when loading the page and change the dropdownlist 2 using javascript.
Pros:
Don't need to communicate with server(less traffic)
Cons:
Can't use the postback feature and validator and more troublesome to write server validation.
Also, I usually write the JSON object to the page as follows:
var locations = <asp:Literal runat="server" id="litLocation" text="[]" />
And then set the "litLocation" in page_load after the data is processed by datacontractjsonserializer.
Do you do it in the same way?
I prefer the second option, no need to reload the whole page just to refresh one dropdown list. I'd also do the client side dev in jQuery, much easier. You can do the client side validation for the change event of the first dropdown in jQuery as well, and keep the form submit validation in ASP.NET.
Have a look at the selectChain plugin for jQuery (demo's etc here).
Why not have your javascript call the server when the select box is clicked on, using a GET method, and fill in the select box, using json as the response, then, when an option is picked then fill in the second select box with another ajax request.
This would be scalable, in that if you want to add more options you just change the server, and everything is centralized.
You will need to validate when the form is submitted anyway, as it is possible to change a value of a form to something illegal using some debugging tools, such as Firebug, so never trust anything from a webpage until you have validated it.
So, no point worrying about the validation until the form is actually submitted.
I have a Repeater control that I bind server-side. It repeats a series of divs, and does so with no problem. I have some buttons that I use to sort the repeater (newest, highest ranked, random) and this works the way it should.
I would like to improve my user experience by making the buttons sort the divs using Ajax/jQuery somehow so that there is no page postback and the user does not lose his/her spot on the page.
Is there a way to use jQuery to access server-side code like this, or use Ajax to re-bind a server-side control?
Thanks... if I need to list more details, please let me know!
EDIT I'm aware of UpdatePanels, but I would prefer not to use them if I don't have to.
Have you considered moving the Repeater's functionality to the client-side?
Doing it that way, functionality like paging and sorting is not very difficult to add. In fact, you can lean on the framework pretty heavily by using ADO.NET data services as the service layer.
It's relatively easy.
Move your repeater to a separate custom control, let's say MyControl. Now repeater in your page becomes uc1:MyControl.
Wrap MyControl into a div:
<div id="mydiv">
<uc1:MyControl ID="MyControl1" runat="server" />
</div>
Create a new page, pgMyControl.aspx, that contains MyControl only.
On your main page, add jQuery handlers to your sort links. Use load method to dynamically replace div contents:
$('#link_sort_random').click(function()
{
$("#mydiv").load("pgMyControl.aspx&sort=random");
}
Use QueryStringParameter in datasource inside MyControl to change order. Or use Request.QueryString in code-behind file.
Using an updatePanel or a jquery Ajax postback are the same thing essentially. Both will ask your code to fetch the new query, then make your control render itself, and then feed the HTML back to the client as a partial page render, and then insert the content in place of the old content in the same DOM location.
It is considerably harder to make JQuery and ASP.NET talk to each other this way due to the nature of web controls and their lifecycle that determines when they render. An updatePanel knows how to call all this, maintain proper viewstate and return the result to the correct location.
In this case, don't make things any harder on yourself, use the updatePanel unless you have some very specific reason not to.
EDIT: If you're having JQuery issues with update panels it is probably due to the fact that new DOM nodes being created. JQuery has the live event to handle this. It will notice when new DOM elements are created and match them against your selector even after the document ready.
Maybe it's an OT, but you can consider to change the way you bind even the client and the server control, using XSLT transformation instead od the classics server controls.
You can find an example here (sorry, it's in italian...).
In an ASP.NET page I have a user control and I want to perform some action within it using javascript. When that action is complete I want to raise an event (again in javascript) to be picked up by the containing ASP.NET page (again in javascript).
The reason I want to do this is because I have more than one user control on the page and I need the action performed in one user control to instantiate an action in another user control without doing a postback.
Does anyone know how to do this?
Many thanks.
Hi and thanks for the response.
What I'm trying to do is create some form of encapsulation. So if the javascript code does something in one user control that user control shouldn't know of the impact else where. It would raise an event in javascript which can be picked up by asp.net page rendered javascript which can in turn call a javascript method in another user control if it needs to.
The idea here is also to eliminate any need for a postback.
Hope this expains it better.
I think the simple way to implement what you are describing, is to forget about JavaScript events, and just supply a "callback" function to the user-controls.
The way i would implement it, would be to expose a public property on the user control, which takes the name of this JavaScript "callback-function". The user-control is then responsible for calling this function after it has finished its client-side job.
So the page that uses the user-controls will have to implement this JavaScript "callback-function", and then supply the name in properties to the user controls.
Makes sense?
You can simply run the javascript you need from the rendered HTML of your user control.
Click Me
By the sounds of things you want to create some form of controller in JavaScript. When the page loads each of your controls register with the controller. Then an action in one of your controls runs a function on the controller, which does something with the controls registered with it.
Your JavaScript could be as simple as:
var oControls = new Array();
doSomething = function() {
for(var i=0;i<oControls.length;i++) {
var oControl = document.getElementById(oControls[i]);
oControl......
}
}
So you need to register your control by using ScriptManager in your user controls render method.
ScriptManager.RegisterStartupScript(Me, Me.GetType(), "Startup", String.Format("oControls.push('{0}');", ClientID), True);