jQWidgets Forums
jQuery UI Widgets › Forums › Grid › getrowdata sometime returns undefined
Tagged: angular grid, angular2 grid, bootstrap grid, javascript grid, jquery grid, jqwidgets grid, jqxgrid
This topic contains 1 reply, has 2 voices, and was last updated by Hristo 8 years, 7 months ago.
-
Author
-
Hi,
I have an issue in my method get_selected_algo_ids() – it looks up the selected rows and then tries to get the row data using getrowdata. The grid is a multiplerowsadvanced grid. The problem is that about 25% of the time, I get undefined when I call getrowdata. This especially happens if I select two non-contiguous rows, and right-click to bring up my context menu when get_selected_algo_ids() / getrowdata is called.
Also of note is that I call updatebounddata every few seconds via a separate timer.
Any ideas on what is wrong.
Many thanks,
PaulHere is my code:
`<!DOCTYPE html>
<html>
<head><title>Backtest Results: Paul Development</title>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<!– Bootstrap –>
<link href=”//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css” rel=”stylesheet”>
<link rel=”stylesheet” href=”/static/jqwidgets/styles/jqx.base.css” type=”text/css” />
<link href=”/static/jqwidgets/styles/jqx.bootstrap.css” rel=”stylesheet”>
<link rel=”stylesheet” href=”/static/jqwidgets/styles/irwin.css” type=”text/css” />
<link rel=”stylesheet” href=”/static/css/irwin.css” type=”text/css” /></head>
<body><script src=”//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js”></script>
<script src=”//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxcore.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxdata.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxbuttons.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxscrollbar.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxmenu.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxlistbox.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxdropdownlist.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxgrid.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxgrid.selection.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxgrid.columnsresize.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxgrid.filter.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxgrid.sort.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxgrid.pager.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxgrid.grouping.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxwindow.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxinput.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxgrid.storage.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxdata.export.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxgrid.export.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxgrid.aggregates.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxgrid.edit.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxsplitter.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxdraw.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxchart.core.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxtabs.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxcheckbox.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxtree.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxdatetimeinput.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxcalendar.js”></script>
<script type=”text/javascript” src=”/static/scripts/utils.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxdraw.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxchart.rangeselector.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxnumberinput.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxslider.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxprogressbar.js”></script>
<script type=”text/javascript” src=”/static/jqwidgets/jqxtabs.js”></script>
<script>
$(document).ready(function () {
// Set the browser ID into the title
var browser_id = getCookie(‘browser_id’);
if (browser_id && browser_id.length > 0) {
$(‘#browser_id_field’).text(” (“+browser_id+”)”);
}
});
</script>
<script>
(function(i,s,o,g,r,a,m){i[‘GoogleAnalyticsObject’]=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,’script’,’//www.google-analytics.com/analytics.js’,’ga’);ga(‘create’, ‘UA-BLANKEDOUT-1’, ‘auto’);
ga(‘send’, ‘pageview’);
</script><script type=”text/javascript”>
$(document).ready(function () {
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Grid Context Menu incl dynamic External Analysis
//////////////////////////////////////////////////////////////////////////////////////////////////////var context_menu_X = -1;
var context_menu_Y = -1;
var context_menu_data = -1;// Icons from: http://www.flaticon.com/packs/font-awesome
var BASE_MENU_DATA = [ {“id”: “1”, “parentid”: “-1”, “label”: “Create Comparison Notebook”},
{“id”: “2”, “parentid”: “-1”, “label”: “Create Comparison Spreadsheet”},
{“id”: “3”, “parentid”: “-1”, “label”: “Create Backtest Detail Report”},
{“id”: “4”, “parentid”: “-1”, “label”: “Show Return Graph”},
{“id”: “5”, “parentid”: “-1”, “label”: “Show Return Graph Incl Benchmark”},
{“id”: “6”, “parentid”: “-1”, “label”: “Show MTM Graph”},
{“id”: “7”, “parentid”: “-1”, “label”: “Show MTM Graph Less Benchmark”},
{“id”: “8”, “parentid”: “-1”, “label”: “Show Backtest Performance”},
{“id”: “prev_analysis_submenu”, “parentid”: “-1”, “subMenuWidth”: ‘400px’, “label”: “Previous Analysis”},
{“id”: “trade_analysis_submenu”, “parentid”: “-1”, “subMenuWidth”: ‘400px’, “label”: “Trade Analysis”}];
// Returns the select list of algo ids
function get_selected_algo_ids() {
var _row_index_list = $(“#runGrid”).jqxGrid(‘getselectedrowindexes’);
var algo_id_list = [];
for (i=0; i < _row_index_list.length; i++) {
var run = $(“#runGrid”).jqxGrid(‘getrowdata’, _row_index_list[i]);
if (run) {
algo_id_list.push(run.id);
}
}
return algo_id_list
};//////////////////////////////////////////////////////////////////////////////////////////////////////
// Run set data spreadsheet / grid
//////////////////////////////////////////////////////////////////////////////////////////////////////var browser_id = getCookie(‘browser_id’);
var data_url = ‘/rundata/none’;
if (browser_id && browser_id.length > 0) {
data_url = “/rundata/”+ browser_id;
}var source =
{
datatype: “json”,
datafields: [
{ name: ‘id’, type: ‘int’ },
{ name: ‘run_id’, type: ‘int’ },
{ name: ‘run_start’, type: ‘date’ },
{ name: ‘start_date’, type: ‘date’ },
{ name: ‘end_date’, type: ‘date’ },
{ name: ‘run_type’, type: ‘string’ },
{ name: ‘class_name’, type: ‘string’ },
{ name: ‘symbols’, type: ‘string’ },
{ name: ‘config’, type: ‘string’ },
{ name: ‘performance’, type: ‘string’ },
{ name: ‘code_version’, type: ‘string’ },
{ name: ‘code’, type: ‘string’ },
{ name: ‘delete_date’, type: ‘date’, format: ‘yyyy-MM-dd’ },
{ name: ‘comments’, type: ‘string’ },
{ name: ‘google_file_ids’, type: ‘string’ }
],
id: ‘id’,
url: data_url
};
var dataAdapter = new $.jqx.dataAdapter(source);
$(“#runGrid”).jqxGrid(
{
width: ‘100%’,
height: ‘100%’,
source: dataAdapter,
columnsresize: true,
theme: “irwin”,
sortable: “true”,
showstatusbar: true,
showfilterrow: true,
filterable: true,
autoshowloadelement: false,
enabletooltips: true,
editable: true,
columns: [
{ text: ‘AlgoID’, datafield: ‘id’, width: 60, editable: false},
{ text: ‘Run Date’, datafield: ‘run_start’, width: 100, cellsformat: ‘dd-MMM HH:MM’, editable: false },
{ text: ‘Start Date’, datafield: ‘start_date’, width: 100, cellsformat: ‘dd-MMM-yyyy’, editable: false },
{ text: ‘End Date’, datafield: ‘end_date’, width: 100, cellsformat: ‘dd-MMM-yyyy’, editable: false },
{ text: ‘Run Type’, datafield: ‘run_type’, width: 80, editable: false },
{ text: ‘Class Name’, datafield: ‘class_name’, width: 150, editable: false },
{ text: ‘Symbols’, datafield: ‘symbols’, width: 200, editable: false },
{ text: ‘Performance’, datafield: ‘performance’, width: 200, editable: false },
{ text: ‘Config’, datafield: ‘config’, width: 500, editable: false },
{ text: ‘Comments’, datafield: ‘comments’, width: 300, columntype: ‘textbox’, editable: true },
{ text: ‘Delete Date’, datafield: ‘delete_date’, width: 100, cellsformat: ‘dd-MMM-yyyy’, columntype: ‘datetimeinput’, editable: true },
{ text: ‘Git Version’, datafield: ‘code_version’, width: 140, editable: false },
{ text: ‘RunID’, datafield: ‘run_id’, width: 60, editable: false }
]
});$(“#runGrid”).jqxGrid({selectionmode: ‘multiplerowsadvanced’});
// disable the default browser’s context menu.
$(“#runGrid”).on(‘contextmenu’, function (e) { return false; });// Handle context menu clicks
$(“#context_menu_div”).on(‘itemclick’, function (event) {if ($.trim($(args).text()).indexOf(“Create Comparison”) >= 0) {
$(‘body’).css(‘cursor’, ‘wait’);
algo_id_list = get_selected_algo_ids()
// Construct a string of the ids to compare
$(“#report_algo_id_list”).val(algo_id_list.join(‘,’));
if ($.trim($(args).text()).indexOf(“Notebook”) >= 0) {
$(“#report_output_type”).val(‘notebook’);
} else {
$(“#report_output_type”).val(‘comparison_report’);
}
$(“#algo_report_form”).submit();
}
else if ($.trim($(args).text()).indexOf(“Create Backtest Detail Report”) >= 0) {
$(‘body’).css(‘cursor’, ‘wait’);
algo_id_list = get_selected_algo_ids()
// Construct a string of the ids to compare
$(“#report_algo_id_list”).val(algo_id_list.join(‘,’));
$(“#report_output_type”).val(‘run_report’);
$(“#algo_report_form”).submit();
}
else if ($.trim($(args).text()).indexOf(“Show Backtest Performance”) >= 0) {
algo_id_list = get_selected_algo_ids();
link = ‘/generic_algo_result/backtest_performance_result/’ + algo_id_list.join(‘+’);
window.open(link);
}
else if ($.trim($(args).text()).indexOf(“Graph”) >= 0) {
// Create a link the a comparison chart
algo_id_list = get_selected_algo_ids();
var link = ‘/backtest_chart/return/’;
if ($.trim($(args).text()).indexOf(“Less”) >= 0) {
link = ‘/backtest_chart/diff/’;
}
else if ($.trim($(args).text()).indexOf(“MTM”) >= 0) {
var link = ‘/backtest_chart/mtm/’;
}
if ($.trim($(args).text()).indexOf(“Benchmark”) >= 0) {
link = link + ‘B+’;
}
link = link + algo_id_list.join(‘+’);window.open(link);
}
else if ($.trim($(args).text()) == “Keep Run Forever”) {
// This is one of the comparison objects
algo_id_list = get_selected_algo_ids()
$.post(‘/keep_runs_forever’, {data: JSON.stringify(algo_id_list.join(‘,’))});
// Refresh the grid so we can see the far ahead delete date
$(“#runGrid”).jqxGrid(‘updatebounddata’, ‘cells’);
}
else if ($.trim($(args).text()) == “Schedule Deletion”) {
// This is one of the comparison objects
algo_id_list = get_selected_algo_ids()
$.post(‘/schedule_deletion’, {data: JSON.stringify(algo_id_list.join(‘,’))});
// Refresh the grid so we can see the new delete date
$(“#runGrid”).jqxGrid(‘updatebounddata’, ‘cells’);
} else {
// This is one of the comparison objects
var id = event.args.id;
for (var i=0; i < context_menu_data.length; i++) {
if (id == context_menu_data[i].id) {
var link = context_menu_data[i].link;
window.open(link);
break;
}
}
}
});var stop_update_on_edit = 0;
$(“#runGrid”).bind(‘cellbeginedit’, function (event) {
stop_update_on_edit = 1;
});$(“#runGrid”).on(‘cellendedit’, function (event) {
var args = event.args;
var algo_id = args.row[‘id’];
var field = args.datafield;
var new_value = args.value;
if (field == ‘delete_date’) {
new_value = new_value.toISOString().slice(0,10).replace(/-/g,””); // Turn into YYYYMMDD
}$.post(‘/update_algo_data’, {data: JSON.stringify(algo_id.toString() + ‘,’ + field + ‘,’ + new_value.toString())});
stop_update_on_edit = 0;
})// Build the context menu based on the right-click
$(“#runGrid”).on(‘rowclick’, function (event) {
if (event.args.rightclick) {
$(“#runGrid”).jqxGrid(‘selectrow’, event.args.rowindex);// Store where we want the context menu to come up
var scrollTop = $(window).scrollTop();
var scrollLeft = $(window).scrollLeft();
context_menu_X = parseInt(event.args.originalEvent.clientX) + 5 + scrollLeft;
context_menu_Y = parseInt(event.args.originalEvent.clientY) + 5 + scrollTop;var algo_id_list = get_selected_algo_ids();
if (algo_id_list != ”) {
$.post(‘/dynamic_context_menu’, {data: JSON.stringify(algo_id_list)},
function(data, status) {var ea_list = [];
if (status == ‘success’) {
ea_list = JSON.parse(data);
}context_menu_data = BASE_MENU_DATA.slice(); // copy the list
var start_index = context_menu_data.length + 1;
var max_len = -1;
for (var i = 0; i < ea_list.length; i++) {
var icon = ”;
if (ea_list[i][2] == ‘gspread’ || ea_list[i][2] == ‘gdata’) {
icon = ‘spreadsheet_16.png’;
} else if (ea_list[i][2] == ‘notebook’) {
icon = ‘ipython_notebook_16.png’;
} else {
icon = ‘bar_chart_16.png’;
}
var label = “” + ea_list[i][1];
var menu_len = ea_list[i][1].length;
if (menu_len > max_len) {
max_len = menu_len;
}var parentid = ”;
if (ea_list[i][0] == ‘ExternalAnalysis’) {
parentid = ‘prev_analysis_submenu’;
} else if (ea_list[i][0] == ‘TradeAnalysis’) {
parentid = ‘trade_analysis_submenu’;
}
context_menu_data.push({“id”: start_index + i, “parentid”: parentid, “label”: label, “link”: ea_list[i][3]});
}
// Add remaining menu items
context_menu_data.push({“id”: ‘menuSeparator’, “parentid”: “-1”, “label”: “”});
context_menu_data.push({“id”: start_index + ea_list.length, “parentid”: “-1”, “label”: “Keep Run Forever”});
context_menu_data.push({“id”: start_index + ea_list.length + 1, “parentid”: “-1”, “label”: “Schedule Deletion”});
// Make the sub menu length correct
max_len = Math.min(600, max_len);
context_menu_data[1][“subMenuWidth”] = (max_len * 9 + 20).toString() + “px”;var source = { datatype: “json”, datafields: [ { name: ‘id’ }, { name: ‘parentid’ }, { name: ‘label’ }, { name: ‘subMenuWidth’ } ],
id: ‘id’, localdata: context_menu_data
};
// create data adapter and perform Data Binding.
var dataAdapter = new $.jqx.dataAdapter(source);
dataAdapter.dataBind();// Create the menu
var records = dataAdapter.getRecordsHierarchy(‘id’, ‘parentid’, ‘items’);
cm = $(‘#context_menu_div’).jqxMenu({ source: records, height: (BASE_MENU_DATA.length + 3) * 24, width: ‘300px’, autoOpenPopup: false, mode: ‘popup’ });// Open the menu now it is created
cm.jqxMenu(‘open’, context_menu_X, context_menu_Y);$(“li[id=’menuSeparator’]”).attr(“class”,”jqx-menu-item-separator jqx-rc-all”); // From http://www.jqwidgets.com/community/topic/separator-inside-source-based-jqmenu/#post-62736
// Disable the previous run menu item if there are none.
if (ea_list.length == 0) {
$(“#context_menu_div”).jqxMenu(‘disable’, “prev_analysis_submenu”, true);
}
});
} else {
var error=1; // Have this so we can at least not show the menu if we can’t get the IDs
}
return false;
}
});//////////////////////////////////////////////////////////////////////////////////////////////////////
// Refresh the grids every 5 seconds
//////////////////////////////////////////////////////////////////////////////////////////////////////setInterval(function () {
if (stop_update_on_edit == 0) {
$(“#runGrid”).jqxGrid(‘updatebounddata’, ‘cells’);
}
}, 15000);//////////////////////////////////////////////////////////////////////////////////////////////////////
// Code to show the new Notebook URL as a popup. When we want to show the popup,
// compare_algos_notebook_url is set and so window.open is in Javascript
//////////////////////////////////////////////////////////////////////////////////////////////////////// If the compare notebook url has been specified (done on algo_report_form POST), open a window for it.
window.open(“http://localhost:5002/notebooks/Compare%20Runs%20-%205163.ipynb”); // Open the compare algo url if supplied});
</script><div id=”help_modal_popup” class=”modal fade” tabindex=”-1″ role=”dialog”>
<div class=”modal-dialog” style=”width: 1024px; height: 768px;”>
<div class=”modal-content”>
<div class=”modal-body”>
</div>
</div>
</div>
</div><!– This makes the body take up the whole frame. Not sure why putting this in the style block does not work.
See http://www.jqwidgets.com/fluid-layout-with-fixed-header-and-footer/ –>
<style type=”text/css”>
html, body {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px;
overflow: hidden;
}
</style><table style=”border-collapse: separate; border-spacing:0; background-repeat: no-repeat;” width=”100%” background=”/static/images/vol_surface_wide.png”>
<tr width=”100%” >
<td width=’4%’ align=”left”></td>
<td width=”6%” align=”left” valign=”middle”><h2 style=”color:black”><b>Irwin</b></h2></td>
<td width=”60%” align=”left” valign=”left”><span style=”font-size:1.9em; color:DimGray”>Backtest Results: Paul Development</span><span style=”font-size:0.7em” id=’browser_id_field’></span></td><td width=”6px” align=”right”></td>
<td width=”140px” align=”right”>
<button type=”button” class=”btn btn-sm btn-block btn-primary” style=”margin-top:1em” onclick=”location.href=’/backtest_algo_list’;”>Algo List</button>
</td><td width=”6px” align=”right”></td>
<td width=”80px” align=”right”>
<button type=”button” class=”btn btn-sm btn-block btn-primary” style=”margin-top:1em” data-toggle=”modal” data-target=”#help_modal_popup”>Help</button>
</td>
<td width=”3px” align=”right”></td>
</tr></table><div id=’jqxWidget’ style=”position: absolute; box-sizing:border-box; -moz-box-sizing:border-box; padding-top: 0px; padding-bottom: 60px; width: 100%; height: 100%;”>
<div id=”runGrid”></div>
</div>
<div id=’context_menu_div’>
</div>
<div style=”overflow: hidden;”>
<form method=”POST” id=”algo_report_form” style=”display: none;”>
<label for=”report_algo_id_list”>report_algo_id_list</label> <input id=”report_algo_id_list” name=”report_algo_id_list” type=”text” value=””>
<label for=”report_output_type”>report_output_type</label> <input id=”report_output_type” name=”report_output_type” type=”text” value=””>
<input id=”algo_report_submit” name=”algo_report_submit” type=”submit” value=”algo_report_submit”>
</form>
</div></body>
</html>Hello phaefele,
We could not spend a time to create/check (private) project.
This is one big data source code and it is difficult to check.
If we focus on the described issue you could try to use thisalgo_id_list.push(run.uid);
instead of algo_id_list.push(run.id);
Hope this helps.Best Regards,
Hristo HristovjQWidgets team
http://www.jqwidgets.com -
AuthorPosts
You must be logged in to reply to this topic.