In my ASP.NET app using the crystal report viewer (ver 13.0.2000.0), when the user clicks "Print" and then either prints or cancels out of printing, when they next Drill Down in the report it will hang forever with the crystal dialog "Please wait while the document is being processed" with spinning triangle circle animation.
It does this in IE and Firefox, but it does NOT do this in Chrome: Instead the print button launches the PDF export with the "The viewer must export to PDF to print." messaging. This is what older versions of crystal did.
Right now I'm going down the road of forcing IE and Firefox to do the same thing as chrome - but if there's a real solution to the print problem - I'd rather use that. It seems when a user clicks Print (vs. export) they want to print (vs. export).
I came up with a work around for this. Since Crystal Reports does not allow overriding the buttons I ended up hiding the print button and adding my own print button using JavaScript/jQuery.
Here is some under-the-hood info on how the printing works. When you press the print button it does a postback with the view states and event arguments. The post back returns a PDF file which the browser opens inline. The PDF file is embedded with a print command which is executed when the file is opened.
So what we can do is use a hidden IFRAME to load the printable PDF. This way the main page is not affected. I think the PDF loading inline is what causes the page/browser to corrupt its state.
Place the below code at the top of your ASPX page. You must place it at the top of the page otherwise the print dialog will be off the screen if you put it at the bottom.
Here is the HTML:
<iframe id="HiddenFrame" name="HiddenFrame" style="display: none;"></iframe>
<form id="PrintForm" action="MyPage.aspx" method="post" target="HiddenFrame">
<!-- Change the name if your object is not named 'CrystalReportViewer1' -->
<input type="hidden" name="__CRYSTALSTATECrystalReportViewer1" id="CRState" />
<input type="hidden" name="__VIEWSTATE" id="VState" />
<!-- Change this value to match your CrystalReportViewer object's name. -->
<input type="hidden" name="__EVENTTARGET" value="CrystalReportViewer1" />
<!-- This is the print command that is sent. -->
<input type="hidden" name="__EVENTARGUMENT" value='{"text":"PDF", "range":"false", "tb":"crpdfprint"}' />
</form>
As mentioned above, the IFRAME will load our PDF. The form is used to do a POST to the server with the view states and event arguments. The target attribute tells the form to load in the IFRAME.
Here is the JavaScript:
// Hide the print button.
$('#CrystalReportViewer1_toptoolbar_print').hide();
// Inject our own print button. You can apply the same icon to your print button using CSS to make it look like the original icon.
$('#CrystalReportViewer1_toptoolbar_print').parent().append('<div id="PrintButtonOverride"></div>');
// When user clicks our print button, copy the states and submit the form.
$('#PrintButtonOverride').click(function () {
$('#CRState').val($('#__CRYSTALSTATECrystalReportViewer1').val());
$('#VState').val($('#__VIEWSTATE').val());
$('#PrintForm').submit();
});
The click event copies the two view states from the main page and then submits the form. I wrote this post quickly so I apologize if I left something unclear.
Related
We're creating a HTA file so withe the information the user has input, we can automate the process of logging a ticket. The user will input the information in the HTA form and click Submit. This will then open a link in IE, input the data from the HTA to the relevant fields and then automatically click the Submit button at the end of the page.
The majority of it works so far but I'm unable to automate the Submit action. I've checked various forums but haven't been able to get this working with any suggestions so far. I'm just looking for a way to automate clicking the submit button in the IE window.
There are 3 buttons on the IE page and I'm not sure how to specify I want to click submit.
New to VBScript so any help is much appreciated.
<input value="Reset" onclick="return myReset();" class="secondary" type="button">
<input value="Add to a Bundle" onclick="return myAddRequisition();" class="secondary" name="submitorderform" type="submit">
<input value="Submit " onclick="return myOrderNow();" class="primary" name="submitorderform" type="submit">
I think the code that you posted is kind of weird, since it has two buttons with the same name.
I assume that the webpage in IE to which the information is to be sent contains only one form.
I also assume that an instance of IE automation object is stored in IE variable.
After you filled out the form via your HTA programmatically, if you want to simulate a click on the button "Add to bundle" , use the code below:
var frm = IE.document.forms[0];
for (var i = 0;i < frm.elements.length;i++)
if (frm.elements[i].type == "submit" && frm.elements[i].value == "Add to a Bundle")
frm.elements[i].click();
Or, if you want to click on the button "Submit ", you can use the code above, but be sure to replace "Add to a Bundle" with "Submit ".
Edit: In VBScript, you can use the code below:
Dim frm, i
Set frm = IE.document.forms.item(0)
For i = 0 to frm.elements.length - 1
If frm.elements.item(i).value = "Add to a Bundle" And frm.elements.item(i).type = "submit" Then
frm.elements.item(i).click
End If
Next
Edit 2: According to your comments, i guess you don't wait for your webpage until it is completely loaded. Thus, you get an Unspecified Error. To solve this problem, you should set an interval to repeatedly check if IE.ReadyState equals 4. To do so, use the code below after calling Navigate method of IE:
Dim interval
interval = window.setInterval(GetRef("fillOutForm"), 1000)
Sub fillOutForm()
If IE.ReadyState = 4 Then
window.clearInterval interval
'Here place code that fills out the form in the webpage and submits it.
End If
End Sub
As you can see, you should call setInterval method and set the first parameter to a function pointer. Use the GetRef function to obtain a function pointer. In the code that I sent, I passed a pointer to the subroutine fillOutForm. So this subroutine will be called every 1 second. In this subroutine, you check if IE.ReadyState equals 4 then you fill out the form and submit it.
I am building an advanced search form, and upon submit of criteria it brings back search results.
I wanted to implement a page loader for this, so on submit it then triggers the loading of the page
This tutorial works for the page itself
https://www.w3schools.com/howto/howto_css_loader.asp
Can anyone help me make this work when the submit button is clicked instead?
You can use JavaScript to show your loader when your submit button is clicked by adding at to the button directly
<input type="submit" onclick="document.getElementById(ID_OF_YOUR_LOADER).style.display='initial';">
or in a separate script-Tag:
<script>
document.getElementById(ID_OF_YOUR_SUBIMT_BUTTON).onclick=function(){
document.getElementById(ID_OF_YOUR_LOADER).style.display='initial';
}
</script>
Your loader would look like this:
<div id="ID_OF_YOUR_LOADER" class="loader" style="display:none"></div>
Let's say we have a classic form - a few input fields that must meet some pattern. When user enters incorrect data and submits this form all the fields that are filled wrong are marked as invalid and appropriate error message is provided for every incorrect field.
I need to make this form WAI ARIA compliant, so that after form submission the accessibility tools will see these errors first.
I've found solution that implements it by dynamic html modification using JS (http://jsfiddle.net/nS3TU/1/):
HTML:
<form id="signup" method="post" action="">
<p id="errors" role="alert" aria-live="assertive"></p>
<p>
<label for="first">First Name (required)</label>
<input type="text" id="first">
</p>
<p>
<input type="submit" id="button" value="Submit">
</p>
</form>
JS:
$('#signup').submit(function () {
$('#errors').html('');
if ($('#first').val() === '') {
$('#errors').append('Please enter your first name.');
}
return false;
});
Here validation does not reload page, and the "alert" area is dynamically modified.
In my case the page is reloaded on validation phase, and I don't know how to make aria alert work. After hours of investigation I didn't find any solution at all. Any ideas?
I think there's a simple solution, but you'll have to say if it covers your cases.
I would be careful about making something "WAI-ARIA compliant", that should not be a goal in itself. WAI-ARIA is intended to map web pages to application roles, but only applications are actually suitable for this treatment.
For a classic web-form, you do not need WAI-ARIA at all. The alert aspect would not work if the page reloads, as it would only alert if the content changed dynamically.
If the page does not reload (as per the example), you would want to ensure that submitting the form doesn't just leave the user sitting on the button. You can manage the focus to achieve this:
$('#errors').append('Please enter your first name.');
// Make the error message focusable, but not in the default tab-order:
$('#errors').attr('tabindex', '-1').css('outline', '0');
// Set the focus on the (first) error message:
$('#errors').focus();
JSFiddle updated here.
A couple of articles on error-message best-practices your question reminded me of, which would help extend this answer to other use-cases:
Displaying error messages
Accessible form validation.
I have a create view where the user and fill some data and if they click on a button a dijit.dialog opens with a list of items to select. Everything works fine, except that when the dialog confirms the selected items it goes to the controller to do some logic and refreshes the create view deleting the data that the user filled previously.
How can I make the dialog persist what the user already filled (maybe going to the controller to set the data before opening it)? Or maybe try to close the dialog, refresh the list that I show on the dialog and part of the create view that uses what the user selected.
Not sure if I make myself clear enough.
Edit
My project is based on Spring Roo:
<form:create .....>
.. inputs and tables ..
<input type="button" ../> //goes to controller and loads page with dialog open
<tiles:insertTemplate template="/WEB-INF/views/dialog.jspx" />
</form>
Dialog code:
<div id="dialog" dojoType="dijit.Dialog">
<form id="items" dojoType="dijit.form.Form">
<jsp:doBody/>
<input id="save" type="submit" name="sendDialogData">
</form>
</div>
I thought that would make the dialog part of the form but just checked with firebug and it is created after the "wrapper" (the div that contains everything)
I have a dev express calendar . Now, the requirement is that i need to print a particular record. But the problem is that, the record details open in a pop up and i need to print only the popup page. But when i used print on the page it printed the whole page i.e. the pop up and side stuff on the main page.
This is what i did:
<input type="button" value="Print Form" onclick="window.print()" />
So, can u let me know what i need to do to print only the pop up. (excluding page stuff)