I'm trying to do this in my AG Grid (Angular 6):
have a column that shows the name of my object
but at the same time, that column should render this as a hyperlink to an edit page, using the Id of that object (not the name)
My current code snippet:
columnDefs = [
{
headerName: 'Name', field: 'Name', width: 125,
cellRenderer: function(params) {
return '' + params.value + '';
}
},
However, right now, all I can do is create a cell renderer, but since it's the cell renderer for the column of the Name column, I can only access that name - but I need the Id to build the hyperlink, which should point to /admin/edit/47 (or whatever the Id might be).
How can I accomplish this? What more do I need to do in order to be able to get both the Name (for display) as well as the Id in my cell renderer?
You can access it using params.data.Id where params.data points to your object bound to your record. So,
cellRenderer: function(params) {
return '' + params.value + '';
}
will give you the result you are expecting.
Related
This is in a C# ASP.NET MVC 5 web application. jQuery version 1.10.2. DataTables jQuery plugin version 1.10.21.
A page in the web application uses a DataTable. The DataTable is configured for server-side processing mode. So, when it receives a response from the server, the data for a row in the table is an object like the following example. (It is not proper JSON syntax; I am trying to represent what I see in the watch window of the browser's debugger.) i.e., each row has a string name, and an array of grade objects.
row: {...}
Id: 42
Name: "Fred"
Grades: (3) [...]
0: {...}
Id: 101
Name: "Quiz 1"
Value: "A"
1: {...}
Id: 102
Name: "Homework 2"
Value: "B"
2: {...}
Id: 103
Name: "Exam 3"
Value: "C"
length: 3
In the DataTable, I want 4 columns: one for the name, and 3 for the several grades, like the following example.
Name Quiz 1 Homework 2 Exam 3
=========================================
Fred A B C
My problem is that I cannot determine the correct notation for the data source for each of the grade columns, so that when a cell in such a column is rendered that the callback function receives an object that contains data about the grade. The following is what I have tried in the CSHTML file for the page. (I provide the number of grades to the page via a ViewBag property.)
...
<table id="gradebook-table" class="table">
...
</table>
...
<script>
$( document ).ready( onPageReady );
function onPageReady()
{
var options = {};
options.serverSide = true;
options.ajax =
{
'url': '#Url.Content( "~/gradebook/load" )',
'type': 'POST',
};
var c = 0;
options.columnDefs = [
{ targets: c++, data: "Id", visible: false, searchable: false },
{ targets: c++, data: "Name" },
];
for ( var i = 0; i < #ViewBag.GradeCount; i++ )
{
var def = {};
def.targets = c++;
def.data = "Grades[" + i + "]";
def.render = renderGradeCell;
options.columnDefs.push( def );
}
$( '#gradebook-table' ).DataTable( options );
}
function renderGradeCell( data, type, row, meta )
{
if ( type === 'display' )
{
// I expect data to be an object containing grade properties.
return '<span>' + data.Value + '</span>';
}
return data;
}
</script>
When the data source for a grade column is "Grades[" + i + "]", the data that the renderGradeCell() function is given is not an object that I expected, but a string like the following. It is just "[object Object]0" repeated for as many items as there are in the Grades array in the data for the whole row.
"[object Object]0[object Object]0[object Object]0"
I changed the data source for a grade column to just "Grades[]". But then, the data that the renderGradeCell() function is given is the entire Grades array for that row.
Any suggestions are appreciated. Thanks.
I followed the example on this link https://datatables.net/reference/option/columns.render and was able to insert the hyperlink into the table. However, I could not make the label of the hyperlink dynamic. Here is my code:
render: function (data, type, row) {
var chipName = data.substring(data.length-6, data.length-1);
return 'chipName';
}
As you can see, I defined chipName as a variable and its value is from the data. However, with this code, the label for the hyperlink is always "chipName" instead of "ABB109", "ABB110" as expected.
Please help
That's because you are not concatenating chipName variable with the string.
The right code:
...
return '' + chipName + '';
...
I'm trying to create a WebGrid which has to be very dynamic. The columns are defined in a list, which I've done like so:
#{
List<WebGridColumn> columns = new List<WebGridColumn>();
foreach (var column in Model.Columns)
{
columns.Add(new WebGridColumn() { ColumnName = column.Name, Header = column.Name });
}
}
#grid.GetHtml(
columns: columns)
All well and good, but the problem I have is with the rows. I'll try and explain...
For this question let's say we have two columns for Name and Address.
I have a collection of row objects, lets say SearchResult objects. A SearchResult contains a Dictionary of any number of attributes, such as Name, Address, Phone, Height, Bra Size, or anything (think of the EAV pattern). I need to access the attributes based on Column Name.
I figured I could do this using format, but I can't seem to figure it out. I want something like this:
columns.Add(new WebGridColumn() { ColumnName = column.Name, Header =
column.Header, Format = #<text>#item.Attributes[column.Name]</text> });
This sort of works but despite creating the format for the separate columns, the rows get populated with only the last column's format. i.e.:
Name Address
1 Main Street 1 Main Street
45 Paradise Av 45 Paradise Av
etc
I think it should work if you leave out the "ColumnName" (superfluous anyway), and also make the dynamic expression a bit more explicit:
columns.Add(
new WebGridColumn() {
Header = column.Header,
Format = (item) => #Html.Raw("<text>" + #item.Attributes[column.Name] + "</text>")
}
);
This issue is related to reference variables. You need to have the Format property in terms of the other properties of the WebGridColumn. This is how I would do it:
#{
List<WebGridColumn> columns = new List<WebGridColumn>();
foreach (var column in Model.Columns)
{
var col = new WebGridColumn();
col.Header = column.Name;
col.Format = (item) => #Html.Raw("<text>" + #item.Attributes[col.Header] + "</text>");
columns.Add(col);
}
}
ExtJS4 grid anticipates appropriate editor (cellEditor or rowEditor) per column.
If a column's header field is dateField - date selector will be applied on every row in that column.
What I need is an editor with different field editors per row, not per column.
The Extjs3 solution is provided here - unfortunately doesn't fit in Extjs4 case.
(please check that link to see explanatory images, cause I can't post images yet)
There's also a single column solution called property grid, but again - it supports only one column and is very deviated from the standard Ext.grid component
I have tried manually changing grid editor by customizing column.field and reloading grid.editingPlugin.editor, but always get a blank rowEditor panel with no fields.
//by default rowEditor applies textField to all cells - I'm trying to force custom numberFiled on apropriate row
var numberField=Ext.form.field.Number();
grid.columns[0].field=numberField;
//destroy current rowEditor's instance
delete grid.editingPlugin.editor;
//now, upon doubleClick on apropriate cell it should reinitialize itself (initEditor()) - and it does, but is an empty panel
what am I missing here? once I delete editingPlugin.editor everything should start from the beginning like during the first time rowEditor is called, but it looses all the fields
Solution for Ext4:
I was looking for a solution for this and this guy said the property grid has this behavior.
I have adapted it to work in a clean way for me
on initComponent I declared:
this.editors = {
'date' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.Date', {selectOnFocus: true})}),
'string' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.Text', {selectOnFocus: true})}),
'number' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.Number', {selectOnFocus: true})}),
'int' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.Number', {selectOnFocus: true})}),
'boolean' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.ComboBox', {
editable: false,
store: [[ true, 'Sim' ], [false, 'Não' ]]
})})
};
I used these functions to help me (copied):
this.renderCell = function(val, meta, rec) {
var result = val;
if (Ext.isDate(val)) {
result = me.renderDate(val);
} else if (Ext.isBoolean(val)) {
result = me.renderBool(val);
}
return Ext.util.Format.htmlEncode(result);
};
this.getCellEditor = function(record, column) {
return this.editors[record.get('type')];
};
And finally, associate these functions to the column:
{text: "Valor", name : 'colunaValor', width: 75, sortable: true, dataIndex: 'valor', width:200,
renderer: Ext.Function.bind(this.renderCell, this),
getEditor: Ext.Function.bind(this.getCellEditor, this)
}
I'm using .NET 3.5, MVC.
I want to use a set of string aliases to represent database values. i.e. when a user selects an option from a dropdown it actually sets the value as 0, 1, 2, etc. in the table, rather than the text shown in the dropdown itself.
e.g. I'm doing:
IdName[] Thing = new[] {
new IdName { Id = 0, Name = "No Selection" },
new IdName { Id = 1, Name = "Thing A9" },
new IdName { Id = 2, Name = "Thing C12" },
new IdName { Id = 3, Name = "Thing F4" }
};
MyDropDownList = new SelectList(Things, "Id", "Name",0);
and in the view:
<%= Html.DropDownList("MyDropDownList")%>
Now, this works just fine. What I can't get to work is displaying the value of the field in a 'details' view and showing "Thing C12" as the text instead of "2".
Also, is this the best way to go about this? I don't want to use the actual string in the database in case I modify the text on an entry (e.g. change the name of "Thing F4" to "Thing F5".) I'm totally open to some other ideas.
Thanks!
So you want your action method (that will store the user choice) to store the value rather than the alias shown on the Dropdown.
I think you have two options here.
1- On the server side by getting the value(the id) from your data source, eg: the Things[] array in your example.
public ActionResult StoreValueFromDropDown(string MyDropDownList) {
var id = Things.Single(thing => thing.Name == MyDropDownList).Id;
// here goes the code to sotre the id
}
2- on the client side by adding a hidden field that store the value of the Dropdown.
here is an example using jQuery(I didn't test it):
<input type="hidden" id="ThingId" />
,
$('#MyDropDownList').change(function(e){
$('#ThingId').value($('#MyDropDownList option:selected').attr('value'));
});
then you need to modify your action method to accept the value of that hidden field
public ActionResult StoreValueFromDropDown(int ThingId) {
// here goes the code to sotre the id
}