Using subgrid on jqGrid with data from parent row - javascript
I have a jqGrid displaying data in groups; there are too many columns to view conveniently, so I want to put less important data in a subgrid. There will only ever be one row in any subgrid. The data for the subgrid row will be obtained at the same time as the data in the parent row; I would like to use the subGridRowExpanded callback to obtain the data from the parent row and put it in the subgrid row when the user expands the row to see the subgrid.
Separately from what is shown here, I have tried using subGridModel to specify the name of the subgrid, but in that case and for the code shown, subGridRowExpanded is not invoked and I don't know why.
$(document).ready(function() {
$(".aclSection").show();
setListGrid();
function setListGrid() {
console.log("entering setListGrid() in opportunitySalesFunnelList.js");
$("#listGrid").jqGrid(getGridSettings());
$("#listGrid").jqGrid('navGrid', '#funnelOpportunityListPager',
{ cloneToTop:true,refreshtitle: "Reload Grid",
refreshtext: "Refresh Grid",
refreshstate:"current",
refresh: false,edit:false, add:false, del:false, search:false
}
);
$(window).bind('resize', function() {
jQuery("#grid").setGridWidth($('.gridParent').width()-30, true);
}).trigger('resize');
}
function getGridSettings() {
return {
url: "/salespoint/secure/funnel/opportunity/list/getDataMap"
,datatype: "json"
,height: "auto"
,width: 950
,shrinkToFit: true
,loadtext: "Loading..."
,colNames: ["Sales Mgr"
,"Agency / Spersn"
,"Sales Code"
,"Pros Name"
,"Prob"
,"Opp ID"
,"Opp Name"
,"Stg/Sts"
,"3 YR MRC"
,"3 YR NRC"
,"Last Activity"
,"Notes"
]
,colModel:[
{name:"salesManager", index:"salesManager" }
,{name:"agencyOrSalesperson", index:"agencyOrSalesperson" }
,{name:"salesCode", index:"salesCode" }
,{name:"prospectName", index:"prospectName" ,align:'left'}
,{name:"probability", index:"probability" }
,{name:"opportunityId", index:"opportunityId" }
,{name:"opportunityName", index:"opportunityName" ,align:'left'}
,{name:"stageAndStatus", index:"stageAndStatus" }
,{name:"mrc3yr", index:"mrc3yr" ,align:'right' , summaryType:'sum', summaryRound: 2, summaryRoundType: 'fixed' }
,{name:"nrc3yr", index:"nrc3yr" ,align:'right' , summaryType:'sum', summaryRound: 2, summaryRoundType: 'fixed' }
,{name:"lastActivity", index:"lastActivity" ,align:'left' }
,{name:"noteCount", index:"noteCount" }
]
,gridview: true
,subGrid: true
,subGridRowExpanded: function(subgrid_id, rowId1) {
console.log("subGridRowExpanded, subGridDivId1/rowId1:" + subGridDivId1 + "/" + rowId1);
var subgrid_table_id;
subgrid_table_id = subgrid_id + "_t";
var listGrid = $("#" + subgrid_id);
listGrid.html("<table id='" + subgrid_table_id + "' class='scroll'></table>");
listGrid.jqGrid({
colNames: ["Pros ID","Pros Age","Opp Age","Location Count by Service","# Locs","Activity Date","Activity Created By"]
,colModel: [ {name:"prospectId", index:"prospectId" }
,{name:"prospectAge", index:"prospectAge" }
,{name:"opportunityAge", index:"opportunityAge" }
,{name:"locationServiceCount",index:"locationServiceCount" ,align:'left' }
,{name:"numberOfLocations", index:"numberOfLocations" }
,{name:"activityDate", index:"activityDate" }
,{name:"activityCreatedBy", index:"activityCreatedBy" }
]
,rowNum: 1
,height: '100%'
})
var rowData = $(this).getRowData(rowId1);
}
,grouping:true
,groupingView:
{
groupField: ["salesManager"]
,groupColumnShow: [true]
,groupText: ["<b>{0}</b>"]
,groupOrder: ["asc"]
,groupSummary: [true] // will use the "summaryTpl" property of the respective column
,groupCollapse: false
,groupDataSorted: true
,formatDisplayField: [function(curValue, srcValue, colModelOption, grpIndex, grpObject) {
return srcValue.toFixed(2);
}]
}
,footerrow:true
,userDataOnFooter:true
,rowNum: 20
,rowList:[20,50,100,100000000]
,rowTotal:4000
,loadonce:true
,ignoreCase:true
,viewRecords:true
,onPaging:function(pgButton) {
var rowNum = $("#listGrid").getGridParam("rowNum");
$.cookie("userOptions_prospectListPagingSize", rowNum);
}
,gridComplete:function(id) {
$("#listGrid").setGridWidth($('.gridParent').width(), true);
$("#listGrid").trigger("resize", [{page:1}]);
}
,emptyrecords: '<span class="jqGridHighlight">No records found</span>'
,pager : '#funnelOpportunityListPager'
};
}
});
When I click on the plus icon (which does appear), nothing visible happens, and a breakpoint set at the first line of code in subGridRowExpanded is not hit. Why doesn't it get invoked, and do I have the rest of the setup right for displaying the data?
edit after Oleg's answer:
Version is the 4.7 trirand version before the free/commercial forks. I'm sorry I didn't put this in originally, I was sort of continuing a previous question, but I should have included it.
Yes, data is sorted on salesManager when it is returned from the server. As I said, the grouping is working; it is the subgrid that is not working.
As I also said, rowNum of 1 is accurate, there is only ever one subrow of the main row. The purpose here is to display more columns about the same index. subgrid is useful when there are children of the row, but in my case there is only ever one child. I'm happy to make the number larger, but that is the largest (and smallest) number of rows for which there are data in my case.
I have tried to correct subGridRowExpanded with your suggestions, this is what it looks like now:
,subGridRowExpanded: function (subgridDivId, rowid) {
var $subgrid = $("<table id='" + subgridDivId + "_t'></table>"),
parentRowData = $(this).jqGrid("getLocalRow", rowid),
// the next line can be used if parent grid doesn't contain local data
//parentRowData = $(this).jqGrid("getRowData", rowid),
$subgridDataDiv = $("#" + subgridDivId);
$subgridDataDiv.append($subgrid); // place subgrid table on the page
// create subgrid
$subgrid.jqGrid({
colNames: ["Pros ID","Pros Age","Opp Age","Location Count by Service","# Locs","Activity Date","Activity Created By"]
,colModel: [ {name:"prospectId", }
,{name:"prospectAge" }
,{name:"opportunityAge" }
,{name:"locationServiceCount", align:'left' }
,{name:"numberOfLocations" }
,{name:"activityDate" }
,{name:"activityCreatedBy" }
]
,rowNum: 1
,height: '100%'
});
}
There is a commented out line you say can be used "if parent grid doesn't contain local data", but my parent grid does contain the data for the subgrid, so I thought the line should remain commented. The JSON for the grid data looks like this:
{
"userdata": {
"nrc3yr": "2705545.00",
"mrc3yr": "2798103.26"
},
"records": "4",
"rows": [{
"prospectName": "Big Daddy Daycare",
"opportunityName": "Opp2018-06-22",
"nrc3yr": "295.00",
"salesCode": "CMR",
"probability": "50%",
"noteCount": 0,
"subgrid": [{
"prospectId": 309,
"prospectAge": "2",
"activityDate": "06-22-2018",
"opportunityAge": 2,
"numberOfLocations": 1,
"locationServiceCount": "Cable (1), IP Hosted (1)",
"activityCreatedBy": "rcook"
}],
"agencyOrSalesperson": "CMR",
"opportunityId": 696,
"salesManager": "CMR",
"stageAndStatus": "Draft\/Create",
"mrc3yr": "223.01",
"lastActivity": "Opportunity (696) created (Opp2018-06-22)"
},
{
"prospectName": "Wine Not",
"opportunityName": "Opp20180410-1051",
"nrc3yr": "0.00",
"salesCode": "ADV004",
"probability": "50%",
"noteCount": 17,
"subgrid": [{
"prospectId": 297,
"prospectAge": "89",
"activityDate": "06-07-2018",
"opportunityAge": 75,
"numberOfLocations": 1,
"locationServiceCount": "EoC Symmetric (1)",
"activityCreatedBy": "rcook"
}],
"agencyOrSalesperson": "ADV",
"opportunityId": 682,
"salesManager": "JWE",
"stageAndStatus": "Proposal\/In Progress",
"mrc3yr": "312.60",
"lastActivity": "Proposal (1,099) published (Prop20180607-1642)"
},
{
"prospectName": "Ever Lovin' Lovin",
"opportunityName": "Opp20180531-1943",
"nrc3yr": "0.00",
"salesCode": "RTB",
"probability": "50%",
"noteCount": 0,
"subgrid": [{
"prospectId": 307,
"prospectAge": "24",
"activityDate": "05-31-2018",
"opportunityAge": 24,
"numberOfLocations": 1,
"locationServiceCount": "EoC Asymmetric (1)",
"activityCreatedBy": "rcook"
}],
"agencyOrSalesperson": "RTB",
"opportunityId": 690,
"salesManager": "RTB",
"stageAndStatus": "Proposal\/Complete",
"mrc3yr": "129.95",
"lastActivity": "Proposal (1,098) published (Prop20180531-1947)"
},
{
"prospectName": "mothra",
"opportunityName": "big",
"nrc3yr": "2705250.00",
"salesCode": "RTB",
"probability": "50%",
"noteCount": 0,
"subgrid": [{
"prospectId": 280,
"prospectAge": "153",
"activityDate": "06-12-2018",
"opportunityAge": 13,
"numberOfLocations": 501,
"locationServiceCount": "Dedicated (501), EoF Symmetric (500), POTS (500)",
"activityCreatedBy": "alexdev"
}],
"agencyOrSalesperson": "RTB",
"opportunityId": 691,
"salesManager": "RTB",
"stageAndStatus": "Proposal\/Complete",
"mrc3yr": "2797437.70",
"lastActivity": "Proposal (1,106) published (big prop 7)"
}]
}
The biggest problem I face at the moment, however, is that the function for subGridRowExpanded is never called. I have put a breakpoint and a console.log() call at the beginning of the routine, and the breakpoint is not hit and the console.log() message does not appear. It is like something is wrong with the setup for calling subGridRowExpanded, and I don't know what it is.
--
Further info -- if I comment out the grouping configuration, then clicking on the plus sign does invoke the subGridRowExpanded function. Is it possible that, in 4.7 jqGrid, one cannot use both grouping and subgrid in the same grid? The expansion only shows the new column headers, none of the data, I'm trying to figure out now why that would be. If there's a way to use both these features in the same grid, I'd like to know about it
The current code of subGridRowExpanded is wrong. On click on subgrid icon (typically "+") jqGrid add row below the current row with div covering the most columns. The id of the div will be forwarded to subGridRowExpanded as the first parameter. By the code var listGrid = $("#" + subgrid_id); you get jQuery wrapper on the div and you call listGrid.jqGrid({...}) on the div. On the other side jqGrid can be created only on <table> element. You can fix the code by adding .children("table") (I mean the usage listGrid.children("table").jqGrid({...})) or using the template like
subGridRowExpanded: function (subgridDivId, rowid) {
var $subgrid = $("<table id='" + subgridDivId + "_t'></table>"),
parentRowData = $(this).jqGrid("getLocalRow", rowid),
// the next line can be used if parent grid doesn't contain local data
//parentRowData = $(this).jqGrid("getRowData", rowid),
$subgridDataDiv = $("#" + subgridDivId);
$subgridDataDiv.append($subgrid); // place subgrid table on the page
// create subgrid
$subgrid.jqGrid({
// ...
});
}
Related
Save slickgrid cell autocomplete value
I have a slickgrid cell with an autocompletion and a custom formatter. The cell value is a key field of dynamically loading autocompletion list. The list is shown as labels (e.g. Contract: ABCDEF-123, thick:10, width:210, City: Chicago) and when I select one it appears in the according input field. The point is that the formatter does not know that label, it only knows the key (order_id). function contractFormatter(row, cell, value, columnDef, dataContext) { var res = ''; var val = get_contract_list()[value] ? get_contract_list()[value]['label'] : ''; res = '<span class="' + getSpanClass() + '" style="float: left;"></span>\n\ '+ (val =='' ? '<span style="color:slategrey;"> Enter 3 symbols </span>' + val : val) + ''; return res; } The function get_contract_list returns the whole list of contracts and it is very big, so it was decided to make that list dynamic. So the function is empty now and it would be nice just to take the selected label into val. Is there any way to achieve it?
You have to remember that Formatters are synchronous and it must return right away in a string format, if it requires a lot of processing power while staying synchronous then you'll end up slowing down your grid. You should probably cache your list once in a separate variable and use it afterward instead of reloading the list every time. If you load something that takes time and is asynchronous (a delayed output) then you'll want to look up the asyncPostRenderer (you can see this Example) So going back to displaying the associated key to a label, I've done something similar in my lib in this Example and a live demo here, in my use case the value is a key index and I use the complexityLevelList to find its associated object which I can then read its label to display in the formatter. export class MyExample { complexityLevelList = [ { value: 0, label: 'Very Simple' }, { value: 1, label: 'Simple' }, { value: 2, label: 'Straightforward' }, { value: 3, label: 'Complex' }, { value: 4, label: 'Very Complex' }, ]; prepareGrid() { this.columnDefinitions = [ { id: 'complexity', name: 'Complexity', field: 'complexity', minWidth: 100, formatter: (_row, _cell, value) => this.complexityLevelList[value].label, filter: { model: Filters.multipleSelect, collection: this.complexityLevelList }, editor: { model: Editors.singleSelect, collection: this.complexityLevelList, massUpdate: true }, }, ]; } } Note that the Filters & Editors are specific to my lib Slickgrid-Universal, but you should get the idea on how to refactor your code to make it work.
Jquery how to use this in a event datatable generated td row
I am trying to add a function call "onblur" where i can type a new value in the TD cell. What I need is the new value to be passes by the function to a other Jquery script. My problem is that the datatable wont see the This value as it seems the code is not written correctly. What am I doing wrong? I cant find anything that helped me so far.. This is the php version that works, this is what I am trying to implent in the Datatable table. <td contenteditable="true" data-old_value="name" onBlur="saveInlineEdit(this,'name','23')" onClick="highlightEdit(this);" > name </td> Concrete. How do i use the new typed value as "this" in the folowing line, or how do i implement the code that works in the HTML table in the jQuery DataTable? var options = { data: 'my_data', render: function ( data, type, row, meta ) { return '<div onBlur="saveInlineEdit('this.innerHTML,'name', + row.data_id + ') " onClick="highlightEdit(this);"><font color='+row.cat_color+'>'+data+'</font></div>'; } } The part in the DataTables script to add the attributes: createdRow: function (row, data, dataIndex) { $('td:eq(4)',row).attr('contenteditable',true); $('td:eq(4)',row).attr('data-old_value', data.bullets); } I want to use the following script to post the value of the saveInlineEdit function function highlightEdit(editableObj) { $(editableObj).css("background",""); } function saveInlineEdit(editableObj,column,id) { // no change change made then return false if($(editableObj).attr('data-old_value') === editableObj.innerHTML) { return false; } // send ajax to update value $(editableObj).css("background","#FFF url(loader.gif) no-repeat right"); $.ajax({ url: "update_inlinedata.php", cache: false, data:'column='+column+'&value='+editableObj.innerHTML+'&id='+id, success: function(response) { console.log(response); // set updated value as old value $(editableObj).attr('data-old_value',editableObj.innerHTML); $(editableObj).css("background",""); } }); }
There are a couple of different pieces to your question - the following covers the capturing of changed cell data, and making sure the DataTable reflects the edits made in the DOM by the user. (I did not tackle the highlighting, but I think you can extend the below approach to cover that as well, since it's handling the same data.) I think using a createdCell option in a columnDef may be a bit easier than using a createdRow, because you will get direct access to the column's value: columnDefs: [ { targets: 4, createdCell: function (td, cellData, rowData, rowIdx, colIdx) { // 'td' is the DOM node, not the DataTable cell td.setAttribute('contenteditable', true); td.setAttribute('spellcheck', false); td.setAttribute('data-old_value', cellData); td.addEventListener("focus", function(e) { original = e.target.textContent; }) td.addEventListener("blur", function(e) { if (original !== e.target.textContent) { console.log( 'row ID: ', rowData.id ); console.log( 'new DOM value: ', td.innerHTML); // 'cell' is the DataTable cell, not the DOM node: let cell = $('#example').DataTable().cell(rowIdx, colIdx); console.log( 'before cell update: ', cell.data() ); cell.data(td.innerHTML); console.log( 'after cell update: ', cell.data() ); } }) } } ] Acknowledgement: The above approach is modified from the one shown in this answer. Here is a self-contained demo: var my_data = [ { "id": "123", "name": "Tiger Nixon", "position": "System Architect", "salary": "$320,800", "bullets": "lorem ipsum", "office": "Edinburgh", "extn": "5421" }, { "id": "456", "name": "Donna Snider", "position": "Customer Support", "salary": "$112,000", "bullets": "dolor sit amet", "office": "New York", "extn": "4226" } ]; $(document).ready(function() { var table = $('#example').DataTable( { data: my_data, columns: [ { title: "ID", data: "id" }, { title: "Name", data: "name" }, { title: "Office", data: "office" }, { title: "Position", data: "position" }, { title: "Bullets", data: "bullets" }, { title: "Extn.", data: "extn" }, { title: "Salary", data: "salary" } ], columnDefs: [ { targets: 4, createdCell: function (td, cellData, rowData, rowIdx, colIdx) { // 'td' is the DOM node, not the DataTable cell td.setAttribute('contenteditable', true); td.setAttribute('spellcheck', false); td.setAttribute('data-old_value', cellData); td.addEventListener("focus", function(e) { original = e.target.textContent; }) td.addEventListener("blur", function(e) { if (original !== e.target.textContent) { console.log( 'row ID: ', rowData.id ); console.log( 'new DOM value: ', td.innerHTML); // 'cell' is the DataTable cell, not the DOM node: let cell = $('#example').DataTable().cell(rowIdx, colIdx); console.log( 'before cell update: ', cell.data() ); cell.data(td.innerHTML); console.log( 'after cell update: ', cell.data() ); } }) } } ] } ); } ); <head> <meta charset="UTF-8"> <title>Demo</title> <script src="https://code.jquery.com/jquery-3.5.1.js"></script> <script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script> <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css"> <link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css"> </head> <body> <div style="margin: 20px;"> <table id="example" class="display dataTable cell-border" style="width:100%"> </table> </div> </body> Update I don't have a server which can handle your ajax call, so I cannot test a "success" response. Having said that, here are my notes: For the saveInlineEdit function, you will no longer need this: if($(editableObj).attr('data-old_value') === editableObj.innerHTML) { return false; } This is because you have already performed that check in the event listener: if (original !== e.target.textContent) { ... } Also, you have already determined what the new value of the cell is - so you might as well just pass that directly to the function: saveInlineEdit(td, 'bullets', rowData.id, cell.data()); The above line needs to be placed in the event listener shown above: td.addEventListener("blur", function(e) { if (original !== e.target.textContent) { console.log( 'row ', rowIdx, ' col ', colIdx ); console.log( 'row ID: ', rowData.id ); console.log( 'new DOM value: ', td.innerHTML); // 'cell' is the DataTable cell, not the DOM node: let cell = $('#example').DataTable().cell(rowIdx, colIdx); console.log( 'before cell update: ', cell.data() ); cell.data(td.innerHTML); console.log( 'after cell update: ', cell.data() ); let columnName = $('#example').DataTable().settings(); console.log( 'column name: ', columnName ); saveInlineEdit(td, 'bullets', rowData.id, cell.data()); // NEW LINE HERE } }) Your saveInlineEdit function therefore changes, to reflect the above points: I removed the unnecessary if condition. I added an extra parameter newValue - since we don;t need to keep retrieving it from the cell (we've already done that). function saveInlineEdit(editableObj, column, id, newValue) { console.log( 'in ajax call' ); console.log(editableObj); console.log(column); console.log(id); console.log(newValue); // send ajax to update value $(editableObj).css("background","#FFF url(loader.gif) no-repeat right"); $.ajax({ url: "update_inlinedata.php", cache: false, data:'column=' + column + '&value=' + newValue + '&id=' + id, success: function(response) { console.log(response); // set updated value as old value $(editableObj).attr('data-old_value', newValue); $(editableObj).css("background",""); } }); } I put logging statements into the function, so you can see what the parameters are. So, for example, the query parameter data submitted by the ajax call will be: column=bullet&value=lorem%20ipsum%20editedbyme&id=123 And just to say again, I cannot test this ajax call - so bear that in mind, i case I made a stupid mistake there, somewhere. That leaves 2 additional point which are outside the scope of the question, but which need to be considered: The question assumes only column index 4 is editable. If you want every cell in a row to be editable you need to enhance this to use the relevant column names. One good way to do this is to use the DataTables name option: { title: "Bullets", data: "bullets", name: "bullets" }, This value can be retrieved and used by the blur event handler, before you call your saveInlineEdit function: let columnName = $('#example').DataTable().settings()[0].aoColumns[colIdx].sName; Then your call becomes: saveInlineEdit(td, columnName, rowData.id, cell.data()); The current code updates the data in the DataTable here: cell.data(td.innerHTML); This happens before the return from the ajax call. If that call fails then you have updated data in your data table, but not in the back end database. So you may want to move that logic around to ensure the DataTable data is updated only in the event of a successful ajax call.
how to append json array in datatable using render function
I want to append json array into one popover attribute called data-content. I am using jQuery DataTables plugin to perform UI functionalities. Using data variable table is populated with the data. How could I insert titleDescription array from data variable into the attribute name called as data-content inside a tag in js , check my fiddle and go to datatable function there inside columnDefs there is render function. In that function I have return and append a tag, there only I have to append titleDescription array. Check this JSFiddle for demonstration.
You can use the row attribute, and have the data in a non visible column. Check the example https://datatables.net/examples/advanced_init/column_render.html $(document).ready(function() { $('#example').DataTable( { "columnDefs": [ { // The `data` parameter refers to the data for the cell (defined by the // `data` option, which defaults to the column being worked with, in // this case `data: 0`. "render": function ( data, type, row ) { return data +' ('+ row[3]+')'; }, "targets": 0 }, { "visible": false, "targets": [ 3 ] } ] } ); } ); That would do the trick.
You just need to add another column at the last of each row then you can access it from row like this render : function(data, type, row) { return '<span class="favlist-icon"></span><span class="immediate-attention-icon"> </span> <span class="docx-name-list-link"> <a class="apopoverdata" href="#" data-content="'+row[4]+'" rel="popover" >'+data+'</a></span>'; } Here is working fiddle https://jsfiddle.net/2cn4b8bz/4/
I'm not sure what library you were using for your pop over so I used tooltipster seeing as you had jQuery already for the DataTable. Your data didn't have everything you needed either so I've altered it a wee bit: $(function() { $('#documentListing-data').DataTable({ data: json.documentAll.document, pageLength: 10, columns:[ { "data": "documentTitle", "title": "Name", "render": (data, type, row) => '' + data + '', }, { "data": "category", "title":"Category", "render": (data, type, row) => data.map((k, v) => k.trim()).join(", "), }, { "data": "publishedDate", "title":"Published Date" }, { "data": "lastUpdatedDate", "title": "Last Updated Date" }, ], "drawCallback": function(settings) { $('.tooltip').tooltipster(); } }); }); Working JSFiddle. Hope that helps!
Plotly hover text not displaying
Although I've specified text and hoverinfo, I'm not getting any hover annotation at all. If I comment out the "text" attribute, I get the default behavior of hoverinfo: "x+y". I've also tried hoverinfo: "text" and hoverinfo: "x+text" (which is what I really want), but these do not change the behavior. https://jsfiddle.net/abalter/0cjprqgy/ var data = { "x":["2014-02-10 00:00:00.0","2014-02-18 00:00:00.0","2014-02-24 00:00:00.0"], "y":[0,0,0], "text":["gemcitabine","gemcitabine + Abraxane","Xeloda"], "hoverinfo": "all", "name":"Treatment", "type":"scatter", "mode":"markers", "marker": { "size":9, "color":"#800000" }, "uid":"c2e171" }; var layout = { "title":"Treatments", "height":600, "width":655, "autosize":true, "yaxis": { "titlefont": { "size":12, "color":"#800000" }, "domain":[0.85,0.9], "showgrid":false, "showline":false, "showticklabels":false, "zeroline":true, "type":"linear", "range":[0,0], "autorange":true }, "hovermode":"closest", "xaxis": { "type":"date", "range":[1389215256994.8186,1434909143005.1814], "autorange":true } }; Plotly.plot('graph', [data], layout);
First of all, thank you for having me to discover this really cool graphic platform! I checked at the documentation to get to know how the data has to be formatted (here: https://plot.ly/javascript/hover-events/#coupled-hover-events-on-single-plot)... And "played" with you fiddle. First, I removed all the unnessessary double quotes you had there, wrapping the param names and placed your value arrays outside of the "data" array. I don't know if it is part of the problem... I just tryed to format it as the example I found. The "x+y+text" suddenly appeared when I played with the "domain" parameter. I don't know what it really defines. I repeat, I have a 10 minutes experience with this thing. (lol) Check this update I made of your fiddle : https://jsfiddle.net/0cjprqgy/6/ var dates = ["2014-02-10 00:00:00.0","2014-02-18 00:00:00.0","2014-02-24 00:00:00.0"], qty = ["0.2","0.5","1"], product = ["gemcitabine","gemcitabine + Abraxane","Xeloda"], data = { x:dates, y:qty, text:product, hoverinfo: "x+y+text", name:"Treatment", type:"scatter", mode:"markers", marker: { size:9, color:"#800000" }, uid:"c2e171" }; var layout = { title:"Treatments", height:600, width:655, autosize:true, yaxis: { titlefont: { size:12, color:"#800000" }, domain:[0.85,1.9], showgrid:false, showline:false, showticklabels:false, zeroline:true, type:"linear", range:[0,0], autorange:true }, hovermode:"closest", xaxis: { type:"date", range:[1389215256994.8186,1434909143005.1814], autorange:true } }; Plotly.plot('graph', [data], layout);
How do I create a delete button on every row in slickgrid with confirmation?
As the title said it, how do I do it?, I am using this button created by jiri: How do i create a delete button on every row using the SlickGrid plugin? when I add an if(confirmation(msg)) inside the function it repeats me the msg ALOT maybe its because i refresh-ajax the table with each modification. ask me if you need more info, I am still noob here in stackoverflow :P (also if there is someway to "kill" the function) here is the button, iam using(link) i added the idBorrada to check whetever the id was already deleted and dont try to delete it twice, also here is a confirm, but when i touch cancel it asks me again. $('.del').live('click', function(){ var me = $(this), id = me.attr('id'); //assuming you have used a dataView to create your grid //also assuming that its variable name is called 'dataView' //use the following code to get the item to be deleted from it if(idBorrada != id && confirm("¿Seguro desea eleminarlo?")){ dataView.deleteItem(id); Wicket.Ajax.ajax({"u":"${url}","c":"${gridId}","ep":{'borrar':JSON.stringify(id, null, 2)}}); //This is possible because in the formatter we have assigned the row id itself as the button id; //now assuming your grid is called 'grid' //TODO grid.invalidate(); idBorrada= id; } else{ }; }); and i call the entire function again. hope that help, sorry for the grammar its not my native language
Follow these steps, Add a delete link for each row with of the columns object as follows, var columns = { id: "Type", name: "Application Type", field: "ApplicationType", width: 100, cssClass: "cell-title", editor: Slick.Editors.Text, validator: requiredFieldValidator, sortable: true }, { id: "delete", name: "Action", width: 40, cssClass: "cell-title", formatter: Slick.Formatters.Link } ]; Add a Link Formatter inside slick.formatters.js as follows, "Formatters": { "PercentComplete": PercentCompleteFormatter, "YesNo": YesNoFormatter, "Link": LinkFormatter } function LinkFormatter(row, cell, value, columnDef, dataContext) { return "<a style='color:#4996D0; text-decoration:none;cursor:pointer' onclick='DeleteData(" + dataContext.Id + ", " + row + ")'>Delete</a>"; } Add the following delete function in javascript function DeleteData(id, rowId) { var result = confirm("Are you sure you want to permenantly delete this record!"); if (result == true) { if (id) { $.ajax({ type: "POST", url: "DeleteURL", data: { id: id }, dataType: "text", success: function () { }, error: function () { } }); } dataView.deleteItem(id); dataView.refresh();} }