Update ASP.NET Page after GridView DataBind - javascript

EDIT:
Apparently, part of the problem is that while an ASP:GridView has an OnDataBound() event (which you can use in the code-behind), the corresponding HTML table that is produced does NOT, so you can attach that event to JavaScript. (Did I get that right?) So, that's why I'm having trouble with that bit of the issue. Back to the drawing board.
I'm a desktop developer (WinForms with VB.NET) transitioning into ASP.NET development. My mind is really bending around the DOM and JavaScript and Session State and all of the stuff that goes along with web development. I'm not stupid, and I've done research (including hours of video watching and hundreds of pages of "Intro to ASP.NET" reading), but I keep hitting the wall with what seem to be fairly straightforward problems.
Basically, my current situation can be summed up as follows:
I have a page that runs a very long process initiated by the user.
The long process can take up to a few minutes , so I want to indicate to the user that SOMETHING is happening.
When the process has completed, I either have:
a. Results to show in a GridView
b. No results to show
If I have results to show, I want to display them.
If I have no results to show, I want to show a label to the user that says "No results to show."
What's working:
I have a basic page where the user selects start and end dates and kicks off the check process.
The check process works fine (using LINQ-to-SQL logic developed for a desktop version of this program).
I've got an UpdatePanel on my page which shows a label and an animated gif to indicate that something's happening.
If I get results, they display appropriately in my GridView.
What's not working:
I'd love to give the user some sort of progress bar to indicate actual progress made toward completion rather than some endlessly-animating gif that doesn't indicate much at all. I could calculate this value quickly and easily, but can't figure out how to transfer said value from server to web page.
I can't figure out how to trigger an "unhide" event for the label. The long-running process is in a button's click event handler, where I run my custom code and generate a DataTable, which I then save as a session variable, assign it as the GridView's DataSource and call GridView.DataBind(). When I try to determine the contents of the DataTable and hide/reveal the label there, nothing seems to happen.
Problem #2 is really what I need to figure out in order to publish this web site. I'm assuming it involves a JavaScript solution, and I've tried some stuff, but I find that I'm truly guessing and don't have a good grasp on what the solution should resemble.
Here's the label I'd like to selectively reveal/make visible:
<tr>
<td colspan="2" align="center">
<h2><asp:Label runat="server" ID="lblNoMissing" Text="No Missing Documentation Found" Visible="false"></asp:Label></h2>
</td>
</tr>
Here's a JavaScript function I'm trying to test:
<script type="text/javascript">
function databound() {
var gridViewID = '<%=_gridView1.ClientID%>';
var labelID = '<%=lblNoMissing.ClientID%>';
var gridView = document.getElementById(gridViewID);
if (gridView.rows.length > 0) {
$get(labelID).style.visibility = "false";
} else {
$get(labelID).style.visibility = "true";
}
}
</script>
Problem: This fails (databound not a member of Default.aspx):
<asp:GridView ID="_gridView1" runat="server"
AllowSorting="True" AutoGenerateColumns="False" CellPadding="4"
ForeColor="#333333" GridLines="Horizontal" PageSize="20" OnDataBound="databound();">
// Rest of GridView definition removed
</asp:GridView>
What am I missing?
Thanks!!!!

For problem #1, there are a whole bunch of free Javascript progress bars out there. As for your value that you can't retrieve, try this:
<asp:Label ID="ProgressValue" runat="server" visible="false" />
And in your code behind.
ProgressValue.Text = //Your value from your database.
And just reference it from your Javascript there.
For your second problem, can't you just do in your code behind (written in C#)
//Process here
if(IDofGridView.Rows != null)
{
lblNoMissing.Visible = true;
}
Or am I missing something?

For #2, set style.visibility="visible"
See: http://www.w3schools.com/cssref/pr_class_visibility.asp
for valid values.
For #1, you can use an update panel with a timer for refreshing it. The server can simply add the current status to that users Session. The update panel code reads the session and shows the result.

So, I'm not sure I solved this exactly the way I wanted, but I have a working version. Here's what I did (for others who might find this useful):
I have abandoned my plans for #1 for now. I just simply don't have the time to continue looking into this issue right now. I'm bummed, though, because it seems like this is something a lot of people need to do, but I can't find a cookie cutter solution. Seems weird to me. Maybe I'm still missing some key info that would make it easy.
I have a GridView, a progress Label, an animated gif and a "no results" Label that I want to show/hide at various times. What ended up working for me was to place them all in UpdatePanels and simply show/hide them in my code-behind. It's kind of starting to make sense, but changing the visibility of a control from the code-behind when the control to change is OUTSIDE of an UpdatePanel but the code is initiated FROM INSIDE an UpdatePanel seems like a barrier that can't be crossed. That is, when my "no missing" Label was OUTSIDE of an UpdatePanel, the long-running process (started by a button INSIDE the UpdatePanel) couldn't change its visibility. (Does that make sense? Anyone want to correct that?)
Thanks for reading! Thanks for the ideas!
Edit:
OK, so I'm apparently wrong again. The code that shows/hides my Label and GridView has nothing to do with any code executed in the long-running process in the code-behind file.
Here's the code that actually does what I want (code is in Default.aspx):
<script type="text/javascript" >
Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(CheckStatus);
function CheckStatus(sender, args) {
var prm = Sys.WebForms.PageRequestManager.getInstance();
if (prm.get_isInAsyncPostBack()) {
args.set_cancel(true); // stop request from being sent
$get("_messageSpan").innerHTML = "<h2>The last request is still processing.</h2>";
}
else {
var lbl = document.getElementById('<%=lblNoMissing.ClientID%>');
if (lbl) {
lbl.style.visibility = "hidden";
}
var gview = document.getElementById('<%=_gridView1.ClientID%>');
if (gview) {
gview.style.visibility = "hidden";
}
$get("_messageSpan").innerHTML = "";
}
}
</script>
The code related to "_messageSpan" is to prevent subsequent button clicks from starting the long-running process again (and also notify the user that it's still running).
So, since it is never correct for either of my items to be showing during a non-AsyncPostBack, I simply try to get the items and, if I get them, set them hidden. Now my page is behaving correctly. This may be some hacky code, but the page at least looks the way I want it!

Related

Passing script variable to the next page

I've got spinning wheel script that I'm trying to use to give away small prizes to visitors when they login to a website. The wheel animation all works great and the script puts the 'result' into a variable and displays that in a modal on the page. You can see it in action here...
https://ezclix.club/wheel2/index.asp
The result value shows up as the third line in the modal, inserted t oa span #displayprice.
var response = "";
response += selectedSegment.winResult;
$("#displayprice").html(response);
I just need to get that value to the next page, so I can actually 'award' the prize, but so far nothing I've tried seems to work.
I tried setting a cookie but that doesn't make it through.
setCookie("Prize", response, 1)
I've tried adding a form to the modal, and using jquery to update an input with the result value, but that doesn't want to work either.
$('input[id=passprize]').val(response);
$('input[name=passprize]').val(response);
I've tried adding a whole new form input, but no go there as well.
I don't do much with jquery and my experience is mostly limited to minor edits to existing scripts, but the edits above are all things I've done in the past, so I'm stumped.
Any ideas at all much appreciated!
Here's the full function...
function alertWinResult(selectedSegment) {
jQuery(".spin_pin").rotate(0);
$("#spinWinResult").text(globlefuncgeneral.gameover_text);
$(".power_controls").hide();
var response = "";
response += selectedSegment.winResult;
$("#displayprice").html(response);
// My variousattempts...
setCookie("Prize", response, 1)
$('input[id=passprize]').val(response);
$('input[name=passprize]').val(response);
}
You can use url parameter to pass the prize when redirect to next page url/action?prize={response}
enter code here
//Using cookie
setCookie("Variable", response, value)
//using url redirect
next page url/action?Variable=value
I'm not sure how or why, but the form part of this is now working. The snippet above is populating the field so that's getting passed to the next page.
I left it for a while, came back a few hours and it worked without any further changes. So guessing there's some caching going on maybe?
Either way, sorry to waste people's time on this and thanks for your suggestions.

Why cant I disable ajaxToolkit:AsyncFileUpload

Iv tried many things (JS/Jquery) to disable this AsyncFileUpload but none are working...please advise..
<ajaxToolkit:AsyncFileUpload OnClientUploadError="uploadError"
OnClientUploadComplete="ajaxUploadImage_ClientUploadComplete" runat="server"
ID="ajaxUploadImage" Width="400px" UploaderStyle="Modern"
CompleteBackColor = "White"
UploadingBackColor="#CCFFFF" ThrobberID="imgLoader"
OnUploadedComplete = "ajaxUploadImage_OnUploadComplete"
OnClientUploadStarted="AssemblyFileUpload_Started"
/>
var upload = $$('ajaxUploadImage');
upload.enableSelection('false');
var upload = $$('ajaxUploadImage');
upload.enableSelection('false');
upload.disableSelection();
document.getElementById("ctl00_MainContent_MapUserControl_ajaxUploadImage").disabled = true;
So...iv tried using the ID assigned by me..iv tried using the ID assigned in the browser....what am I doing wrong? user can still click of the text box or the select button and the pictures folder pops up, allowing the user to select an image for upload
should note that iv also tried disabling it from code behind
ajaxUploadImage.Enabled = false;
Have also tried setting disabled="true" inside the control, and checking the control in developer tools it is disabled, but I can still click on the text box or button and the pictures folder opens
The control emits its own markup and is hard to manage.
You can try set Visible=false, because its logic runs every time the page is loaded and the control is visible.
I have been putting my head into the disabling part and it seems we can surely disable the AsyncFileUpload control.
The trick is, ajax toolkit re-assigns the ids to the its controls, so whatever your id is, it will re-assign a new id to it even if you are using <%= control.ClientID %> this approach to get the names of the control.
So, I would suggest you inspect the element in the browser and copy the element ID from there.
My Scenario:
This was my control in the markup:
<asp:AsyncFileUpload CssClass="custom-file-input" ID="fileupload" runat="server" OnUploadedFileError="fileupload_UploadedFileError" OnUploadedComplete="fileupload_UploadedComplete" />
Notice, My control's ID is fileupload. And this is how I was disabling it before:
$('#<%= fileupload.ClientID %>').attr('disabled', true);
Which obviously never worked because $('#<%= fileupload.ClientID %>') this returned me the ID as #fileupload which is not correct because originally, ajaxtoolkit had modified it from #fileupload to #fileupload_ctl02 so, I had to hard code the ID in my javascript to get it working. e.g:
$('#fileupload_ctl02').attr('disabled', true); // I am using an older version of jQuery,
For newer versions of jQuery, you would disable it using the prop() method instead.
JS
document.getElementById('fileupload_ctl02').disabled = true;
Hope it helps someone.

Textbox becomes readonly on postback even when setting the readonly attribute to false manually

So, in my current application in ASP.net, I have a weird bug. Textbox that I have added in the existing page, goes in read only mode after the postback. When the page loads the first time, textbox works fine. But after page load, it stays enabled and in read only mode.
I checked Dev tools in IE, and the text box has readonly attribute set to false, as expected. I can even set the other properties from the js function called during page load, and they work fine. Only the readonly attribute doesn't work.
I am unable to figure out a reason as to why this is happening, so I am unable to solve it either.
<tr> <td nowrap align="right"> <asp:Label ID="lblResTimeDescription" runat="server" EnableViewState="False" CssClass="Common">Response Time Comments</asp:Label> : </td>
Textbox code:
> <asp:TextBox ID="txtResTimeDescription" CssClass="TextBox"
> MaxLength="200" TextMode="MultiLine" runat="server" Width="100%"
> Height="50px" ReadOnly="false"></asp:TextBox>
P.S. Do let me know, which code I can post here.
Edit: JS function called at the very end of the page load.
function fnEnableComments(e) {
var strCompletion = document.getElementById("ddlCompletion").value;
if (strCompletion == "Y") {
document.getElementById("txtResTimeDescription").disabled = false;
document.getElementById("txtResTimeDescription").setAttribute("value", "zyx");
document.getElementById("txtResTimeDescription").setAttribute("ReadOnly",false);
}
else {
document.getElementById("txtResTimeDescription").disabled = true;
document.getElementById("txtResTimeDescription").value = "";
}
}
This function gets called properly, as I can see the value change to zyx.
Edit 2:
Removed all hints of readonly from code and js. Still the same problem. Also, the textbox is getting enabled properly, on change of dropdown, gets the value set properly. I can even click on the text box to set the focus, but I just can't change the value in it.
Edit 3:
Program workflow explanation:
User select a record from the listings page and the page loads with information about that record. User can enter data, and save the same. But user can't set the completion flag to yes, without providing comments. In other cases, the comment is not needed at all. This textbox is used to add comments. Typically user updates all the data, and saves the information. After saving the information, page refreshes, and at which point user changes the completion flag. So, on dropdown change and on page load, I check for the completion flag and enable and disable the comments textbox.
This all works fine as far as logic goes. Only thing is when users saves the data first time, and page reloads, textbox stays readonly even when user changes the completion flag. If user refreshes the page again, then code works fine. Basically, this bug causes user to refresh the page, manually after every save, defeating the purpose of refreshing from the code.
attempts to place this before finalizing what you need the first time in the code behind
txtResTimeDescription.Attributes.Remove("readonly");
with this if you put readonly attribute when you take away this textbox
Finally found a solution. I still don't know why it is happening. But below code did the trick.
document.getElementById("txtResTimeDescription").setAttribute("readOnly", false);
I was using the same code earlier too, sadly with wrong capitalization of the attribute.

Keep cell color changed with checkbox on refresh

I have cells changing background color on checkbox check and I worked out how to keep the checkboxes checked on refresh (though looking back I don't think that works anymore), but I don't know how to keep the color change on refresh. I don't actually know Javascript at all and this is all from other questions but I want it to work. If I've done something completely wrong please correct me and don't assume I did it on purpose because I have absolutely no idea what I'm doing.
$(document).ready(function() {
$(".colourswitcher").click(function() {
if($(this).is(":checked")) {
$(this).closest("td").css("background","#ff3333");
}else {
$(this).closest("td").css("background","#202020");
}
});
});
$(function(){
var test = localStorage.input === 'true'? true: false;
$('input').prop('checked', test || false);
});
$('input').on('change', function() {
localStorage.input = $(this).is(':checked');
console.log($(this).is(':checked'));
});
Since you're new to javascript, I'm going to ask the dumb question: Have you included jQuery?
This code that you've pulled makes use of jQuery, a very useful library (not built-in to javascript) that has become so commonplace that people often don't even state its name when asking or answering a question involving it. But anytime you see that $ notation, you're probably dealing with jQuery.
You need to include the library file in your html file so it knows what those special symbols and syntax are:
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
If you're testing this stuff in Google Chrome, press F12 and view the developer console. You will see "undefined" errors in red when you are missing things like this.
Here's another answer assuming you have a better working knowledge than my first answer:
The first bit of your code runs when the html document has loaded and attaches an event listener to change the nearest cell background color accordingly when the checkbox is clicked. Note two things here though. 1) that behavior will be attached to all html elements with the class "colourswitcher", not just inputs. 2) that behavior assumes that what was clicked has a property "checked", which only a checkbox does.
The middle bit I presume is supposed to run once, when the page is first loaded, to get the saved state of the checkbox from localStorage. This bit could be moved into the document ready bit.
The third bit of your code attaches an event listener to every input element (not just checkboxes) such that every time one is clicked, a checked true/false state will be saved in localStorage.
localStorage is a convenient way to save information between browser refreshes. You can save anything you want, ie. localStorage.CandyCanes = 7 and that variable will be stored in the user's browser and can be recalled later. Note that your above code will only work as intended if there's a single checkbox, because you're using one slot, or one variable, in localStorage to save: localStorage.input.
That's all I'm going to elaborate on this for now. If this is more than you expected, then it's time to hunker down and learn, or get a professional involved.

Can't seem to change the h:outputText "value", or even the value expression, using JavaScript/jQuery

So here is my problem. I am trying to take the value that comes from the backend and get rid of unwanted text in the value. So basically I get a color back and there is an asterisk or two at the end of the color name. I send that value to a JavaScript function and remove any asterisks that may be present in the string. This has been working fine for me up until now. I found one other location that this was happening and when I try to do the same thing, it doesn't work. The string comes in with the asterisks, I remove them and replace the html with the new string and for a brief moment, it works, then the original string comes back.
So, here is a bit more detail. In the app I am working on, there is a link that when clicked opens a richfaces modal window. Then, there is a table that is populated with various quotes that have come in from the website. At the end of each row is a "View" link to view the details of the quote. When that is clicked, it opens another modal that has a table with each product, color, size, and other information they customer wants quoted on. In the "View" link code there is an onclick, this is where I put my function call.
<a4j:commandLink ajaxSingle="true" action="# editRequestedQuoteController.viewRequestedQuote}"
reRender="mainRequestedQuotePanel,subpanel,btnPanel,messagPanelView"
onclick="#{rich:component('viewRequestedQuotePanel')}.show(); changeColorName()">
<span>View</span>
<f:param name="orderId" value="#{order.id}"/>
</a4j:commandLink>
The changeColorName() function is called and runs the following code:
function changeColorName() {
jQuery(".managedorder-color-name").each(function(){
var existingColor = jQuery(this).text();
var newColor = existingColor.replace(/\*/g, '');
jQuery(this).text(newColor.trim(newColor));
});
}
The code newColor.trim(newColor) is just removing leading/trailing spaces from the string.
Here is the code where the string is being rendered:
<c:forEach var="orderItem" items="#{editRequestedQuoteBean.orderItems}" varStatus="status" >
...
<td rowspan="#{orderItem.logo.logoName != null ? '4' : '2'}">
<h:outputText styleClass="managedorder-color-name" value="#{orderItem.itemColor.swatchcolor}" />
</td>
...
</c:forEach>
When I debug it with FireBug, I can walk through the code and see it execute, so I know it is getting called. However I should point out here that sometimes on the first run through, the code does not seem to execute, but if I click the "veiw" link a second time then it does execute. When I step over the last line, I can see the text is replaced with the string I am sending, but then if I "continue" (F8), the string goes back to the version I started with, the one with the asterisks. Does anyone know why this might be happening? Please, anyone, let me know if this is unclear or if you need more information.
Thanks.
The changes are been overridden by the ajax rendering. The onclick is executed before the ajax request. But when the ajax request completes, then the HTML DOM tree is changed with new elements from the server side. You need to execute the changeColorName() JS function after the ajax rendering. You can use the oncomplete attribute for this.
<a4j:commandLink ... oncomplete="changeColorName()" />

Categories