Okay, so it took some digging here, I hope the solution I found is useful. I hope even more, though, that there is a less jacked-up way to do this, and someone can point it out.
I was trying to figure out how to get the source of a delegated tap event from an item that is in a carousel, rather than a list or other similar structure with built-in passable arguments in Sencha Touch 2; the scope of the event is, by default, the container that has the listener. All of the arguments that were passed through the function were related to the mouse click event, rather than the source. See below for my solution.
One more way
tap: function(list, index, target, record, e, eOpts){
var elm = Ext.get(e.target);
Ext.getCmp(elm.dom.id);
}
Like I said, this is a hacky solution, if there's something better that'd be awesome, please post it here. Anyway, this is the delegate listener code I used:
{
element: 'element',
delegate: '.completed_button',
event: 'tap',
fn: function(element){
var source_id = element.getTarget().id;
Ext.getCmp(source_id);
}
}
In other words, pass the click event argument, get its target, and get that target's id. I found this through snooping around what console.log(element) showed me.
Related
I've added a plugin that allows the user to add a specially styled div via a dialog. The issue now is, this element should not be clickable inside the edtior. The problem is the users manage it to click inside the div and enter text there and by this screw it up.
I've already spent some time searching the documentation but couldn't find the right approach to do this yet. I'm not asking for code, just some advice how to do it, a pointer to the right API method would be good enough for me. I guess I can somehow access the elements or intercept an users click and prevent them from adding something to my element somehow, I just couldn't yet figure out how to do it.
Use the Widget System.
Widget Tutorial.
Demos.
I've finally managed to get this done by making the elements content not editable. When I create the element in my dialog:
hrElement.setAttribute('contenteditable', false);
When loading the plugin:
init: function (editor) {
editor.on('contentDom', function () {
var stiching = (this.document.getElementsByTag('div'));
console.log(stiching);
for(var i=0;i<stiching.count();i++){
if (stiching.getItem(i).hasClass('stitching')) {
stiching.getItem(i).setAttribute('contenteditable', false);
}
}
});
}
I'm pretty sure this is not the most best solution (don't like to iterate over the elements) but at least it works for me now. Any suggestions how to improve it for future cases are welcome.
$('#my-view').on('show', showHandler)
Doesn't work. Using data-show is not an option either because the code that sets/unsets the event is within class that is instantiated later. Also creating the view programatically and passing in the event handler doesn't work because I need to set the event on/off at different times.
Is this not possible with kendoUI? If not, why? This seems like such an incredibly obvious feature to relay those events to the element themselves similar to what is possible with jquery ui widgets.
This works:
var view = $('#my-view');
var widget = kendo.widgetInstance(view);
widget.bind('show', showHandler);
Better answer, just delegate the events yourself so the code in the question actually works:
<div data-role="view" ... data-show="onShow">...</div>
and
function onShow () {
this.element.trigger('show');
}
Now the it works :). The problem I still has was that 'show' isn't triggered when a view is first shown if it is the first view shown. Er, so yeah I had to add some extra code for that too like this:
if ($('#my-view').is(':visible')) {
$('#my-view').trigger('show');
}
Lame but it works.
I'm using a Kendo Grid's removeRow function. It works, but it always prompts "Are you sure you want to delete this record?" whenever I programmatically remove a row. I've already done the decision-making as to whether or not the row should be removed, so I don't want this message to show up. Googling didn't help and I couldn't find any similar question on StackOverflow or Kendo's forum. I know I could change the code, but I was wondering if there's a way to configure the grid to just not show it? Another solution would maybe be to temporarily block confirm prompts, possibly? Not sure if that's possible.
Setting editable.confirmation to false should do the trick:
kendoGrid( {
editable: {
confirmation: false
}
})
I have a workaround that I just figured out, in the meantime. It works fine, but it's a bit hacky:
var oldConfirm = window.confirm;
window.confirm = function() { return true; };
grid.getKendoGrid().removeRow(selectedRow);
window.confirm = oldConfirm;
I'd still be interested in hearing about any disabling of the confirmation, however, and I'll accept that as the answer if it comes along.
So we all know in an ajax update events must be rebound to new dom elements. Yes delegate is an option, but delegate doesn't work for all scenarios. For instance delegate won't help for something that needs to be done simply on load rather than on a click event.
Rather than split my code into delegate handlers and handlers that need to be rebound on updates, I would rather define a single method with a context parameter that gets called every time the page changes like so:
function onPageUpdate(context) {
$('a', context).click(...); // event handlers
$('.chart', context).addClass(...); // load handlers
}
On dom ready this will be called with the context parameter null. On an ajax update the context will container the new dom elements. This way I'll never have to worry about delegating or ajax updates again.
I'm having trouble getting this to work however. Given the ajax callback:
function onSuccess(data) {
// data contains new dom elements like: <div><a>Click</a><span>chart<span></div>
// replace old elements with new ones
$('a').replaceWith('a', data);
$('span').replaceWith('span', data);
// call pageUpdate with the new context
onPageUpdate(data);
}
Is it possible to make this work like I expect? The replacing works fine, but onPageUpdate isn't binding anything to these new elements, I don't know if thats because the context is just a string object or what. Can anyone think of a way to make this work?
In my mind this is a better solution than delegate, because theres only one method for all handlers and only the elements that need a binding will own it.
From jQuery() - jQuery API
jQuery( selector [, context] )
selector A string containing a selector expression
context A DOM Element, Document, or jQuery to use as context
If the context isn't the correct type - such as passing a string - it's simply going to be ignored. Try wrapping your HTML string in a jQuery object, then use that as the context for your selectors, like so:
var $context = $(data);
$('a').replaceWith('a', $context);
$('span').replaceWith('span', $context);
// call pageUpdate with the new context
onPageUpdate($context);
I won't answer to your question, Anthony Grist's answer is quite right, but there are some things you said that I don't understand. Could you explain them to me ?
For instance delegate won't help for something that needs to be done simply on load rather than on a click event
Sorry but I don't get it, do you have an example ?
In my mind this is a better solution than delegate, because theres
only one method for all handlers and only the elements that need a
binding will own it.
I don't get it too:
only one method: which method are you talking about ?
only the elements ... will own it: it's also the case with delegate, and more, if you have let's say 10 anchor element, only ONE handler would be bound, instead of 10 in your solution
On your method onPageUpdate you're mixing two things: event handling ($("a").click(...)) and DOM modification ($(".char").addClass(...)). Maybe that's why you're confusing about delegate's ability to resolve your problem.
[revised]
I'm creating a TreePanel in ExtJs that is loading its children from a JSON file. I'm having trouble adding a click action to the nodes. I'm not sure whether it's added in the script creating the tree, or if its added as a property in the JSON, and if so, what the syntax would be. Any help would be appreciated! Please provide an example if possible.
Add a listener to the TreePanel:
listeners: {
click: function(node, event){
console.log(node);
}
}
and use the data in the node.
This is a very commonly talked about question(events in general), so I would suggest searching the extjs forums and reading what they have in their learning center.
Event listeners can be assigned on creation of the TreePanel or attached to an existing TreePanel.
I have a similar (and common) setup where I have a tree that I use as a navigation menu and each leaf node acts as a link that should be opened in a TabPanel.
To handle the node clicks, you could do something like:
Ext.get('your-tree').on('click', function(node, event){
if(node.isLeaf()){
// do what you need to with the node.
}
});
Jozef Sakalos(aka Saki) has allot of great information on his site extjs.eu. I think you would be most interested in the component communication example.
Gerry is putting you on the right track, and you can never go wrong with Saki's examples. I just answered a very similar question. That answer may give you more information as well:
How do I find the selected node in an ExtJS TreePanel?