Dojo: how to get row data in grid's context menu item handler? - dojo

I'm using Dojo 1.4.
Given a dojox.grid.DataGrid in markup:
<table jsId="grid1" dojoType="dojox.grid.DataGrid"
structure="layout"
delayScroll="true"
columnReordering="true"
selectable="true"
onRowDblClick="onRowDblClick"
onRowContextMenu="onRowContextMenu"
headerMenu="grid1_headerMenu"
>
<div dojoType="dijit.Menu" id="grid1_rowMenu" jsId="grid1_rowMenu" style="display: none;">
<div dojoType="dijit.MenuItem" onClick="gridRowContextMenu_onClick">Edit</div>
</div>
</table>
I haven't found a better way to show grid's contex menu that this one:
function onRowContextMenu(e) {
grid1_rowMenu.bindDomNode(e.grid.domNode);
}
It works, menu pops up and function 'gridRowContextMenu_onClick' has being called.
function gridRowContextMenu_onClick(e) {
// how to get a row data???
}
My question is how inside menuitem's onClick handler (gridRowContextMenu_onClick) can I get original row for which menu was poped up?

You can use the event grid object:
var item = e.grid.getItem(e.rowIndex);

I had a similar question. I wanted to create a context menu which allowed the user to remove the item that they right clicked on from the datagrid and delete the item from the datastore. Thought it should be pretty simple and with your help and some other sites, I came up with the following code. I hope this helps someone in the future.
Javascript
var selectedItem; // This has to be declared "globally" outside of any functions
function onRowContextMenuFunc(e) {
grid5_rowMenu.bindDomNode(e.grid.domNode);
selectedItem = e.grid.getItem(e.rowIndex);
}
function gridRowContextMenu_onClick(e) {
store3.deleteItem(selectedItem);
}
HTML
<div dojoType="dijit.Menu" id="grid5_rowMenu" jsId="grid5_rowMenu" style="display: none;">
<div dojoType="dijit.MenuItem" onClick="gridRowContextMenu_onClick">Delete</div>
<div dojoType="dijit.MenuItem">Cancel</div>
</div>
and
<div id="grid" dojoType="dojox.grid.DataGrid" jsId="grid5" store="store3" structure="layoutStructure" rowsPerPage="40" onRowContextMenu="onRowContextMenuFunc"></div>
Of course, if you were programatically creating your DataGrid, you would just add onRowContextMenu: onRowContextMenuFunc to your declaration, as you did in your question above.
Finally, to actually get information about the item:
console.log(e.grid.store.getValue(selectedItem, 'type'));
console.log(e.grid.store.getValue(selectedItem, 'color'));
// Where type and color are fields specified in the DataGrid Layout Structure //

Did you try e.rowIndex?

Related

How to disable blur call on the active element from SwiperJS in onTouchStart handler?

Is it possible to disable this blur call on the active element from SwiperJS in the onTouchStart event handler?
Some background:
For touch and desktop devices I'm using swiper for forms on swiper-slides. Within a form I'm using vue-select (a combobox).
The Problem: When the user selects an entry, the entry get not selected on the first time but on the second time.
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">
<div>First form</div>
<v-select :options="selectionEntries"></v-select>
</div>
<div class="swiper-slide">
<div>Second form</div>
<v-select :options="selectionEntries"></v-select>
</div>
</div>
</div>
See also this example on codepen
I figured out that it seems to work correctly:
When I remove the blur-listener on the input field of the vue-select box. But it is used to close the selection list when the user leaves the field.
When I comment out this blur call in SwiperJS. I'm not sure why it is used there.
The first point is not an option, so is it possible to disable the blur call of SwiperJS via configuration?
Currently I'm using this workaround (SwiperJS V6.4.1):
const swiper = new Swiper(".swiper-container", {
// Workaround part 1:
touchStartPreventDefault: false
})
// Workaround part 2:
swiper.touchEventsData.formElements = 'notExistingHtmlTagName'
Part 1: To handle mouse down and click events on all elements, set the swiper parameter touchStartPreventDefault: false.
That will disable this code block: https://github.com/nolimits4web/swiper/blob/9dead9ef4ba5d05adf266deb7e3703ceb199a241/src/components/core/events/onTouchStart.js#L90-L97
Part 2: Set swiper.touchEventsData.formElements = 'undefined' to define nothing as formElements. That will disable the code block that calls blur: https://github.com/nolimits4web/swiper/blob/9dead9ef4ba5d05adf266deb7e3703ceb199a241/src/components/core/events/onTouchStart.js#L81-L88

DebugElement.query does not work with elements added dynamically to the dom in a spec

I have an app that is using ngx-bootstrap to show a tooltip on mouseover. I want to test that the content, which is dynamically added, shows properly. In order to do this I have a test that looks like this:
it(shows the right tooltip', fakeAsync(() => {
fixture.debugElement.query(By.directive(TooltipDirective))
.triggerEventHandler('mouseover', null);
tick();
fixture.detectChanges();
expect(fixture.debugElement.query(By.css('.tooltip-inner')).nativeElement)
.toBe('the tooltip text');
}
This results in an error that indicates that fixture.debugElement.query(By.css('.tooltip-inner')): "Cannot read property 'nativeElement' of null"
If I print out the content of fixture.debugElement.nativeElement I get this:
<div id="root1" ng-version="5.2.9">
<my-component>
<div ng-reflect-tooltip="the tooltip text">
<img src="images/test.png">
</div>
<bs-tooltip-container role="tooltip" class="tooltip in tooltip-right">
<div class="tooltip-arrow arrow"></div>
<div class="tooltip-inner">the tooltip text</div>
</bs-tooltip-container>
<my-component>
</div>
The important take away is that the html exists - it is just not accessible by the DebugElement.query.
My current solution to get the spec passing is to change the expect to:
expect(fixture.debugElement.nativeElement.textContent.trim())
.toBe('the tooltip text');
This works, but it is a hack that will fall to pieces if I run into a similar situation with multiple tooltips (for example). Has anyone been able to handle this in a better way? Am I not setting this spec up correctly?

Unable to get radio button value in Bootstrap

NOTE: Please see edit below. Primary issue is that I did something dumb.
This question is a duplicate, but the accepted answer didn't actually address the problem, and the listed workaround didn't work for me.
My HTML looks like this:
<div class="row checkbox_row">
<div class="col-xs-1 checkbox_cell">
<input type="radio" class="answerCheckbox assessmentQuestion" name="currently_employed_select" value="yes" id="currently_employed_select_1"/>
</div>
<div class="col-xs-11">Yes</div>
</div>
<div class="row checkbox_row">
<div class="col-xs-1 checkbox_cell">
<input type="radio" class="answerCheckbox assessmentQuestion" name="currently_employed_select" value="no" id="currently_employed_select_2"/>
</div>
<div class="col-xs-11">No</div>
</div>
Neither this jQuery:
var name = $(this).attr('name');
var value = $('input[name=' + name + ']:radio:checked').val();
Nor this Javascript:
var radios = document.getElementsByTagName(name);
for(var x = 0; x < radios.length; x++){
if(radios[x].checked){
return radios[x].value;
}
}
... are getting a value out of the radio button.
Is there something obvious and stupid I'm overlooking here? Is there some Bootstrap formatting that's mandatory when using radio buttons?
EDIT: I've figured out what piece of code is killing me, and it has bugger-all to do with Bootstrap.
This:
$(document).ready(function() {
$('.answerCheckbox').val(function() {
highlightCheckedRow(this);
});
... is meant to highlight the container rows of any checked boxes (including radio buttons) on page load. Which it does, admirably, but apparently at the expense of nuking the values of said radio buttons.
... which, given that val() overwrites the value when you give it a parameter, should not come as a surprise to me.
That'll teach me to do cargo cult programming.
Right, so, need to figure out some other way to run that function on all my answerCheckbox elements on page load, and I'm all set.

WIndows 8 Metro List View Event Listener

I am trying to create a simple HTML Metro App for Windows 8. I want to display a list view, and based on the clicked item display different content on the screen. It sounds trivial, right?
But it doesn't work! Here is my code:
<div id="frameListViewTemplate" data-win-control="WinJS.Binding.Template">
<img data-win-bind="src: picture" class="thumbnail" />
</div>
<div id="basicListView" data-win-control="WinJS.UI.ListView"
data-win-options="{itemDataSource : DataExample.itemList.dataSource, itemTemplate: select('#frameListViewTemplate'),onselectionchanged : handler}">
</div>
Than in the defult.js
var myListView = document.getElementById("basicListView").winControl;
myListView.addEventListener("selectionchanged", handler);
And the handler:
function handler() {
console.log("Inside the handler : ");
}
handler.supportedForProcessing = true;
So the handler is never called. My questions are: How can I add an event listener and its handler to the listview control.
How can I recognize which element on the list view was clicked.
P.S.
The listview is displayed properly in my app.
Thank you for help,
J
To get the item that is "clicked", you need to use itemInvoked. Selection changed would happen when the user cross slides on the item to select it, rather than taping/clicking to "invoke" it.
http://msdn.microsoft.com/en-us/library/windows/apps/br211827.aspx has some basic details.

Jquery toggle div hide/show from dynamic id's

I have, essentially, an unlimited number of containers with dynamic ids and a dynamic menu to load each containers content. I have done this with static id's (but still seems such a heavy use) but do not know where to go to use dynamic.
When a nav link (from .img_select) is clicked it shows the corresponding div and hides all others in the group. It also updates the class of the menu items so the clicked item becomes selected, and the remaining become unselected.
<div id="pf1_1">
My content for pf1_1 container goes here
</div>
<div id="pf1_2">
My content for pf1_2 container goes here
</div>
<!-- This could have a dozen+ or more divs, or only 1 //-->
<p class="img_select"><span class="pf_current" id="pfc1_1">1-1</span> <span class="pf_next" id="pfc1_2">1-2</span></p>
<div id="pf2_1">
My content for pf2_1 container goes here
</div>
<div id="pf2_2">
My content for pf2_2 container goes here
</div>
<div id="pf2_3">
My content for pf2_3 container goes here
</div>
<!-- This could have a dozen+ or more divs or only 1 //-->
<p class="img_select"><span class="pf_current" id="pfc2_1">2-1</span> <span class="pf_next" id="pfc2_2">2-2</span> <span class="pf_next" id="pfc2_3">2-3</span></p>
the jquery I would like to create dynamically something similar to this
<script>
$(document).ready(function(){
$("#pf1_2").hide();
$("#pf2_2").hide();
$("#pf2_3").hide();
$('#pfc1_1').click(function(){
$("#pf1_2").hide('fast');
$("#pf1_1").show('fast');
$("#pfc1_1").removeClass("pf_next").addClass("pf_current");
$("#pfc1_2").removeClass("pf_current").addClass("pf_next");
});
$('#pfc1_2').click(function(){
$("#pf1_1").hide('fast');
$("#pf1_2").show('fast');
$("#pfc1_2").removeClass("pf_next").addClass("pf_current");
$("#pfc1_1").removeClass("pf_current").addClass("pf_next");
});
$('#pfc2_1').click(function(){
$("#pf2_2").hide('fast');
$("#pf2_3").hide('fast');
$("#pf2_1").show('fast');
$("#pfc2_1").removeClass("pf_next").addClass("pf_current");
$("#pfc2_2").removeClass("pf_current").addClass("pf_next");
$("#pfc2_3").removeClass("pf_current").addClass("pf_next");
});
$('#pfc2_2').click(function(){
$("#pf2_1").hide('fast');
$("#pf2_3").hide('fast');
$("#pf2_2").show('fast');
$("#pfc2_2").removeClass("pf_next").addClass("pf_current");
$("#pfc2_1").removeClass("pf_current").addClass("pf_next");
$("#pfc2_3").removeClass("pf_current").addClass("pf_next");
});
$('#pfc2_3').click(function(){
$("#pf2_2").hide('fast');
$("#pf2_1").hide('fast');
$("#pf2_3").show('fast');
$("#pfc2_3").removeClass("pf_next").addClass("pf_current");
$("#pfc2_2").removeClass("pf_current").addClass("pf_next");
$("#pfc2_1").removeClass("pf_current").addClass("pf_next");
});
});
</script>
If you can point me in the right direction, be much appreciated, thank you.
Seeing as I found a way, not saying was right way, but it worked, I wanted to share it with you.
I would like to point out it didn't take 2 months to sort a solution, just 2 months to post it here.
To combat this;
$("#pf1_2").hide();
$("#pf2_2").hide();
$("#pf2_3").hide();
I used this;
$("div[id^=pf_]").hide();
$("div[id$=_1]").show();
first it hides all id's starting with pf_
then it shows only the first by matching id ending in _1
To combat this;
$('#pfc1_1').click(function(){
$("#pf1_2").hide('fast');
$("#pf1_1").show('fast');
$("#pfc1_1").removeClass("pf_next").addClass("pf_current");
$("#pfc1_2").removeClass("pf_current").addClass("pf_next");
});
// etc.....
I used this;
$('span[id^=pfc_]').live("click", function(e) {
e.preventDefault();
var id = $(this).attr('id').split('_');
var classname = $(this).attr('class');
var navwidth = $("div[id^=pf_"+id[1]+"_"+id[2]+"]").width();
if(classname != 'pf_current'){
$("span[id^=pfc_"+id[1]+"_]").removeClass("pf_current").addClass("pf_next");
$("span[id^=pfc_"+id[1]+"_"+id[2]+"]").removeClass("pf_next").addClass("pf_current");
// change portfolio item
$("div[id^=pf_"+id[1]+"_]").hide();
$("div[id^=pf_"+id[1]+"_"+id[2]+"]").delay('5').show();
}
});
Hope this helps someone else