I want my selectable to work as an autopostback control, when something is selected the script clicks on a button and postback the values of the selectable. But it doesnt play to well with my ASP.NET Ajax and UpdatePanels. Sometimes a full postback occurs, and not a partial one.
My conclusions from my debugging is that jQuery does something behind the scene while the stop function runs. If I add an alert to halt the stop function, the partial postback works fine.
To add some more confusion, this works in IE9 and Chrome, but not in IE7 or IE8. So it also might be browser specific.
jQuery version is: v1.6.2
Script:
<script language="javascript">
$('.selectable').live("mouseover", function () {
if (!$(this).data("selectable-init")) {
$(this).data("selectable-init", true);
$(this).selectable({
filter: '.item',
stop: function () {
$("#<% =btnPostback.ClientID %>").click();
}
});
}
});
</script>
HTML:
<div class="selectable">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Literal ID="litIsPostback" runat="server"></asp:Literal>
<asp:Button ID="btnPostback" runat="server" OnClick="btnPostback_OnClick" />
</ContentTemplate>
</asp:UpdatePanel>
Code behind:
protected void btnPostback_OnClick(object sender, EventArgs e)
{
litIsPostback.Text = ScriptManager.GetCurrent(this).IsInAsyncPostBack.ToString();
}
This is the closest to a solution I've come up with.
$('.selectable').selectable({
filter: '.item',
stop: function (event, ui) {
$('.ui-selectable-helper').remove();
setTimeout(function () {
$("#<% =btnPostback.ClientID %>").click();
}, 1);
}
});
By removing the helper (lasso) before the postback, I'm able to drag from top to bottom, but I cant do it the other way. In jQuery the helper is removed after the stop event.
Im not sure why setTimeout works, but it fixes the problem with full postback aswell.
Related
I am creating an ASP.NET with C# calendar application. When a user clicks on a day, I am using a jQuery Popup Overlay which will allow the user to add an 'appointment' and click a button to process the entered information in the codebehind.
The Popup overlay basically hides an HTML element and makes it visible when another element is clicked (great examples by following link above).
The Code:
<asp:Button ID="ButtonA" runat="server" OnClick="Button_Click" Text="Button A" />
<asp:Label ID="Label" runat="server" Text="Foo"></asp:Label>
<div id='slide'>
<div id="content">
Content of the 'popup panel'
<asp:Button ID="ButtonB" runat="server" OnClick="Button_Click" Text="Button B" />
</div>
</div>
CodeBehind:
public void Button_Click(Object sender, EventArgs e)
{
Label.Text = "Bar";
}
Javascript:
$(document).ready(function () {
$('#slide').popup({
//options
});
});
I tried adding the AutoPostBack="true" parameter to the buttons, but it doesn't make a difference (should be automatic regardless, correct?). I also tried adding the runat="server" parameter to the div elements, but that made the issue worse.
I am afraid that I don't understand the nature of the issue enough to provide more information than this - Sorry!
It's likely that the jQuery plugin is overriding the behaviour of the button. You could use the onclose callback from the URL you provided to have a function like so:
function() {
__doPostBack("ctl00$MainContent$ButtonB","");
}
Failing that, you could have another button outside the popup div which you do a click() event on manually during the onclose event of the popup, but that seems like a bit of a hack!
I have a simple enough problem: I have an ASP.NET control button and I want to make it fade out and then call some function (such as an alert) using JQuery. Here is what I have so far:
ASP Code for the Button:
<div id="begin">
<span id="startButtonSpan">
<asp:Button ID="startButton" class="startButton" runat="server" Text="Click Me!" OnClientClick="startButtonClick()"/>
</span>
</div>
JavaScript:
function startButtonClick()
{
$("#startButtonSpan > input").fadeOut(500, callAlert());
}
function callAlert()
{
alert("Made it here...");
}
When I click the button, the alert displays but the page does not even seem to try to perform the fadeOut. When I close the alert, the button is still there, staring at me.
Can anyone see any mistakes or does anyone have any suggestions on how I might be able to achieve the intended goal of fading out my button? Fadeout is really just my way of testing whether I can manipulate ASP controls using jQuery, so more than just the simple fadeOut, this is me trying to learn how to do that.
I tried a slightly more simple jQuery call using the code below, but it does not seem to work either:
ASP Portion:
<div id="begin">
<span id="startButtonSpan">
<asp:Button ID="startButton" class="startButton" runat="server" Text="Click Me!" OnClientClick="startButtonClick()"/>
</span>
</div>
<div id="jQueryTest" style="display:none;">
Block for testing jQuery.
<h1 id="testMessage">Child element for the ASP div.</h1>
</div>
Javascript Portion:
function startButtonClick()
{
$("#jQueryTest").css("display", "block");
$("#jQueryTest").show();
}
For this example, the text does display, but it immediately disappears again.
Any help or suggestions as to what I might be doing wrong would be greatly appreciated.
Use the class as a selector $('.startButton') instead of the ID since ASP.Net controls change their IDs dynamically when rendered by appending its Page & Control information.
$(".startButton").fadeOut(500, callAlert);
Or, if you're adamant about using the ID, here is another way to handling the selector,
$("#<%=startButton.ClientID %>")
Or, as Jacob suggested in his answer, you could ClientIDMode="Static", but this works only if your application is .Net 4.0 or above.
Also, use CssClass instead of class
<asp:Button ID="startButton" Csslass="startButton" runat="server" Text="Click Me!" />
The first example has 2 problems.
1. You should write
$("#startButton").fadeOut(500, callAlert);
and not
$("#startButton").fadeOut(500, callAlert());
2. For ASP.NET you must set ClientIDMode="Static" ortherwise asp.net will alter your id.
<asp:Button ID="startButton" ClientIDMode="Static" ... OnClientClick="startButtonClick()"/>
How about the fact that your code is fine (although other answers here should be considered) but your button is making a post back to the server and simply your browser does not have enough time to render the fade effect.
To test this, add a return false; to the OnClientClick property. This will of course cancel your action on the server but you will obtain the fade effect:
<asp: Button ... OnClientClick="startButtonClick();return false;"></asp:Button>
To work around this and still submit your request, you can try to use the ASP.NET __doPostBack method in JavaScript
ASP.NET:
<asp:Button ID="startButton" class="startButton" runat="server" Text="Click Me!" OnClientClick="startButtonClick(this);return false;"/>
JavaScript:
function startButtonClick(button)
{
$("#startButtonSpan > input").fadeOut(500, function(){__doPostBack(button.name, "")});
}
The __doPostBack method takes two arguments: the name of the control that is doing the postback and a postback argument that can be use to send more info on the server. In the case of the asp:Button, the name of the button should be sufficient to send the request without a problem.
Using this technique you will fade the button on the client and also trigger the action on the server. I cannot guarantee that this exact code will work (I don't have access to a dev environment right now) but you should get the idea.
If I could, I would like to provide another answer for those that use MasterPages and find that you can't always use $("#<%= SomeContentControl.ClientID %>") when working with Content controls.
What I do is set the MasterPage ID in my Init() like this:
protected void Page_Init( object sender, EventArgs e )
{
// this must be done in Page_Init or the controls
// will still use "ctl00_xxx", instead of "Mstr_xxx"
this.ID = "Mstr";
}
Then, you can do something like this with your jQuery:
var masterId = "Mstr",
$startButton = getContentControl("startButton"),
$message = $("#jQueryTest");
function getContentControl( ctrlId )
{
return $("#" + masterId + "_" + ctrlId);
}
function hideStartButton()
{
$startButton
.stop(true, true)
.fadeOut("slow", showMessage);
}
function showMessage()
{
$message
.stop(true, true)
.fadeIn("slow");
}
$startButton.on("click", hideStartButton);
Here is a jsFiddle that has the Mstr_ prefix already inserted as if ASP.NET rendered it.
All,
Environment: ASP.NET 2.0, AjaxToolkit build 1.0.20229.0, IE9
I am using $find() to find a behaviour of a call out extender so I can show explicitly using .show() method. Unfortunately, $find() returns null.
$find('my auto generated behvaiour Id').show();
FYI: The BehaviorID on the ValidatorCalloutExtender is generated using ClientID of the control (ClientID_ + "BehaviourID" <- is also what I use in my $find() function) because I have many instances of this control on the same page.
I looked at the rendered code and I can see JS to create that creates the behaviour:
Sys.Application.add_init(function() {
$create(AjaxControlToolkit.ValidatorCalloutBehavior ...
The $find() executes AFTER a postback in an UpdatePanel and returns always null.
EDIT (ADDED):
I created new page and below is the code, find() returns still null,- is there a bug in Ajax control tooklit for ASP.NET 2.0?
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScripManager1" runat="server" EnablePageMethods="True" >
</asp:ScriptManager>
<asp:TextBox runat="server" ID="txtInputField" />
<asp:RequiredFieldValidator runat="server" ID="valInput"
ControlToValidate="txtInputField"
ErrorMessage="ERROR STRING"
Display="none" /> <ajaxToolkit:ValidatorCalloutExtender runat="server" ID="extValInput" TargetControlID="valInput" BehaviorID="myID" />
<asp:Button runat="server" ID="btn" OnClick="btn_click" CausesValidation="True" />
<script type="text/javascript">
var obj = $find("myID");
alert(obj);
</script>
</form>
ADDED:
After observation in JS debugger, I realized that the validator callout extender only appears (is added dynamically to the DOM) when there's error, hence, if there's no error you cannot find it.
THE QUESTION NOW IS: How to reposition the call out extender baloon before displaying it? It is really catch 22, you can't access it when it is not displayed and when it is displayed, it is already to late because it displays in the wrong place.
The cause of the problem is that you try to find component before page completes component initialization. Try to access your editor in Sys.Application.add_load event handler. I tried the following code and everything works fine:
<script type="text/javascript">
Sys.Application.add_load(function() {
var obj = $find("myID");
alert(obj);
});
</script>
Edit:
To address your latest question: how you can reposition it. Callout ValidatorCalloutExtender uses PopupExtender to show it. So, you can try to bind to 'showing' and 'shown' events of the popup extender and then try to reposition callout.
<script type="text/javascript">
Sys.Application.add_load(function() {
var callouotComponent = $find("myID");
var popupBehavior = callouotComponent._popupBehavior;
popupBehavior.add_showing(function(){alert("I am showing");});
popupBehavior.add_shown(function(){alert("I was shown");});
});
</script>
Note: I didn't verify this code, but it can be used as start point.
Modified your code and verified, popup position is changing.
<script type="text/javascript">
Sys.Application.add_load(function () {
var callouotComponent = $find("myID");
//Below line is to init popup ballon, otherwise popup behaviour will return null
callouotComponent._ensureCallout();
var popupBehavior = callouotComponent._popupBehavior;
popupBehavior.set_x(100);
popupBehavior.set_y(100);
});
</script>
Hey,
Before I start to write my problem, I will excuse for my bad English and I hope you can understand me.
I have in a ASP.NET Webapplication an AJAX Updatepanel. In this Updatepanel is a
Textbox for dynamic search results. When I start to write in the Textbox, the results comes like Google suggest.
Now, the focus must be always on the Textbox (inputn field), now metter whereto the User clicks.
Currently the ASP.NET updatepanel refreshed after a few seconds when the User starts to type.
Thanks for help :-)
there is an event when updatepanel finish updated html dom
Sys.WebForms.PageRequestManager.getInstance().add_endRequest
try this
function EndRequestHandler() {
//get focus on the textbox
myTextbox.focus(); }
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
That is pretty fun but here is a possible solution. The idea is: if user gets out of the textbox (onblur), then take him back to the textbox (focusOnTxt function):
<head runat="server">
<title></title>
<script type="text/javascript">
function focusOnTxt(sender) {
sender.focus();
sender.value = sender.value;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="upnl" runat="server">
<ContentTemplate>
<asp:TextBox ID="txt" runat="server"
onblur="focusOnTxt(this)"></asp:TextBox>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
And on Page_Load:
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
txt.Focus();
}
}
A simple SetFocus f.e. in Page.Load should work:
ScriptManager1.SetFocus (TextBox1.ClientID)
UPDATE: according to this post following works...
Add this script into a script block in your page's head:
function SetEnd(TB){
if (TB.createTextRange){
var FieldRange = TB.createTextRange();
FieldRange.moveStart('character', TB.value.length);
FieldRange.collapse();
FieldRange.select();
}
}
Then add the onfocus event to your Textbox:
onfocus="SetEnd(this)"
In your codebehind's Page.Load or TextChanged-Event handler add the standard SetFocus call:
ScriptManager sm = ScriptManager.GetCurrent(this);
sm.SetFocus(myTextBox)
I've got UpdatePanel with Div
<telerik:RadAjaxPanel runat="server" ID="RadAjaxPanel1">
<div class="pnlFind" style="display:none;">
</div>
</telerik:RadAjaxPanel>
wanna use js for showing this div
<script type="text/javascript">
function pageLoad(sender, args) {
if (args.get_isPartialLoad()) {
$('.btAddUser').click(function () {
$('.pnlFind').show('slow');
$('.pnlFind').attr('display', 'block');
return false;
});
}
}
</script>
but after partial postback, I got div invisible again(right! restore DOM) How can I remember that div should be always visible after button click. Thanks
You have to inject javascript into the page to simulate the click event again. Page.RegisterClientScriptBlock or Page.RegisterStartUpScript should do it.