my web application is based on dojo 1.6.0.
The problem that I have is based on event handlers basically and/or their utilization
in dojos "dojox.grid.EnhancedGrid" library.
My application contains a dojox Enhanced Grid with a great number of rows. (100+)
This Enhanced Grid makes use of the "cellMenu"-Plugin to show a context menu
for each Grid Cell on right click.
My goal is to use the context menu for "smart" selection of rows.
For example:
The user right clicks on a cell wich is positioned in the column "lastname" and has the value "miller". He then clicks "smart select" in the context menu.
The application will then loop over the row data and select all rows wich have "miller" as "lastname".
In the aftermath the user will innitiate actions with the selected rows through press of a button.
Here is a small sourcecode example illustrating the declarative approach for visualization of the Enhanced Grid with Context Menu:
<table dojoType="dojox.grid.EnhancedGrid" plugins="{cellMenu:'myMenu'}">
<div id="myMenu" dojoType="dijit.Menu">
<div id="mi1" dojoType="dijit.MenuItem">Do something with this cell</div>
<div id="mi2" dojoType="dijit.MenuItem">Do something else with this cell</div>
</div>
<thead>
definition of columns
</thead>
</table>
Action code is handled separate from the visualization in js-Files:
<script type="text/javascript">
dojo.addOnLoad(function(){
dojo.connect(dijit.byId('mi1'),'onClick',function(event){
//Use Data from the cell clicked to do something
});
dojo.connect(dijit.byId('mi2'),'onClick',function(event){
//Use Data from the cell clicked to do something else
});
});
</script>
I am relatively new to dojo and do not have experience with the handling of the EnhancedGrid.
So my problem is the following:
When I click inside the context-menu which is a "dijit.Menu" the "onClick" event
of the "dijit.MenuItem" contained therein is triggered.
Inside this event handler I need to read the contents of the "Grid Cell" the context menu
was opened on, but I do not have (or do not currently know) a way to get a reference to the "Grid Cell".
With default tactics I might be able to get a reference to the MenuItem and from there maybe to the Menu, but I was unable to find an attribute containing the reference to the "Grid Cell" or a row/column ID that would enable me to access the Cell clicked.
Since context menus are there to do something with the "item" they were opened with by right clicking I think that there has to be a way (as meant by the designer) to access this "item".
I have not yet found a documentation or example illustrating this and would appreciate all your help.
Here is a possible sollution (maybe not the best there is) for using a context menu on a dojo grid for selection purposes:
Visual Part (Declarative)
<table id="grid" dojoType="dojox.grid.EnhancedGrid"
plugins="{indirectSelection:true,menus:{cellMenu:'GridCellMenu'}}">
<div dojoType="dijit.Menu" id="GridCellMenu" style="display:none;">
<div dojoType="dijit.MenuItem" id="mi_selectSimilar">select similar items</div>
<div dojoType="dijit.MenuItem" id="mi_deSelectSimilar">DEselect similar items</div>
</div>
<thead>
<tr>
<th field="id">ID</th>
<th field="lastname">Lastname</th>
<th field="firstname>firstname</th>
</tr>
</thead>
</table>
JavaScript Background
// Stylesheets and Dojo Groundwork are neglected in this example
<script type="text/javascript">
dojo.require('dijit.Menu');
dojo.require('dijit.MenuItem');
dojo.require('dojox.grid.EnhancedGrid');
dojo.require('dojox.grid.enhanced.plugins.IndirectSelection');
dojo.require('dojox.grid.enhanced.plugins.Menu');
var currentEvent = null;
var fn_selectSimilar = function(){
var data = currentCell.grid.store.objectStore.data;
dojo.forEach(data,function(row,idx){
if(row[currentEvent.cell.field] == data[currentEvent.rowIndex][currentEvent.cell.field]){
currentEvent.cell.grid.selection.addToSelection(idx);
}
}
}
var fn_deSelectSimilar = function(){
var data = currentEvent.cell.grid.store.objectStore.data;
dojo.forEach(data,function(row,idx){
if(row[currentEvent.cell.field] == data[currentEvent.rowIndex][currentEvent.cell.field]){
currentEvent.cell.grid.selection.deselect(idx);
}
}
}
dojo.addOnLoad(function(){
dojo.connect(dijit.byId('grid'),"onCellContextMenu",function(e){
currentEvent = e;
});
dojo.connect(dijit.byId('mi_selectSimilar'),"onClick",fn_selectSimilar);
dojo.connect(dijit.byId('mi_deSelectSimilar'),"onClick",fn_deSelectSimilar);
});
</script>
This will go through all the selected items in the grid and get the value of the cell named "YourGridColumnName".
var items = YourDataGridId.selection.getSelected();
if (items.length) {
dojo.forEach(items, function(selectedItem) {
alert(YourDataGridId.store.getValues(selectedItem, "YourGridColumnName"));
})
}
Hope it helps.
You can link an event handler into the mouse and keyboard events that will bring up the context menu. The event has a row index that you can store in a place where the menu item will find it.
Related
I would like to know if it would be possible to select the menu item from one created almost entirely with javascrip with selenium. As html tags for this table are only available in view source
<table id = "table_id"> <tr> <td> <script> *** </script> </td> </tr> </table>
and instead of asterisks there is a javascript that dynamically creates this menu with
with (milonic = new menuname ('menu_name'))
and aI () strings. When you click on a menu item, a submenu opens. My question - how can i for example select item no.2 from the menu and then item no.3 from the submenu? Such a construction as
driver.find_element_by_id ('table_id').click ()
does not help, only the menu item in the middle is selected, but not clicked.
Ok i got solution, i used F12 in FF and found all the links i needed. The instability can be solved with this code:
wait = WebDriverWait (driver, 10)
wait.until (EC.element_to_be_clickable ((By.ID, "id"))). click ()
I have a table that is built from items in a DB and they contain sensitive information that I don't want to display until you click on a link contained in another table cell.
|item1|item2|click to show item3|(hidden span within cell)|
When you click on the link in cell 3 it will then show cell 4. I know how to accomplish this in typical jquery, but am not sure how to accomplish this in emberjs. Any ideas?
A JS fiddle of your setup would make this easier, but basically you would set a property on your controller from an action.
<span {{action showCell4}}>click to show item3</span>
on your controller have the showCell4 action:
actions: {
showCell4: function() {
this.set('cell4visible', true);
}
}
then for the table add a class binding
<td {{bind-attr class="cell4visible:visibleClassName:hiddenClassName">
sensitive info here
</td>
Dojo 1.5. I have an enhanced grid that has a rowMenu defined like so:
<div dojoType="dijit.Menu" id="rowMenu" style="display: none;">
<div dojoType="dijit.MenuItem" id="menuUsers">Add/Edit Users</div>
</div>
I listen to the onclick for that menu item like this:
dojo.connect(dijit.byId("menuUsers"), "onClick", addEditUsers);
If I try to use e.rowIndex in addEditUsers, it is undefined. The only way I've been able to figure out how to get the row the user right clicks on is by a separate row listener:
dojo.connect(dijit.byId("grid"), "onRowContextMenu", rowContextMenu);
From rowContextMenu(), e.rowIndex is available, so I can get row data using
var item = e.grid.getItem(e.rowIndex);
console.log(e.grid.store.getValue(item, 'name')); // this will show the value of a 'name' column for the row the user right clicked.
So I could use this to toggle a global/object (e.g. currentContextItem), but it seems like there's gotta be an easier approach. Is there not a direct way to get at the rowIndex/data from the context menu item listener? Note that I cannot use grid.selection.getSelected() because that is whatever row the user last left clicked on.
AFAIK, there is no other solution. In fact, I asked the same question months ago, and that was the only solution I got.
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.
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);
}
.
<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>
.
<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.
I've asked a lot of jQuery questions recently as I'm trying to use it rather good old Javascript, as I mentioned in previous questions, "I'm currently having to extend an very old ASP.NET site which has a database generated front end and is a behemoth of an application, it needs completely rewriting - however I've been told to add to it than redevelop it "
Now what I'm doing is once the backend is rendering a table to the interface I wish to loop through the tr elements of the table, within one of the td elements of the tr there are two radio buttons. I need to determine the name of the radio button group as I don't define them, the systems does using a GUID or something?
This is the table for example...
<table id="tableID">
<tr>
<td class="qCol">
<!-- Label here -->
</td>
<td class="qCo2">
<!-- img here -->
<!-- and a text box -->
</td>
<td class="qCo3">
<!-- select menu here -->
</td>
<td class="qCo4">
<!-- radio buttons here -->
</td>
<td class="qCo5">
<!-- select menu here -->
</td>
<td class="qCo6">
<!-- hidden validation image here -->
</td>
<tr>
</table>
Okay, I'm looping through the table and at the same time switching the innerHTML of one cell to another and hiding some of the rows, I'll be adding functionality to show these later, here's the jQuery:
$('#tableID tr').each(function (i) {
/*switch select and validation and clear */
$(this).children('td.qCol').html($(this).children('td.aCol5').html());
$(this).children('td.aCol5').html($(this).children('td.vCol'.html(""));
/* hide all but the first row*/
if (i >= 1) {
$(this).hide();
}
now I'm trying to determine the name attribute of the radio buttons that will be in the cell with class .qCo4, however I'm having no luck as the following returns an error and is "undefined"...
/* get the radio button name and check if either are selected*/
// check something exists...
if ($('input:radio', this).attr('name')) {
var thisRadioName = $(this).closest("input:radio").attr('name').val();
alert(thisRadioName);
}
$this is the tr element, so should I be using child rather than closest? If this makes no sense I can expand and explain better.
you should use find() or children(). closest() goes up the tree, while find looks for elements down the tree
var thisRadioName = $(this).find("input:radio").attr('name');
you can use also ':checked' to check if any radio is checked
var checkedRadio = $(this).find("input:radio:checked")
You should use children if you are absolutely sure that the elements you are looking for are direct child of the element, otherwise use find(). (using finds protect you from refactoring code if you modify the html, like adding a wrapping div for other reasons like styiling)
look at this fiddle: http://jsfiddle.net/nicolapeluchetti/Evq6y/
var thisRadioName = $(this).find("input:radio").attr('name');
should do what you want
I'm writing myself a little game in JavaScript, using jQuery. The game has a board, with cells in it, much like Minesweeper: the user clicks a cell, and its data needs to be changed in some way. Each cell is presented by a simple image, but has some more data associated with it.
What I mostly need is, when the user clicks a cell, I have to somehow determine the row and column which was clicked, manipulate the data appropriately and change the view.
On one hand, setting the click handler on every individual cell seems like an overkill, but if you set the click handler on the whole table, it becomes PITA to determine which table cell was clicked.
How would you handle such a situation? Maybe there is a plugin already that can simplify the whole thing?
add the click handler on the whole table. use event.target to get the clicked cell. add an attribute to each cell that will tell you what row/col it is, that way you dont have to run any massive/heavy JS to figure it out.
psuedocode:
$("table.game").click(function(e){
var cell = e.target;
var pos = $(cell).attr("name").split["_"];
var x = pos[0];
var y = pos[1];
return false;
});
markup:
<table class="game">
<tbody>
<tr>
<td name="0_0">
sdfasdfa
<td>
</tr>
</tbody>
</table>
note: having a name start with a digit isnt good, so fix as needed
This is a perfect example of a great use of the live() function. To find the x and y positions you just need to count the number of cells before or rows above this one:
$('#minesweeperTable td').live('click', function() {
var $this = $(this),
xPos = $this.prevAll('td').length,
yPos = $this.closest('tr').prevAll('tr').length
;
// your code here
});
The best thing about this is that no matter how many cells you have, there's only one event handler which makes for much better performance.
If your table is generated dynamically (js or php for instance) you could have each cell with a class and / or id attributes that gave you the information.
I don't know how you represent your cells so in pseudo code :
<table id="board">
<row>
<cell id="cell-0x0" />
<cell id="cell-0x1" />
...
</row>
<row>
<cell id="cell-1x0" />
...
</row>
...
</table>
Then in jQuery :
$('#board cell').click(function(){
var coord = $(this).attr('id').substr(5).split('x');
// do your stuff
});
If you have too many table cells setting the click handlers would be heavy, but you can make a workaround to calculate the box number from mouse click's event.page.X and event.page.Y this will give coordinatesof clicked pixel on your screen and you can calculate which box is under that pixel.
Or
You can also use event.target the get the node clicked.
check out jquery.event.
hope it helps, Sinan.
The click event bubbles and the original target can be found in the srcElement property of the event object (I think, or it might be another property, but it's there).