I'm trying to make a combined map/chart visualization work. I want to be able to mouseover/select a country on the map, and have an effect applied not only to the country but also to the line on the chart representing the country's data (of whatever, let's say population growth over the last decade).
In the done section of the map initialization, I use a callback highlightMap and pass in the countryName. This in theory would also be called by the chart when I mouseover that.
Questions:
1) In highlightMap my attempt to get the country element and change it's border width doesn't work. What's the right way to grab a map subunit and apply an effect to it?
2) Is this the right way to do this in general?
var map;
function setupMap(mouseoverCallback, mouseoutCallback) {
var width = mapWidth;
var height = mapHeight;
map = new Datamap({
element: document.getElementById(mapContainerDiv),
projection: 'mercator',
// responsive: true,
width: width,
height: height,
fills: {
defaultFill: "#ffffff"
},
geographyConfig: {
borderColor: '#000000',
},
data: {},
done: function(datamap) {
datamap.svg.selectAll('.datamaps-subunit').on('mouseover', function(geography) {
var countryName = geography.properties.name;
highlightMap(countryName);
});
datamap.svg.selectAll('.datamaps-subunit').on('mouseout', function(geography) {
var countryName = geography.properties.name;
highlightMap(countryName);
});
}
});
}
function highlightMap(name, highlight) {
var code = country2Code[name];
if (highlight) {
var countryElement = map.svg.select("#datamaps-subunit "+code);
countryElement.attr('stroke-width', 10); // Change border of country to something nutty
// reset color
...
}
}
Sort out your selectors:
.datamaps-subunit is not the same as #datamaps-subunit
Moreover, each country geometry has an additional class (like "ESP" or "USA") with the country code
To later select the country you just use map.svg.selectAll(".datamaps-subunit.ESP") or map.svg.selectAll(".datamaps-subunit.USA")
Notice there is no space between class names, as they are applied to the same SVG element
Use select() or selectAll() depending on how many elements you expect to get (one or possibly many)
EDIT: A much easier option would be to simply add this rule to your CSS sheet:
.datamaps-subunit:hover {
stroke-width: 2px;
}
I'm in the situation I need to save the state op the grid after re-sizing, reordering, hiding columns.
All works well, except that the column filters (drop-downs, text field, date-picker) are not restored in the correct column after the column with the filter in is moved (collumnchooser).
Using the following JavaScript, I can restore most what I need (size, order and visibility of the columns), but restoring the filters in the right columns doesn't work. (Filters appear several columns after where they should.
var listName = jQuery('#list').jqGrid('getGridParam', 'customName');
var colModel = LoadColumnModel(listName);
var perm = jQuery.cookies.get(listName + '_list_perm');
var rowNumber = jQuery.cookies.get(listName + '_list_rowNumber');
if (colModel) {
var grid = jQuery('#list');
for (var i = 0; i < colModel.length; i++) {
var column = colModel[i];
if (column.hidden) {
grid.jqGrid('hideCol', column.name);
};
***//I hoped next line would do the trick, but it didn't :(***
if (column.search && column.searchoptions) {
grid.jqGrid('setColProp', column.name, { search: true, searchoptions: column.searchoptions });
};
}
grid.jqGrid('setGridParam', { colModel: colModel });
loadGrid = false;
if (rowNumber) {
grid.jqGrid('setGridParam', { rowNum: rowNumber });
jQuery('.ui-pg-selbox').val(rowNumber);
}
grid.trigger('reloadGrid');
if (perm) {
grid.jqGrid("remapColumns", perm, true);
}
}
Anyone has a clue?
You should don't set searchoptions in the grid. instead of that you can save/restore the postData parameter of jqGrid.
I would recommend you to look at the answer, the answer and this one. It shows how to implement the saving/restoring of the grid state. I used localStorage instead of the cookies because of reasons which I explained in the answer.
I've got a jqGrid where I need to change the model after the data is loaded, but before it's parsed into the grid. In otherwords, I think I want to do it in the loadComplete handler. I see this approach: Setting JqGrid's colName and colModel from JSON data, but I'm have a bunch of grids already written that use the "load data with jqGrid" approach, rather than the "pre-load data and pass it to jqGrid" one used there, and I'm hoping to avoid re-coding, or making this one different.
(Hiding and showing hidden columns isn't practical, either.)
Is this possible?
More details:
Basically, I don't know what columns I need till I see the data. Say I'm showing traffic by state:
Date CA WA NY MN
4/20 100 90 85 72
4/21 95 85 89 70
There's only room to show four states, but there might be many more in the data (or there might be fewer), so I want them listed in order of traffic. Right now, the data is coming in like:
{
date : 4-20,
ca : 100,
wa : 90,
ny : 85,
mn : 72
hi : 56,
il : 30
},
{
date : 4-21,
ca : 95,
wa : 85, // note: for a given row, a column might be relatively lower
ny : 89, // than another. The column order is based on the overall
mn : 70
hi : 60,
il : 45
}
or it could be:
{
date : 4-20,
ny : 110,
hi : 95,
il : 90,
wa : 80
}
I've tried setting up columns like state1, state2, state3, state4 and then using jsonmap to remap them, but it didn't work.
loadonce = true, datatype = json
I found one way which seems work OK.
The idea of my solution is following. You use colModel having many hidden columns with the dummy names like 'cm0', 'cm1', 'cm2', ... All the columns has the same data like you need in your case. To fill the data more easy I use column templates existing since jqGrid 3.8.2:
var mygrid=jQuery("#list"),
cmIntTemplate = {
width:50,
sorttype:"int",
formatter:"integer",
align:"right",
hidden:true
},
cm = [
// here we define the first columns which we always has
// the list can be empty or has some columns with
// the properties other as the rest (without cmIntTemplate)
{name:"date",label:"Date",key:true,width:100, fixed:true,
formatter:'date',formatoptions:{srcformat:"m-d",newformat:"m/d"}}
], maxCol = 30, dummyColumnNamePrefix = "cm";
// Add dummy hidden columns. All the columns has the same template
for (i=0;i<maxCol;i++) {
cm.push({name:dummyColumnNamePrefix+i,template:cmIntTemplate});
}
After that I create jqGrid in the standard way, but with the jsonReader which use the page as function:
jsonReader: {
repeatitems: false,
page: function (obj) {
// ------------------------
// here I add the main code
// ------------------------
return obj.page;
}
}
The function from the jsonReader.page return the same value like as do default jsonReader, but I use the way with function because the function will be called directly before the reading of the main contain of JSON data. Inside of the code I get the first row of the data and use it's property names to fill jsonmap property of the corresponding column and set the column name. Additionally I make some dummy columns needed to display all the JSON data visible and the rest dummy column hidden. The last thing which should be done is correction of the grid width which was calculated previously. So the grid will look like this:
or like this
depend on the JSON input data.
The code of the page function is following:
page: function (obj) {
var rows = obj.rows, colModel = mygrid[0].p.colModel,
cmi, iFirstDummy, firstRow, prop,
orgShrinkToFit, isFound,
showColNames = [], hideColNames = [];
if (typeof(rows) === "undefined" || !$.isArray(rows) || rows.length === 0) {
// something wrong need return
return obj.page;
}
// find the index of the first dummy column
// in the colModel. If we use rownumbers:true,
// multiselect:true or subGrid:true additional
// columns will be inserted at the begining
// of the colModel
iFirstDummy = -1;
for(i=0;i<colModel.length;i++) {
cmi = colModel[i];
if (dummyTestRegex.test(cmi.name)) {
iFirstDummy = i;
break;
}
}
if (iFirstDummy === -1) {
// something wrong need return
return obj.page;
}
orgShrinkToFit = clearShrinkToFit();
// we get the first row of the JSON data
firstRow = rows[0];
for (prop in firstRow) {
if (firstRow.hasOwnProperty(prop)) {
// we will use the properties name of the first row
// as the names of the column headers of the grid
// find column index having prop as the name
isFound = false;
for(i=0;i<colModel.length;i++) {
cmi = colModel[i];
if (cmi.name === prop) {
isFound = true;
showColNames.push(prop);
break;
}
}
if(!isFound) {
// labels defines the column names
cmi = colModel[iFirstDummy];
showColNames.push(cmi.name);
mygrid.jqGrid('setLabel',cmi.name,prop);
// because of bug in jqGrid with calculation of width
// we have to reset the width
cmi.width = cmIntTemplate.width;
// we set jsonmap which jqGrid will use instead
// of dummy column names to read all row data
cmi.jsonmap = prop;
iFirstDummy++;
}
}
}
// fill the list of unused columns
for(i=0;i<colModel.length;i++) {
cmi = colModel[i];
if ($.inArray(cmi.name, showColNames) === -1 && dummyTestRegex.test(cmi.name)) {
hideColNames.push(cmi.name);
}
}
mygrid.jqGrid('showCol',showColNames);
mygrid.jqGrid('hideCol',hideColNames);
setGridWidthAndRestoreShrinkToFit(orgShrinkToFit);
return obj.page;
}
Inside of the page function I use small helper functions
var clearShrinkToFit = function() {
// save the original value of shrinkToFit
var orgShrinkToFit = mygrid.jqGrid('getGridParam','shrinkToFit');
// set shrinkToFit:false to prevent shrinking
// the grid columns after its showing or hiding
mygrid.jqGrid('setGridParam',{shrinkToFit:false});
return orgShrinkToFit;
},
setGridWidthAndRestoreShrinkToFit = function(orgShrinkToFit) {
// calculate the new grid width
var width=0, i=0, headers=mygrid[0].grid.headers, l=headers.length;
for (;i<l; i++) {
var th = headers[i].el;
if (th.style.display !== "none") {
width += $(th).outerWidth();
}
}
// restore the original value of shrinkToFit
mygrid.jqGrid('setGridParam',{shrinkToFit:orgShrinkToFit});
// set the grid width
mygrid.jqGrid('setGridWidth',width);
},
dummyTestRegex = new RegExp(dummyColumnNamePrefix+"(\\d)+");
The working demo you can see here.
UPDATED: Another answer with the demo shows how to create the grid which has another format of input data: [[], [], ...] (array of arrays) - matrix.
How to get a jqGrid cell value when in-line editing (getcell and getRowData returns the cell content and not the actuall value of the input element).
General function to get value of cell with given row id and cell id
Create in your js code function:
function getCellValue(rowId, cellId) {
var cell = jQuery('#' + rowId + '_' + cellId);
var val = cell.val();
return val;
}
Example of use:
var clientId = getCellValue(15, 'clientId');
Dodgy, but works.
Here is an example of basic solution with a user function.
ondblClickRow: function(rowid) {
var cont = $('#grid').getCell(rowid, 'MyCol');
var val = getCellValue(cont);
}
...
function getCellValue(content) {
var k1 = content.indexOf(' value=', 0);
var k2 = content.indexOf(' name=', k1);
var val = '';
if (k1 > 0) {
val = content.substr(k1 + 7, k2 - k1 - 6);
}
return val;
}
After many hours grief I found this to be the simplest solution. Call this before fetching the row data:
$('#yourgrid').jqGrid("editCell", 0, 0, false);
It will save any current edit and will not throw if there are no rows in the grid.
As you stated, according to the jqGrid documentation for getCell and getRowData:
Do not use this method when you editing the row or cell. This will return the cell content and not the actual value of the input element
Since neither of these methods will return your data directly, you would have to use them to return the cell content itself and then parse it, perhaps using jQuery. It would be nice if a future version of jqGrid could provide a means to do some of this parsing itself, and/or provide an API to make it more straightforward. But on the other hand is this really a use case that comes up that often?
Alternatively, if you can explain your original problem in more detail there may be other options.
Try this, it will give you particular column's value
onSelectRow: function(id) {
var rowData = jQuery(this).getRowData(id);
var temp= rowData['name'];//replace name with you column
alert(temp);
}
Basically, you have to save the row before you access the cell contents.
If you do, then you get the value for the cell instead of the markup that comes when the cell is in edit mode.
jQuery.each(selectedRows, function(index, foodId) {
// save the row on the grid in 'client array', I.E. without a server post
$("#favoritesTable").saveRow(foodId, false, 'clientArray');
// longhand, get grid row based on the id
var gridRow = $("#favoritesTable").getRowData(foodId);
// reference the value from the editable cell
foodData += foodId + ":" + gridRow['ServingsConsumed'] + ',';
});
Hi, I met this problem too. Finally I solved this problem by jQuery. But the answer is related to the grid itself, not a common one. Hope it helps.
My solution like this:
var userIDContent = $("#grid").getCell(id,"userID"); // Use getCell to get the content
//alert("userID:" +userID); // you can see the content here.
//Use jQuery to create this element and then get the required value.
var userID = $(userIDContent).val(); // var userID = $(userIDContent).attr('attrName');
you can use this directly....
onCellSelect: function(rowid,iCol,cellcontent,e) {
alert(cellcontent);
}
This is my solution:
function getDataLine(grida, rowid){ //vykradeno z inineeditu a vohackovano
if(grida.lastIndexOf("#", 0) === 0){
grida = $(grida);
}else{
grida = $("#"+grida);
}
var nm, tmp={}, tmp2={}, tmp3= {}, editable, fr, cv, ind;
ind = grida.jqGrid("getInd",rowid,true);
if(ind === false) {return success;}
editable = $(ind).attr("editable");
if (editable==="1") {
var cm;
var colModel = grida.jqGrid("getGridParam","colModel") ;
$("td",ind).each(function(i) {
// cm = $('#mygrid').p.colModel[i];
cm = colModel[i];
nm = cm.name;
if ( nm != 'cb' && nm != 'subgrid' && cm.editable===true && nm != 'rn' && !$(this).hasClass('not-editable-cell')) {
switch (cm.edittype) {
case "checkbox":
var cbv = ["Yes","No"];
if(cm.editoptions ) {
cbv = cm.editoptions.value.split(":");
}
tmp[nm]= $("input",this).is(":checked") ? cbv[0] : cbv[1];
break;
case 'text':
case 'password':
case 'textarea':
case "button" :
tmp[nm]=$("input, textarea",this).val();
break;
case 'select':
if(!cm.editoptions.multiple) {
tmp[nm] = $("select option:selected",this).val();
tmp2[nm] = $("select option:selected", this).text();
} else {
var sel = $("select",this), selectedText = [];
tmp[nm] = $(sel).val();
if(tmp[nm]) { tmp[nm]= tmp[nm].join(","); } else { tmp[nm] =""; }
$("select option:selected",this).each(
function(i,selected){
selectedText[i] = $(selected).text();
}
);
tmp2[nm] = selectedText.join(",");
}
if(cm.formatter && cm.formatter == 'select') { tmp2={}; }
break;
}
}
});
}
return tmp;
}
I have a solution:
1. Using this.value to get the current editing value in the editing row.
2. Save the cell value to a hidden field when the cell lost its focus.
3. Read the hidden field when you need.
The code:
colModel="[
{ name: 'Net', index: 'Net', editable:true, editoptions: { dataEvents: [ { type: 'focusout', fn: function(e) {$('#HiddenNet').val(this.value);} }] }, editrules:{custom:true,}},
{ name: 'Tax', index: 'Tax', editable:true, editoptions: { dataEvents: [ { type: 'focus', fn: function(e) {this.value=$('#HiddenNet').val(); } }] }, editrules:{custom:true}}
]"
Good Luck
You can get it from the following way...!!
var rowId =$("#list").jqGrid('getGridParam','selrow');
var rowData = jQuery("#list").getRowData(rowId);
var colData = rowData['UserId']; // perticuler Column name of jqgrid that you want to access
In my case the contents of my cell is HTML as result of a formatter. I want the value inside anchor tag. By fetching the cell contents and then creating an element out of the html via jQuery I am able to then access the raw value by calling .text() on my newly created element.
var cellContents = grid.getCell(rowid, 'ColNameHere');
console.log($(cellContents));
//in my case logs <h3>The Value I'm After</h3>
var cellRawValue = $(cellContents).text();
console.log(cellRawValue); //outputs "The Value I'm After!"
my answer is based on #LLQ answer, but since in my case my cellContents isn't an input I needed to use .text() instead of .val() to access the raw value so I thought I'd post this in case anyone else is looking for a way to access the raw value of a formatted jqGrid cell.
its very simple write code in you grid.php and pass the value to an other page.php
in this way you can get other column cell vaue
but any one can make a like window.open(path to pass value....) in fancy box or clor box?
$custom = <<<CUSTOM
jQuery("#getselected").click(function(){
var selr = jQuery('#grid').jqGrid('getGridParam','selrow');
var kelr = jQuery('#grid').jqGrid('getCell', selr, 'stu_regno');
var belr = jQuery('#grid').jqGrid('getCell', selr, 'stu_school');
if(selr)
window.open('editcustomer.php?id='+(selr), '_Self');
else alert("No selected row");
return false;
});
CUSTOM;
$grid->setJSCode($custom);
I think an extension of this would get it for you.
retrieving-original-row-data-from-jqgrid
I think a better solution than using getCell which as you know returns some html when in edit mode is to use jquery to access the fields directly. The problem with trying to parse like you are doing is that it will only work for input fields (not things like select), and it won't work if you have done some customizations to the input fields. The following will work with inputs and select elements and is only one line of code.
ondblClickRow: function(rowid) {
var val = $('#' + rowid + '_MyCol').val();
}
I've got a rather indirect way. Your data should have an unique id.
First, setting a formatter
$.extend(true, $.fn.fmatter, {
numdata: function(cellvalue, options, rowdata){
return '<span class="numData" data-num="'+rowdata.num+'">'+rowdata.num+'</span>';
}
});
Use this formatter in ColModel. To retrieve ID (e.g. selected row)
var grid = $("#grid"),
rowId = grid.getGridPara('selrow'),
num = grid.find("#"+rowId+" span.numData").attr("data-num");
(or you can directly use .data() for latest jquery 1.4.4)
In order to get the cell value when in-line editing you need to capture this event(or another similar event, check documentation):
beforeSaveCell: function (rowid, celname, value, iRow, iCol) { }
In the value parameter you have the 'value' of the cell that was currently edited.
To get the the rest of the values in the row use getRowData()
I lost a lot of time with this, hope this helps.
My workaround is to attach an object containing orignal values to each tr element in the grid. I've used afterAddRecord callback to get my hands on the values before jqGrid throws them away and jQuery's "data" method to store them in the work.
Example:
afterInsertRow: function( rowid, rowdata, rowelem ) {
var tr = $("#"+rowid);
$(tr).data("jqgrid.record_data", rowelem);
},
“rowelem” is the array of cell values from our JSON data feed or [jsonReader] (http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data#jsonreader_as_function)
Then at any point I can fetch those attributes using:
$(tr).data(“jqgrid.record_data”).
More at: http://wojciech.oxos.pl/post/9423083837/fetching-original-record-values-in-jqgrid
I think that Aidan's answer is by far the best.
$('#yourgrid').jqGrid("editCell", 0, 0, false);
This commits any current edits, giving you access to the real value. I prefer it because:
You don't have to hard-code any cell references in.
It is particularly well suited to using getRowData() to get the entire grid, as it doesn't care which cell you've just been editing.
You're not trying to parse some markup generated by jqGrid which may change in future.
If the user is saving, then ending the edit session is likely the behaviour they would want anyway.
Before i was getting :
html tag of the textbox something like
but Here is the solution to get the value from that particular column, working and tested
function getValue(rowId, cellId) {
var val = $("[rowId='"+rowId+"'][name='"+cellId+"']").val();
return val;
}
var values = getValue(rowId, 'cellid');
I obtain edit value using javascript:
document.getElementById('idCell').value
I hope this info useful for someone.
I needed the original value before the formatter, so this is what I did:
{
name: 'Slot', title: false, formatter: function (cellValue, options, rowObject) {
rowObject['SlotID'] = cellValue; // <--- This saves the original ID
if (somelogic) {
return someString;
} else {
return someOtherString;
}
}
},
{ name: 'SlotID', hidden: true }
Now SlotID contains the original ID. Also, you don't need to have SlotID property on your original model.
try subscribing to afterEditCell event it will receive (rowid, cellname, value, iRow, iCol) where value is your a new value of your cell
You can use getCol to get the column values as an array then index into it by the row you are interested in.
var col = $('#grid').jqGrid('getCol', 'Sales', false);
var val = col[row];