YUI Datatable Drag and Drop together with Cell Editor - javascript

I have a problem with YUI (2) Datatable and Drag and Drop combo. I have a table of items, one of them is item description which I made editable (and saveable) with YUI's TextboxCellEditor. I also made the rows draggable (so I can drop them to another container).
But I'm stuck with two items:
- I can only get DnD by clicking on the second column (the first one does not work)
- I can only get it to work on the second attempt since initialization.
Here is a snipet from my JS (simplified):
nameFormatter = function (elCell, oRecord, oColumn, oData) {
var link = '/share/page/site/' + Alfresco.constants.SITE + '/document-details?nodeRef=' + oRecord.getData('nodeRef');
elCell.innerHTML = '<span>' + oData + '</span>';
};
descFormatter = function(elCell, oRecord, oColumn, oData) {
elCell.innerHTML = '<pre class="desc">' + oData + '</pre>';
};
columnDefs = [
{key: "name", label: "Name", sortable: true, formatter: nameFormatter, resizable: true}
, {key: "description", label: "Description", sortable: true, formatter: descFormatter, editor: new YAHOO.widget.TextboxCellEditor(), resizable: true}
];
this.mediaTable = new YAHOO.widget.DataTable(this.id + "-media-table", columnDefs, this.dataSource, {
MSG_EMPTY: "No files"
});
// now we want to make cells editable (description)
var highlightEditableCell = function(oArgs) {
var elCell = oArgs.target;
if(YAHOO.util.Dom.hasClass(elCell, "yui-dt-editable")) {
this.highlightCell(elCell);
}
};
this.mediaTable.subscribe("cellMouseoverEvent", highlightEditableCell);
this.mediaTable.subscribe("cellMouseoutEvent", this.mediaTable.onEventUnhighlightCell);
this.mediaTable.subscribe("cellClickEvent", this.mediaTable.onEventShowCellEditor);
this.mediaTable.subscribe("editorSaveEvent", this.saveDesc);
this.mediaTable.subscribe('cellMousedownEvent', this.onRowSelect);
The saveDesc function is simple Ajax call to save that items' description.
Here is the onRowSelect function:
onRowSelect = function(ev) {
console.log(" == method onRowSelect");
var tar = Event.getTarget(ev)
, dd
;
dd = new YAHOO.util.DDProxy(this.getTrEl(tar));
dd.on('dragDropEvent', function(e) {
YAHOO.Bubbling.fire('myCustomEvent', { target: e.info, src: tar});
dd.unreg();
});
};
If I just click on desc, I get the text editor, if I click on name, I get the link open.
Like I said, when I mouseDown on the second column (description), in first attempt I get nothing. Then I click and hold the second time, and this time it works (I get a DDProxy and I can Drag and drop it to the target, everything works there).
And the other issue is that when I click and hold on the name column, I don't get the DDProxy (I get my onRowSelect event and the correct row).
What am I doing wrong here?
UPDATE: Resolved the first issue by using Satyams answer - removing the formatter for my cell with link.
The second issue (only on the second click) was resolved because I added the missing dd.handleMouseDown(ev.event) in my onRowSelect function.

Dav Glass, who wrote DD, has this example in his page: http://new.davglass.com/files/yui/datatable4/ I used it in my example: http://www.satyam.com.ar/yui/2.6.0/invoice.html and it works just fine, though it is somewhat more involved than you have there. I'm sorry I cannot help you more precisely with your issue, D&D is not my string point but I hope the examples might help.
One reason for your problem might be that link in the cell. This is not a good idea, whether you have DD or not. In general, the recommended way to deal with this is to listen to the cellClickEvent and if the column of the cell that got clicked is the one that 'navigates', you build the URL based on the information in the record clicked and then navigate or do whatever you want with it. This allows the DataTable to render much faster, as it needs no formatter and, in the odd event that someone does click the cell, then and only then you bother to make the calculations. The size and number of DOM elements on the page also goes down.
Likewise, with the other cell with the pre-formatted tag, you can easily avoid it. The cells in each column in a DataTable gets a CSS class name made from the "yui-dt-col-" prefix and the 'key' value of the column (for example: yui-dt-col-description). Thus, you can simply add a style declaration for that CSS class name and spare yourself the formatter. Likewise, for highlighting the editable cells, how about defining some style for the .yui-dt-editable:hover selector? I've never done it myself but I imagine it should work.

Related

How to get rowIndex in extjs widget column

I need a button in a widget column to know its rowIndex in an ExtJS 6 panel.grid, so that on button click it can use that functionality. I know I can pull that information from the renderer function, but that seems to execute before the button has been created. Any ideas on how I can get the index?
Use indexOf on the gridview. You need to pass it the node as argument, which is the HTML element representing the row. In Ext JS 6, grid rows are HTML tables, so the button's row element can be found from the button element b as b.el.up('table'). The gridview can also be found as b.up('gridview'). So you get:
var rowIndex = b.up('gridview').indexOf(b.el.up('table'));
See in action: https://fiddle.sencha.com/#fiddle/snq
Building on Drake's answer, I'm using the event.record property instead. Unfortunately, it looks like you have to make the click event have a slight buffer, so it gets the proper record added to it. This works, but I'm not entirely sure if it's a proper way. Example:
{
width: 150,
xtype: 'widgetcolumn',
widget: {
text: 'Button',
xtype: 'button',
text: 'Get row index',
listeners: {
buffer: 1,
click: function(button, event, eOpts) {
var record = event.record;
alert(store.find('postid', record.get('postid'), 0, false, true, true))
}
}
}
}
Use the onWidgetAttach
A function that will be called when a widget is attached to a record. This may be useful for doing any post-processing.
http://docs.sencha.com/extjs/5.1.2/api/Ext.grid.column.Widget.html#cfg-onWidgetAttach
The function has both widget and record parameter.
You can do widget.record = record, and then the button will have the record member which you can access in the click listener

dgrid add new row on button click

I am trying to make an editable grid. I would like to provide users to be able to like more rows if needed. I tried going to their documentation yet it wasn't obvious.
Also, what does grid.newRow() do?
If you're trying to add a new row, you can always just add a new entry to the underlying grid store first.
Say you have a grid (named "grid" of users), you can have your button do this:
var button = new Button({
label: "Add User",
onClick: function() {
var user = {id: 1, name: "test"};
grid.store.add(user);
}
});
Also I don't believe the regular grids have a newRow option, only the onDemandGrid or onDemandList has a newRow option. But the above code should work for what you asked for.

How to rebind a Kendo ListView after changing template

I'm attempting to rebind the listview data after changing the template, based on a DropDownList value. I've included a JSFiddle for reference. When I rebind currently the values in the template are undefined.
Thanks!
JSFiddle link
I was thinking the best way to handle it would be in the 'select' or 'change' function:
var cboDetailsCategory = $("#detail").kendoDropDownList({
data: [
"All",
"Customer",
"Location",
"Meter",
"Other"],
select: function (e) {
var template = $("#" + e.item.text()).html();
console.log("template", template);
$("#details").html(template);
},
change: function (e) {
},
please refer to the JSFiddle link and this graphic as a visual
Here is a lengthier workflow:
User completes a name search and clicks a search button.
Name results are populated in a listview, rendered individually as button controls using a template.
User then clicks one of the name results (shown as the button text).
A dropdownlist of categories ('All' <--default , 'Location', 'Customer'...) gives the user the ability to target what subject of data they want to see. 'All' is the default, showing all details about the selected name.
So by default the 'All' template is populated.
If user wants to see the 'Location' details (template) they select it from the dropdownlist.
The template shows but the values are all blank. The only way to populate it is to click the name (button) again.
I want to remove the need for having to re-click the button (name) to populate the template ('Location', etc...).
I have put together a JSFiddle showing the structure. Though due to the data being private and served over secure network I cannot access it.
Refer to JSFiddle:
I believe the issue is that the onclick event grabs the data-uid and passes it to the initial default template (named 'All' but it's not included in code as it's lengthy). When the user changes the dropdownlist (cboDetailsCategory) and selects a new template I lose the data.
Thanks for your help. I'm really stuck on this and it's a current show stopper.
There isn't an officially supported way to change templates, without destroying the listview and rebuilding it. However, if you don't mind poking into into some private api stuff (be warned I can't guarantee that kendo won't break it without telling you) you can do this
var listview = $("#MyListview").getKendoListView();
listview.options.template = templateString;
listview.template = kendo.template(listview.options.template);
//you can change the listview.altTemplate the same way
listview.refresh(); //redraws the elements
if you want to protect against unknown API changes you can do this, which has A LOT more overhead, but no risk of uninformed change (untested!)
var listview = $("#MyListview").getKendoListView(),
options = listview.options;
options.dataSource = listview.dataSource;
listview.destroy();
$("#MyListview").kendoListView(options);
Here's the solution, thanks for everyone's help!
JSFiddle Link
The issue was where I was setting the bind:
$("#list").on("click", ".k-button", function (e) {
var uid = $(e.target).data("uid");
var item = dataSource.getByUid(uid);
var details = dropdown.value();
var template = $("#" + details).html();
$("#details").html(template);
kendo.bind($("#details"), item);
currentData = item;
});

Dojo: for each row in a grid, have a button that when clicked shows more information from the data store

This is proving to be surprisingly difficult.
Suppose I have a grid that displays the name and size of files.
Information is loaded from a JSON file into an instance of dojo/store/Memory and then key attributes presented in the grid. How would I include a button on each row of the grid, that when clicked, displays more attributes about the file? These attributes are stored in the dojo/store/memory.
Right now I have a row like this in the grid:
{name:"More", field:"id", formatter: buttonFormatter, datatype:"string", noresize: true, width: "120px"}
And I attempted to pass the ID to a button using the formatter:
var buttonFormatter = function(inValue){
var newButton = new Button({
label: "Details",
onClick: function(inValue){
alert("More information about " + inValue + " goes here");
}
});
return newButton;
}
This doesn't work however.
The difficulties, as far as I can tell, are:
1) Associating each specific button with a specific file from the store
2) Giving the onClick javascript access to data from the store
Thanks for your help!
Tristan
You can use dojo-data-type-event attach point to do the operation. The corresponding method in the grid widget instance will show your more attributes in different style like tooltip,append,dialog and etc as you need
Not sure if this might helps you, but have a look at it.
In this example there's an onclick-Event on a button to zoom to the clicked row.
https://developers.arcgis.com/en/javascript/jssamples/fl_zoomgrid.html
Regards

jqGrid, how to add a row in any position inside the grid via modal form?

Is there any way to do that?
I use jqGrid form editing feature to populate my grid. But jqGrid only permits to add a row on top or bottom position inside the grid. What I want to do is be able to previously select the desired position on the grid (by clicking in any existing row) and then add a row above or below that selected row.
Sorry for my poor english. Thanks in advance.
What you need is possible and is not so complex. Look at the very old demo from the answer. If you have the column with name: 'myColName', and you want to insert any information in the edit or add form after the information about the column, you can just inset the row of data inside. The form contain <table>. So you should insert the <tr> having one or two child <td> elements (the cell for the label and the cell for the data). To be conform with other data in the form you should use class="FormData" for the <tr> element. The first <td> element (in the column for the labels) should has class="CaptionTD ui-widget-content" and the second <td> element (in the column for the data for the input of modification) should has class="DataTD ui-widget-content":
{ // edit options
recreateForm: true,
beforeShowForm: function ($form) {
var $formRow = $form.find('#tr_Name'); // 'Name' in the column name
// after which you want insert the information
$('<tr class="FormData"><td class="CaptionTD ui-widget-content">' +
'<b>Label:</b>' + // in the line can be any custom HTML code
'</td><td class="DataTD ui-widget-content">' +
'<span></span>' + // in the line can be any custom HTML code
'</td></tr>').insertAfter($formRow);
}
}
UPDATED: OK, now I understand what you want. The problem is that addRowData will be called for adding of new row with the option addedrow of editGridRow. So if you use reloadAfterSubmit: false option you can add the new row either as 'first' or as the 'last' in the grid. To be able to use 'after' or 'before' parameter of addRowData the method addRowData must be called with one more parameter which specify the id of the row before which (or after which) the new row will be inserted.
At the first look it seems that only with respect of modification of the source code of jqGrid your requirement can be implemented. In reality you can do implement your requirements with very small code and without modification of the source code of jqGrid. I suggest the following:
You can save the pointer to the original implementation of addRowData in a variable and overwrite it
with your implementation:
var oldAddRowData = $.fn.jqGrid.addRowData;
$.jgrid.extend({
addRowData: function (rowid, rdata, pos, src) {
if (pos === 'afterSelected' || pos === 'beforeSelected') {
if (typeof src === 'undefined' && this[0].p.selrow !== null) {
src = this[0].p.selrow;
pos = (pos === 'afterSelected') ? 'after' : 'before';
} else {
pos = (pos === 'afterSelected') ? 'last' : 'first';
}
}
return oldAddRowData.call(this, rowid, rdata, pos, src);
}
});
The code above introduce two new options of addRowData: 'afterSelected' and 'beforeSelected'. If you include the code before creating of jqGrid the grid will be created using your custom addRowData, so you can use new addedrow: 'afterSelected' or addedrow: 'beforeSelected' as the options of Add form.
The demo shows live that the suggestion work. You should don't look at many other code of the demo. The current implementation of form editing don't support local editing, but in I used in the demo just old code which do this. So the total code of the demo is relatively long, but the part which I want to demonstrate you can easy find inside.

Categories