When I subscribe to the onChange event of an InputElement, the event type is Event and has the target property set:
new InputElement()
..onChange.listen((e) {
print(e.runtimeType);
print(e.target);
});
How do I copy this behavior (for my own custom input box) and create events with the target property set?
None of the Event constructors allow you to pass a target, and the target property is get-only.
I tried finding the source for InputElement to see how it worked; but was unable to locate it in the Dart repo :(
I think you should use a CustomEvent instead.
dispatchEvent(new CustomEvent('nameOfEvent'));
Just call dispatchEvent from the element you want to have set as target
final someDiv = dom.querySelector('#some');
someDiv.dispatchEvent(new dom.CustomEvent('xxx-yyy'));
In this question it is shown how to do it in Polymer elements How do I fire a custom event from Polymer Dart?
You do this by calling dispatchEvent on the element, passing the Event:
var e = new Event.eventType('Event', 'change', canBubble: true, cancelable: false);
dispatchEvent(e);
Related
The question basically is how to convert this:
var evt = 'click' || 'touchstart'; // Based on some logic
$('.selector').on(evt, function(){});
into Meteor event handler
Template.MyTemp.events({
....??? : function(e, t){}
});
UPDATE
Based on the comments below, seems like chrome is the problem, as it sets the touch events passive = true.
So the new question would be:
How to set the passive property for event listeners in Blaze Template
Events?
You can specify multiple events in a single handler by using a / as a delimiter between the event types. docs
Template.MyTemp.events({
'click/touchstart .selector'(e,t){
e.preventDefault(); // prevents default click after touchstart
// your handler
}
});
In english:
for the template MyTemp handle click or touchstart events on the
selector class.
This is also useful reading: touch and mouse
I've read through the Ractive Documentation and I'm scratching my head a bit, because it seems like the default events initialization option allows me to do something - create new eventtypes - far more complex than what i need but conversely, there's no hook for the simpler, (more common?) task of defining default events
Could someone advise on how to provide global events that could be fired for traditional DOM events?
Example:
I have a 3 Component application page. I want to define a getOptions event, such that any <select on-click='getOptions'>...</select> will be handled by the same function. I don't want to have to define that function in each component.
My intuition would have been to do the following:
Ractive.events['getOptions'] = function(event){
//logic for getting the options for the value in event.keypath
}
or, if i wanted a true default that could be overridden...
Ractive.default.events['getOptions'] = function(event){
//logic for getting the options for the value in event.keypath
}
but my understanding of the documentation, is that Ractive.events and Ractive.default.events do not provide this, but rather provide a way to define new event plugins, that depend on a separate mechanism for getting fired:
Ractive.events.getoptions = function(node,fire){
//here goes logic for interacting with DOM event listeners, etc
}
//and then i would need to do this
ractive = Ractive.extend({...});
ractive.on('someOtherEventName',function(event){
//logic for getting the options for the value in event.keypath
});
//and then I could do this...
<select on-getoptions='someOtherEventName'>...</select>
but what would fire the getoptions in this case - from the template, rather than js ractive.fire()?
Would something like <select on-getoptions='someOtherFunction' on-click=getoptions>...</select> work? That seems very strange to me. Do I understand the concept correction? If not, what am i missing?
Is there a simple way to achieve the first example?
Ractive.events refers to custom events for mediating between the dom and the template:
Ractive.events.banana = function( node, fire ) { ... };
<div on-banana="doSomething()"/>
The handler for the event can either be the name of an event to fire, or a method on the component instance.
In your case, I think defining a method on the Ractive.prototype would be the best way to have a common handler:
Ractive.prototype.getOptions = function( /* pass in arguments */ ){
// and/or this.event will give you access
// to current event and thus context
// you can also override this method in components and
// call this base method using this._super(..)
}
// now any ractive instance can use:
<select on-click="getOptions(data)">...</select>
An event based approach usually entails letting the root instance or common parent in the view hierarchy handle same event across child components:
var app = new Ractive({
template: "<componentA/><componentB/>",
oninit(){
this.on( '*.getOptions', ( event, arg ) => {
// any child component (at any depth)
// that fires a "getOptions" event will
// end up here
});
}
});
// in component A or B:
<select on-click="getOptions">...</select>
UPDATE: If you wanted to assign an event handler to the prototype, so in essence every component is pre-wired to handle an event of a set name, you could do:
Ractive.prototype.oninit = function(){
this.on( 'getOptions', ( event ) => {
// handle any "getOptions" event that happens in the instance
});
}
Just be aware that you must call this._super(); in any component in which you also implement oninit:
var Component = Ractive.extend({
oninit() {
// make sure we call the base or event listener won't happen!
this._super();
// do this component instances init work...
}
}
I'm trying to create a spy on Jquery that's making a call like:
$('#AccountNumber').val();
How would I set up the spy to return a value based on the #AccountNumber selector?
You could try this:
var spy = ('#AccountNumber', 'ValueChanged');
$('#AccountNumber').trigger('ValueChanged');
expect(spy).toHaveBeenTriggered();
var val = $(spy.selector).val();
Update after edit:
You could add this -
Watch for object properties changes in JavaScript
then inside handler trigger event 'ValueChanged', and on spy add listener to that event.
How can I get a reference to the click handler of an element in JQuery?
Here is what I am trying to do:
Store the click handler,
Change the click handler for the next click,
Restore the original click handler
var originalClick = $(settings.currentTarget).click;
$(settings.currentTarget).off("click");
$(settings.currentTarget).click(function (e) {
e.preventDefault();
settings.model.modal.close();
$(settings.currentTarget).off("click");
$(settings.currentTarget).click(originalClick);
});
The above code works the first time, however, when I click on the element again it fails:
Uncaught TypeError: Object [object HTMLAnchorElement] has no method 'on'
Update:
I now realize that this is a really bad design that I am trying to do. I have resolved this issue by maintaining a visibility boolean in my viewmodel, if it is true, don't re-open the modal.
$(...).click is the jQuery click() method, not your event handler.
You can use an undocumented internal API to get the list of event handlers:
jQuery._data( elem, "events" );
What happens if you try it this way?
var originalClick = $(settings.currentTarget).click;
$(settings.currentTarget).off("click");
$(settings.currentTarget).on("click",function (e) {
e.preventDefault();
settings.model.modal.close();
$(settings.currentTarget).off("click");
$(settings.currentTarget).click(originalClick);
});
I have an autocomplete inside of a panelBar. When a panelBar is activated, I would like to set the focus to the autoComplete input. I have tried several ways to get this to work, but cannot find a way to do this.
The method is invoked and I can find the autocomplete. However, I am unable to set focus.
//Kendo PanelBar
function onPanelBarActivate(e) {
var $autoComplete = $('input .txtProductText', e);
$autoComplete.focus();
}
var $panelBar = $('#panelbar').kendoPanelBar({ expandMode: "single", expand: onPanelBarActivate }).data("kendoPanelBar");
This returns empty jQuery object:
$('input .txtProductText', e);
First e is the event argument of the activate event. It cannot be used as the context of jQuery. You should use e.item instead. Second 'input .txtProductText' means 'child of an input whose class is txtProductText'. This is probably not what you need since 'input' elements can't really have children.
Try this instead:
$('.txtProductText', e.item);