Anchors in a HTML-Object in GWT - html

I'm writing a Webpage in GWT and I use the following structure: I have a VerticalPanel as navigationmenu containing some gwt-buttons. Then I have a VerticalPanel as a contentPanel where different HTML-Pages could be loaded into (via ClientBundle).
The contentPane contains a single gwt-HTML-Object for that, in which the HTML-File is loaded.
Now I have some buttons in the navigationmenu, I'd like to use like HTML anchors in the contentPanel. Is that possible?
So when a longer HTML-File is loaded into the contentPanel and I perform a click on one of these buttons, that the page jumps to the specific anchor in the HTML-Object.
Any ideas how to realize this?

Well I think there should be two solutions:
If you use Anchor widgets or plain html anchor's in the navigation menu you can do it just like with regular html:
Navigation menu:
<a href='#myAnchor'>
If you really want to use GWT-Buttons you probably have to use Window.Location. Something like this might work tough I haven't tried it myself:
button.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
Window.Location.assign('#myAnchor');
}
});
Alternatively you could set the id of the Anchor's in your contentPanel <a id='myAnchor'> and use following function to scroll to the anchor.
Element elem = DOM.getElementById('myAnchor');
if (elem != null) {
elem.scrollIntoView();
}
I recommend the first approach.

Related

How to pass html element into rowDragText callback

I am not even sure if what I am trying to do is possible. I want to present the "floating" DOM element created when dragging a row as something more than just text. Seems like when I try to use html code as the returned value it is rendered as text rather than html:
rowDragText: function(params) {
return `<div [innerHTML]=${params.rowNode.data.RULE_NAME}></div>`;
}
This is what happens:
There is public static GHOST_TEMPLATE defined in dragAndDropService.ts.
You can try modifiying that template and perhaps also inspect the createGhost function nearby.
rowDragText probably not used with this method...

How to refresh a page and load at top after an anchor has been clicked, ignoring the anchor, and resetting back to the top?

I have a page with a few anchors. When a user clicks an anchor, the anchors work, and user is taken to the correct location.
If a user tries to refresh the page, it retains the anchor ID in the URL window and so naturally, when refreshing, it does not go back to the top of the page.
I think it would be more user friendly to go back to the top of the page on a refresh.
How would I achieve this?
My page currently is primarily using bootstrap, css, jquery, javascript, and php.
I think I need to set up some code so that after clicking the anchor, it removes the anchor from the url window, so that if someone refreshes, they'd be refreshing just the initial page state without an anchor, but I don't know how to begin. Or maybe I'm over thinking this and there's some way to always go to top of page on a refresh regardless of anchors or not. I'm not too code savvy.
Right now my code is like this...
An example of one of my anchors:
<a class="hoverlink" href="#firefighter"><li style="float:left; margin-right:1em; color:white; background-color:red" class="appao-btn nav-btn">Fire Fighter</li></a>
One of the elements for example that the anchor will jump to:
<div style="min-height:10px;" name="firefighter" id="firefighter" class="anchor"><p style="min-height: 10px;"> </p></div>
CSS style on my anchors:
.anchor:target { height:200px; display: block; margin-top:-2em; visibility: hidden;}
Actual Results With My Code: Page Refresh Stays At Anchor Location
Desired Results: Page Refresh Goes To Top Of Page
After some searching, I found a solution that almost works for me:
<script>
window.onbeforeunload = function () {
window.scrollTo(0, 0);
}
</script>
But it creates a flickering effect that doesn't look the best such as my example site at
https://graceindustries.com/gracetest/Grace%20Industries%20Website%20Design%202019%20Alternate%20Version/documentation.html
Anyone know how to remove the "flicker"?
You can try this (with the .some-anchor is the class for all a tag that points to some destinations within the page).
$('.some-anchor').click(function() {
var target = $(this).attr("href");
$('html, body').animate({
scrollTop: $("" + target).offset().top
}, 1000);
return false;
});
The "return false;" or preventDefault() event method will prevent the page from flickering. As I observed this does not make the # to the URL so refreshing is not a problem.
Other helpful answer: jQuery flicker when using animate-scrollTo
Navigating to page content using URL Fragments (#someLink) in anchor tags is a core part of the HTML specification. The standard implementation in most (if not all) web browsers is to add the fragment to the address bar. The fragment is part of the URL and therefore, when the page is refreshed the browser scrolls to the element with that ID. Most users will be familiar with this behaviour, even if they don't understand how or why it works like that. For this reason, I'd recommend not working around this behaviour.
However, if it is absolutely necessary, the only way to achieve the result you're looking for is to not use URL fragments for navigation and use JavaScript instead, therefore not putting the fragment in the URL in the first place. It looks like the Element.scrollIntoView() method might do what you're looking for. Rather than having
Click me
you'd use
<a onclick="document.getElementById('element1').scrollIntoView();">Click me</a>
or even better, implement this in an external JS file. If you experience issues due to the element not having the href attribute, you could always add an empty fragment href="#".
You can remove the id from the url right after the user click on the anchor tag
history.scrollRestoration = "manual" will set the scroll to the top of the page on refresh
<a onclick="removeAnchorFormURL()" href="#sec-2">here</a>
<script>
history.scrollRestoration = "manual";
const removeAnchorFormURL = () => {
setTimeout(() => {
window.history.replaceState({}, "", window.location.href.split("#")[0]);
}, 100);
};
</script>
window.location docs
location.href docs
location.replace docs
scrollRestoration docs (check it for info on scrollRestoration compatibility)

How do I link to mid-page content that's already inside a mid-page link?

I'm making a page that has 4 in-page tabs on it. To link to those tabs, the URL is
URL/#tab-1-tab; URL/#tab-2-tab etc
Now, in one of the tabs I want to have buttons that link to specific points on a page inside another tab, but not sure if it's actually possible to link to.
I've made the anchors on that page with
<a name="1"></a>
But I can't figure out how to link to them. I tried
URL/#tab-4-tab/#1 and URL/#tab-4-tab#1
Not sure what else to try. The links do work if I go to the tab with the anchors, then erase the tab url bit and just put in the anchor link, so instead of
URL/#tab-4-tab, I type in URL/#1
Then it jumps to the right point.
But that doesn't work if I'm on any other tab or page.
Is it possible to do this somehow?
If your using tabs to switch div CSS properties like display:none / display:block then you will need some jQuery / JavaScript to switch them based of URL no differently then your jQuery that listens for the tabs "onclick" event then shows that relative div.
First step would be to obtain a JavaScript URL reader that listens for variables or hashtag-bookmarks. Here is an example of a variable reader I have used before.
http://jsfiddle.net/googabeast/hhkuj/
function getUrlVars() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
vars[key] = value;
});
return vars;
}
//usage
var myVar = getUrlVars()["tab"];
That would make the URL format slightly different then your above posting, something more like "index.php?tab=2" / "index.php?tab=3" etc...
Next phase would be generate a switch based off the incoming URL variables to properly show the requested div.

How to capture a click event on a link inside a HTML widget in GWT?

I´m evaluating GWT as one of the alternatives to develop AJAX applications for my future projects. Untill now it is as good as it gets, but now I´m stuck looking for a way to capture a click on a tag inside HTML widget. I want to write links inside the HTML but I want to process the clicks in my application, withou reloading the page. Imagine I have the following HTML:
<p>GWT is a great tool and I think it will be my preferred tool to develop web applications. To check out my samples <a id='mylink'>click here</a></p>
I want to capture the click over the "click here" part of the text. What I´ve done so far is to try to attach the id "mylink" to some sort of clickable widget and process the click with a ClickHandler for that widget, but nothing is working.
Is there a way to do that? By the way, I know very little about Javascript.
Thank you in advance.
You can also do it like this:
Anchor.wrap(DOM.getElementById("mylink")).addClickHandler(yourClickHandler);
DOM class is com.google.gwt.user.client.DOM.
Edit after comments.
OK, the method works for elements out of GWT widgets (element comes with HTML file). If you need to generate it in GWT code then you can add link element separately. But it won't work if your content goes for instance from DB.
HTMLPanel html = new HTMLPanel("GWT is a great tool and I think it will be my preferred tool to develop web applications. To check out my samples ");`
Anchor a = new Anchor("click here");
a.addClickHandler(yourClickHandler);
html.add(a);
If it is fully dynamic I don't have an idea at this point. I was trying with HTML() widget, where you can plug your click handler, but I couldn't find a right way to determine whether the click was in A element. Strange.
The final approach (I hope)
This one should work finally. And I think this is the way it should be done, especially that it allows any structure of the HTML. The are two ways:
1. Convert links within HTMLPanel
This one will find all A elements and convert them into Anchors. It ignores href attribute, but you can add it easily :)
HTMLPanel html = new HTMLPanel("<p>Multilink example 2: <a>link1</a> and <a>link2</a></p>");
NodeList<Element> anchors = html.getElement().getElementsByTagName("a");
for ( int i = 0 ; i < anchors.getLength() ; i++ ) {
Element a = anchors.getItem(i);
Anchor link = new Anchor(a.getInnerHTML());
link.addClickHandler(...);
html.addAndReplaceElement(link, a);
}
2. Insert links into prepared spots
Just insert placeholders, where the widgets should be inserted. You could also use the addAndReplaceElement() method but with string ID.
Anchor a1 = new Anchor("a1");
a1.addClickHandler(...);
Anchor a2 = new Anchor("a2");
a2.addClickHandler(...);
HTMLPanel html = new HTMLPanel("<p>Multilink example: <span id='a1'></span> and <span id='a2'></span></p>");
html.add(a1, "a1");
html.add(a2, "a2");
Try something like this.
For your web page, you can use UiBinder:
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<g:HTMLPanel ui:field="panel">
<p>
GWT is a great tool and I think it will be my preferred tool to
develop web applications. To check out my samples
<g:Anchor ui:field="myLink" text="click here" />
</p>
</g:HTMLPanel>
</ui:UiBinder>
Notice that I've replaced your tag with an Anchor widget. There is also a Hyperlink widget, which has hooks into the history system.
The Anchor has a id of "myLink", which is used in the GWT companion to the XML file:
public class So extends Composite {
private static SoUiBinder uiBinder = GWT.create(SoUiBinder.class);
interface SoUiBinder extends UiBinder<Widget, So> {
}
#UiField
Anchor myLink;
public So() {
initWidget(uiBinder.createAndBindUi(this));
myLink.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
GWT.log("caught the click");
}
});
}
}
I've added a ClickHandler that captures and acts on the click event.
The main program is simple:
public class SOverflow implements EntryPoint {
public void onModuleLoad() {
RootLayoutPanel.get().add(new So());
}
}
Run this after and a webpage appears with the text and hyperlink. Click on it and "caught the click" appears in the console window (I'm using Eclipse).
I hope this is what you're after. If not exactly, it might at least give you some ideas of how to attack your problem.

Integrating a GWT Dialog into an existing HTML application

I have a situation where I need to integrate a gwt dialog (which to the best of my understanding is implemented as a div with z-index manipulation) into an existing html page.
There are two scenarios:
1. Which is the preferrable and more complicated is where i give the host html page another page which they embed as an iframe and I work my magic through there (maybe connect somehow to the parent window and plant my dialog I'm not sure).
2. Where I have limited access to the html page and I plant some code there which will load my dialog box.
Any ideas or thoughts on how I can implement these?
I've been working for a few months now with GWT and have found it quite nice although I have stayed far far away from the whole HTML area and until now all my work has been done strictly inside my java classes.
Thanks for any ideas and help handed
Ittai
I'll assume by dialog you mean a popup that is invisible at page load and made visible by, say, a click on something in the existing HTML. A simple strategy to make this happen is wrapping the existing HTML.
I have no experience with option 1. As for 2, all you need to alter in the existing HTML is
adding the JS import, e.g.
<script type="text/javascript" language="javascript" src="/com.your.org.Module/com.your.org.module.client.Module.nocache.js"></script>
then adding an id to some clickable element you want to activate your dialog, e.g.
<button id="launchDialog">Show Dialog</button>
and finally adding an empty div with an id to insert your dialog into the DOM.
<div id="dialog"></div>
Then all you need in your Module is
public class Module implements EntryPoint {
#Override
public void onModuleLoad() {
Button b = Button.wrap(DOM.getElementById("launchDialog"));
b.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
RootPanel panel = RootPanel.get("dialog");
Widget w = ... // your dialog widget here
panel.add(w);
}
});
}
}
Lastly, you can play with the visibility of your popup div with the "display: none" style and the show() and hide() methods on the widget.