Average time on page is 0 even after adding another event - gwt

I understand that in Google Analytics, if the user just visits the page for a while and then leaves without doing further interaction, the time registered will be equal to 0.
In order to solve this problem, I added the following (Note: I'm using GWT):
Window.addCloseHandler(new CloseHandler<Window>() {
#Override
public void onClose(CloseEvent<Window> event) {
GoogleAnalyticsWrapper.endSession();
}
});
Where the function endSession looks as follows:
public static native void endSession() /*-{
$wnd.ga('send', 'event', 'Session', 'Ending', {'sessionControl': 'end'});
}-*/;
So what I did basically was to send another event just as the window closes, that way an interaction is happening and the time should not be zero. I also added a sessionControl end command to make sure that the session ends.
However, I'm still getting a zero, so does anyone know how to solve this problem?
Thank you.

Related

GWT input event on TextBox

Given the following code:
TextBox tb = new TextBox();
tb.addValueChangeHandler(new ValueChangeHandler<String>() {
#Override
public void onValueChange(ValueChangeEvent<String> event) {
Window.alert(event.getValue());
}
});
onValueChange will be called if the TextBox loses focus. I am trying to have it called whenever the input value changes. The solutions I have read all involve handling the keyup and paste events such as in this answer. How to build a Facebook-style input box in GWT Hasn't this been addresses in GWT 2.5.1? Is there a way to bind to the native input change method? Another widget or using the UI framework would be acceptable if they have this functionality
The only way in GWT is to bind to the key down/key up and paste events.
Please send a patch to add support for the input event (using addBitlessDomHandler): http://www.gwtproject.org/makinggwtbetter.html, it should be rather easy (add a acase in DOMImpl) and has good chances to make it in (and if sent early enough, would have good chances to ship in GWT 2.6)
The solution is use the right event and that is the input event, so look how to hook on it, there are many ways to do it. Because I work with elements and not with Widgets this the code that I use it:
Element input = Document.get().getElementById("my-input");
DOM.sinkBitlessEvent(input, "input");
DOM.setEventListener(input, event -> GWT.log("Event!"));
You can just use addChangeHandler() and onChange, tb.getValue().
I used the following to detect when the value of a textbox changes. Just bare in mind this only detects if the text box goes from empty to full or full to empty. This was done to try reduce async calls to the server to validate the input
#UiHandler("notes")
#SuppressWarnings("unused")
public void notes(KeyUpEvent event) {
if (!areNotesCaptured && !notes.getText().isEmpty()){
fireLeaveSelectionUpdatedEvent();
areNotesCaptured = true;
} else if (areNotesCaptured && notes.getText().isEmpty()){
fireLeaveSelectionUpdatedEvent();
areNotesCaptured = false;
}
}

How to distinguish whether a page is published first time or multiple times in publish environment of Adobe CQ5

I need to display labels "New" and "Updated" besides the links displayed on a page on my website.
For this I applied a logic of checking number of versions. If number of versions are more than 2 I displayed "updated" else i displayed "New". I am able to achieve it in the Author environment.
But in Publish environment, number of versions created for a page, even though the page is modified and republished, are one only. So how can i identify that whether the page is published first time or it has been published multiple times.
One suggestion to this is to implement you own servlet/listener that listens to the replication events. Look at the EventHandler and JobProcessor interfaces. This servlet could then for example set a property value on the component instance so that the component could be displayed different the first time. It could just be a small counter variable that keeps track of how many times the actualy thing has been published or some more fancy logic there :)
//imports
#Service...
#Component...
#Property(name = "event.topics", value = ReplicationAction.EVENT_TOPIC)
public class MyCustomEventHandler implements EventHandler, JobProcessor {
private static final Logger LOGGER = LoggerFactory.getLogger(MyCustomEventHandler.class);
#Override
public void handleEvent(Event event) {
LOGGER.info("Handling an event of some kind !!");
process (event);
}
#Override
public boolean process(Event event) {
LOGGER.info("Processing an event !!");
ReplicationAction action = ReplicationAction.fromEvent(event);
if (action.getType().equals(ReplicationActionType.ACTIVATE)) {
LOGGER.info("Processing an activation job, this is just what we are looking for !!!!!");
//Logic for fetching/setting the properties you want from the component you want
//goes here. Here you can make use of the action.getPath(); to get hold of the containing page
//and then later on any specific components...
}
return true;
}
}
To see my original answer head over to: http://help-forums.adobe.com/content/adobeforums/en/experience-manager-forum/adobe-experience-manager.topic.html/forum__kbyb-i_need_to_displayla.html

Handle Window close event

I'm trying to handle the event when the close button of a Window is clicked:
// View Code
#Override
public void attachWindowListener(WindowListener listener) {
window.addWindowListener(listener);
}
// Presenter code
view.attachWindowListener(new WindowListener(){
public void windowHide(WindowEvent we) {
GWT.log("Window Event - Processing fields");
processFields();
}
});
However, the windowHide function seems to be not executed since I can't see the log I placed there.
How to properly handle that event?
How about
Window.addCloseHandler(
new CloseHandler<Window>()
{
public void onClose( CloseEvent<Window> windowCloseEvent )
{
// Do your worst here
}
} );
I usually put this in onModuleLoad() in my EntryPoint class.
Cheers,
Based on the information provided I would guess that either a.) the events you think are firing do not fire for the Window component (even if it seems like they should) or b.) the events are firing but in a different order than you expect.
For example, it's possible that a BrowserEvent or some other event is firing first as the window is being closed and the Window object's WindowEvent never fires. According to the API docs for GXT 2.x, the WindowEvent will fire on hide and deactivate but it does not specify that it fires on close. The GXT 3.0.x API doc is less clear on this point but I would assume the same behavior. Unfortunately Sencha does not provide good documentation on what events fire for a given component and in what order.
With that said, I have had some luck working through similar issues to this by using a debug class which outputs all the events on a component to which it is attached. This may shed some light on which events are firing and their order of execution, and you may find an optimal event to which you can attach your processFields() method.
For a good example of a debugger class, see this answer from a related post: https://stackoverflow.com/a/2891746/460638. It also includes an example of how to attach the debugger to your component.
API Doc for Window, GXT 2.x: http://dev.sencha.com/deploy/gxt-2.2.5/docs/api/com/extjs/gxt/ui/client/widget/Window.html
API Doc for Window, GXT 3.0.x: http://dev.sencha.com/deploy/gxt-3.0.0/javadoc/gxt/com/sencha/gxt/widget/core/client/Window.html
This worked:
window.addListener(Events.Hide, new Listener<ComponentEvent>() {
#Override
public void handleEvent(ComponentEvent be) {
// Do stuff
}
});

silverstripe dopublish function for ModelAdmin managed Pages

in the silverstripe backend I´m managing certain PageTypes via a ModelAdmin. That works fine so far, the only thing i can´t figure out is how to make a Page being "Published" when saving it.
Thats my code:
class ProjectPage extends Page {
public function onAfterWrite() {
$this->doPublish();
parent::onAfterWrite();
}
}
At the moment I can still see the ModelAdmin-created Pages in the Sitetree and I can see they are in Draft Mode. If I use the code above I get this error:
Maximum execution time of 30 seconds exceeded in
.../framework/model/DataList.php
Many thx,
Florian
the reason why you get "Maximum execution time exceeded" is because $this->doPublish(); calls $this->write(); which then calls $this->onAfterWrite();. And there you have your endless loop.
So doing this in onAfterWrite() or write() doesn't really work
you should just display the save & publish button instead of the save button
But I guess its easier said than done.
Well adding a button is actually just a few lines, but we also need a provide the functions that do what the button says it does.
This sounds like the perfect call for creating a new Module that allows proper handling of Pages in model admin. I have done this in SS2.4, and I have a pretty good idea of how to do it in SS3, but no time this week, poke me on the silverstripe irc channel on the weekend, maybe I have time on the weekend.
I found the same need/lack and I built a workaround that seems to work for me, maybe it can be useful.
public function onAfterWrite()
{
if(!$this->isPublished() || $this->getIsModifiedOnStage())
{
$this->publish('Stage', 'Live');
Controller::curr()->redirectBack();
}
parent::onAfterWrite();
}
Create a class that extends ModelAdmin and define an updateEditForm function to add a publish button to the actions in the GridFieldDetailForm component of the GridField.
public function updateEditForm($form) {
if ( ! singleton($this->owner->modelClass)->hasExtension('Versioned') ) return;
$gridField = $form->Fields()->fieldByName($this->owner->modelClass);
$gridField->getConfig()->getComponentByType('GridFieldDetailForm')->setItemEditFormCallback(function ($form) {
$form->Actions()->push(FormAction::create('doPublish', 'Save & Publish'));
});
}
Then create a class that extends GridFieldDetailForm_ItemRequest to provide an action handler for your publish button.
public function doPublish($data, $form) {
$return = $this->owner->doSave($data, $form);
$this->owner->record->publish('Stage', 'Live');
return $return;
}
Make sure the extensions are applied and you're done.
Or, you could just grab all the code you need from GitHub.

UiHandler doesn't work with SuggestBox SuggestionEvent

I am using a SuggestBox and trying to capture the SuggestionEvent that is fired when the user selects a Suggestion. I can do this with normal event handlers easily enough:
itemInputBox.addEventHandler(new SuggestionHandler() {
#Override
public void onSuggestionSelect(SuggestionEvent event) {
Window.alert(event.getSelectedSuggestion().getReplacementString());
}
});
That works fine, event fires with the correct replacement string. However, I like to use UiHandler whenever possible due to how much cleaner the code is. So I've tried the following:
#UiHandler("itemInputBox")
void onSuggestionSelect(SuggestionEvent event) {
Window.alert(event.getSelectedSuggestion().getReplacementString());
}
But this results in the following errors:
[WARN] [jsonp] - Method 'getAssociatedType()' could not be found in the event 'SuggestionEvent'.
[ERROR] [jsonp] - Parameter 'SuggestionEvent' is not an event (subclass of GwtEvent).
I have a different UiHandler working correctly on the same SuggestBox so I am kind of confused where I'm going wrong:
#UiHandler("itemInputBox")
void onKeyUp(KeyUpEvent event) {
Window.alert("Key up event firing.");
}
I don't understand why one UiHandler fires correctly, while the other results in a error.
SuggestionEvent does not extend GwtEvent instead it extends java.util.EventObject.
This is why it will not work with UiBinder. I will bring this up on the GWT contributer list to see if there is a specific reason for this. Right now I am just guessing that it was forgotten when moving to the new event system.