How to get element assoicated to onClick event - dart

I'm very new to Dart, and I'm encountering a problem with this code:
DivElement badge = querySelector('.badge');
badge.onClick.listen(onBadgeClick);
The event handler looks like this:
void onBadgeClick(MouseEvent e){
print(e.relatedTarget);
}
I get this exception
Exception: Unsupported operation: Cannot call matchingTarget if this
Event did not arise as a result of event delegation.
How can I get the element that the click is associated with?

e.target should you give the element that created the event. If you set a breakpoint in DartEditor the code execution halts on the line with the breakpoint and you can investigate the properties of the e instance.

Related

JQuery UI spinner spin event not as expected in Scala JS

When I define a spinner in ScalaJS and handle the spin value I am not able to get the new spin value in the event as I would have expected. According to the JQuery UI documentation the second parameter to the spin event is the ui object that contains a value attribute. So I defined a trait:
trait Number extends js.Object {
val value: Int = js.native
}
And then handle my spin event thus:
jQuery("#mySpinner").spinner(js.Dynamic.literal(spin = { (e: HTMLInputElement, ui: Number) =>
log("Change: " + ui.value)
}: js.ThisFunction1[HTMLInputElement, Number, Any]))
But the "value" attribute does not seem to be a member of the ui object as I get the exception below in my log statement. Can someone tell me what I am doing wrong?
uncaught exception: scala.scalajs.runtime.UndefinedBehaviorError: An
undefined behavior was detected: undefined is not an instance of
java.lang.Integer
You say e: HTMLInputElement but it should be e: Event
I suspect the problem is a combination of the previous comments. You are correct that, since you're using ThisFunction, the first element should be an Element of some sort. (Although, is it really an HTMLInputElement? That's a slightly unusual element type to put a spinner on.)
But that Element gets prepended to the function parameters, whereas you've got it replacing one.
In other words, you have
(e: HTMLInputElement, ui: Number)
but it needs to be
(elem: HTMLInputElement, e:Event, ui: Number)
in order to match the expected signature. So in practice, the system is trying to cast the value member of an Event, which of course doesn't exist, to Integer. It finds that value is undefined, tries to cast it to Integer, and boom.
I can't say I'm 100% certain (and IMO that ui parameter is just plain weird to begin with -- I'm a little suspicious of the jQueryUI documentation there), but that's my guess. Try fixing the signature of your call, and see if the error goes away...

Provide callback for custom component

I made a custom component which basically wraps a d3 line chart. Now I want to be able to register a callback for clicks on the lines in the chart.
I gave the component a #NgCallback parameter, which I then send events to:
class NetworkSummaryComponent implements NgShadowRootAware {
#NgCallback('callback')
Function callback;
void onShadowRoot(ShadowRoot shadowRoot) {
...
chart.callMethod('listen', ['line-click', (ev) {
var name = ev.callMethod('getLineName');
print(name);
callback({'name': name});
}]);
}
}
When using the component, I specify a function of my controller as callback:
<network-summary
...
callback="ctrl.lineClicked">
</network-summary>
However, that function is never actually called, put I know the callback arrives from the JS side because the print in the first snippet is executed.
If I instead specify the attribute as callback="ctrl.lineClicked()" I get a strange exception:
Closure call with mismatched arguments: function 'call'
I could not find any official documentation on how to properly do callbacks, so I'm not exactly sure what I'm doing wrong.. Any ideas?
It turns out that I had to explicitly name the expected arguments in the attributes:
<network-summary
...
callback="ctrl.lineClicked(name)">
</network-summary>
Hope this is useful to the next person having this problem.

Return response object in event listener not working when triggered in controller plugin

I implemented a shared event listener that manipulates and returns the response object with an error template showing the message of the triggered error code. (I'm not talking about throwing exceptions and catching them in a dispatch.error listener!)
This works fine when I call this event in a controller action. However, when I trigger my error event in a controller plugin that is called in the onDispatch method of the controller, only the status code is set correctly. But the called action is fully executed and no error page is shown.
I have absolutely no idea why this happens and I hope, someone is able to explain me the dispatch/event triggering/short circuiting/returning response issue here.
Following extracts might give you an impression of my code:
Listener:
class SharedErrorListener implements SharedListenerAggregateInterface {
...
public myErrorFunction(EventInterface $e) {
// get error code
// set status code to injected response object
// add error template to injected view model
// return response
}
}
Random controller action (works fine):
return $this->getEventManager()->trigger('error', $this, array(
'errorCode' => my_error_code
));
onDispatch() of controller:
// call plugin, if return value given return it (response must be returned?!).
$r= $this->plugin('myplugin')->doIt();
if (isset($r)) {
return $r;
}
class myplugin doIt() where error is triggered, but error template not showing up:
return $this->getController()->getEventManager()->trigger('error', $this, array(
'errorCode' => my_error_code
));
As the code in the controller and the controller plugin ist pretty much the same, I think it must depend on some application state. I did a lot of research, but couldn't find, what the problem might be. But as the event is triggered correctly and also the right status code is set to the response, I am just very confused. I don't want to implement an ErrorController (which would allow to call a redirect), because I think the solution via EventManager is actually very nice.
I'm too busy to actually read all the above, but from what my impression is, this code-snipped may actually help you out:
$trigger = $this->getEventManager()->trigger(self::EVENT_IDENTITY_GET, $identity);
if ($trigger instanceof ResponseCollection && !is_null($trigger->last())) {
return $trigger->last();
}
I finally found the problem here. By returning the response during the onDispatch process, the onDispatch() of the AbstractActionController wasn't called. In that function the return value of the controller action, e.g. the view model, is set as "result" of the MvcEvent. I just had to set the template that was set in the listener as the result for the event:
$r = $this->plugin('my_plugin')->doIt();
if ($r instanceof ResponseCollection) {
$e->setResult($this->getServiceLocator()->get('view_manager')->getViewModel()->getChildren());
return $r;
}
Hope this helps someone.

How to trigger a KeyboardEvent in Dart

Like I said in the title, I would like to simulate a keyup event in Dart. The problem is that I have not found how create a new KeyboardEvent object.
The only way that I've found is to use the Event(String type) constructor and then dispatch it on window object. But that doesn't work because of my "keyup" handler who takes a KeyboardEvent in parameter. Example:
window.on.keyUp.add((KeyboardEvent e){
print('keyUp handler');
});
KeyboardEvent e = new Event("KeyboardEvent");
window.on.keyUp.dispatch(e);
Is there a way to create and dispatch a KeyBoardEvent to simulate a "keyup" in Dart?
Also, I should mention that I tried too to trigger the event in JavaScript, thanks to js-interop library, but it only fires the JS handlers.
Try the following code:
window.on.keyUp.add((Event event){
print('keyUp handler');
if(event is KeyboardEvent)
{
KeyboardEvent keyEvent = event as KeyboardEvent;
//do stuff with keyEvent if needed
}
});
window.on.keyUp.dispatch(new Event("keyup"));
I think the parameter on the Event constructor must be the type of the event. Also, you can check if the event is a keyboardEvent, so you can handle KeyIdentifier, for example.
It's possible now to Dispatch a KeyBoardEvent from window, please see discussion on Google Group for more information: https://groups.google.com/a/dartlang.org/d/topic/misc/mgnd1TUGn68/discussion

Doctrine Record Listener never fired

I'm trying to create one record listener for all models.
In ProjectConfiguration.class.php I added:
public function configureDoctrineConnection(Doctrine_Connection $connection)
{
$connection->addRecordListener(new doctrineLogger());
}
And I created lib/doctrineLogger.class.php
class doctrineLogger implements Doctrine_Overloadable
{
public function __call($m, $a)
{
echo 'caught event '. $m .'<br />';
}
}
But no event is ever caught.
When I tried general connection listener with this:
$connection->addListener(new doctrineLogger());
... and the same doctrineLogger class, I got expected output properly:
caught event preConnect
caught event preExec
caught event postExec
caught event postConnect
caught event prePrepare
caught event postPrepare
...
What am I doing wrong? Am I implementing it incorrectly? Please help, I'm clueless. I'm trying to use Doctrine listeners for a first time.
Yeah, you're doing it wrong. Looking at the API-docs, it's not easy to spot though. The connection does indeed have an addRecordListener-method, inherited from Doctrine_Configurable. However, it is not usable for adding global record listeners on the connection level. Instead, you should add it to the Doctrine_Manager-instance:
Doctrine_Manager::getInstance()->addRecordListener(new doctrineLogger());
You can look at the reference documentation about record listeners here.

Resources