In attempting to use SlickGrid in my page, I have noticed that a jQuery click handler I declare after the grid is rendered only works for approximately 2x the number of rows visible.
Moreover, when a button is clicked the value property is changed to provide visual confirmation to the user. However, upon scrolling too far down past one of the previously clicked buttons, scrolling back up appears to reset the value to the original/default value.
As far as I can tell, it looks like the grid is re-rendering at various intervals. If that suspicion is correct, how do I preserve the effect of the click handler and the values in those buttons already clicked?
It may be important to note that I am not using dataView.
<script type="text/javascript">
var j$ = jQuery.noConflict();
var grid,
data = [],
columns = [
{ id: "rownum", name: "Row #", field: "rownum", width: 50 },
{ id: "accname", name: "Account Name", field: "accname", width: 500 },
{ id: "accid", name: "Id", field: "accid", width: 150 },
{ id: "rectypeid", name: "Record Type ID", field: "rectypeid", width: 150 },
{ id: "itemurl", name: "Item URL Link", field: "itemurl", width: 300, formatter: function (r,c,v,def,datactx) { return "<a target='_blank' href='" + v + "'>" + v + "</a>" } },
{ id: "rfrbtn", name: "Notify Staff", field: "rfrbtn", width: 75, formatter: function (r,c,v,def,datactx) { return "<input class='rfrch' value='Yes' type='button' id='" + datactx.accid + "'/>" } }
],
options = {
enableCellNavigation: false,
enableColumnReorder: true,
};
var acc = new SObjectModel.Acc();
// Query Accounts
var count = 1;
acc.retrieve({ where: {Name: {like: '%Test Acct%'}, RecordTypeId: {eq: '01230000003MJmr'}}, limit: 100 }, function(err, records, event){
if(err) {
alert(err.message);
}
else {
records.forEach(function(record) {
data.push({
rownum: count++,
accname: record.get("Name"),
accid: record.get("Id"),
rectypeid: record.get("RecordTypeId"),
itemurl: record.get("itemurl")
});
});
}
grid.invalidate();
rfrClickHandler();
});
grid = new Slick.Grid("#container", data, columns, options);
var rfrClickHandler = function() {
j$(".rfrch").click(function() {
var rfrbtnClicked = j$(this).prop('id');
j$(this).prop('value','Cancel');
console.log(rfrbtnClicked);
});
}
</script>
Use .on() so that you do not have to re-bind the click handlers after the rows are re-rendered.
j$("#container").on('click', '.rfrch', function(){
//... your handler code
}
In your formatter for the button you can add a property to dataContext for the current value state of the button and also a data property to hold the row index:
if(datactx.rfrchState === undefined){
datactx.rfrchState = "Yes";
}
return "<input class='rfrch' value='"+datactx.rfrchState+"' data-row-index='"+r+"' type='button' id='" + datactx.accid + "'/>"
Then in your button handler add code to retrieve the data object and set rfrchState. That way when you scroll up and down and the rows are re-rendered the state will be preserved and set on the button via the formatter.
var rowIndex = j$(this).data('row-index');
var dataItem = grid.getDataItem(rowIndex);
dataItem.rfrchState = dataItem.rfrchState === 'Yes'?'No':'Yes';
Hope this helps.
Related
I am using USA/state map fusionchart so when I clicked any USA state it will trigger a new bar chart in another section and vice versa the data filter each time when I clicked any chart either world map or bar chart I know we can use event listener but here my concern is how data filter in another section suppose when I clicked any chart other chart data also filter or trigger.Below I have attached screenshot where left side image i.e USA Map when I cliked any state other bar chart data will trigger on right side
const dataset = [
{
id: "HI",
value: "3189000",
//link: "j-drillDownState-HI|Hawaii",
link: "Detailed/TotalSales.html",
alpha: "100",
usehovercolor: "1",
showtooltip: "1",
},
{
id: "DC",
value: "2879000",
link: "Detailed/TotalSales.html",
},
{
id: "MD",
value: "33592000",
link: "j-drillDownState-MD|Maryland",
},
{
id: "DE",
value: "4607000",
link: "j-drillDownState-DE|Delaware",
},
{
id: "RI",
value: "4890000",
link: "j-drillDownState-RI|Rhode Island",
},
{
id: "WA",
value: "34927000",
link: "j-drillDownState-WA|Washington",
},]
const chartConfigs = {
type: "maps/usa", // The chart type
id: "data-plot-click-mouse-event",
width: "500", // Width of the chart
height: "400", // Height of the chart
dataFormat: "json", // Data type
dataSource: {
// Map Configuration
chart: {
numbersuffix: "%",
includevalueinlabels: "1",
labelsepchar: ": ",
entityFillHoverColor: "#FFF9C4",
theme: "fusion",
color: "red",
},
events: {
dataPlotClick: function (e) {
var infoElem = document.getElementById("infolbl");
var index = e.data.dataIndex;
infoElem.innerHTML =
"The average value from <b>" +
e.data.startText +
"</b> to <b>" +
e.data.endText +
"</b> is <b>" +
Math.round(e.data.binValue * 100) / 100 +
"k</b>";
},
},
events: {
// Attach to beforeInitialize
initialized: function () {
console.log("Initialized mychart...");
},
},
data: dataset,
},
};
class Map extends React.Component {
constructor(props) {
super(props);
this.state = {
actualValue: "Hover on the plot to see the value along with the label",
message: "Hover on the plot to see the value along with the label",
};
this.dataplotrollover = this.dataplotrollover.bind(this);
this.dataplotrollout = this.dataplotrollout.bind(this);
}
dataplotrollover(eventObj, dataObj) {
this.setState({
message: [
"You are currently hovering over ",
<strong>{dataObj.categoryLabel}</strong>,
" whose value is ",
<strong>{dataObj.displayValue}</strong>,
],
});
}
dataplotrollout(eventObj, dataObj) {
this.setState({
message: this.state.actualValue,
});
}
render() {
return (
<div>
<ReactFC
{...chartConfigs}
fcEvent-dataplotRollOver={this.dataplotrollover}
fcEvent-dataplotRollOut={this.dataplotrollout}
/>
{console.log("map", this.state.message)}
</div>
);
}
}
export default Map
In FusionCharts you can easily update the chart/ map data on triggering the respective click events . For charts, you need to use the "dataplotClick" event API and for maps use the "entityClick " ëvent API. In the event callbacks you need to use the "setJSONData()" method to update the chart/ map data.
Reference sample in react: https://codesandbox.io/s/setjsondata-sample-wojt5?file=/src/index.js
Documentation Links:-
https://www.fusioncharts.com/dev/api/fusioncharts/fusioncharts-events
https://www.fusioncharts.com/dev/api/fusioncharts/fusioncharts-methods#setJSONData
Thanks,
Srishti Jaiswal
I have an handsontable like the below image. After selecting any one of the rows (for example LastName) it should remove that particular row permanently. How can I achieve this using jQuery?
This is my code which I have written using the afterSelection function but I don't know how to delete that row.
this.tab.handsontable({
data: self.data,
dataSchema: {
columnsexpo: null,
placeholder: null
},
colHeaders: ['Columns Export'],
rowHeaders: true,
fixedColumns: true,
fillHandle: {
autoInsertRow: false,
},
columnSorting: true,
columns: [{
data: 'columnsexpo',
readOnly: true
}, ],
stretchH: 'all',
className: "htCenter",
height: 420,
afterChange: function() {},
beforeRemoveRow: function(row, col) {
var m = this.getDataAtCell(row, 0);
var mandatory = true;
self.MandatoryFields.forEach(function(item) {
if (!_.isEmpty(m)) {
var found = m.toLowerCase().includes(item.toLowerCase());
if (found) {
mandatory = false;
}
}
});
if (!mandatory) {
return false
} else
return true;
},
afterSelection: function(r, c) {
var da = this.getDataAtRow(r);
selectedRow = "";
selectedRow = da[0];
console.log(selectedRow);
},
afterRender: function() {
if (init) {
Events.trigger("DEW:ValidRequest", 1, self.checkValid());
}
init = true;
$('#tablesortable thead th div').filter(function() {
return $(this).text() == "Columns Export";
}).popup({
title: 'Columns Export',
position: 'top center'
});
}
});
EDIT
afterSelection: function(r,c,e){
var dat = this.getDataAtRow(r)
this.alter('remove_row', r, 1);
console.log(r);
},
Now after applying above function it is removing selected Row but if i select last row it is removing all previously selected row
use hot.alter('remove_row', 10, 2); inside after selection method of handsontable.
No need for jquery.
Or if you want to use jquery, store the handsontable instance in some varitable and call the same on row selection.
Update -- added deselectCell before removing the row. after removing the row, previous row is getting selected which is causing the problem.
afterSelection: function(r, c, e) {
this.deselectCell()
this.alter('remove_row', r, 1);
}
I am trying to show the data history in jsgrid as asked here.
$("#jsGrid").jsGrid({
...
rowRenderer: function(item) {
var row = $("<tr>");
var historyGrid = $('<tr>').addClass('nested-grid').hide();
historyGrid.jsGrid({
width: "100%",
height: "auto",
editing: false,
data: [{"a":"d1","b": "d2"},{"a":"d3","b":"d4"},{"a":"d5","b":"d6"}],
heading: false,
fields: [{ name: "a", type: "text"}, {name: "b",type: "text"}]
})
var items= Object.keys(item);
items.forEach(function(key){
if(key!=items[items.length-1]) {
var cell = $("<td>").addClass("jsgrid-cell").append(item[key]);//line 1
row.append(cell);
}
});
row.click(function () {
historyGrid.toggle();
})
row.append(historyGrid);
return row.add(historyGrid);
}
});
The history appears as below. I want to display in such a way that, it spans the entire blank(row) area.
if I change it tr to td at line 1, it appears as below
Any help?
I'm using ECharts in order to create dynamically some line charts.
They are created within div which are dynamically created in my js script based on the server response. The problem is that they are not shown.
I did some test and I noticed that if a div has height 0, the chart will not be shown. So I moved the charts initialization when the div is visible: also now I can't see anything.
var chartsIds = []; // div id list
var lineCharts = []; // charts array
var optionLineCharts = [];
this is the charts initialization function
function init_echart(id, index) {
if ($("#" + id).length) {
var echartLine = echarts.init(document.getElementById(id), theme);
echartLine.setOption(optionLineCharts[index], true);
lineCharts.push(echartLine);
}
}
which is called for each div id in this moment if ($("#block").is(":visible")).
The options are like this one:
var echartLineOptions = {
tooltip:
{
trigger: "item",
formatter: function(params) {
var date = new Date(params.value[0]);
data = date.getFullYear() +
"-" +
(date.getMonth() + 1) +
"-" +
date.getDate() +
" " +
date.getHours() +
":" +
date.getMinutes();
return data + "<br/>" + params.value[1];
}
},
legend:
{
data: []
},
toolbox:
{
show: true,
feature: {
mark: { show: true },
dataView: { show: true, readOnly: false },
restore: { show: true },
saveAsImage: { show: true }
}
},
dataZoom: {
show: true,
start: 70
},
xAxis: [
{
type: "time",
splitNumber: 2
}
],
yAxis: [
{
type: "value"
}
],
series:
[]
};
where the series are populated (correctly) based on the server response. I can see with the debug all the data and the series.
I noticed that even if the biggest div is visible, the div created by the charts initialization function has height = 0. I can't find any solutions..any help is really appreciated!!
My page contains multiple x-editable elements with data-type="select":
True
False
I'm trying to initiate them with x-editable with the following javascript code:
var services = ['services_0', 'services_1'];
$.each(services, function(index, value) {
$('#' + value).editable({
prepend: 'Select one',
source: [
{
value: 1,
text: 'True'
},
{
value: 0,
text: 'False'
}
],
display: function(value, sourceData) {
var colors = {
1: "green",
0: "blue"
},
elem = $.grep(sourceData, function(o) {
return o.value == value;
});
if (elem.length) {
$(this).text(elem[0].text).css("color", colors[value]);
} else {
$(this).empty();
}
}
});
});
The problem is that it only binds the first element.
Inspecting the page source I found out that query $.grep was giving me a TypeError on e.length(). It triggered on 'value' on this line:
display: function(value, sourceData) {
Once i added data-value="" to the elements, everything was working as expected:
True
False