I have a DevExpress gridview with the following settings.
settings.Name = "DetailGridView";
// this calls DetailGridView.StartEditRow() on client side
settings.ClientSideEvents.RowClick = "Fn.startEditingRow";
settings.SettingsEditing.Mode = DevExpress.Web.GridViewEditingMode.Inline;
I have removed many other settings I have for simplicity, but ask if you think I need to show some other settings which are relevant.
Now I want to invoke a JavaScript function at each cell click. To do that I have added this settings, as per this SO answer, and this DevExpress thread
settings.HtmlDataCellPrepared += (sender, e) =>
{
string onClickFunctionJS = "Fn.DetailOnlyOnCellClick({0},'{1}');";
e.Cell.Attributes.Add("onclick", String.Format(onClickFunctionJS, e.VisibleIndex, e.DataColumn.FieldName));
};
The JS function Fn.DetailOnlyOnCellClick() prints to console the value of the field name (the 2nd argument). But it only prints clicked cell's field name the first time the row is clicked. After that clicking on a different cell in the selected row doesn't trigger the function Fn.DetailOnlyOnCellClick() anymore. I have observed that if I turn off ClientSideEvents.RowClick, it works fine, but I can't turn that off for other reasons. How can I get the which cell the user clicks on while keeping ClientSideEvents.RowClick on?
I have solved my problem, thanks to DevExpress support center. First, I couldn't use settings.HtmlDataCellPrepared because, as I mentioned in the question, the grid view enters edit mode when a row is clicked, and in edit mode settings.HtmlDataCellPrepared is not supposed to work the way I need it for my situation. So I started to use this code:
settings.CellEditorInitialize = (s, e) =>
{
var elementEditor = e.Editor;
string onClickFunctionJS = "DetailOnlyOnCellClick({0},'{1}');";
DevExpress.Web.Rendering.GridViewTableInlineEditorCell cell =
elementEditor.Parent as DevExpress.Web.Rendering.GridViewTableInlineEditorCell;
cell.Attributes.Add("onclick",
String.Format(onClickFunctionJS, e.VisibleIndex, e.Column.FieldName));
};
This code worked fine for every different control. The only catch was when the field is a checkbox and the cell is disabled. To get around this, I have used this code for checkbox controls:
string func = String.Format(
"ASPxClientUtils.AttachEventToElement(s.GetMainElement(), 'click', function() {{ {0} }} )",
String.Format(onClickFunctionJS, e.VisibleIndex, e.Column.FieldName));
(elementEditor as ASPxCheckBox).ClientSideEvents.Init = String.Format("function(s,e){{ {0}; }}", func);
This code works perfectly.
Links to the two methods used:
ASPxClientUtils.AttachEventToElement
ASPxClientControlBase.GetMainElement
P.S.: Both these approaches I have shown here are from DevExpress experts, and I got these answers from DevExpress's support center. I will provide link to my question once I can fix the issue with license and the ticket becomes public.
Related
Is there a way to set a listener to column-menu, so that an event is fired when I open and close the menu?
Feature description: https://www.ag-grid.com/javascript-grid-column-menu/
I already searched in the official documentation, but didn't find an answer.
Background is:
I want to store the table state with displayed cols, sorting, position of cols, filter etc. in a database. Of course I could use the listeners like onFilterChanged, onDisplayedColumnsChanged or onSortChanged.
Problem is, that it will be fired every time when something changes and so there are produced a lot of unwanted api-calls.
Thats why I want to perform one call when the column-menu is closed.
Update
As Viqas said in his Answer, there is no official way to do it. I
tried to avoid the solution with postProcessPopup and tried to find a cleaner
solution for my problem - to store the table state.
For a workaround with a callback when ColumnMenu is closed Viqas Answer is more appropriate.
Notice that this is no workaround for the callback itself - it is just a (possible) solution to store the table state and perform ONE API Call
I used the ngOnDestory() function of Angular.
ngOnDestory(): void {
const tableState = {
columnState: this.gridOptions.columnApi.getColumnState(),
columnGroupState: this.gridOptions.columnApi.getColumnGroupState(),
sortState: this.gridOptions.api.getSortModel(),
filterState: this.gridOptions.api.getFilterModel(),
displayedColumns: this.gridOptions.columnApi.getAllDisplayedColumns()
};
// submit it to API
}
You're right, there's no official way to do it. A workaround could be to detect when the menu is closed yourself. Ag-grid does provide you the postProcessPopup callback (see here) which provides the parameter of type PostProcessPopupParams; this contains the column menu popup element that is displayed, so you could check when the menu is no longer visible.
Create a variable to store the columnMenu element in:
columnMenu: any = null;
Store the columnMenu in this variable using the ag-grid event postProcessPopup:
<ag-grid-angular [postProcessPopup]="postProcessPopup"></ag-grid-angular>
this.postProcessPopup = function(params) {
this.columnMenu = params.ePopup;
}.bind(this);
Then create a listener to detect when the column menu is no longer visible in the dom:
this.renderer.listen('window', 'click',(e:Event)=>{
console.log(this.columnMenu)
const columnMenuIsInDom = document.body.contains(this.columnMenu);
if (!columnMenuIsInDom && this.columnMenu != null)
{
this.columnMenu = null;
}
});
This is slightly hacky and a workaround, but I can't think of a better way at the moment.
Take a look at this Plunker for illustration.
Here is a drop down list in SmartClient: http://www.smartclient.com/#dropdownGrid.
I want to make a selection using JavaScript. Like, I run some JavaScript in console, and the drop list will select a specific item.
I did some research, found a code snap to do this (the code is in Java, but I think there should be similar functions in JavaScript):
Record rec = perdomainGrid.getRecordList().find("domaine_id", domaine_id);
perdomainGrid.selectSingleRecord(rec);
If I want to make selection, first I need to obtain perdomainGrid object. In my above giving link, the drop down list id in GWT is exampleForm (can be seen in dropDownGrid.js tab). I try to get the object by:
var form = isc.DynamicForm.getById("exampleForm");
form does exist, but there is no getRecordList() function on it, there is selectSingleRecord() function on it though.
I try to check form's class by form.className, its value is normal. I don't know what does that mean.
I'm kind of confused now. Could somebody help me on this?
isc_SelectItem_5 has a function called pickValue(), it takes one parameter SKU. This function can be used to select item.
var itemName = "Letter Tray Front Load Tenex 200 Class Blk #23001";
var data = isc_SelectItem_5.optionDataSource.cacheData;
var targetSKU = data.find(function(e) {
if (e.itemName == itemName) {
return e;
}
}).SKU;
isc_SelectItem_5.pickValue(targetSKU);
I am using DataTables.
What I am trying to do is: by using one of the columns values, get page number, where this value is located.
I have tried this: jumpToData()
BUT this didn't work out. The reason is that
var pos = this.column(column, { order: 'current' }).data().indexOf(data);
in jQuery.fn.dataTable.Api.register('page.jumpToData()' returns value >=0 ONLY if I was placed on page where value was.
For example, I want to detect page where needed value is, but I am staying on another page, so to detect value on... page 3, I need to go to this page and only then I can detect it, which makes no sence at all.
What I need to do, is: by staying on pirst page, using value from another pages, detect those pages numbers and then navigate to them:
$('#Grid_grid').DataTable().page(PageNumber).draw(false);
How can I accomplish that?
EDIT:
Got some idea (several changes in jumpToData()):
jQuery.fn.dataTable.Api.register('page.jumpToData()', function (data, column) {
for (var i = 0; i < this.page.info().pages; i++) {
var test = this.page(i).column(column, { order: 'current' }).data().indexOf(data);
if (test >= 0) {
this.page(i).draw(false);
return this;
}
}
return this;
});
(EDIT 2: idea didn't paid off, no difference)
BUT now I got second issue:
None methods of datatable works in .cshtml page.
For example I need to get overall page count. I doing this:
$('#Grid_grid').DataTable().page.info().pages;
and this return me 0;
Meanwhile, putting it in to console (Chrome F12) works fine (returns 5). Whats the matter?
EDIT 3:
Came up with this:
function LoadPage(value) {
var table = $('#Grid_grid').DataTable();
var pageNumber = table.search(value).page();
table.page(pageNumber).draw(false);
}
Looks promising BUT, I still cant validate it because in console DataTable methods are working, but in .cshtml no. (search() or page() returns nothing).
EDIT 4:
Moved issue to another question
CAUSE
Your new API method page.jumpToData() tries to query all pages data because second argument selector-modifier in column() API method has property page: 'all' by default. As written it will always stay on first page.
SOLUTION
There is original page.jumpToData() plug-in posted by Allan Jardine, creator of DataTables. It works as intended and can be used instead of your modification to avoid unnecessary iterations.
$.fn.dataTable.Api.register('page.jumpToData()', function (data, column) {
var pos = this.column(column, {
order: 'current'
}).data().indexOf(data);
if (pos >= 0) {
var page = Math.floor(pos / this.page.info().length);
this.page(page).draw(false);
}
return this;
});
DEMO
See this jsFiddle for code and demonstration.
NOTES
In the demo above I added console.log("Number of pages", table.page.info().pages); just to demonstrate that API method works. However they may work because I have HTML-sourced data.
If you have Ajax-sourced data, you need to query number of pages only when data has been loaded. Use initComplete option to define a callback function that will be called when your table has fully been initialised, data loaded and drawn.
This is my first post so please be kind with me. :D
What i want is to select a person from a DropDownList (which is on table 1) and when i press a button, I want to move the selected person to another table (on table 2).
I will post some screens from my PC because i cant add code (i receive some error where say is too much code or something like that...)
Here is the link with Photos. I dont have 10 reputation so i cant post different URL with description...:D
http://postimg.org/gallery/13lmzz4kq/
I write description in every photo :D
Ty in advance !
In your plunker you have a method moveAudit. This method receives an item:
$scope.moveAudit = function (item) //Function for moving the unassigned audits
{
//var assignedAudit = $scope.assignedAudit; //--> you dont need this here
//var audit = $scope.unassignedAudit; //--> unused variable
//var auditId = $scope.unassignedAudit.IdUnassignedAudit; //--> unused variable
//TODO: here you need to add the selected 'expert' to item
// inspect/debug how your form POST passes this information to the controller
// ideally put it in a scoped var or pass it in the method: $scope.moveAudit = function (item, selectedExpert)
item.AssignedExpert = $scope.selectedExpert
//add to AssignedAudit
$scope.assignedAudit.push(item);
console.log("Row added: ", $scope.assignedAudit);
//TODO: probably you want to remove the item from $scope.assignmentExperts
};
I cannot debug the plunker since it is incomplete, but this should do the trick.
Upon further inspection of your code it looks like $scope.ddSelection is the selected expert.
I have a field named "selectedTime" in a document, this fields stores the selected timings added by user.Adding times is working perfect.This is back-end.
Now I will explain this issue of selecting date from front end.I have given a button add to add times.The custom control of date-time gets added to repeat control on click of Add button.Even if I check in document it shows the list of selected times.Even this works fine.
Now if I want to delete a selected time from repeat control randomly, it deleted that particular record from document, but on the page the last record of the repeat gets disappears,
I was assuming that this is the issue with partial refresh of repeat control,I have even tried that but no result.Full refresh breaks the page.
java script code for the delete button
`var doc:NotesDocument = database.getDocumentByUNID(context.getUrlParameter("refId"))
var selectedTimes:java.util.Vector = doc.getItemValue("selectedTimes");
if(selectedTimes != null){
var sdtString = getComponent("inputHidden1").getValue();
if(selectedTimes.contains(sdtString))
selectedTimes.remove(sdtString);
doc.replaceItemValue("selectedTimes",selectedTimes);
doc.save();
};
var url:XSPUrl = context.getUrl();
view.postScript("window.refresh('"+url+"')");`
I know it is difficult to understand what i want to explain but any suggestion on this will be appreciated.
Even if anybody have any idea to delete the a field values of a documents,In my case field name is "selectedTimes" and the values are added times in repeat control, Please share.
Edit 1:
//Repeat Control
var doc:NotesDocument = database.getDocumentByUNID(context.getUrlParameter("refId"))
var selectedTimes:java.util.Vector = doc.getItemValue("selectedTimes");
return selectedTimes;
Another try could be link the repeat with a viewScope instead of the document:
1) In the event beforeLoadPage/afterLoadPage: Get the value from the document, and put it in a viewScope variable:
// beforeLoadPage event:
// ... get the doc
viewScope.selectedTimes = doc.getItemValue("selectedTimes");
2) In the repeat control, use the viewScope:
<xp:repeat value="#{viewScope.selectedTimes}"...
3) When an update is done, update both the viewScope and the document:
//...update the View Scope variable and get the document:
doc.replaceItemValue("selectedTimes", viewScope.selectedTimes);
This could be a hint if the document would be added as DataSource:
Do you have the document included in the XPage as a DataSource? In that case, try to get and update the NotesXspDocument instead of the Document from the DB:
XPage:
<xp:this.data>
<xp:dominoDocument var="xspDocument"
action="editDocument"
documentId="#{param.unid}">
</xp:dominoDocument>
</xp:this.data>
SSJS code: work directly with the XspDocument
var selectedTimes:java.util.Vector = xspDocument.getItemValue("selectedTimes");
...
xspDocument.replaceItemValue("selectedTimes", selectedTimes);
This could be a hint if the value would not be removed from the document:
In sdtString you are getting a String value:
var sdtString = getComponent("inputHidden1").getValue();
If you have the time values stored as NotesDateTimes, you will get this type of value inside the Vector and the remove method won't find the String and nothing will be removed.
// In a Vector<NotesDateTime> the String cannot be found:
selectedTimes.remove(sdtString);
Be sure you remove the same type of value you get in the Vector