Add an Editor control dynamically inside of a repeater using AJAX - asp.net

I'm looking for a way to add an Editor control (from the ASP.NET AJAX Control Toolkit) to each element of a repeater. It's working fine if I just include it in the ItemTemplate of the repeater, but my problem is that the markup it produces is massive, which slows down the page considerably (even with compression on).
I haven't had any luck adding the control inside the repeater item using an Update Panel - I think this is probably the preferred method, but dynamically adding a control inside an Update Panel inside of a Repeater Item isn't something I've had any success doing, and there don't seem to be any good examples of this that I can find.
The other alternative I considered was using PageMethods to render the control and send the HTML back to the page to let the javascript put it in the appropriate place, then deal with it, but it won't let me render the control - I get an InvalidOperationException of "Page cannot be null. Please ensure that this operation is being performed in the context of an ASP.NET request.". My guess is that all the javascript that's generated makes it so that I can't just render an Editor control on the fly.
Can you point me in the right direction for accomplishing this?
Thanks
EDIT: Another alternative, if it is possible, would be to put a normal Editor control in the markup of the page, then move it around inside of the repeater as needed, using javascript. I can do this with normal controls, but when I do it with an editor, it is not behaving nicely - the textbox appears, but won't let me click inside it. If you have any ideas on this one, I'd appreciate that as well. Here's the code for this:
<span id="spanHiddenEditor" style="display: block;">
<cc1:Editor ID="ed1" runat="server" Height="200" Width="400" />
</span>
<script type="text/javascript">
function createTextBox(idx) {
var span = $get("span1_" + idx); // this gets me the target location
var hiddenEditorSpan = $get("spanHiddenEditor")
var editorHtml = hiddenEditorSpan.innerHTML;
hiddenEditorSpan.innerHTML = "";
span.innerHTML = editorHtml;
}
</script>

identify the location within the repeater with a class then use jquery to inser the html on page ready
$(function() {
$(".myclass").Append("<htmlz>");
});
Then if you need to identify each text box you can do it using the parent container ID eg.
$("#myID div.class input").value
I'm a total jquery newb so none its likely none of it will work, but i believe the idea is a good one!

Related

Referencing ids unknown at compile time

I'm making a user control to gather all the functionality for popups on my website in one place. When someone instantiates the control, they'll pass in a PopupID attribute, which is assigned to the id of a div inside the control, and will be used to call show() and hide() functions in javascript. I'm going to use content templates so that different stuff can be put inside the control by different kinds of popups.
The html for the popup will look something like this:
<div id="<%=PopupID %>" class="popup box" runat="server">
<asp:PlaceHolder runat="server" ID="popupPlaceHolder"></asp:PlaceHolder>
</div>
However, there is a problem: asp.net has the habit of giving controls different IDs when served up to the client than what you write in the html. So the ID of that div might not be <%=PopupID%> It could be somethling like #ctl00_whatever_<%=PopupID%>. Usually I get around this by putting something like:
<script type="text/javascript">
var ddlCountry0 = '<%=ddlCountry0.ClientID%>';
var ddlActivity0 = '<%=ddlActivity0.ClientID%>';
var chkPrivateContacts = '<%=chkPrivateContacts.ClientID%>';;
</script>
In the header for the page. Then when refering to things in the javascript you just do $(ddlCountry0) instead of $('ddlCountry0'). However, I don't see how I can do that in this case, As I don't know the ID of the element until someone instantiates it. What do I do to get around this?
Does the user control have CreateChildControls and OnPreRender methods you can override?
If a control is added and ID set correctly during CreateChildControls...the ClientID property is populated during OnPreRender, at which point the control itself could inject the necessary script block into the body or page header. People often use jQuery to help with this situation:
headerScript.AddLine("var ddlCountry0 = $('[ID$=" & Control.ClientID & "]').attr('id');")
Is that along the right lines?
In the end, I used ClientIDMode=Static to get around these problems.

issues with having same custom control twice in a page

I am facing issues when I tried to add same custom control twice in the same page. The issue is because instance of one control is caling the java script of the other. Added to that I am using ajax popup extender where in I have popup divs with in that control itself.
Now it is leading to java script errors because it is geting confused among the popup div ids and scripts etc.
Please help me.
Take one step further in taking care about client-side IDs generated uniquely for the tags inside each instance of your custom control.
This can be easily fixed by adding runat="server" attributes to the tags which you want to have unique client side IDs when rendered to the browser. Then you should use this kind of code in JS:
document.getElementById("<%= control.ClientID %>");
As about tags which you don't want to mark using runat attribute, you can assign them their IDs uniquely on the server-side manually in each instance of the custom control.
I hope this helps!
There's no automatic fix for this. If a custom control is going to be used more than once on a page, you have to design it to be aware of this. In particular, you'll probably need to refer to generated elements using their generated id:
var ele = document.getElementById("<%= serverSideControl.ClientID %>");
Javascript emitted by the control will have to also emit the appropriate ID's.
And so on.

ASP.NET: Bind Repeater using jQuery?

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...).

JQuery output a dynamic control in a div

How do I handle the click of a checkbox to show another control preferrably a user conrtrol (ASP.NET ) dynamically.
I don't know anything about the system you're using but the low down dirty way I'd do this is...
Stick the user control on a blank page of it's own.
When the checkbox is clicked, have JQuery go get the HTML content of the page the user control is on and stick it in the div.
This will result in not-so-neat html in the calling page though.
And is this an asp:CheckBox or an html input?
If you want to create a new object, you can do this:
var checkbox = $("<input type='checkbox' ... />");
$('div#someID').append(checkbox);
Though it sounds like you perhaps want to get the data to append from an AJAX call. I can't quite tell from the question.
Assuming you hide the control with CSS by default you could shorten TStamper's code to something like:
$(function() {
$('#checkbox').click(function() {
$('#control').toggle();
});
});
<mycontrol:UC id="control" runat="server" />
I'm partial to using jquery's taconite plugin. It enables you to return multiple controls from a single ajax call.
For a simple show/hide control scenario rendering a hidden control on a page is good enough. If your control is big or changes due to user actions then your best bet is rendering control on the server and using js to update DOM.
If you're using jquery for your DOM updates and wish to find control by id use:
$("[id$=controlId]")
This will locate your control even with asp.net prefixes to the id.
I'm working on a simple c# wrapper for the taconite plugin which should enable you to use the plugin more easily (sample web site coming soon).
Are you looking for something like this:
$(function(){
$('#Control').hide(); //initially hide the control
$('#checkbox').click(function(){ // bind the checkbox click event
if ($('#checkbox').attr('checked')) {
$('#Control').show();
}
});
});
<mycontrol:UC id="Control" runat="server" />

Easiest/Best Hide/Show Client Side Hide/Show for ASP.NET

I have a DropDownList and a TextBox on a Page. When the user chooses the "other" option in the DropDownList I want to display a TextBox just to the right of it. I do not want to use the traditional PostBack technique. I want this interaction to be client side.
I am aware that I can get a get a reference to the DOM element and set its style to "display:none" or "display:". What I am looking for is something that is built into the ASP.NET framework for handling something like this. I mean, in jQuery this is as simple as $('controlID').hide. Is there a Control Extender that can do this? Is jQuery part of the ASP.NET framework yet?
jQuery will be/is distributed with VisualStudio/ASP.NET MVC, though I wouldn't call it part of the framework. I think that you can feel free to use it and trust that it will be supported.
Note that Microsoft has said that they will be using the main line of development for jQuery so the code itself won't be any different than you can download from jQuery.com, except perhaps for built-in Intellisense.
EDIT: To set up your functionality download the code from jquery.com. Put it in your scripts folder, or wherever you store javascript stuff. Add a script reference for it to your page. Use jquery to add an onchange handler to your dropdown list and when the value of the dropdown list is other show the textbox, otherwise hide it. The example below assumes that other isn't the default selection. If you are using runat="server" controls with MasterPages or inside UserControls, you'll need to adjust the names in the javascript functions to account for the name mangling that ASP.NET does. Probably simpler to give them unique CSS classes and reference them using the ".class" notation rather than "#id" notation.
<script type="text/javascript" src="...pathtoscript../jquery.1.2.6.js"></script>
<script type="text/javascript">
$(document).ready( function() {
$("#DropDownListID").bind('change', function() {
if (this.options[this.selectedIndex].value == 'other')
{
$("#TextBoxID").show();
}
else
{
$("#TextBoxID").hide();
}
});
});
</script>
...
<select id="DropDownList">
<option value='first'>First</option>
...
<option value='other'>Other</option>
</select>
<input type='text' id='TextBox' style='display: none;' />
You could also use the asp.net client side framework(via the scriptmanager) to get a reference to the element. But then you still have to use the normal DOM manipulation.
$get('<%= myDropDown.ClientID %>').style.display = 'none';
Just make sure you have the script manager referenced.
For something so simple, I wouldn't think it is worth referencing jquery, but maybe you've got bigger plans ;-)

Resources