I created a SIMILE Timeline that uses an XML file as data source which is created by a method when an aspx command is invoked.
The problem is that when the XML file is updated the Timeline isn't updated and shows the data of the first load. The data is only refreshed when I close the browser and open again the Web Application with the Timeline. Even if I go to another page of my Web Application and then come back to the page with the Timeline the data showed stills the same.
I already confirmed that the XML file is created/updated before the script that creates the Timeline be invoked and I also tried some tricks like force the PageLoad(), do a Response.Redirect() and don't use cache.
My function onLoad() is similiar to the original provided by simile-widget. Code:
<head>
...
<meta http-equiv="pragma" content="no-cache" />
<META HTTP-EQUIV="Expires" CONTENT="-1">
...
var tl;
function onLoad() {
$(document).ready(function() {
var eventSource1 = new Timeline.DefaultEventSource(0);
var theme1 = Timeline.ClassicTheme.create();
theme1.timeline_start = new Date(Date.UTC(2010, 0, 1));
theme1.timeline_stop = new Date(Date.UTC(2014, 0, 1));
var d = theme1.timeline_start;
var bandInfos = [
Timeline.createBandInfo({ ... }),
Timeline.createBandInfo({ ... })
];
bandInfos[1].syncWith = 0;
bandInfos[1].highlight = true;
// create the Timeline
tl = Timeline.create(document.getElementById("tl"), bandInfos);
var url = '.';
// references in the data
tl.loadXML("batch_data.xml", function(xml, url)
{eventSource1.loadXML(xml, url); });
tl.finishedEventLoading();
});
}
...
</head>
<body onload="onLoad();" onresize="onResize();">
<form id="form1" runat="server">
<div id="tl" runat="server">
...
</div>
</form>
</body>
Thanks!
The first clue you wrap your javascript code onLoad function. Try to create a button to update the page using the function onClick event. If you like to upgrade to a period of time you can use the JavaScript timing event.
Here is a link to a documentation of a timing event examples
I put the example this simple as posible:
setInterval(function(){alert("Hello")},3000);
and this is the sintax
window.setInterval("javascript function",milliseconds);
Related
I am currently using JxBrowser 6.19.1 and I would like to ask if it is possible to set a variable value when I first start loading a page, by using onStartLoadingFrame. Then I am going to use that data in the page.
For example:
final JFrame frame = new JFrame("Hello World!");
final Browser browser = new Browser();
BrowserView view = new BrowserView(browser);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(view, BorderLayout.CENTER);
frame.setSize(400, 300);
frame.setVisible(true);
browser.addLoadListener(new LoadAdapter() {
#Override
public void onStartLoadingFrame(StartLoadingEvent event) {
browser.executeJavaScriptAndReturnValue("var data = 1"); // does not work every single time, real question
}
});
browser.loadURL("echo.html");
where my echo.html will be something like this:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<h1>Echo Page</h1>
<script>
alert(data);
</script>
</body>
The question comes, sometimes it prompt the alert, sometimes doesn't. Does anyone know why? (Due to Multitheading?) Is that any work around for this?
Hope someone can help me with that. Thanks.
If you need to execute some JavaScript code before any other JavaScript on the loaded web page is executed, then you should use the onScriptContextCreated JavaScript context event as shown below:
browser.addScriptContextListener(new ScriptContextAdapter() {
#Override
public void onScriptContextCreated(ScriptContextEvent event) {
event.getBrowser().executeJavaScript("var data = 1");
}
});
In this case, the data JavaScript variable will be set properly, and the script on the web page will always work as expected.
I'm building a GUI extension that includes a popup that is opened on the click of a new button in the ribbon bar. The popup includes a dropdown that is dynamically populated with some information gathered from the system using the Core Service. At least that's the idea. I am able to get the button to appear, and it opens the popup, but as soon as I start with the javascript for the popup I get an error Unable to get unique id for element and the CME doesn't finish loading. Here's what I have so far:
Popup ASPX
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="SwitchUserPopup.aspx.cs" Inherits="SwitchUser.Popups.SwitchUserPopup" %>
<%# Import Namespace="Tridion.Web.UI.Core" %>
<%# Import Namespace="Tridion.Web.UI" %>
<%# Import Namespace="System.Web" %>
<!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" xmlns:c="http://www.sdltridion.com/web/ui/controls">
<head runat="server">
<title>Select User</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>Select User</h1>
<c:dropdown id="SwitchUserDropdown" runat="server" nullable="false"/>
</div>
</form>
</body>
</html>
Popup ASPX Code
namespace SwitchUser.Popups
{
[ControlResourcesDependency(new [] { typeof(Popup),
typeof(Tridion.Web.UI.Controls.Button),
typeof(Stack),
typeof(Dropdown),
typeof(List) })]
[ControlResources("SwitchUser.Resources")]
public partial class SwitchUserPopup : TridionPage
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
TridionManager tm = new TridionManager();
tm.Editor = "SwitchUser";
System.Web.UI.HtmlControls.HtmlGenericControl dep =
new System.Web.UI.HtmlControls.HtmlGenericControl("dependency");
dep.InnerText = "Tridion.Web.UI.Editors.CME";
tm.dependencies.Add(dep);
System.Web.UI.HtmlControls.HtmlGenericControl dep2 =
new System.Web.UI.HtmlControls.HtmlGenericControl("dependency");
dep2.InnerText = "Tridion.Web.UI.Editors.CME.commands";
tm.dependencies.Add(dep2);
//Add them to the Head section
this.Header.Controls.Add(tm); //At(0, tm);
}
}
}
Popup JS
Type.registerNamespace("SwitchUser.Popups");
SwitchUser.Popups.SwitchUser = function (element) {
Type.enableInterface(this, "SwitchUser.Popups.SwitchUser");
this.addInterface("Tridion.Cme.View");
};
SwitchUser.Popups.SwitchUser.prototype.initialize = function () {
$log.message("Initializing Switch User popup...");
this.callBase("Tridion.Cme.View", "initialize");
var p = this.properties;
var c = p.controls;
c.UserDropdown = $controls.getControl($("#SwitchUserDropdown"), "Tridion.Controls.Dropdown");
};
$display.registerView(SwitchUser.Popups.SwitchUser);
The extension is configured correctly in System.config - I can see the log message in the javascript console. However, I also see this Unable to get unique id for element error with the following additional information:
anonymous(object{..})
WebRequest.completed(object{..})
Net.loadFile$onComplete(object{..})
Net.loadFile$onOperationCompleted()
Xml.loadXmlDocuments$onSuccess(array1)
Xml.loadXmlDocument$onSuccess(array1)
Dropdown.setup$filesLoaded(object{..})
setupDone()
anonymous(function: DisplayController$start())
DisplayController.start()
anonymous()
anonymous(undefined, "Tridion.Controls.Dropdown")
Tridion.Assert$raiseError("Unable to get unique id for element.")
From that logged info it seems that the problem is the dropdown. If I comment out the line in my JS that registers the view then I don't get the error, but I also don't get the log message so I suspect that this is a mandatory call. Can anyone shed any light on why this might be happening? I've been using the Example PowerTool code as a reference, and I believe I've replicated what is there...
Update
I tried to step through the code - I found a suitable line and placed a breakpoint there. Then I reloaded the CME and suddenly my breakpoint was on a line that had no relevance to my code, and I couldn't find anything related to my code. However, according to the console it is still being executed.
So, instead I put log messages in my initialize method as follows:
SwitchUser.Popups.SwitchUser.prototype.initialize = function () {
$log.message("Initializing Switch User popup...");
this.callBase("Tridion.Cme.View", "initialize");
$log.message("Tridion.Cme.View callBase done");
var p = this.properties;
var c = p.controls;
$log.message("Set properties and controls");
c.UserDropdown = $controls.getControl($("#SwitchUserDropdown"), "Tridion.Controls.Dropdown");
$log.message("Got UserDropdown control");
};
I can see in the console that it logs as far as Set properties and controls and then I get the error.
I put a breakpoint in the getControl method and was able to determine why I was getting the error. $("#SwitchUserDropdown") was not finding anything so when the code below was running it threw the error:
var id = Tridion.Utils.Dom.getUniqueID(element);
if (id)
{
var control = instances[id];
if (!control)
{
control = instances[id] = new ctor(element, settings);
if (Tridion.Type.isFunction(control.initialize))
{
control.initialize();
}
}
}
else
{
Tridion.Utils.Assert.raiseError("Unable to get unique id for element.");
}
return control;
It seems obvious now that I know why it was happening that the code was running at the wrong time. I believe it shouldn't run when the CME loads, but only when the popup is opened. This leads me to look at the configuration of the resources in my Editor config file. I had previously grouped my popup's JS with other resources associated with the ribbon toolbar button. By placing the popup specific resources in their own resource group I was able to stop the error and successfully get the control.
I'm developing a Qt program that contains an OpenStreetMap application as a HTML page and this page is able to access a database -via submitting an ajax form that contains the start and end dates of queries- in order to retrieve and visualize queries on the map. I would like to move this querying process to Qt from the HTML/Javascript part. So far I managed to interact with the browser via Qt but I still have a problem that is below:
1) The fetch queries button of Qt is clicked and an alert box is supposed to pop up saying that Ajax POST is failed -the database is not on my current laptop and I should be getting the error when I click either the HTML Browser window's fetch queries button or the Qt's fetch button-
2) But also, whenever I click the Fetch queries button of the HTML Browser, it displays the POST warning but also displays extra POST warning alert boxes depending on how many times I have clicked the Qt's Fetch queries button. -for example if I have clicked the Qt's fetch queries button 5 times in a row and then clicked the HTML window's fetch button once, I get 6 POST failed messages in a row-
The HTML code is like the following:
<form id="ajaxForm" action="index.php" method="post">
Start <input type="text" name = "date1" id = "datepicker" value = "2011-07-13" style = "width:70px">
<input type="text" name = "time1" id = "timepicker1" value = "00:00" style = "width:40px">
End <input type="text" name = "date2" id = "datepicker2" value = "2011-07-13" style = "width:70px">
<input type="text" name = "time2" id = "timepicker2" value = "00:01" style = "width:40px">
The post method of AJAX form is this:
<script type="text/javascript">
$(document).ready(function(){
// ajaxForm submit
$('#ajaxForm').submit(function() {
$.ajax({
type: 'POST',
url: 'heatQuery.php',
data: $(this).serialize(),
dataType: 'json',
success: function(response)
{
// update the points for heatmap layer
updateHeatMap(response);
},
error: function(errorMsg)
{
alert('Error in Ajax POST');
}
});
return false;
});
});
</script>
And finally, the Qt code that calls the function is this:
void MainWindow::onButtonClicked() // clicking the button in order to POST
{
//the QString a is the same ajax post function as declared above
QString a = "$(document).ready(function(){$('#ajaxForm').submit(function() {$.ajax({type: 'POST',url: 'heatQuery.php',data: $(this).serialize(),dataType: 'json',success: function(response){updateHeatMap(response);},error: function(errorMsg){alert('Error in Ajax POST');}});return false;});});";
this->view->page()->mainFrame()->evaluateJavaScript(a);
}
Any ideas on what is wrong here? Thanks.
I think I have got the problem. XMLHttpRequest loads your local file successfully, but it returns 0 in request.status, thats why error() gets fired from your jQuery code.
I ran following example code in QWebView..
var request = new XMLHttpRequest();
request.open('POST', 'file:///C:/hello.txt', true);
request.onreadystatechange = function(e) {
if(request.readyState == 4)
{
// 'responseText' will not be empty if file present..
alert("response text: " + request.responseText);
alert("status: " + request.status);
}
}
request.send();
Hope this helps..
I have this code in some of my ASCX files:
<%=Html.ActionLink(Resources.Localize.Routes_WidgetsEdit, "Edit", "Widget",
new { contentType = Model.ContentType, widgetSlug = Model.Slug, modal=true},
new
{
rel = "shadowbox;height=600;width=700",
title = Resources.Localize.Routes_WidgetsEdit,
#class = "editWidget"
})%>
Take note of that rel="shadowbox..." there. This is to wire up ShadowBox Lightbox clone for this ActionLink.
This works fine when user requests a page containing this User Control thru normal browser request. But I also render/build those View User controls trough AJAX requests. For instance, I would make request to /Widget/RenderToString/... using jQuery .ajax() method and it would return HTML code for that control. This works fine and it renders the code fine. I would then insert (append) the result to a DIV in a page from where the AJAX request was made. This also works fine and the returned HTML gets appended. The only problem is - ShadowBox is not wired up. Even though the code for it gets rendered.
It seems it requires page reload (F5) every time to wire ShadowBox up. Since I am doing AJAX GET and instant append to get rid of having to make a server roundtrip, I would also want ShadowBox to wire up without doing refresh.
Can someone help me with that? Thank you
UPDATE:
Yes, I have this in my Site.Master head:
<script src="<%=Url.Content("~/Scripts/shadowbox-build-3.0rc1/shadowbox.js") %>" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
// insert functions calls here that provide some default behaviour
externalLinks();
});
Shadowbox.init({
language: "en",
players: ["img", "html", "iframe"],
onClose: function() { location.reload(true) }
});
</script>
How do I init the Shadowbox again after AJAX call?
There are many shadowbox plugins... which one are you using? (I can't give you exact code without it.) In any case I imagine you have something in your $(document).ready(function () { ... }); that tells shadowbox plungin to bind itself. You need to call that again after the AJAX call.
Just found the solution here
// call this after adding the new HTML to the page
// set up all anchor elements with a "editWidget" class to work with Shadowbox
Shadowbox.setup("a.editWidget", {});
Suppose we have the following HTML file:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test iframe download</title>
<script type="text/javascript">
var init = 0;
function download() {
document.getElementById("dload_frame").src = "http://example.com/dload.py";
}
function alert() {
if (init == 0) {
init = 1;
}
else {
document.getElementById("alert_span").innerHTML = "Got it!";
}
}
</script>
</head>
<body>
<span id="alert_span">Main content.</span><br/>
<input type="button" value="Download" id="btn" onclick="download()" />
<iframe id="dload_frame" src="http://404.com/404" onload="alert()"> </iframe>
</body>
</html>
Now, if the URL to which iframe's src is being rewritten to (in this case - "http://example.com/dload.py") returns HTML, no problem: the onload event fires, the span's contents are replaced, everybody's happy.
However, if the content type of the file returned by the URL is set to something that forces the browser to open the save file dialog, the iframe's onload event never fires.
Is there any workaround? Using iframes isn't necessary, the desired behavior is to launch a callback after the browser begins downloading the supplied file.
I have encountered the same problem as this:
Here is my work-around, please see if it works for you:
<script>
function download(){
var url = 'http://example.com/dload.py';
var htm = '<iframe src="' + url +'" onload="downloadComplete()"></iframe>';
document.getElementById('frameDiv').innerHTML = htm;
}
</script>
<div style="display:none" id="frameDiv">
</div>
<button onclick="download()">download file</button>
As far as I can remembered iframe's onload event fires only once.
Setting another value for src attribute will not cause the onload event to fire again.
I have the same problem, onLoad handler is only fire when the content change. If you download a file. If you delete HTTP header to print file content on iframe, the onload is correctly fire.
My solution after many different approaches to get this working across ff ie safari and chrome was not have a 2 step download.
the original JS request to create an iframe loads a src that would normally have loaded the pdf
However, the src now loads a page with yet another iframe inside of it, which now contains the url of the pdf.
in the html response I trigger the onload and also a catchall setTimeout funciton which calls my response on window.parent.window.handlerfunction which my onload on the top iframe would have been. The result is a PDF download and a trigger on the top level parent of the handler function that works across the browsers since it no longer relies on detecting an actual iframe load but rather relies on supported parent/child window relationships.
hope this helps someone who was also stuck
You can check iframe readyState property repeatedly after short time intervals until it gets completed.
function iframe_onload(iframe_id, js) {
var iframe = document.getElementById(iframe_id);
var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
if (iframeDoc.readyState == 'complete') {
eval(js)
return;
}
window.setTimeout('iframe_onload("' + iframe_id + '",`' + js + '`);', 100);
}
You might need help of jquery for this, for instance you can do this:
$.get('http://example.com/dload.py',{},function(result){
$('alert_span').html(result);//or some content
});