I hava implemented a datagrid using dojo which get updated every 5 seconds. I use following code to update the datagrid.
jsonStore.fetch({
query: {id:'*'},
onComplete: function(items, result){
dojo.forEach(items, function(item){
jsonStore.setValue(item, "time" , data.update[0].netchange);
.....
'data' is the new data i need to set to the grid which is an json object as follows
var data = {"update":[{...}]}
what I need to do if the netchage is negative i need set cell color to red. if netchange is positive it should be green. So I need a way to change cell formatting dynamically. can some one please tell me how to this. thanks in advance
grid4 = new dojox.grid.DataGrid({
query : {
Title : '*'
},
id : "grid",
jsId : "grid",
clientSort : true,
rowSelector : '0px',
structure : layout4
}, document.createElement('div'));
grid4.setStore(jsonStore);
dojo.byId("gridContainer4").appendChild(grid4.domNode);
var layout4 = [ {
field : 'time',
name : 'time',
width : '40px',
formatter: geticon()
}, {
field : 'netchange',
name : 'netchange',
width : '30px'
} ];
Before I answer the question, just a trivial misnomer when you say, "change the cell formatting dynamically".
You aren't changing the cell formatter, you are changing how the cell is styled.
Every time a value is loaded into a cell, the formatter is called. Additionally, the onStyleROw function is called for the row that the cell is within.
This means that you have two options for changing the color of the cell. You can do it on a cell wide basis, or you can have your formatter do something simple like wrapping the value with a <span> that has a different style color. I'll show you both.
Here is the first solution without changing any of your existing grid code and it will change the entire row using onStyleRow.
Solution 1 using onStyleRow
Step 1. (Connect the onStyleRow)
dojo.connect( grid4, "onStyleRow", styleRowGridPayment );
Step 2. (Create you styleRowGridPayment method.)
var styleGridPayment = function(inRow) {
if( null !== grid4.getItem( inRow.index ) ) {
item = grid4.getItem( inRow.index );
if( item.netchange < 0 ) {
inRow.customStyles += "color:red;";
} else {
inRow.customStyles += "color:green;";
}
}
}
That should do it for using onStyleRow.
Solution 2, using the formatter
In your field declaration, you would have
{
field : 'netchange',
name : 'netchange',
width : '30px'
formatter: formatNetchange
}
Notice that I have added the formatNetchange as the formatter.
Then you just create your formatter.
formatNetchange = function(value){
if(value < 0){
color = "red";
} else {
color = "green";
}
return "<span style='color:" + color "'>" + value "</span>";
}
Related
I've created a qooxdoo list with customized items containing checkbox and label.
My problem is: when I check the check box, it gets bigger which gives an ugly user experience. Also when I check some first items and scroll down, I see many items checked which should be unchecked by default.
Here's the code that someone can paste into play ground for qooxdoo:
// Create a button
var button1 = new qx.ui.form.Button("click to see list!", "icon/22/apps/internet-web-browser.png");
// Document is the application root
var doc = this.getRoot();
// Add button to document at fixed coordinates
doc.add(button1,
{
left : 100,
top : 50
});
var popup;
// Add an event listener
button1.addListener("execute", function(e) {
if (!popup) {
popup = new myApp.list();
}
popup.placeToWidget(button1);
popup.show();
});
/*
* class: list inside popup.
*/
qx.Class.define("myApp.list",
{
extend : qx.ui.popup.Popup,
construct : function()
{
this.base(arguments);
this.__createContent();
},
members : {
__createContent : function(){
this.set({
layout : new qx.ui.layout.VBox(),
minWidth : 300
});
//prepare data
var zones = [];
for (var i=0; i<100; i++){
zones.push({"LZN" : "ZONE " + i, "isChecked" : false});
}
var lstFences = new qx.ui.list.List();
this.add(lstFences, {flex : 2});
var delegate = {
createItem : function() {
return new myApp.customListItem();
},
bindItem : function(controller, item, id) {
controller.bindProperty("isChecked", "isChecked", null, item, id);
controller.bindPropertyReverse("isChecked", "isChecked", null, item, id);
controller.bindProperty("LZN", "LZN", null, item, id);
}
};
lstFences.setDelegate(delegate);
lstFences.setModel(qx.data.marshal.Json.createModel(zones));
lstFences.setItemHeight(50);
}
}
})
/**
* The custom list item
*/
qx.Class.define("myApp.customListItem", {
extend : qx.ui.core.Widget,
properties :
{
LZN:
{
apply : "__applyLZN",
nullable : true
},
isChecked :
{
apply : "__applyChecked",
event : "changeIsChecked",
nullable : true
}
},
construct : function()
{
this.base(arguments);
this.set({
padding : 5,
decorator : new qx.ui.decoration.Decorator().set({
bottom : [1, "dashed","#BBBBBB"]
})
});
this._setLayout(new qx.ui.layout.HBox().set({alignY : "middle"}));
// create the widgets
this._createChildControl(("isChecked"));
this._createChildControl(("LZN"));
},
members :
{
// overridden
_createChildControlImpl : function(id)
{
var control;
switch(id)
{
case "isChecked":
control = new qx.ui.form.CheckBox();
control.set({
padding : 5,
margin : 8,
value : false,
decorator : new qx.ui.decoration.Decorator().set({
width : 2,
color : "orange",
radius : 5
})
});
this._add(control);
break;
case "LZN":
control = new qx.ui.basic.Label();
control.set({allowGrowX : true});
this._add(control, {flex : 2});
break;
}
return control || this.base(arguments, id);
},
__applyLZN : function(value, old) {
var label = this.getChildControl("LZN");
label.setValue(value);
},
__applyChecked : function(value, old)
{
var checkBox = this.getChildControl("isChecked");
console.log(value, old);
checkBox.setValue(value);
}
}
});
There are two problems here:
The first one is the fact that by creating the checkbox as a subwidget via _createChildControlImpl makes the checkbox loosing its appearance (in sense of qooxdoo theme appearance) leading to the lost minWidth attribute which makes the checkbox having a width of 0 when unchecked and a width which is needed to show the check mark when it's checked. The solution here is to add an appearance to the myApp.customListItem class like this:
properties : {
appearance: {
refine : true,
init : "mycustomlistitem"
}
}
and afterward add a corresponding appearance to your theme:
appearances :
{
"mycustomlistitem" : "widget",
"mycustomlistitem/isChecked" : "checkbox"
}
You could also add all the styling you've done when instantiating the checkboxes (orange decorator etc.) within the appearance definition.
The second problem is that you’ve defined only a one way binding between the checkbox subwidget of the custom list item and its "isChecked" sub widget. You need a two way binding here, thus if the value of the property "isChanged" changes it’s value it prpoagates that to the checkbox and vice versa.
I've modified your playground sample accordingly by creating the missing appearance on the fly and by creating a two way binding between the checkbox and the list items “isChecked” property. Note that I've created the list directly in the app root for simplicity:
https://gist.github.com/level420/4662ae2bc72318b91227ab68e0421f41
I am using YUI Paginator API for pagination and I need to show Total number of pages on screen. I saw that there is a function getTotalPages() in API but I am unsure about how to use it, there isn't enough documentation. Also after looking at some other documentation I tried using {totalPages} but didn't work.
Can somebody help me out in this issue? Thanks in advance!!
Below is the code snippet I am using. Please refer to template object from config:
config = {
rowsPerPage: 100,
template :
'<p class="klass">' +
'<label>Total pages: {totalPages}</label>'+
'<label>Page size: {RowsPerPageDropdown}</label>'+
'</p>',
rowsPerPageDropdownClass : "yui-pg-rpp-options",
rowsPerPageOptions : [
{ value : 100 , text : "100" },
{ value : 250 , text : "250" },
{ value : 500 , text : "500" },
{ value : 1000 , text : "1000" },
{ value : tstMap[tabName].length , text : "All" }
],
};
var myPaginator = new YAHOO.widget.Paginator(config);
The Paginator utility allows you to display an item or a group of items depending on the number of items you wish to display at one time.
Paginator's primary functionality is contained in paginator-core and is mixed into paginator to allow paginator to have extra functionality added to it while leaving the core functionality untouched. This allows paginator-core to remain available for use later on or used in isolation if it is the only piece you need.
Due to the vast number of interfaces a paginator could possibly consist of, Paginator does not contain any ready to use UIs. However, Paginator is ready to be used in any Based-based, module such as a Widget, by extending your desired class and mixing in Paginator. This is displayed in the following example:
YUI().use('paginator-url', 'widget', function (Y){
var MyPaginator = Y.Base.create('my-paginator', Y.Widget, [Y.Paginator], {
renderUI: function () {
var numbers = '',
i, numberOfPages = this.get('totalPages');
for (i = 1; i <= numberOfPages; i++) {
// use paginator-url's formatUrl method
numbers += '' + i + '';
}
this.get('boundingBox').append(numbers);
},
bindUI: function () {
this.get('boundingBox').delegate('click', function (e) {
// let's not go to the page, just update internally
e.preventDefault();
this.set('page', parseInt(e.currentTarget.getContent(), 10));
}, 'a', this);
this.after('pageChange', function (e) {
// mark the link selected when it's the page being displayed
var bb = this.get('boundingBox'),
activeClass = 'selected';
bb.all('a').removeClass(activeClass).item(e.newVal).addClass(activeClass);
});
}
});
var myPg = new MyPaginator({
totalItems: 100,
pageUrl: '?pg={page}'
});
myPg.render();
});
ag-Grid provides a mechanism using the cellStyle to modify the style of a cell.
However, I want to change the color of a cell while processing nodes. I know the exact node which I want to change the color of.
Is there some way to do that?
The simplest solution would be to use a cell rendering function:
// put the value in bold
colDef.cellRenderer = function(params) {
return '<b>' + params.value.toUpperCase() + '</b>';
}
You can apply the style depending on the value of the node - this will be made available in the params argument
Use cellStyle or cellClass or cellClass in column property and return the
var colDef = {name: 'Dynamic Styles', field' 'field2', cellStyle: cellStyling}
function cellStyling(params){
if(true){
return {'background-color':''};
} else {
return {'color': '#9B9999' ,'background-color':'#E8E2E1'};
}
}
as per your comment, code can be use like--
$scope.gridOptions.api.forEachNode(function(node){
for(var j=0;j<node.gridOptionsWrapper.columnController.allDisplayedColumns.length;j++){
if(node.gridOptionsWrapper.columnController.allDisplayedColumns[j].colDef.headerName==="column Name"){
node.gridOptionsWrapper.columnController.allDisplayedColumns[j].colDef.cellStyle = {apply style};
}
}
}
It looks like a simple task, but I already spent 4 hours to find a solution. How can I highlight the entire row by cell click?
On register api I have next
$scope.gridOptions.onRegisterApi = function(gridApi){
$scope.gridApi = gridApi;
gridApi.cellNav.on.navigate($scope,function(selected){
if('.ui-grid-cell-focus '){
console.log("fired class")
$(selected.row.entity).addClass('ui-grid-cell-focus')
}
console.log("fired cell")
$(selected.row.entity).addClass('ui-grid-cell-focus')
});
};
I see how click on cell is fired, but I cannot force to color the row and I don't want to select the row, because I use check box selection for this purpose, I just want to highlight the row by click on any cell in this row. Could somebody tell me where my mistake is?
Attached plunker
One way to accomplish what you want is to add a cellClass definition to your columnDefs. That function takes two params: grid and row.
$scope.gridOptions.columnDefs = [{
name: 'id',
width: '150',
cellTemplate: "",
cellClass: getCellClass
}, {
name: 'name',
width: '200',
cellClass: getCellClass
} ...
];
function getCellClass(grid, row) {
return row.uid === selectedRow ? 'highlight' : '';
}
On click you could set a variable to the uid of the row, and inside the cellClass function you can check if the uid of the current row matches the uid of the selected, if so, you can set the class to a class that properly reflects the background color of the selected row.
var selectedRow = null;
gridApi.cellNav.on.navigate($scope, function(selected) {
if ('.ui-grid-cell-focus ') {
selectedRow = selected.row.uid;
gridApi.core.notifyDataChange(uiGridConstants.dataChange.COLUMN);
}
});
Here's a link to your updated plunker: http://plnkr.co/edit/AgpAI2cmdqgNsSLVNjYA?p=preview
If you don't like the cellClass approach you could define custom cellTemplates and similarly react to a property you set on the row entity.
I have a jqGrid where I want all the rows to be in edit mode. Under certain conditions, however, I want a cell in that row to be readonly based on some condition of the row data, but I can't seem to get the grid to bend to my will (yet).
This is what I currently have.
$(grid).addRowData(...); // omitted for clarity
$(grid).jqGrid('editRow',rowid);
if (someCondition){
$(grid).setCell(rowid, 'col1', '', '', {editable: false});
}
The row is added and put into edit mode just as I want, but when it gets to the call to setCell(), it doesn't seem to affect the cell.
Any ideas what I'm doing wrong here?
The grid was already using column formatters for other columns so I decided to go that route. I couldn't get it to not change the entire column to readonly/editable using the method described by Oleg. I also decided to store readonly state as part of the grid cell value.
colModel:
{ name: 'ARNumber', width: 70, editable: false, sortable: false, formatter: 'optionalReadonlyInputCellFormatter'},
setup of my formatter/unformatter:
$.extend($.fn.fmatter, {
optionalReadonlyInputCellFormatter: formatOptionalReadonlyInputCell
});
$.extend($.fn.fmatter.optionalReadonlyInputCellFormatter, {
unformat: unformatOptionalReadonlyInputCell
});
formatter/unformatter functions:
function formatOptionalReadonlyInputCell(cellvalue, options, rowdata) {
var readonly = cellvalue === undefined;
if (readonly)
return displayARNumberInput('');
vals = cellvalue.split(",");
var cellValue = vals[0];
var readonly = !(vals[1] === undefined) || vals[1] == 1;
if (readonly) {
return displayARNumberSpan(cellValue);
}
else {
return displayARNumberInput(cellValue);
}
}
function unformatOptionalReadonlyInputCell(cellvalue, options, cellobject) {
var readonly = (cellvalue == "") ? "0" : "1";
if (readonly == "1") {
return cellvalue + "," + readonly;
}
else {
return $(cellobject).children().val() + "," + readonly;
}
}
function displayARNumberInput(value) {
var element = document.createElement("input");
element.type = "text";
element.value = value;
return element.outerHTML;
}
function displayARNumberSpan(value) {
var element = document.createElement("span");
element.innerText = value;
return element.outerHTML;
}
You should try to modify the property of the cell before you call the editRow method.
Moreover I know only editable attribute for the row which can be "1" or "0" and class "not-editable-row" also for the class. Does the editable attribute for the cell exist?
There is one way which can work. You can modify the editable attribute for the column in the colModel before the call of the editRow method and reset this to the original state after the editRow call. See jqGrid: Enable paging while converting HTML table to grid for an example how to make a dynamic modification in the colModel.
UPDATED: If you already use custom formatter, you can also include that in your code custom editing. An example you will find here Add multiple input elements in a custom edit type field. Custom formatter will be used only to display the data in the grid, but custom_element and custom_value if the row is in the editing mode.