handle dojo EdgeToEdgeStoreList event - javascript

I create an EdgeToEdgeStoreList from dojox/mobile as follow:
<ul id="listCustomers"></ul>
storeCustomers = new Memory({data: data, idProperty: "label"});
var listCustomers = new EdgeToEdgeStoreList({
select: "single",
store: storeCustomers
}, "listCustomers");
listCustomers.startup();
then I want to handle the onCheckStateChanged event:
var listCustomers = dom.byId("listCustomers");
on(listCustomers, "checkStateChanged", function (listItem, newState) {
console.log(listItem, newState);
});
but this never fires.
What is the correct method?
It's ok also a way to get an array of selected items (just one in my specific case, of course).

There are two ways to do this, either use the listitems onclick, or if you want to use checkStateChanged you have to add that listener Widget.
var listCustomers = dijit.registry.byId("listCustomers");
on(listCustomers, "checkStateChanged", function (listItem, newState) {
console.log(listItem, newState);
});

Related

Programmatically trigger onRowClicked-event

Is there a way to manually trigger the Grid-Event onRowClicked programmatically? If I set a node to selected via
node.setSelected(true);
, the event isn't being triggered... Only if I really click on it, but I need to trigger it programmatically too, as a reaction to a service-call.
Seems pretty simple to me. Just call the onRowClicked function on your gridOptions. Seeing as you already have your node, you should be able to get the row and pass it to your onRowClicked function.
var gridOptions = {
columnDefs: columnDefs,
rowData: rowData,
onRowClicked: function(params)
{
console.log('Row Make: ' + params.data.make);
}
};
function clickRowOne()
{
const node = gridOptions.api.getRowNode(0);
gridOptions.onRowClicked(node);
}
Demo.

knockout kendo events fires twice

Hej, I have a problem here with the knockout-kendo framework.
Every event gets fired twice. Can someone tell me whats wrong with my code?
I created a small fiddle.
var StoreViewModel = function () {
var self = this;
this.stores = ko.observableArray(stores);
this.selectedStore = ko.observable(stores[0].Id);
// this event fires twice, dont know why!
this.dataBoundEvent = function () {
alert('databound event ...');
//doSomething();
};
this.changeEvent = function () {
alert('change event ...');
//doSomething();
};
};
Thanks!
The binding event is called when the grid is initialize and when the data is set.
To stop this, just use dataSource instead of data
<div id="wrapper">
<select data-bind="kendoDropDownList: {
dataSource: stores,
dataTextField: 'Address',
dataValueField: 'Id',
dataBound: dataBoundEvent,
change: changeEvent
}"></select>
</div>
dataSource is the normal way and the supported way of kendo.
I believe dataBoundEvent is being called for
Binding the backing data (stores)
Binding the selected value (selectedStore)

How to re-run JavaScript when DOM mutates?

I'm using Template.rendered to setup a dropdown replacement like so:
Template.productEdit.rendered = function() {
if( ! this.rendered) {
$('.ui.dropdown').dropdown();
this.rendered = true;
}
};
But how do I re-run this when the DOM mutates? Helpers return new values for the select options, but I don't know where to re-execute my .dropdown()
I think you don't want this to run before the whole DOM has rendered, or else the event handler will run on EVERY element being inserted:
var rendered = false;
Template.productEdit.rendered = function() {rendered: true};
To avoid rerunning this on elements which are already dropdowns, you could give new ones a class which you remove when you make them into dropdowns
<div class="ui dropdown not-dropdownified"></div>
You could add an event listener for DOMSubtreeModified, which will do something only after the page has rendered:
Template.productEdit.events({
"DOMSubtreeModified": function() {
if (rendered) {
var newDropdowns = $('.ui.dropdown.not-dropdownified');
newDropdowns.removeClass("not-dropdownified");
newDropdowns.dropdown();
}
}
});
This should reduce the number of operations done when the event is triggered, and could stop the callstack from being exhausted
Here's my tentative answer, it works but I'm still hoping Meteor has some sort of template mutation callback instead of this more cumbersome approach:
Template.productEdit.rendered = function() {
if( ! this.rendered) {
$('.ui.dropdown').dropdown();
var mutationOptions = {
childList: true,
subtree: true
}
var mutationObserver = new MutationObserver(function(mutations, observer){
observer.disconnect(); // otherwise subsequent DOM changes will recursively trigger this callback
var selectChanged = false;
mutations.map(function(mu) {
var mutationTargetName = Object.prototype.toString.call(mu.target).match(/^\[object\s(.*)\]$/)[1];
if(mutationTargetName === 'HTMLSelectElement') {
console.log('Select Changed');
selectChanged = true;
}
});
if(selectChanged) {
console.log('Re-init Select');
$('.ui.dropdown').dropdown('restore defaults');
$('.ui.dropdown').dropdown('refresh');
$('.ui.dropdown').dropdown('setup select');
}
mutationObserver.observe(document, mutationOptions); // Start observing again
});
mutationObserver.observe(document, mutationOptions);
this.rendered = true;
}
};
This approach uses MutationObserver with some syntax help I found here
Taking ad educated guess, and assuming you are using the Semantic UI Dropdown plugin, there are four callbacks you can define:
onChange(value, text, $choice): Is called after a dropdown item is selected. receives the name and value of selection and the active menu element
onNoResults(searchValue): Is called after a dropdown is searched with no matching values
onShow: Is called after a dropdown is shown.
onHide: Is called after a dropdown is hidden.
To use them, give the dropdown() function a parameter:
$(".ui.dropdown").dropdown({
onChange: function(value, text, $choice) {alert("You chose " + text + " with the value " + value);},
onNoResults: function(searchValue) {alert("Your search for " + searchValue + " returned no results");}
onShow: function() {alert("Dropdown shown");},
onHide: function() {alert("Dropdown hidden");}
});
I suggest you read the documentation of all plugins you use.

stopListening() race condition?

var PlaylistView = Backbone.View.extend({
el: '#expanded-container',
initialize: function() {
var playlistModel = this.model;
this.stopListening(playlistModel.get('songs'), 'add');
var form = this.$('input');
$(form).keypress(function (e) {
if (e.charCode == 13) {
console.log("hey")
var query = form.val();
playlistModel.lookUpAndAddSingleSong(query);
}
});
this.listenTo(playlistModel.get('songs'), 'add', function (song) {
var songView = new SongView({ model: song });
this.$('.playlist-songs').prepend(songView.render().el);
});
This is a snippet of my Backbone view and I cant figure out why sometimes the same songView is rendered twice. In other view, I call PlaylistView.initialize() manually without recreating the view. Because of that, I deregister all the events in the beginning of initialize to prevent it from listening to the same event multiple times. It does its job but only once in a while, the same songView is rendered twice. I suspect this might be some kind of a race condition but I haven't been able to figure out the reason. Does anyone have an idea?
That may happen if playlistModel.get('songs') are not returning the same objects, try to remove only the event whatever the objects are, like this:
this.stopListening(null, 'add');

Get Component Reference in AuraJS

I'm using jQuery dataTables to display a table. I need to be able to pass a row selection event on to my Aura component that handles the selection and performs some operations on the data from that row.
In the initialize() function:
initialize: function()
{
$("#mytable tbody").click(function(event)
{
$(mytable.fnSettings().aoData).each(function ()
{
$(this.nTr).removeClass('row_selected');
});
$(event.target.parentNode).addClass('row_selected');
});
mytable = $('#mytable').dataTable();
},
I set up the click handler for the row selection, but how do I get a reference to the enclosing component so I can sandbox.emit() function to issue messages? I can put a reference to the component into the Closure, but that essentially makes this component a singleton and I could never have two instances of the component on the page at the same time.
Is there a standard way, using jQuery selectors or some other method, that I can retrieve a reference to the enclosing component from inside the click() handler?
Edit: I should never try to write code until I have had 32oz of caffine. You can pass a reference to the current component via the click() method itself. Like so:
$("#mytable tbody").click(this, function(event)
{
$(mytable.fnSettings().aoData).each(function ()
{
$(this.nTr).removeClass('row_selected');
});
$(event.target.parentNode).addClass('row_selected');
event.data.sandbox.emit('mychannel', {data: 'stuff'});
});
If I understand your question correctly, you could try something like this
initialize: function () {
var that = this;
$("#mytable tbody").click(function(event) {
//have acces to component as 'that'
});
}
what I used for events is view inside component configuration:
View: {
events: {
'click a[data-question-edit-id]': function (e) {
var button = $(e.currentTarget),
id = button.attr('data-question-edit-id'),
examId = this.component.examModel.get('id');
this.sandbox.router.navigate('/exams/' + examId + '/questions/' + id + '/edit', {trigger: true});
},
'click a[data-question-delete-id]': function (e) {
var button = $(e.currentTarget),
id = button.attr('data-question-delete-id');
this.component.showDeleteConfirmation(id);
}
}
}
If you'll find be helpful, here is my repo of aura project I'm working on:
https://github.com/lyubomyr-rudko/aura-test-project

Categories