I have read that to Log Out of the application you need to close the window and I found this code:
This answer has what you are looking for:
How to run JavaScript function from GWT Java with JSNI?
Specifically in Java:
myButton.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event) {
closeWindow();
};
});
public static native void closeWindow() /*-{ $wnd.closeWindow();}-*/;
Then in JavaScript in your app's .html page:
<script type="text/javascript" language="javascript">
function closeWindow() {
window.open('','_self','');
window.close();
}</script>
I have implemented this in my application by:
//Log Out Button
Button logOutButton = new Button("Log Out");
logOutButton.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event) {
closeWindow();
}
});
public static native void closeWindow() /*-{ $wnd.closeWindow();}-*/;
And the HTML:
<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!-- -->
<!-- Consider inlining CSS to reduce the number of requested files -->
<!-- -->
<!-- <link type="text/css" rel="stylesheet" href="org.AwardTracker.AwardTracker.AwardTracker.css"> -->
<!-- -->
<!-- Any title is fine -->
<!-- -->
<title>Wrapper HTML for AwardTracker</title>
<!-- -->
<!-- This script loads your compiled module. -->
<!-- If you add any GWT meta tags, they must -->
<!-- be added before this line. -->
<!-- -->
<!-- script language="javascript" src="org.AwardTracker.AwardTracker/org.AwardTracker.AwardTracker.nocache.js" --><!-- /script -->
<script src="org.AwardTracker.AwardTracker/org.AwardTracker.AwardTracker.nocache.js">
<type="text/javascript">
function closeWindow() {
window.open('','_self','');
window.close();
}
</script>
</head>
<!-- -->
<!-- The body can have arbitrary html, or -->
<!-- we leave the body empty because we want -->
<!-- to create a completely dynamic ui -->
<!-- -->
<body>
<!-- OPTIONAL: include this if you want history support -->
<iframe id="__gwt_historyFrame" style="width:0;height:0;border:0"></iframe>
</body>
</html>
However, I get the following error on the lines:
closeWindow();
"The method closeWindow() is undefined for the type new ClickHandler(){}"
public static native void closeWindow() /*-{ $wnd.closeWindow();}-*/;
Multiple markers at this line
- Syntax error, insert "EnumBody" to complete BlockStatement
- Syntax error on token "void", # expected
- Syntax error, insert "enum Identifier" to complete
EnumHeaderName
Thank you to all who responded. Based on your responses...
I am using sessions like (via RemoteServiceServlet) in my app. Therefore, as per below in the responses, I need to invalidate session first followed by removal of element from dom. So tried the following:
On the client side:
logOutButton.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event) {
//Invalidate the session and then reload the application.
AsyncCallback<Void> callback = new InvalidateSessionHandler<Void>(SelectPersonView.this);
rpc.invalidateSession(callback);
}
});
class InvalidateSessionHandler<T> implements AsyncCallback<Void> {
SelectPersonView view;
public InvalidateSessionHandler(SelectPersonView view) {
this.view = view;
}
public void onFailure(Throwable ex) {
System.out.println("RPC call failed - InvalidateSessionHandler - Notify Administrator.");
Window.alert("Connection failed - please retry.");
}
public void onSuccess(Void result) {
//Reload the application.
Window.Location.assign("/");
}
}
On the server side:
public void invalidateSession() {
getThreadLocalRequest().getSession().invalidate(); // kill session
}
This seems to work. However, I am having trouble testing more than one session locally and I do not have a test server I can deploy to. So can I please ask for someone who knows what they are doing in this space to check it to ensure I am not introducing issues into production. My greatest concern is that this will log everyone out. I am particularly toey because I had a situation where sessions were not compartmentalised and users could see other people's data. This has been fixed and I do not want to break that fix!!
You cannot close a window using JavaScript if the window was opened by a user. You can only close a new window that was opened by your app.
Closing window will have no effect on user authentication as most authentication mechanisms rely on server sessions or cookies.
If your authentication is session-based, when a user clicks on the Log Out button you need to (1) invalidate user's session, and (2) reload your app, which will display default entry point for non-authenticated users (home page or login page).
Javascript can only close the page if it is opened by same script. So closeWindow() won't even work. So :
If you are not using sessions in your app i.e. you think that only closing the window is a goal to achieve. Then simply delete that iframe from DOM rather closing page. (You can do that by using js.)
document.getElementById('iframeid').innerHTML = '';
If you are using sessions like (via RemoteServiceServlet) in your app, then you need to invalidate session first followed by removal of element from dom. (For this i am not sure how to do.)
Or
Instead of removal, you can just reload the iframe (which is considered to be as a reload of your app):
document.getElementById('iframeid').src =
document.getElementById('iframeid').src
This is the final code I used:
I am using sessions (via RemoteServiceServlet) in my app. Therefore I need to invalidate the session first followed by removal of element from dom. So the following is the final code:
On the client side:
logOutButton.addClickHandler(new ClickHandler(){
public void onClick(ClickEvent event) {
//Invalidate the session and then reload the application.
AsyncCallback<Void> callback = new InvalidateSessionHandler<Void>(SelectPersonView.this);
rpc.invalidateSession(callback);
}
});
class InvalidateSessionHandler<T> implements AsyncCallback<Void> {
SelectPersonView view;
public InvalidateSessionHandler(SelectPersonView view) {
this.view = view;
}
public void onFailure(Throwable ex) {
System.out.println("RPC call failed - InvalidateSessionHandler - Notify Administrator.");
Window.alert("Connection failed - please retry.");
}
public void onSuccess(Void result) {
//Reload the application.
Window.Location.assign("/");
}
}
On the server side:
public void invalidateSession() {
getThreadLocalRequest().getSession().invalidate(); // kill session
}
getThreadLocalRequest().getSession().invalidate(); returns me to my login window.
Window.Location.assign("/"); returns me to the tomcat page.
So use which ever suits you.
Related
Im am currenlty working on a integration of a nps widget within a Chatbot. I cannot show you all the code, but i imported the html file inside the chat.ts file. I want to call the entire html file after a button press from the chatbot. I have tried a lot, but nothing seems to help.
this is the chat.ts code (small part of it)
private showAskNicely() {
// #ts-ignore
window.location.assign('npshtml.html');
}
private askNicelyButton() {
const el = document.getElementById('detractbut');
el.addEventListener('click', this.showAskNicely);
}
this is the npshtml file
<html>
<body id="try">
<p>
AskNicely Web Survey Popup Example for traditional websites.<br>
Running in 'force' mode.<br>
Responses will be recorded.
</p>
<script type="text/javascript" src="https://static.asknice.ly/dist/standalone/asknicely-in-app-conversation.js"></script>
<link href="https://static.asknice.ly/dist/standalone/asknicely-in-app-conversation.css" rel="stylesheet" type="text/css" charset="utf-8">
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function () {
askNicelyConversation({
config: {
--- cannot show this part ---
},
customData: {
a_custom_property: 'business', // Optional - Send extra data about this customer for reporting and leaderboards
another_custom_property: 'New York' // Optional - Send extra data about this customer for reporting and leaderboards
}
});
});
</script>
</body>
</html>
I also have the button rendered inside another html file with css, but that all works fine.
I have it currently on windows.location.assign, so that it opens a new page. It would be ideal if the script could be triggered without opening a new page.
Using jquery.load does not work and does not give me a error of some sort.
I have modified the Map Route in my Dot Net Core application that for every request goes to one controller, so not lots of controller or Action Result is needed for each page that we build.
greedy Routing
routes.MapRoute("", "/{*article}",
defaults: new { controller = "Pages", action = "Killme" });
In Page Controller build an object that has list of CSS and JavaScript locations, this object is being passed to Page view
public IActionResult Killme()
{
var PageInfo = GetPage_Data();
ViewBag.PageInfo = t;
return View("Pages");
}
and i have tried to pass this information as model or view bag to Page view.
in the Page view i try to build the JavaScript and CSS dynamically based on the model like
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
#{
RootObject PageInfo = ViewBag.PageInfo;
foreach (var JavaScript in PageInfo.js)
{
var JSsrc = JavaScript.src;
<script type="text/javascript" src="#JSsrc ">
</script>
}
<script type="text/javascript" src=""></script>
</head>
<body>
</body>
</html>
Now the Issue is when i build the JavaScript the controller is called 2 times and the page is being rendered 2 times, when i comment the
<script type="text/javascript" src="#JSsrc ">
</script>
the page controller will get called once,
any help regarding why this happening and what am i doing wrong would be appreciated
The reason for this behavior is that the staticFileHandler is either not configured or is not able to find your Javascript file and passes the request further down the pipeline. The MVC handler captures all requests (because of your route) and returns therefore the same page again.
First check that your startup class uses the staticFileHandler before the mvcHandler, so something like this:
public class Startup
{
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseStaticFiles();
..
app.UseMvc();
}
}
Secondly make sure that your Javascript is placed inside the wwwroot and uses the correct path.So a file like wwwroot/js/mysite.js should a script tag like:
<script src="/js/mysite.js"></script>
These improvements should resolve your issue.
I am following this example to include a SkyScanner widget on my website:
http://business.skyscanner.net/portal/en-GB/Documentation/Widgets
For some reason I just get an empty div - could this be something to do with the key? When I clicked on the activation link I got from SkyScanner for the widget key, I got a page saying the following:
Description: An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed remotely (for security reasons). It could, however, be viewed by browsers running on the local server machine.
Details: To enable the details of this specific error message to be
viewable on remote machines, please create a tag within
a "web.config" configuration file located in the root directory of the
current web application. This tag should then have its
"mode" attribute set to "Off".
I have created a web.config file with the following code:
<!-- Web.Config Configuration File -->
<configuration>
<system.web>
<customErrors mode="Off"/>
</system.web>
</configuration>
I've had a look at 'inspect element' on Chrome and get the error
Uncaught TypeError: Object # has no method 'write'
api.ashx?key=[KEY]:1
This is the JS:
var API_KEY = 'b7290ac3-1f9f-4575-88a7-89fed0c61f7f',
MAIN_URL = 'http://api.skyscanner.net/api.ashx?key=' + API_KEY;
function main(){
console.log('loaded module');
var snippet = new skyscanner.snippets.SearchPanelControl();
snippet.setCurrency('GBP');
snippet.setDeparture('uk');
snippet.draw(document.getElementById('snippet_searchpanel'));
};
function newWrite(str) {
$(str).appendTo('body');
}
var oldWrite = document.write;
document.write = newWrite;
function onMainSkyscannerScriptLoad(e) {
console.log('loaded main script');
skyscanner.loadAndWait('snippets', '1', {'nocss' : true}, main);
}
$('button').click(function() {
console.log('getting main script');
$.getScript(MAIN_URL, onMainSkyscannerScriptLoad);
});
I also used this to personalise the widget:
skyscanner.load("snippets","2");
function main(){
var snippet = new skyscanner.snippets.SearchPanelControl();
snippet.setShape("box300x250");
snippet.setCulture("en-GB");
snippet.setCurrency("USD");
snippet.setColourScheme("classicbluelight");
snippet.setProduct("flights","1");
snippet.setProduct("hotels","2");
snippet.setProduct("carhire","3");
snippet.draw(document.getElementById("snippet_searchpanel"));
}
skyscanner.setOnLoadCallback(main);
Skyscanner B2B support engineer here. Are you still having trouble with this?
For the quickest response, please contact us here: http://business.skyscanner.net/portal/en-GB/Home/Contact
The first thing to check is that the file is on a web server (localhost is fine), and not loaded from the desktop (or local disk in general). This is because some of the Skyscanner JS code looks up other files using URLs like //api.skyscanner.net. In other words, saving the file to the desktop and opening it from there will not work (will show as an empty div). Here's the most basic example of drawing a widget. Can you try putting this in a file and accessing it through a server? If it works we can build on it :)
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" >
<head>
<script type="text/javascript" src="//api.skyscanner.net/api.ashx?key=b7290ac3-1f9f-4575-88a7-89fed0c61f7f"></script>
<script type="text/javascript">
skyscanner.load("snippets","2");
function main(){
var snippet = new skyscanner.snippets.SearchPanelControl();
snippet.setShape("box300x250");
snippet.setCulture("en-GB");
snippet.setCurrency("USD");
snippet.setProduct("flights","1");
snippet.setProduct("hotels","2");
snippet.setProduct("carhire","3");
snippet.draw(document.getElementById("snippet_searchpanel"));
}
skyscanner.setOnLoadCallback(main);
</script>
</head>
<body>
<div id="snippet_searchpanel" style="width: auto; height:auto;"></div>
</body>
</html>
I have a site where 6 css files are linked, But in a page i need to use only 3 css files. My developers are using master page in .net, so they don't want to change that. So, my question is: Is there any way I can skip few css files which is linked?
It is not very 'elegant' but you can use a jQuery script to manipulate and remove the link:
<script type="text/javascript">
$(document).ready(function () {
$("link[type='text/css']").remove();
});
</script>
You can use jQuery selector to refine the search. I.e.
$("link[href='Styles/Site.css']").remove();
Another solution (doesn't need jQuery) is adding a configuration property to the master page like this:
Site.Master.cs
private bool _IncludeOtherCss = true;
public bool IncludeOtherCss {
get { return _IncludeOtherCss; }
set { _IncludeOtherCss = value; }
}
Site.Master (head section)
<%if (IncludeOtherCss)
{ %>
<link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
<%} %>
Other page:
protected void Page_Init(object sender, EventArgs e)
{
(Master as SiteMaster).IncludeOtherCss = false;
}
we are running a click-to-call service, my idea is basically like this: website have a link on their page, when the link is clicked, a web page(say it is popup.aspx) hosted on our server is popup, user can input their phone number, and click "call me" button to let the website call him. In the button click event, I want to get Request.UrlReferrer, then query the db to get website's phone. But in IE, Request.UrlReferrer is null(firefox is ok, not test chrome yet),my question is how to get opening window' url in IE?
we put popup.aspx on our server because
our client website is not force to use asp.net.
we have the control what we put on the popup window, and can modify the page just from our side, if we put the pop window on our partner's side, if we have 100 partner, and we change the page's design, we will notify everyone of them to change this, change that...
we can implement a statics system to know how popup a day, which site is most popular,etc
Did you try window.opener.location.href (in javascript)?
You could also call a pageMethod in javascript with the opener to get back your CSS from your (server side query) and apply it to your page in javascript.
Link
Popup.aspx
<form id="form1" runat="server">
<asp:ScriptManager EnablePageMethods="true" runat="server"></asp:ScriptManager>
<div>
<script>
function call() {
var location = window.opener.location.href;
PageMethods.GetPhoneNumber(location, clientcall);
}
function clientcall(phone){
alert(phone);
}
</script>
Call
</div>
</form>
Popup.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Services;
public partial class Popup : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
[WebMethod]
public static string GetPhoneNumber(string referer)
{
// Put your code to call your database here
return "888-888-888";
}
}
Calling page
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<script>
function opening() {
window.open("Popup.aspx","mywindow", "status=1,toolbar=1");
}
</script>
Ouvrir
</body>
</html>