Struts 2 ajax sx:div refresh not working after upgrade - ajax

I recently upgraded from Struts 2.0.11 to the latest version (2.3.15) and have found that I can not get an sx:div tag to refresh. This is the code:
<%# taglib prefix="sx" uri="/struts-dojo-tags" %>
<sx:head debug="true" />
<script language="javascript" type="text/javascript">
var controller = {
refresh : function() {}
};
dojo.event.topic.registerPublisher("/refresh", controller, "refresh");
</script>
<s:url id="URLAjaxKaptcha" namespace="%{#attr.kaptchaNamespace}" action="kaptcha"/>
<sx:div id="prosoc_kaptcha" theme="ajax" href="%{URLAjaxKaptcha}"
loadingText="<small>loading …</small>"
errorText="Security code is loading - please wait"
listenTopics="/refresh" cssClass="kaptchaDiv">
</sx:div>
<s:a href="javascript:void(0)" onclick="controller.refresh()">click to get a new image</s:a>.
Before the upgrade, when the user clicked the refresh hyperlink a new kaptcha image was returned to the sx:div. After the upgrade this doesn't work any more.
I am not getting any error messages and I can place an alert in a beforeNotifyTopics and afterNotifyTopics so I know that the refresh function is being called. I just don't get a new kaptcha image in the sx:div.
Does anyone have any ideas?

Related

Cannot print this document yet, it is still being loaded - Firefox Printer Error

My API generates dynamic HTML document and dumps it into a popup window like so:
var popup = window.open('', "_blank", 'toolbar=0,location=0,menubar=1,scrollbars=1');
popup.document.write(result);
After the document is reviewed by a user, they can print it calling
window.print();
Chrome handles it without any problems, but Firefox shows a Printer error:
"Cannot print this document yet, it is still being loaded"
Printer window opens only if I hit Ctrl+R.
It appears that $(document).ready() never happens in firefox and it keeps waiting for something to load.
Status bar in popup says Read fonts.gstatic.com
Here's a brief content of a document:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="https://fonts.googleapis.com/css?family=Orbitron|Jura|Prompt" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<title>Invoice #15001</title>
<style>
...
</style>
</head>
<body>
<div id="invoice_body" >
...
</div><!-- Invoice body -->
</body>
</html>
I have a feeling it has something to do with Google fonts. Any help is appreciated
When you pass "" as the URL to window.open, Firefox loads 'about:blank' at which point script security is likely preventing you from pulling in external resources via http or https ...
I am able to reproduce your problem and have it popup with the same error when I try to print-- I was able to get it working by using a data url when calling window.open ...
Based on your example, result is a string containing the HTML for the popup, so you would call window.open like this, and no longer use document.write for anything:
var popup = window.open("data:text/html;charset=utf-8,"+result, "printPopup", "toolbar=0,location=0,menubar=0,scrollbars=1");
I tested this with result being a string containing:
<html><head>
<link rel="stylesheet"href="https://fonts.googleapis.com/css?family=Tangerine">
<style> body { font-family: 'Tangerine', serif; font-size: 48px; } </style>
<title>Test</title></head>
<body>
<div>Testing testing</div>
<div>Print</div>
</body>
</html>
And clicking the print link worked as expected...
I had to go an extra mile, but:
I added server side code that would save a html file and pass a link to that file instead of html content:
ob_start();
include('ezts_invoice_template.php');
$dom = ob_get_clean();
$ezts_file_path = EZTS_PLUGIN_PATH.'kernel/tmp/'.session_id().'_tmp.html';
$ezts_file = fopen($ezts_file_path, 'w+');
$result = fwrite($ezts_file, $dom);
fclose($ezts_file);
print_r('{"result":"success", "file":"'.plugin_dir_url(__FILE__).'tmp/'.session_id().'_tmp.html"}');
in JS I open a popup by a link passed from PHP:
var popup = window.open(result.file, "_blank", 'toolbar=0,location=0,menubar=0,scrollbars=1');
and, finally, in template file I added event listener to request deletion of temporary file when the window is closed
window.addEventListener('beforeunload', function(event) {
window.opener.eztsApiRequest('deleteTempFile',
'',
function(result, status){ console.log(result); });
}, false);
It's not as easy, but it works great.

Grails remoteLink ajax issue populating JQuery accordion

Following the simple example from Jquery: Accordion Example
Using a remoteLink function from grails (AJAX) the information is pulled back from the controller and sent back to the GSP, which works fine. I do however want this data to be placed within a Accordion container... click here for screenshot of current functionality.
(Event Create Page rendering form template) _form - GSP:
<g:remoteLink controller="event" action="showContacts" method="GET" update="divContactList">Show Contacts!</g:remoteLink>
<div id="divContactList">
<g:render template="contactListAjax" model="[contactList: contactList]" />
</div>
<script type="text/javascript">
$(document).ready(function()
{
alert("Checking if I'm ready :)");
$( "#accordion" ).accordion({
header: 'h3',
collapsible: true
});
});
</script>
_contactListAjax - GSP Template
<div id="accordion">
<g:each in="${contactList}" status = "i" var="contact">
<h3>${contact.contactForename}</h3>
<div><p>${contact.email}</p></div>
</g:each>
</div>
Not quite sure what I'm doing wrong here, as I'm encasing the data with the div with an id accordion, yet doesn't load. Please refer to screenshot link above to see what is currently happening.
UPDATE
Event (Standard Generated CRUD, only showing where the relivant imports are) create - GSP
<link rel="stylesheet" href="${resource(dir: 'css', file: 'jquery.ui.accordion.css')}"/>
<g:javascript src="jquery-1.7.1.min.js"></g:javascript>
<g:javascript src="jquery-ui.min.js"></g:javascript>
Try replacing:
$(function() {
$( "#accordion" ).accordion({
collapsible: true
});
})
with
$( "#accordion" ).accordion({
collapsible: true
});
Edit:
You can't use an <r:script /> tag after the request is finished. The server has already laid out all of the resources. Change it to a standard javascript tag. Also the inclusion of your javascript and css files should be elsewhere on the page.
I solved this... (well Hack & Slash for now... not the best, but only viable solution for now)
var whatever is the stored HTML generated by the AJAX and placed into the divContactList on the update function. The Accordion is deleted and then rebuilt (not the best approach I realise)
var whatever = $('#divContactList').html();
$('#accordion').append(whatever)
.accordion('destroy').accordion({
collapsible: true,
active: false
});

How to Return a View from a Controller to an iFrame

I am new to MVC 3 and have come accross the following scenario:
First let me explain how I have setup my application:
All post backs to the server use jquery ajax which which return a view from the controller that either appended or prepended or replace a targeted div.
The Scenario:
I have come to a point where I would like to upload images but unfortunately because of the jquery ajax posting I cannot get the values for an html in C# Request.Files. I know there are plugins out there to help out with this but I would like to do this myself so I have created an <iframe> which i then use a bit of javascript and post the form targeted to the iframe (old classic way of doing things):
function UploadImg(SACTION) {
alert(SACTION);
validatorform.action = SACTION;
validatorform.target = "fraImage";
validatorform.method = "POST";
validatorform.submit();
}
the SACTION parameter looks like this #Url.Action("UploadFile", "Response"). This all works well as it hits the controllers action method and I can then save the image:
[HttpPost]
public ActionResult UploadFile(string ArticleID)
{
ViewBag.PreviewImage = cFileUploads.UploadFile(ArticleID, Request.Files[0]);
return View("ImagePreview");
}
I would now like to return a view to the iframe (simply to preview the image and then do a couple of other things but this is besides the point)
The View for previewing the Image:
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<form action="">
<img alt="" src="#ViewBag.PreviewImage" />
</form>
</body>
</html>
The Problem:
Unfortunately when I return the View (ImagePreview.cshtml) in C# the whole page is refreshed, all I want is for the iFrame to be refreshed. How should I return the view from the controller?
Fiqured out the problem, I had a bit of javascript that was replacing the contents of a div that the iframe was sitting in ... (slap on my forehead). All working perfectly now :)
Will leave this question here just incase ..

Ajax using <g:remoteLink> in Grails

Reading through the Grails docs (see here http://grails.org/doc/latest/guide/theWebLayer.html#ajax), I was led to believe that I could use Ajax to update a div using the following syntax:
My view (Ajax/index.gsp)
<!doctype html>
<head>
<meta name="layout" content="main"/>
</head>
<body>
<div id="error"></div>
<div id="message"></div>
<g:remoteLink action="retrievePets" update="message">Ajax magic... Click here</g:remoteLink>
</body>
</html>
My controller (AjaxController):
package genericsite
class AjaxController {
def index() { }
def retrieveMessage() {
render "Weeee! Ajax!"
}
}
However, when I select the link, it just sends me to a page with "Weeee! Ajax!" I know how to do this the typical jQuery way. This is slightly more convenient...
The default "main" layout doesn't include a javascript library by default, so if you want to use remoteLink or any of its associates you'll need to add
<r:require module="jquery"/>
or (if you're on a pre-2.0 version of Grails or not using the resources plugin)
<g:javascript library="jquery"/>
to the <head> section of your GSP.

asp.net mvc partialview #Ajax.ActionLink doesn't work

I have a view page
my view page
<div id="beReplaced">
#Ajax.ActionLink("please click on me to bring the partial view",
"PatrialViewToBeCalled",
new AjaxOptions()
{UpdateTargetId = "beReplaced",
InsertionMode = InsertionMode.InsertAfter,
HttpMethod="Get",
LoadingElementId = "prgress" })
</div>
i have a Controller
public PartialViewResult PatrialViewToBeCalled()
{
var customer = db.Customers.First();
return PartialView("PartialViewThatMustBeShow",customer);
}
but when i click on the generated link it brings me to a new page instead of
replacing or appending the partial view to the div tag.
What's the problem?
It could have been that you were missing the:
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
In the main view. This tells the main view to recognize the ajax helper.
I found the solution. The problem was due to the corrupted unobtrusive-ajax.min.js file.
If you have jQuery loaded into your page, why not use the simple jquery get / load method to get the partial view ?
<div id="beReplaced">
please click on me to bring the partial view
</div>
Javascript
$("#lnk1").click(function(){
$.get('/controller/PatrialViewToBeCalled', function(data) {
$('#beReplaced').html(data);
});
});
If you are working with ASP .NET MVC 4 make sure that
#Scripts.Render("~/bundles/jquery")
is in the end of the body tag as well.
#Scripts.Render("~/bundles/jquery")
#RenderSection("scripts", required: false)
</body>
</html>
I've just been working on it for too long, thinking it did not work. Viewing the page source didn't show anything either.
Eventually, I found out it actually did work when I saw the successful requests in the console of Firebug. It only was showing it off screen. In the HTML tab of Firebug I finally found the output, even though it does not show up in the page source.

Resources