Dears,
I am sitting with a problem for days now, cannot get to solve it on my own, however.
I have a script reading a CSV file and displaying it in pqgrid.
CSV data is displayed in two tables. Whenever to select a row in the top table, the below data and view has to be updated. Basically works fine, but one problem occured:
1: after selecting in the above table,
2: then filtering in the below table,
3: then unselecting in the above table,
4: and then unfiltering the below table
the data gets mixed up.
Once I reselect in the above table, data is correct again.
I can solve the issue with using
$("#selector").pqGrid({
filter: function( event, ui ) {
$("#selector").pqGrid.dataModel ={data:filter_data};
$("#selector").pqGrid( "refreshDataAndView" );
}
});
but as a result, whenever I use the filter in the below table it loses its focus after typing 1 character (using filter listener 'keyup'). Filtering itself then works fine. It also works with listener 'change'. But that is not the intented filtering behaviour.
Can you help me out of my pit? I cannot make it work.
code
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>roomsys display</title>
<!--jquery import -->
<script src="js/jquery.min.js"></script>
<!--jquery ui import + css -->
<link rel="stylesheet" href="css/jquery-ui.css" />
<script src="js/jquery-ui.min.js"></script>
<!--jquery csv import -->
<script src="js/jquery.csv-0.71.min.js"></script>
<!--paramquery grid import + css-->
<link rel="stylesheet" href="pqgrid/pqgrid.min.css" />
<script type="text/javascript" src="pqgrid/pqgrid.min.js" ></script>
<!--main script organization -->
<script type="text/javascript">
// method that checks that the browser supports the html5 file api
function browserSupportFileUpload() {
var isCompatible = false;
if (window.File && window.FileReader && window.FileList && window.Blob) {
isCompatible = true;
}
return isCompatible;
}
// filter member data according to the selected rooms
function select_members(data_members,first){
var filter_members = [];
// get all selected rows
var selectionArray= $( "#grid_array_rooms" ).pqGrid( "selection",{
type:'row', method:'getSelection'
});
// set array with members, that fits filter criteria
// for all members ...
for (i = 0; i < data_members.length; i++){
// ... and all selected rooms ...
for (j = 0; j < selectionArray.length; j++){
// ... if idents are the same ...
if (data_members[i][5] == " "+selectionArray[j].rowData[0]){
// ... then push data into a new array
filter_members.push(data_members[i]);
}
}
// ... but if nothing is selected and members ident is unknown...
if (selectionArray.length == 0 && data_members[i][5] == " (no room booked) "){
// ... then push all unknown members into that array
filter_members.push(data_members[i]);
}
}
// call function that updates just the data in the already drawn member table
if (first == 1){
// table is already drawn, now just update data according to the new selection of rooms and refresh view. update filterd members in the table
$("#grid_array_members").pqGrid( "option" , "dataModel.data",filter_members );
$("#grid_array_members").pqGrid( "refreshDataAndView" );
}
// call function that draws table with the filtered members initially
if (first == 0){
draw_members(filter_members, data_members);
}
}
// draw table with the members for the first time
function draw_members(filter_members, data_members){
// draw filtered members in table with pqgrid
var obj_members = {
filterModel: { on: true, mode: "AND", header: true, type: 'local' },
};
obj_members.width = 1323;
obj_members.height = 300;
obj_members.title = "members";
obj_members.colModel = [{title:"attr1", width:110, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr2", width:120, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr3", width:120, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr4", width:60, dataType:"integer", filter: {type: 'textbox', condition: 'equal', listeners: ['keyup']}},
{title:"attr5", width:65, dataType:"integer", filter: {type: 'textbox', condition: 'equal', listeners: ['keyup']}},
{title:"attr6", width:110, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr7", width:139, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr8", width:139, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr9", width:139, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr10", width:139, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr11", width:139, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr12", width:139, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr13", width:139, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr14", width:139, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr15", width:139, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr16", width:138, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}}];
obj_members.dataModel = {data:filter_members};
// initialize pqgrid
$("#grid_array_members").pqGrid( obj_members );
// set event listeners for filtering in member area. without it, member data will be shown wrong after filtering and then reselecting rooms
$("#grid_array_members").pqGrid({
filter: function( event, ui ) {
//select_members(data_members, 1);
$("#grid_array_members").pqGrid( "option" , "dataModel.data",filter_members );
$("#grid_array_members").pqGrid( "refreshData" );
}
});
}
// draw table with the rooms for the first time
function draw_rooms(data_rooms, data_members, initiate){
// if function is called for the first time draw and initiate the table
if (initiate == 0) {
// draw filtered rooms in table with pqgrid
var obj_rooms = {
selectionModel: { type: 'none', subtype:'incr', cbHeader:true, cbAll:true},
filterModel: { on: true, mode: "AND", header: true, type: 'local' },
};
obj_rooms.width = 1323;
obj_rooms.height = 300;
obj_rooms.title = "rooms";
obj_rooms.colModel = [{title:"attr1", width:110, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr2", width:120, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr3", width:120, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr4", width:60, dataType:"integer", filter: {type: 'textbox', condition: 'equal', listeners: ['keyup']}},
{title:"attr5", width:50, dataType:"integer", filter: {type: 'textbox', condition: 'equal', listeners: ['keyup']}},
{title:"attr6", width:70, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr7", width:70, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr8", width:90, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr9", width:50, dataType:"integer", filter: {type: 'textbox', condition: 'equal', listeners: ['keyup']}},
{title:"attr10", width:70, dataType:"integer", filter: {type: 'textbox', condition: 'equal', listeners: ['keyup']}},
{title:"attr11", width:20, dataType:"integer", filter: {type: 'textbox', condition: 'equal', listeners: ['keyup']}},
{title:"attr12", width:100, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
// is hidden
{title:"attr13", hidden: true, width:50, dataType:"integer", filter: {type: 'textbox', condition: 'equal', listeners: ['keyup']}},
{title:"attr14", width:140, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr15", width:110, dataType:"string", filter: {type: 'textbox', condition: 'contain', listeners: ['keyup']}},
{title:"attr16", width:30, align: "center", type:'checkBoxSelection', resizable: false, sortable:false}];
obj_rooms.dataModel = {data:data_rooms};
// initialize pqgrid
$("#grid_array_rooms").pqGrid( obj_rooms );
// draw members after loading the csv file without anything has to be selected
select_members(data_members, 0);
// set event listeners for select or unselect row or filtering
$("#grid_array_rooms").pqGrid({
rowSelect: function( event, ui ) {
select_members(data_members, 1);
},
rowUnSelect: function( event, ui ) {
select_members(data_members, 1);
},
// use it after filter is used in the table and view is refreshed therefore
refresh: function( event, ui ) {
select_members(data_members, 1);
}
});
}
// if function is called again, just update the data
if (initiate >= 1) {
// update rooms in already drawn table after loading a new csv
$("#grid_array_rooms").pqGrid( "option" , "dataModel.data",data_rooms );
$("#grid_array_rooms").pqGrid( "refreshDataAndView" );
// draw members after loading a new csv file without anything has to be selected
select_members(data_members, 1);
// set event listeners for select or unselect row or filtering
$("#grid_array_rooms").pqGrid({
rowSelect: function( event, ui ) {
select_members(data_members, 1);
},
rowUnSelect: function( event, ui ) {
select_members(data_members, 1);
},
// use it after filter is used in the table and view is refreshed therefore
refresh: function( event, ui ) {
select_members(data_members, 1);
}
});
}
}
// main function
$(document).ready(function() {
// define var to determin if it is the first run oder a following run
var initiate = 0;
// the event listener for the file upload
document.getElementById('txtFileUpload').addEventListener('change', upload, false);
// method that reads and processes the selected file
function upload(evt) {
if (!browserSupportFileUpload()) {
alert('The File APIs are not fully supported in this browser!');
}
else {
var data = null;
var file = evt.target.files[0];
var reader = new FileReader();
reader.readAsText(file);
reader.onload = function(event) {
var csvData = event.target.result;
data = $.csv.toArrays(csvData);
if (data && data.length > 0) {
// 1st row has to be empty, 2nd refer to if-clause. then file is rommsys csv export, else abort
if (data[0].length == 1 && data[1] == "attr1, attr2, attr3, attr4, attr5, attr6, attr7, attr8, attr9, attr10, attr11, attr12, attr13, attr14, attr15"){
// cut two arrays for each members and rooms out of the csv import array
// start in row 3 (it is an array, for this slice_start = 2. this is the 1st row with room data)
var slice_start = 2;
var slice_end = 0;
// filter out rooms
// for each row in main array (begin with row 3, since this is the first room data after empty 1st line and 2nd head line) ...
for (i = 2; i < data.length; i++){
// ... if row is empty after rooms data ...
if (data[i].length == 1){
// ...then set cut-point for the room data part
slice_end = i;
break;
}
}
// cut array for rooms
var data_rooms = [];
data_rooms = data.slice(slice_start,slice_end);
// set offset: after cut point of rooms there follows an empty row in the csv, followd by headings for the members. jump 2 rows therefore
slice_start = slice_end+2;
// last row is empty. this row has to be cut off
slice_end = data.length-1;
// cut array for members
var data_members = [];
data_members = data.slice(slice_start,slice_end);
// draw rooms
draw_rooms(data_rooms, data_members, initiate);
initiate++;
}
else {
alert("File format not compatible!");
}
}
else {
alert("No data to import!");
}
};
reader.onerror = function() {
alert('Unable to read ' + file.fileName);
return data;
};
}
}
});
</script>
<style type="text/css">
.fileupload {
padding-bottom: 20px;
width: 665px;
}
.float {
float: left;
}
#grid_array_rooms, #grid_array_members {
margin:auto;
margin-top: 20px;
}
#panel {
width: 1330px;
margin: auto;
}
</style>
</head>
<body>
<div id="panel">
<div id="dvImportSegments" class="fileupload float">
<fieldset>
<legend>Upload your CSV File</legend>
<input type="file" name="File Upload" id="txtFileUpload" accept=".csv" />
</fieldset>
</div>
<div id="dvImportSegmentsBatch" class="fileupload float">
<fieldset>
<legend>Batch Upload with Folder</legend>
<input type="file" name="File Upload" id="txtFileUploadBatch" accept=".csv" />
</fieldset>
</div>
</div>
<div id="grid_array_rooms"></div>
<div id="grid_array_members"></div>
</body>
</html>