Wicket AjaxLink javascript handler shows strange behaviour - wicket

I have a ListView that displays a list of Panels, one below the other. Every panel features a button (implemented via AjaxLink) that closes the panel and removes it from the list.
This is how the ListView is initalized and how the panels are created:
panelsList = new ArrayList<MyPanel>();
pnlContainer = new WebMarkupContainer("pnlContainer");
ListView<MyPanel> pnlItems = new ListView<MyPanel>("pnlItems", panelsList) {
#Override
protected void populateItem(final ListItem<MyPanel> item) {
item.add(item.getModelObject());
item.add(new AjaxLink<Void>("pnlClose") {
#Override
public void onClick(AjaxRequestTarget target) {
panelsList.remove(item.getModelObject());
target.add(pnlContainer); // repaint panel container
}
});
}
};
pnlContainer.setOutputMarkupId(true);
pnlContainer.add(pnlItems);
add(pnlContainer);
This works so far - the actions that trigger adding new panels (usually also AjaxLinks) do what they should and the new panel is added and displayed correctly. But I have problems getting the close button to fully work.
Please see the following steps:
1) I start the server and navigate to the main page. The ListView is initially populated with one panel.
Close-button-code of this panel:
<a wicket:id="pnlClose" id="pnlClose7" href="javascript:;">Close</a>
Searching the page code for pnlClose7 finds the following javascript code that makes the button work as expected:
Wicket.Ajax.ajax({"u":"./?0-1.IBehaviorListener.0-pnlContainer-pnlItems-0-pnlClose","e":"click","c":"pnlClose7"});;
Note: I do not press the button now, if i would, it would work as expected (thoroughly tested).
2) I trigger an action that opens a second panel. The panel is displayed below the first one as expected.
Close-button of the first panel:
<a wicket:id="pnlClose" id="pnlClosef" href="javascript:;">X</i></a>
Close-button of the second panel:
<a wicket:id="pnlClose" id="pnlClose10" href="javascript:;">X</i></a>
But now, neither searching for pnlClosef nor pnlClose10 finds some javascript code. The buttons (both!) do not work. I can still find the javascript code for pnlClose7.
3) I reload the page via pressing F5.
The button IDs change to pnlClose1a and pnlClose1b. Both IDs have javascript counterparts and work.
4) I press the first button (upper panel, ID pnlClose1a). The panel is closed as expected.
The remaining button's ID changes to pnlClose1c, again without a javascript counterpart. Javascript code for pnlClose1a and pnlClose1b is still present.
To make a long story short, the javascript handlers for my AjaxLinks seem to have shyness issues and only appear after I press F5 or reload the whole page in any other manner. I guess thats because repainting the pnlContainer changes the IDs of the current panels - but why is the linked javascript not updated at the same time? Is there anything I can change in my code to update the whole page without completely reloading it?
Wierd thing is that I am pretty sure this worked before... But I checked the whole class history and can't find any major change that would have triggered that. The ListView-code is mainly static since I added it.

I was had similiar problem. if you have any hardcoded javascript code in your page or panels html file (using <script> tag) remove it and set that js code in renderHead of your panel.

Related

GWT: Opening new mail window without browser tab opened

I am trying to open an email client just like using mail me tag.
But I want to use my custom widget, which is not hyperlink, anchor or so. I added a DOM handler to my widget to listen to clicks:
public class VContactWidget extends VHorizontalLayout implements ClickHandler {
private HandlerRegistration clickHandler;
public VContactWidget() {
// added some content here
clickHandler = addDomHandler(this, ClickEvent.getType());
}
#Override
public void onClick(ClickEvent event) {
Window.open("mailto:john.doe#mail.com", "_blank", "");
}
}
Everything is working fine except one detail: When the widget is clicked, new empty browser tab will open with url set to mailto:john.doe#mail.com. I don't want the new tab opened. Can I avoid it somehow?
Note I set _blank parameter, as used in many examples. I also tried to use empty string or some other values as well. I looked into documentation, but didn't find anything useful.
https://developer.mozilla.org/en-US/docs/Web/API/window.open
One solution may be to use Anchor, but my component is more complex, not just single <a> link.
Another detail to note may be application server - I am using Tomcat 7 now.
Trying to fire native event on hidden Anchor programatically did not work for me. (Which does not mean it cannot be done.)
This is, how I actually solved my problem: Instead of Window.open(), I used following call:
public void onClick(ClickEvent event) {
Window.Location.assign("mailto:john.doe#mail.com");
}
This is not something that you can control. Whether this link opens in a new tab or a new window depends on the browser settings and user preferences.
I don't think it will make a difference if you use an Anchor or Window.open. In either case, the behavior may be different in different browsers. Also remember that for some users a click on this link will open Outlook or Mail, while for other users it will open Gmail in a browser window.
UPDATE:
If you want an exact behavior of an <a> element, create a hidden anchor element and fire a click on it when a user clicks on your composite widget.
Firing click event from code in gwt

Google Closure add onclick to button after adding this button with custom editor plugin

I am making a custom plugin for the editor provided by Google Closure. The plugin makes it able to add a button.
I am having problems by setting an onclick on the button, the other values are nicely set.
button.innerHTML = event.label;
button.className = event.initialClass;
var extraClasses = event.extraClasses;
if (extraClasses)
{
button.className += ' ' + extraClasses
}
button.onclick = function() { event.onclick };
Does anyone know what I am doing wrong and how I can fix this?
After creating a button it is added to the editors SeamlessField. A second problem that I currently have is that after creating the button, my pointer is inside the button and I can't seem to get it out of there.
I've got the follow piece of code for handling this at the moment. The var button is the created button. button contains: <button class="orange">test</button>
// We want to insert the button in place of the user's selection.
// So we restore it first, and then use it for insertion.
this.restoreOriginalSelection();
var range = this.fieldObject.getRange();
button = range.replaceContentsWithNode(button);
// Done making changes, notify the editor.
this.fieldObject.dispatchChange();
// Put the user's selection right after the newly inserted button.
goog.editor.range.placeCursorNextTo(button, false);
// Dispatch selection change event because we just moved the selection.
this.fieldObject.dispatchSelectionChangeEvent();
Any ideas about how I could fix this second problem aswell?
For the first, it does not look like you have begun using Google Closure event code. Wiring up the button to the 'click' event in Google Closure would be as follows:
goog.events.listen(button, goog.events.EventType.CLICK, event.onclick)
You should also be investigating the goog.dom and goog.dom.classes namespaces if you'd like to use Google Closure's wrappers around standard CSS class and text DOM manipulation.
For the second, were you testing in Chrome? If so, you might have ran into a range issue in Webkit, documented within the Closure code itself:
https://code.google.com/p/closure-library/source/browse/closure/goog/editor/range.js#174
I have gotten around this in the past by inserting an empty <span> element as a sibling after the offending element (the button, in your case), and placing the cursor next to the <span> instead. However, there's nothing stopping the user from moving the cursor back inside your button. You'll have to add more logic to prevent a user from placing the cursor within the button's text.

"Send" button popup not appearing correctly

I'm using the Facebook Like/Send buttons along with dynamically generated HTML (loaded via AJAX requests). I've found that even though the Send button works fine when the element exists on page load, dynamically created Send buttons aren't working correctly. Clicking the button activates it and the button greys out, but the popup doesn't appear.
Here is a demonstration of what is happening: http://jsfiddle.net/Daniel15/VxpSj/
Any suggestions?
Thanks!
Yes, I can confirm the problem from your fiddle.
function addLikeButton()
{
// […]
FB.XFBML.parse(newEl);
document.getElementById('container').appendChild(newEl);
}
For some reason, this seems to be “the wrong way around”. Reverse the order of these two lines – put the new element into the DOM first and let FB.XFBML.parse parse it afterwards, then (from my test with your fiddle) it seems to work in the desired way.

How to create a "New xxx" popup?

I have a Grid object and added a [ (+) New Client ] button which I'd like to open a popup form to create the new client with a couple fields.
I've looked at the code examples in the website but haven't found how to do it (sorry if I've missed something).
This is the current page code:
function page_clients_listing($p){
$g = $p->add('Grid');
$g->addColumn('text','first_name');
$g->addColumn('text','last_name');
$g->addColumn('inline','telephone');
$g->addColumn('expander','comments');
$g->setSource('client');
$g->addButton('With Icon')->set('Add New Client')->setIcon('Plus');
}
Thanks in advance!
You can either create a popup or a dialog. Dialog is based on jQuery UI dialog implementation. Popups are likely to be blocked and are harder to control.
This is actually working for any object (you can apply to view, button, image, icon, etc), but I'll use button).
$b=$g->addButton('Add New Client')->setIcon('Plus');
$b->js('click')->univ()->frameURL($title,$url);
// OR
$b->js('click')->univ()->dialogURL($title,$url);
$url would most likely be returned by api->getDestinationURL(). The other page would be loaded and scripts on that page will be evaluated. Let's say you are on other page and now need to close the window.
$result = $this->addButton('Close')->js('click')->univ()->closeDialog();
closeDialog() returns a jQuery chain object pointing to a view which originally opened the frame. As a result if you do $result->hide(); then after dialog is closed, the original button ('add new client') will also be hidden.
Here is example to show some additional things you can do with frames, reloading and custom event handlers:
http://agiletoolkit.org/example/refresh1

AutoCompleteExtender positioning menu incorrectly when scrolled

We have an AutoCompleteExtender linked to a TextBox. Both controls are placed inside an UpdatePanel, and the UpdatePanel is displayed as a pop-up dialog using a Javascript library (Ext.BasicDialog).
The pop-up is a div on the page, not a separate window.
The problem is that when the user scrolls inside the pop-up, the AutoCompleteExtender shows its menu in the wrong place. It looks like it is taking the visible distance from the top of the popup and positioning the menu from the top of the inner html of the popup (which is not visible)
We are using Version 1.0.20229.20821 of the AjaxControlToolkit, and we are targetting ASP.NET Framework vewrsion 2.0.
I have tried to fix the menu by attaching the following Javascript to the OnClientShown event, but it pretty much does the same thing:
function resetPosition(object, args) {
var tb = object._element; // tb is the associated textbox.
var offset = $('#' + tb.id).offset();
var ex = object._completionListElement;
if (ex) {
$('#' + ex.id).offset(offset);
}
}
I fixed this by setting position:relative on a div containing the TextBox and the auto-complete extender. The extender must have been using the wrong element to position on when inside the popup panel.
Add an empty <div id="AutoCompleteContainer"></div> element right after the AutoCompleteExtender. In AutoCompleteExtender, add an attribute pointing to this container, CompletionListElementID="AutoCompleteContainer". The list items should be contained in that div then.
I know this is an old post, but thought this information may help someone else. There is a newer version 15.x of the Ajaxtoolkit now (April 2015) and it fixes this issue. From my reading the CompletionListElementID property was deprecated some time ago, and at the least seems to behave differently in different versions. I upgraded my references to the 15.x version and it just started working as needed.