How can I get value attribute from players.html using Marionette's click event? I basically need to know which player was clicked. Here is my code:
players.html
{#myplayers}
<player class="standard" value="{player}" style="{style}"></player>
{/myplayers}
players.js
...
return Marionette.ItemView.extend({
model: new Models.Players(),
template: 'tmp/players',
events: {
'click player': 'playerSelect'
},
initialize: function() {
},
playerSelect: function(e) {
console.log('click test');
// I need here value (attribute), of player that was clicked
}
});
...
You can inspect e.currentTarget in your event handler:
playerSelect: function(e) {
var playerValue = e.currentTarget.getAttribute('value');
}
As an aside, player is not a known HTML tag or a valid name for a custom element. The HTML spec caters for unrecognised tags so your template will still be rendered, but it will be treated as an unknown element.
If that isn't what you intended may want to use a standard HTML5 tag.
Related
I have made some code to fire some instructions after a click on an html element :
const datepicker = document.querySelector(".datepicker")
datepicker.addEventListener("click", () => {
//ajax request
}
The click on the element generates some more html elements through javascript (it displays a datepicker).
How can I add another Eventlistener on the newly created element document.queryselector(".month-next") by the previous click ?
edit : I use materialize datepicker, the "month-next" class is generated by the materialize javascript
I don't think this answers my question
The only variant here is to check for a class instead of an id.
// Set an event handler using delegation
document.addEventListener('click', function(e) {
if (e.target && e.target.classList.contains('brnPrepend')) {
console.log("Click!")
}
});
// Append a dynamic element to DOM
setTimeout(function() {
let dynamicElement = document.createElement("div")
dynamicElement.innerText = "CLICK ME"
dynamicElement.classList.add("brnPrepend")
document.querySelector("body").append(dynamicElement)
}, 2000)
Im trying to handle a click event on a div.There are 2 separate click events that I need to handle on div, one is on element <a> and another on element <span> I have a psedo code for the if-else conditions depending on what element I have clicked.
below is my function after rendering the page:
afterrender: function() {
Ext.fly('div').createChild({
tag: 'div',
html: "<label class='highlight'> Try the new <a href='#'>Beta version</a><span class='icon-clear'></span></label>"
}).on("click", function(e) {
if (e.target is <a>) {
//do some fun
}else if (e.target is <span>) {
//do some func
}
}, this, { delegate: 'label' });
}
I'm not sure how to check which element was clicked to execute fun depending on that element..Any ideas??
Use the getTarget method on the event, which will climb check if the event target (or any parent) matches the selector.
if (e.getTarget('a')) {
} else if (e.getTarget('span') {
} else if (e.getTarget('.someClassName') {
}
// etc
I am using the same structure as explained in the answers for this question -- > How to handle nested CompositeView using Backbone.Marionette?
to render my composite views and Item view. My Item view consists of LI tag. I want to handle click event for this Itemview. I am trying my code as below :which is not working The same events code snippet If I write in my first composite view, It get's triggered. But events do not get triggered in ItemView. Please help.
var topNavMenuView = Backbone.Marionette.ItemView.extend({
tagName :'li',
className:'dropdown',
template : _.template(topNavMenuItemTemplate) ,
initialize:function(options){
console.log("initialize");
this.id=options.menuCode;
},
events: {
'click li' : function(event){
alert('click');
},
'click ' : function(event){
alert('click');
}
}
});
View events should return events hash like this
events: {
'click': 'onClick'
},
onClick: function(){
alert('click');
}
I want to add some content to my page after data binding, e.g.:
$("<li>
<div>text</div>
<div data-bind='event: { click: selectContact }'></div>
</li>")
.appendTo($("#userClientGroup")
.find("#searched-client-ul-UCG"));
However, in this case the click event is not working; can any one can give me solution?
You can use ko.applybindings(viewModel, $('#yourNewElement')).Just be careful not to try binding an element already bound, or you'll have an error.
The best approach would be to avoid using jQuery (or any DOM method) to append new elements, in order to avoid having to bind your viewmodel against these elements. You can solve the problem either with existing bindings in your HTML or with a custom binding, or a combination. Your bindings should handle the DOM manipulation, not your other code (which shouldn't need to be aware of the DOM).
Another approach is to use a delegated event handler. I use the following custom binding:
ko.bindingHandlers.delegatedEvent = {
init: function (element, valueAccessor) {
var options = ko.unwrap(valueAccessor()) || {},
setupEventHandler = function (settings) {
if (settings.data) {
$(element).on(settings.event, settings.target, settings.data, settings.handler);
} else {
$(element).on(settings.event, settings.target, settings.handler);
}
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$(element).off(settings.event, settings.target, settings.handler);
});
};
if ($.isArray(options)) {
$.each(options, function () {
setupEventHandler(this);
});
} else {
setupEventHandler(options);
}
}
};
Use this on the <ul> you're inserting the li into as such:
<ul data-bind="delegatedEvent: { event: click, target: '.contact-select', handler: selectContact }">
Add the class in your original insertion code, and remove the data-bind there.
$('<li><div>text</div><div class="contact-select"></div></li>')
.appendTo($("#userClientGroup").find("#searched-client-ul-UCG"));
Not only have you solved the problem, but you've replaced potentially lots of event handlers with just one.
I am learning backbone.js and am quite new. I have a view that acts as a button:
simpleButton = Backbone.View.extend({
template: "<button class='${classes}'>${text}</button>",
el: $("body"),
events: {
"click": "onClick",
"focus": "onFocus",
"blur": "onBlur"
},
initialize: function (args) {
_.bindAll(this, 'render');
this.rendered = false;
this.text = args.text || 'button';
this.classes = args.classes || [];
this.classes.push('ui-button');
//console.debug("Wh.views.simpleButton.initialize classes ",this.classes);
if (args.autoRender === true) this.render();
},
render: function () {
//console.debug("Wh.views.simpleButton.render classes ",this.classes);
if (this.rendered === false) {
$.tmpl(
this.template, {
classes: this.classes.join(' '),
text: this.text
}
).appendTo(this.el);
this.rendered = true;
}
},
//event handlers
onClick: function (ev) {
console.debug(this);
alert("click on ", ev, this);
},
onFocus: function (ev) {
////console.debug(ev);
},
onBlur: function (ev) {
}
});
My problem is that if I create two buttons, and click just one of them, I get the alert box two times, and the debug showing me "this" shows the first button first, and the second button next.
Am I missing something?
The events you define are bound to the "el" property of your view. In your case it is "body" so when you fire up click with 2 simpleButton views instantiated, you have 2 of them listening for the same event.
Each view you instantiate should represent one and only one DOM element defined by the el property. So if you want to create a button view (not sure this is 'best practice' in a real program) you could have :
SimpleButton = Backbone.View.extend({
template : "<button class='${classes}'>${text}</button>",
tagName : "div", // defines the html tag that will wrap your template
className: ".buttonbox",
...
});
mybtn = new SimpleButton();
mybtn.render().appendTo('body')
That way your click event will only concern the one div.buttonbox inside of which your button lives.
Notice : Backbone idea of the render function is creating an html string you'll use afterwards to append prepend or whatever in the DOM. That way if you create many you can do it so you only refresh the DOM once (refreshing the DOM is expensive)...
Use this in your View .it will unbind the click events
initialize : function() {
$(this.el).unbind("click");
}
Just a thought that creating a Backbone.View for each and every button in your app could be a performance overkill and you can't leverage the "delegate" feature in jQuery. I'd instead create a Backbone.View for the parent element of those buttons instead.
Of course, if you have a few special buttons with complicated logic then they probably do deserve their own View classes. :)
Give your buttons unique ids, for example <button id="button1"> and <button id="button2">, then in your events hash, you need to specify the click event and the id of the button you want to handle that event for, e.g:
events : {
"click #button1" : "onClick",
"click #button2" : "doSomethingElse"
}
Now this will call onClick() only when you click on the button with id=button1 and call doSomethingElse() when you click on the button with id=button2