Using cellUpdateEvent with YUI DataTable and JSON DataSource - javascript

I'm working with a UI that has a (YUI2) JSON DataSource that's being used to populate a DataTable. What I would like to do is, when a value in the table gets updated, perform a simple animation on the cell whose value changed.
Here are some relevant snippets of code:
var columns = [
{key: 'foo'},
{key: 'bar'},
{key: 'baz'}
];
var dataSource = new YAHOO.util.DataSource('/someUrl');
dataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
dataSource.connXhrMode = 'queueRequests';
dataSource.responseSchema = {
resultsList: 'results',
fields: [
{key: 'foo'},
{key: 'bar'},
{key: 'baz'}
]
};
var dataTable = new YAHOO.widget.DataTable('container', columns, dataSource);
var callback = function() {
success: dataTable.onDataReturnReplaceRows,
failure: function() {
// error handling code
},
scope: dataTable
};
dataSource.setInterval(1000, null, callback);
And here's what I'd like to do with it:
dataTable.subscribe('cellUpdateEvent', function(record, column, oldData) {
var td = dataTable.getTdEl({record: record, column: column});
YAHOO.util.Dom.setStyle(td, 'backgroundColor', '#ffff00');
var animation = new YAHOO.util.ColorAnim(td, {
backgroundColor: {
to: '#ffffff';
}
});
animation.animate();
};
However, it doesn't seem like using cellUpdateEvent works. Does a cell that's updated as a result of the setInterval callback even fire a cellUpdateEvent?
It may be that I don't fully understand what's going on under the hood with DataTable. Perhaps the whole table is being redrawn every time the data is queried, so it doesn't know or care about changes to individual cells?. Is the solution to write my own specific function to replace onDataReturnReplaceRows? Could someone enlighten me on how I might go about accomplishing this?
Edit:
After digging through datatable-debug.js, it looks like onDataReturnReplaceRows won't fire the cellUpdateEvent. It calls reset() on the RecordSet that's backing the DataTable, which deletes all of the rows; it then re-populates the table with fresh data. I tried changing it to use onDataReturnUpdateRows, but that doesn't seem to work either.
Edit2:
To achieve the control that I wanted, I ended up writing my own <ul>-based data list that made a bit more sense for the problem I was trying to solve. Jenny's answer below should help solve this for most others, so I've accepted it as the solution.

cellUpdateEvent only fires in response to a call to updateCell(). What you want is to subscribe to the cellFormatEvent. There were a couple other issues in your code, so this should work:
dataTable.subscribe('cellFormatEvent', function(o) {
YAHOO.util.Dom.setStyle(o.el, 'backgroundColor', '#ffff00');
var animation = new YAHOO.util.ColorAnim(o.el, {
backgroundColor: {
to: '#ffffff'
}
});
animation.animate();
});
var callback = {
success: dataTable.onDataReturnReplaceRows,
failure: function() {
// error handling code
},
scope: dataTable
};
dataSource.setInterval(1000, null, callback);

dataTable.subscribe('cellFormatEvent',
function(o) {
YAHOO.util.Dom.setStyle(o.el, 'backgroundColor', '#ffff00');
var animation = new YAHOO.util.ColorAnim(o.el, {
backgroundColor: {
to: '#ffffff'
}
});
animation.animate();
});
var callback = {
success: dataTable.onDataReturnReplaceRows,
failure: function() {
// error handling code
},
scope: dataTable
};
dataSource.setInterval(1000, null, callback);
This example will not work beceause you added an interval and this is not the right solution. Because the function will be called each time.

Related

Select2 Trigger Additional Data

I'm trying to load additional data on my select (select2), but the Trigger Event is not loading the additional data. The code and results are shown below.
$('#section').select2();
var data = {
id: 1,
text: 'text_default',
anothertext: 'text_2'
};
var newOption = new Option(data.text, data.id, true, true);
$('#section').append(newOption).trigger('change'); //until this point, everything works
$('#section').trigger({
type: 'select2:select',
params: {
data: data
}
});
console.log($('#section').select2('data')[0]['text']);// return text_default
console.log($('#section').select2('data')[0]['anothertext']);// return undefined
console.log($('#section').select2('data')['anothertext']);//only for test, return undefined
console.log($('#section').data('anothertext'));//only for test, return undefined
Is anything wrong with the code?

ExtJs 4.1.2 ComboBox Update or Reload Based on another ComboBox

I'd like to know a way of how to update the list values of a ExtJs ComboBox. For instance, I have two comboboxs.
One Combobox determine what values the another ComboBox should have. So, after selecting some of those,
I click the drowndown list (combobox) to see the values. But i dont get reflected.
change: function (combofirst, record) {
Ext.Ajax.request({
-- -- --
-- -- --
success: function (response) {
var combosecond = Ext.getCmp('defaultPackageType');
//I am unable to update the combosecond from below snippet.
combosecond.store = Ext.create('Ext.data.Store', {
fields: ['value', 'display'],
data: [
["N", "No"],
["A", "All accounts"]
] //json response
});
},
failure: function (record, action) {}
});
});
In short, how can I change the values of a ComboBox already has with ajax only.
Hope someone can help me
Thanks
I would also agree to the comment, that creating every time a new store and bind it to the combobox is not the optimal solution. I don't know really the reason why this should be done, but nevertheless here is a working example by using bindStore:
https://fiddle.sencha.com/#view/editor&fiddle/3ci0
Ext.create('Ext.form.field.ComboBox', {
// ...
listeners: {
change: {
fn: function (cb) {
Ext.Ajax.request({
url: 'https://jsonplaceholder.typicode.com/albums',
method: 'GET',
timeout: 60000,
success: function (response) {
var jsonResp = response.responseText;
let jsonObj = Ext.JSON.decode(jsonResp, true)
var combo2 = Ext.getCmp('myCombo2');
combo2.bindStore(Ext.create('Ext.data.Store', {
fields: ['id', 'title'],
data: jsonObj
}));
}
});
}
}
}
});
For selection of value 1 the data is loaded from a different url.
But I would think about whether a new proxy call is necessary and whether you can achieve your requirements by using filters or something else.

I want to use JsArray with the Webix component DataTable

I want to use JsArray with the Webix component DataTable. But I have one problem. When I use JsArray format I can’t update the data in the Webix datagrid. Unfortunately, I can see only the beginning of its data. Check the sample to understand the issue:
var array1 = [ [1,"Marie","Oslo"],[2,"John","Los Angeles"],[3,"Kate","London"] ];
var array2 = [ [4,"Martin","Manchester"],[5,"Joana","Lisbon"],[6,"Ronaldo","Barcelona"],[7,"Matthew","Portland"] ];
webix.ui({
view:"button",
label:"test new data",
click: function() {
new_data()
}
});
webix.ui({
view:"datatable",
id: "mytable",
columns:[
{id:"data0", header:"ID" },
{id:"data1", header:"Name" },
{id:"data2", header:"City" }
],
datatype: "jsarray",
data: array1
});
function new_data () {
var mytable = $$("mytable");
mytable.parse(array2);
}
After pressing the button “test new data”, 4 new empty lines appear in the table.
To solve this issue, you should specify data format in the parse command
mytable.parse(array2, "jsarray");
The component will expect the json data, by default.
I hope that it'll help you)

When is "is_initial" true in Dygraph's drawCallback?

I have a Dygraphs chart that works perfectly when I provide a file URL for a data source. When I embedded the data directly into the HTML wrapper, however, the functions in my drawCallback don't fire. Tracing with Firebug, I find that is_initial is True when I load the page with the URL reference, but False when I embed the data (and labels) in native format, even if I place onLoad="drawCallback(vGraph,True);" within the <body> tag. I've "solved" this by setting my own variable to test for first-time execution.
Here's the original, functional, code for an external data source:
var vGraph = new Dygraph(document.getElementById("dgraphChartContainer"),
ExternalDataSource.csv,
{ //options
connectSeparatedPoints: true,
labelsDiv: "dygraphLabelsContainer",
...
}
);
vGraph.updateOptions({
highlightCallback: function(event, xdate, points_array, rowNumber, seriesName) {
...
},
unhighlightCallback: function(event) {
...
},
drawCallback: function(g, is_initial) {
if (!is_initial) return;
buildTagList(vGraph.getLabels());
mySeriesColors = vGraph.getColors();
buildStyleDefinitions();
}
});
As I said, this works great, even with the blind g parameter in the drawCallback.
This is the work-around I developed for the scenario when I embed the data source.
var vFirstTime = true;
var vGraph = new Dygraph(document.getElementById("dgraphChartContainer"),
[
[ new Date("2011/10/15 00:04:55"),null,null,-9.2,null,null,null,null,null,null],
[ new Date("2011/10/24 10:39:32"),null,null,null,null,null,-9.2,null,null,null],
...
[ new Date("2011/10/25 21:02:30"),null,null,null,null,null,null,null,20.3,null],
[ new Date("2013/10/28 08:49:52"),null,null,-17.9,null,null,null,null,null,null]
],
{ //options
labels: ["Event_Date","code-32565","code-32566","code-32568","code-32569","code-32573","code-32574","code-32575","code-32577","code-32578"],
connectSeparatedPoints: true,
labelsDiv: "dygraphLabelsContainer",
...
}
);
vGraph.updateOptions({
highlightCallback: function(event, xdate, points_array, rowNumber, seriesName) {
...
},
unhighlightCallback: function(event) {
...
},
// drawCallback: function(g, is_initial) {
// if (!is_initial) return;
drawCallback: function() {
if (!vFirstTime) return;
buildTagList(vGraph.getLabels());
mySeriesColors = vGraph.getColors();
buildStyleDefinitions();
vFirstTime=false;
}
});
Is there something I can do to use is_initial in my drawCallback call regardless of the data source?
Your first example will work if you move your callbacks into the constructor:
var vGraph = new Dygraph(document.getElementById("dgraphChartContainer"),
ExternalDataSource.csv,
{ //options
connectSeparatedPoints: true,
labelsDiv: "dygraphLabelsContainer",
highlightCallback: function(event, xdate, points_array, rowNumber, seriesName) {
...
},
unhighlightCallback: function(event) {
...
},
drawCallback: function(g, is_initial) {
if (!is_initial) return;
buildTagList(vGraph.getLabels());
mySeriesColors = vGraph.getColors();
buildStyleDefinitions();
},
...
});
So, what's going on here?
The drawCallback gets fired with is_initial = true when the chart draws for the first time. In your original code, this happens after the XMLHttpRequest for the data comes back.
The order of operations is:
constructor
updateOptions
drawCallback(is_initial=true)
When you inline your data, dygraphs doesn't need to wait for the XHR to come back. Now, the order of operations is:
constructor
drawCallback(is_initial=true)
updateOptions
drawCallback(is_initial=false)
The second drawCallback happens because you called updateOptions(). So drawCallback is getting fired with is_initial = true, it's just that you're not listening for it early enough.
dygraphs provides a .ready() method to let you avoid all this intricacy. You may be happier using it instead:
var vGraph = new Dygraph( ... );
vGraph.ready(function() {
buildTagList(vGraph.getLabels());
mySeriesColors = vGraph.getColors();
buildStyleDefinitions();
});

ExtJS - Creating hyperlinks with a function

I'm trying to build an edit column, but my routine isn't quite right for some reason. My value of "store" is not returning anything like I thought it would.
Any thoughts?
function editLinkRenderer(value, metadata, record, rowIndex, colIndex, store) {
if (store == V2020.ServiceStore)
return 'Edit';
else if (store == V2020.PriceStore)
return 'Edit';
else if (store == V2020.PromoStore)
return 'Edit';
return "Edit";
}
I'm using it in my gridpanel like so:
{ header: "Edit", width: 60, dataIndex: 'serviceID', sortable: false, renderer: editLinkRenderer },
You might consider using an ActionColumn. That way you can do this:
var items = [ ... ]; // existing items
if (store.constructEditColumn) {
items.push(store.constructEditColumn());
}
Where your constructEditColumn might look like this:
...
constructEditColumn: function() {
return {
xtype: 'actioncolumn',
items: {
text: 'Edit',
handler: function() {
// do stuff
},
scope: this
}
}
},
...
Barring that, I'd be suspicious of doing equality on the stores. Are the two params before store ints? Can you breakpoint and take a look at whether the record.store property is what you expect? Old version of Ext, perhaps, with a different signature to the renderer?
I appreciate you taking a look, but I figured out the issue.
I had two V2020.ServiceStore defined by mistake and the latter one was mucking everything up.

Categories

Resources