I have an update panel which is causing a postback on part of the page and after postback the control that had focus (which is not in the update panel) loses focus. How can I identify which control had focus and save that value, so that I can refocus to it when the page reloads. Thank you.
First I bind the focus on all input and keep the last focused control ID. Then after the UpdatePanel finish the load, I set the focus to the last one
// keep here the last focused id
var LastFocusedID = null;
function watchTheFocus()
{
// on every input that get the focus, I grab the id and save it to global var
$(":input").focus(function () {
LastFocusedID = this.id;
});
}
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_initializeRequest(InitializeRequest);
prm.add_endRequest(EndRequest);
function InitializeRequest(sender, args) {
}
// after the updatePanel ends I re-bind the focus, and set the focus
// to the last one control
function EndRequest(sender, args) {
if(LastFocusedID != null)
$('#' + LastFocusedID).focus();
watchTheFocus();
}
jQuery(document).ready(function()
{
watchTheFocus();
});
The only think is that I use jQuery to make it, but I present here my idea, you can make it with little more code with out jQuery.
You can get what element has focus with javascript using the activeElement and hasFocusproperty to HTMLDocument object.It might not be supported by all since it's HTML5.
You can solve like this
var last_focused = null;
$(function () {
//store last focused element.
$("input").live("focus", function(){
last_focused = $(this);
});
});
//in Script manager
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(pageLoaded);
function pageLoaded(sender, args)
{
if(last_focused != null)
{
last_focused.focus();
}
}
Related
I'm a newbie in C# language and I'm quite lost trying to extend an already existent and non-mantained .NET web application.
The application has a Web User Control with a button that, when clicked, refreshes its inner content through this piece of JavaScript code within the .ascx:
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequestHandler);
function endRequestHandler(sender, args) {
var btnId = '<%= btn.ClientID %>'
if (sender._postBackSettings.sourceElement.id == btnId) {
// loads a popup with the new content
}
}
This works perfectly. The problem comes when I try to add a new Web User Control which does practically the same, but of course through a different button and loading different content. I replicated the code structure, both in the front and in the back, but I cannot get the second endRequestHandler to execute:
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequestHandlerStats);
function endRequestHandlerStats(sender, args) {
alert("I'm here!");
var btnStatsId = '<%= btnStats.ClientID %>'
if (sender._postBackSettings.sourceElement.id == btnStatsId) {
// loads another popup
}
}
Suprisingly, that alert pops when the first btn is clicked, but not with the second btnStats.
I think the problem is caused because the btnStats doesn't trigger a request, but as I said I am new at this and I have no idea why. And the operation is done properly, the only thing that doesn't work is what is done in that script. Any hints, please?
I believe that is what the if condition is for - it is to check which button was clicked. The event model of JavaScript doesn't allow multiple handlers to be attached (at least not without some extra work), so this is probably the next best thing.
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequestHandler);
function endRequestHandler(sender, args) {
var btnId = '<%= btn.ClientID %>'
var btnStatsId = '<%= btnStats.ClientID %>'
if (sender._postBackSettings.sourceElement.id == btnId) {
// loads a popup with the new content
}
else if (sender._postBackSettings.sourceElement.id == btnStatsId) {
// loads another popup
}
}
There is a problem to find a dynamic control on a page. The dynamic control is created every time when a user press a button. The button calls the following JavaScript function and create a new components.
<script type="text/javascript">
var uploadCount = 1;
function addFileInput(fName) {
var only_file_name = fName.replace(/^.*[\\\/]/, '');
var $div = $('<div />', {runat: 'server'});
var $cbox = $('<input />', { type: 'checkbox', id: 'attachement' + uploadCount, value: fName, checked: "true", runat: 'server'}).addClass;
var $label = $('<label />', { 'for': 'attachement' + uploadCount, text: only_file_name });
$div.append($cbox);
$div.append($label);
$('#newAttachment').append($div);
$("#uploadCountValue").prop("value", uploadCount);
uploadCount++;
}
</script>
newAttachment is DIV section on the page.
<div id="newAttachement" runat="server" />
The DIV section is situated inside section. The problem is when a user presses the button on the form I can't find the dynamic created components. The following code shows how I try to find the components:
for (int i = 1; i <= Convert.ToInt32(uploadCountValue.Value); i++)
{
if (RecursiveFind(newAttachement, "attachement" + i) != null)
{
... to do something
}
}
public Control RecursiveFind(Control ParentCntl, string NameToSearch)
{
if (ParentCntl.ID == NameToSearch)
return ParentCntl;
foreach (Control ChildCntl in ParentCntl.Controls)
{
Control ResultCntl = RecursiveFind(ChildCntl, NameToSearch);
if (ResultCntl != null)
return ResultCntl;
}
return null;
}
I have detected that Controls count value is always zero in spite of there are dynamic components there.
I would be happy to get any help from us. Thanks.
to find the controls created in the client-end you can't search them in the Page.Controls collection instead try to look for them in the Request.Form[] array
you are creating the dynamic controls in javascript? i.e. you are creating html elements in javascript. It won't matter even if you put a runat="server" attribute in there, because it is still at the client-end. That would not be a part of the viewstate bag, so not populated in the controls collection.
you need to change your logic. create dynamic control in code-behind on button postback.
I currently use a hidden input field that is assigned the value of the tab that has just been selected, via javascript, like so:
function onTabSelecting(sender, args) {
var tab = args.get_tab(); //get selected tab
document.getElementById("MainContent_hdnPreviousTab").value = tab.get_text(); //assign value to hidden field
if (tab.get_pageViewID()) { //ignore
tab.set_postBack(false);
}
}
I then use this assigned value when the page is returned to, on client-side (ajax) PageLoad() event:
<script type="text/javascript" language="javascript">
var runOnce = false;
function pageLoad() {
if (!runOnce) {
var lastTab = document.getElementById("<%= hdnPreviousTab.ClientID %>");
if (lastTab.value) {
if (tabStrip) {
var tab = tabStrip.findTabByText(lastTab.value);
if (tab) {
tab.click();
}
}
}
runOnce = true;
}
}
</script>
Currently in IE this works fine (I know right?), the value that was previously set in javascript is still there and i am able to lcoate the tab that the user left the page on. However in FF, Chrome, etc. i have no such luck. The hidden field is returned to it's empty state (value = "") regardless of utilising viewstate or not.
Very curious as to whether anyone has an alternative method that would be appropriate in this situation. Please let me know if this is unclear.
Many thanks.
You could use localstorage.
localStorage.setItem('tab', value);
I have a textbox in web form(asp.net). when user already keyin data, then they will press Enter key, so that the data will be update to database.
Is there any way possible to perform this?
function InitTextBox() {
//var _txt = $('#<%= txt.ClientID%>'); or
var _txt = $('input:[id*="txtId"]');
if (_txt.length < 1) return;
_txt.get(0).autocomplete = 'off';
_txt.on('keydown', function (evt) {
var _self = $(this);
event = evt ? evt : window.event;
if (event.keyCode == 13) {
if ($.browser.msie)
{ event.cancelBubble = true; event.returnValue = false; }
else { event.preventDefault(); }
if (_self.val().length > 0 && _self.val().match(/^\s*$/) == null)
__doPostBack(_self.attr('name'), '');
}
});
}
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(InitTextBox);
And set autopostback for textbox to false, please
Dino Esposito had wrote about this a while back. You wouldn't necessarily need a custom control, but can use his JavaScript.
If you have a control wrapped around a Panel, and you have the DefaultButtonID property set, the panel will trigger a postback on enter too by clicking the desired button specified by the ID. That's another way.
I am using a treeview control. I am buliding the tree dynamically. sometimes the tree becomes larger and the down scroll bar is need to see the entire tree.
user can select a node from the tree. if one node is selected ,i change the color of the node from server side.
my problem is that if a user selected a node which is bottom in the tree(means, the user used the down scrollbar to see that node), after postback it shows the top of the tree.to see the selected node the user need to use the down scroll bar.
I need to show the selected node after postback. How can I do this?
I am using c# and asp.net
With help of jquery we can send the selected node id to the query string and on document.ready we can read back and highlight that node.
Have a look on the code:
Code behind onclick code:
public void TreeView1_OnClick(Object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript(
Page,
Page.GetType(),
"HighlightSelectedNode",
"HighlightSelectedNode();",
true
);
}
and the javascript:
<script type="text/javascript" language="javascript">
function HighlightSelectedNode() {
var selectedNodeID = $('#<%= TreeView1.ClientID %>_SelectedNode').val();
if (selectedNodeID != "") {
document.location.href = "http://" + window.location.host
+ window.location.pathname
+ "?Node=" + selectedNodeID;
return false;
} else {
// alert("Not found");
}
}
// Highlight active node on pageload.
$(document).ready(function () {
var querystring = location.search.replace('?', '').split('&');
var queryObj = {};
for (var i = 0; i < querystring.length; i++) {
var name = querystring[i].split('=')[0];
var value = querystring[i].split('=')[1];
queryObj[name] = value;
}
var nodeID = queryObj["Node"];
$('#' + nodeID).css({ 'background-color': '#888'});
});
</script>
You can use update panel to work around this issue.