I am using a checkbox to display boolean data (the checkbox will be checked in the case of 'Y' and will not be checked in the case of 'N' or (null)). While the cell/data is displaying correctly in the grid, when I click on the checkbox, I would also like for the data in the cell to be changed - not just the checkbox (in other words, two way binding, but in ag grid with values that are not true/false - but rather, 'Y' and 'N', and have the check/uncheck change the very cell value(s) themselves).
I am currently using cellRenderer to display the checkbox based off of the data of the cell.
Here is the code in which I define my grid:
var columnDefs = [
{headerName: 'name', field: 'a', editable: true, valueParser: numberValueParser},
{headerName: 'read', field: 'b', editable: true, cellRenderer: checkboxCellRenderer},
{headerName: 'write', field: 'c', editable: true, cellRenderer: checkboxCellRenderer},
{headerName: 'delete', field: 'd', cellRenderer: checkboxCellRenderer},
{headerName: 'upload', field: 'e', cellRenderer: checkboxCellRenderer},
];
function createRowData() {
var rowData = [];
for (var i = 0; i<20; i++) {
rowData.push({
a: Math.floor( ( (i + 323) * 25435) % 10000),
b: Math.floor( ( (i + 323) * 23221) % 10000)<5000,
c: Math.floor( ( (i + 323) * 468276) % 10000)<5000,
d: Math.floor( ( (i + 323) * 468276) % 10000)<5000,
e: Math.floor( ( (i + 323) * 468276) % 10000)<5000
});
}
return rowData;
}
function numberValueParser(params) {
return Number(params.newValue);
}
function formatNumber(number) {
// this puts commas into the number eg 1000 goes to 1,000,
// i pulled this from stack overflow, i have no idea how it works
return Math.floor(number).toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,");
}
function checkboxCellRenderer (params){
var input = document.createElement("input")
input.type = "checkbox";
input.checked = params.value
return input
}
var gridOptions = {
defaultColDef: {
valueFormatter: function (params) {
return formatNumber(params.value);
},
cellClass: 'align-right'
},
columnDefs: columnDefs,
rowData: createRowData(),
enableColResize: true
};
// setup the grid after the page has finished loading
document.addEventListener('DOMContentLoaded', function() {
var gridDiv = document.querySelector('#myGrid');
new agGrid.Grid(gridDiv, gridOptions);
gridOptions.api.sizeColumnsToFit();
});
Much like like this working plunker,https://plnkr.co/edit/cV5wFLY4nnyQgVIcnGrF?p=preview
Sure you can click on the checkbox and the check inside the box will go away, but that won't necessarily also change the value of the cell as well. In both these examples (both my code and the plunker I provided), you have to double click on the cell and manually change the value of the cell yourself - for the cell value to be changed. I would like for the checkbox to be able to change the cell-value.
Any help/suggestions would be much appreciated!
Plunker main.js checkboxCellRenderer function modify :
function checkboxCellRenderer (params){
if(params.value !== 'Y' && params.value !== 'N'){
params.setValue(params.value === true || params.value === 'Y' ? 'Y' : 'N');
}else{
var input = document.createElement("input");
input.type = "checkbox";
input.value = params.value === true || params.value === 'Y' ? 'Y' : 'N';
input.checked = params.value === true || params.value === 'Y' ? true : false;
input.onclick = function(){
params.setValue(this.checked === true ? 'Y' : 'N');
}
return input;
}
}
Working plunker : https://plnkr.co/edit/qMXxp2axYbeLwssAuueZ?p=preview
Related
I'm new to JavaScript.
I creating a table with cells where we can add values and I'm using HandsOnTable.
I need to create an inactive cell and we can't set the value in the inactive cell in HandsOnTable if the previous cell has a value.
It's my code :
<div id="downtimetable"></div>
<script script type="text/javascript" th:inline="javascript">
let dataFromSpringDown = [[${downtimes}]];
let dataObjDown = [];
let temp1 = {
name: ' ',
town: ' ',
tent: ' ',
izoterm: ' ',
ref: ' '
}
for(let obj of dataFromSpringDown){
let object = {
name: obj["name"],
town: obj["town"],
tent: obj["tent"],
izoterm: obj["izoterm"],
ref: obj["ref"]
};
dataObjDown.push(object);
}
dataObjDown.push(temp);
let container2 = document.getElementById('downtimetable');
let hot2 = new Handsontable(container2, {
data: dataObjDown,
rowHeaders: true,
colHeaders: true,
autoWrapRow: true,
colHeaders: [
'Name',
'Town',
'Cost'
],
manualRowMove: true,
manualColumnMove: true,
contextMenu: true,
filters: true,
dropdownMenu: true,
collapsibleColumns: true,
nestedHeaders : [
[
'Name',
'Town',
{
label: 'Cost',
colspan: 3
}
],
[
'','','Tent','Izo','Ref'
]
],
manualColumnResize : true
});
function myFunctionDown() {
var json = JSON.stringify(dataObjDown);
var xhr = new XMLHttpRequest();
xhr.open("POST","/downtime_rows_json");
xhr.setRequestHeader("Content-Type","application/json");
xhr.send(json);
}
</script>
<button onclick="myFunctionDown()" class="btn btn-info">From table</button>
It's a table created with script:
I need to change the status to inactive in cell2 if cell1 has a value and vice versa. How I can do that?
I think we can use this script, but I don't understand how get the previous cell
hot2.updateSettings({
cells: function (row, col, prop) {
var cellProperties = {};
if (hot2.getDataAtRowProp(row, prop) === 'Town1') {
cellProperties.editor = false;
} else {
cellProperties.editor = 'text';
}
return cellProperties;
}
})
The code below will disable cell 2 and delete its value if cell 1 has a value and vice versa. In other words: you can't have values in both column 1 and 2.
hot2.addHook( 'afterChange', function( changes, src ) {
[
[row, prop, oldVal, newVal]
] = changes;
if ( prop == 0 && hot2.getDataAtRowProp( row, prop + 1 ) && newVal?.length > 0 ) {
// delete value of cell 2 if cell 1 has a value
hot2.setDataAtCell( row, prop + 1, '' );
} else if ( prop == 1 && hot.getDataAtRowProp( row, prop - 1 ) && newVal?.length > 0 ) {
// delete value of cell 1 if cell 2 has a value
hot2.setDataAtCell( row, prop -1, '' );
}
})
hot2.updateSettings( {
cells: function ( row, col, prop ) {
cellProperties = {};
if ( prop == 1 && hot2.getDataAtRowProp( row, prop - 1 ) ) {
// this disables cell 2 if cell 1 has a value
cellProperties.readOnly = true;
} else if ( prop == 0 && hot2.getDataAtRowProp( row, prop + 1 ) ) {
// this disables cell 1 if cell 2 has a value
cellProperties.readOnly = true;
} else {
cellProperties.readOnly = false;
}
return cellProperties;
}
})
It's working for me :
hot1.addHook('beforeRenderer', function(td, row, col, prop, value, cellProperties) {
if (prop === 'name') {
var cellMeta = this.getCellMeta(row, this.propToCol('town'));
cellMeta.readOnly = (value != ' ' && value != '' && value != null) ? true : false;
} if (prop === 'town') {
var cellMeta = this.getCellMeta(row, this.propToCol('name'));
cellMeta.readOnly = (value != ' ' && value != '' && value != null) ? true : false;
}
});
You can change the columns name, and it's will still working
I need to display custom string values base on the selected values from an object array.
I think I'm close but there is a small issue that I cannot figure out.
Right now If I selected everything from "Gained" and one Item from "Static"
the return statement will be "Gained" and if I selected all from "Static" and one item from "Gained" the result will be Static,
HTML Block
<a class="customSegmentSelectorButton" title="{{ ::$parent.Labels.SEGMENTSELECT }}">
<span ng-if="totalSelectedOptions() == 0">No KPIs</span>
<span ng-if="totalSelectedOptions() > 0">Sum of {{selectedOptionsLabel()}} </span>
</a>
Component
customSegmentOptions = [
{
Label: "Gained",
Children: [
{
Label: "New",
Value: "New",
Selected: true
},
{
Label: "Win",
Value: "Win",
Selected: true
},
{
Label: "Add-On",
Value: "AddOn",
Selected: true
}
]
},
{
Label: "Static",
Children: [
{
Label: "Restart",
Value: "Restart",
Selected: true
},
{
Label: "Repeat",
Value: "Repeat",
Selected: true
}
]
}
];
selectedOptionsLabel = function(){
var customSegmentOptions = scope.$parent.customSegmentOptions;
var isGainedSelected = false;
var isStaticSelected = false;
var isChildrenSelected = false;
var selectedChildrenToDisplay = [];
for(var index = 0; index < customSegmentOptions.length; index++){
var item = customSegmentOptions[index];
var children = item.Children.filter(x => x.Selected == true);
if(item.Children.length == children.length){
if(item.Label.toLowerCase() == 'gained'){
isGainedSelected = true;
}else{
isStaticSelected = true;
}
}
selectedChildrenToDisplay = selectedChildrenToDisplay.concat(children.map(x => x.Label));
}
isChildrenSelected = selectedChildrenToDisplay.length < 5 && !isGainedSelected ? true : false;
switch (true) {
case isGainedSelected && !isStaticSelected && !isChildrenSelected:
return "Gained";
case isStaticSelected && !isGainedSelected && !isChildrenSelected:
return "Static";
case isStaticSelected && isGainedSelected:
return "Gained & Static";
case (!isStaticSelected || !isGainedSelected) && isChildrenSelected:
console.log(selectedChildrenToDisplay);
return "children"
}
};
What I am trying to build is when all of one section is selected then I need to return a string such as
"Sum of Gained" - if only Gained is selected
"Sum of Static - if only Static is selected
"Sum of Gained & Static" - if both Gained and Static are selected
When all of one section is NOT selected then I want to list the individual children names separated by commas when applicable and the last comma should be a "&" for example -
"Sum of New, Win & Restart")
It looks like the following is only evaluating to true when all children have Selected equal to true.
if(item.Children.length == children.length){
If I’m not mistaken to get your desired output you would want:
if(children.length > 0){
Because children represents the Selected items in your list.
I have a function in React which renders options in checkbox form.
I want to add another option by appending it to this list.
My render function
typeof this.state.vendorsOccasionTypesList != 'undefined'
? this.state.vendorsOccasionTypesList.map(function(row, i) {
if (
row.ifActive == '1' &&
row.cityId == that.props.sessionData.CityId
) {
var mainName = row.name;
var id = row.contractorVendorsTypeId;
var mainName1 = mainName.replace('BookEventZ', '');
options.push({ value: id, label: mainName1 });
options.concat({ value: 57, label: 'mainName1' });
}
}, this)
: null;
I am using SweetAlert2, and have a Select List. My challenge is that the values in the select list are added programmatically. While my code runs, the dropdown has the right NUMBER of values, the text says [object Object] rather than what I added. What am I doing wrong? Code is below.
var outputStr = [];
for (var i = 0; i < data.rows.length; i++) {
// If here, we have data, so show the information....
var vREGISTRY_ID = data.rows[i].REGISTRY_ID ? data.rows[i].REGISTRY_ID : '-';
var vNN_NAME = data.rows[i].NN_NAME ? data.rows[i].NN_NAME : '-';
var vACCOUNT_NAME = data.rows[i].ACCOUNT_NAME ? data.rows[i].ACCOUNT_NAME : '-';
var vSITE_DUNS_9DIG = data.rows[i].SITE_DUNS_9DIG ? data.rows[i].SITE_DUNS_9DIG : '-';
var vPRIMARY_CITY = data.rows[i].PRIMARY_CITY ? data.rows[i].PRIMARY_CITY : '-';
var vPRIMARY_STATE_PROVINCE = data.rows[i].PRIMARY_STATE_PROVINCE ? data.rows[i].PRIMARY_STATE_PROVINCE : '-';
outputStr.push({
value:vREGISTRY_ID,
label: vACCOUNT_NAME
}) ;
}; // end of FOR loop
swal({
title: 'Select Account Name or Division',
input: 'select',
inputOptions: outputStr ,
inputPlaceholder: 'Select from dropdown',
showCancelButton: true,
inputValidator: function(value) {
return new Promise(function(resolve, reject) {
if (value === 'abc') {
resolve();
} else {
reject('You need to select abc :)');
}
});
}
}).then(function(result) {
swal({
type: 'success',
html: 'You selected: ' + result
});
})
You have to add dynamical properties to the JavaScript object
Like this: data[propertyName] = propertyValue;
var inputOptions = {}; // Define like this!
// Instead of sample variables,
// your data handling here
var vREGISTRY_ID = "500";
var vACCOUNT_NAME = "Peter";
// Add the Variables like this
// This will create '500' : 'Peter',
inputOptions[vREGISTRY_ID] = vACCOUNT_NAME;
inputOptions["455"] = "Martin";
// Note that the options will get sorted by their value
swal({
title: 'Select Account Name or Division',
input: 'select',
inputOptions: inputOptions,
inputPlaceholder: 'Select from dropdown',
showCancelButton: true,
inputValidator: function(value) {
return new Promise(function(resolve, reject) {
if (value == "500") {
resolve();
} else {
reject('You need to select Peter :)');
}
});
}
}).then(function(result) {
swal({
type: 'success',
html: 'You selected: ' + result
});
})
<link href="https://cdn.jsdelivr.net/sweetalert2/4.1.5/sweetalert2.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/sweetalert2/4.1.5/sweetalert2.js"></script>
Let's say your 'data' is the response from an Api call and you can change the response format.Then, you can return a dictionary of this form Dictionary<int,string> and bind directly the response: inputOptions: data.
I want to remove the columns which have total = 0.
So I've tried in different ways.
First, I assigned ID to all columns, for example; every <td> is of column will have their ID eg: First columns <td ID = 'col_1'> , second column all <td ID = 'col_2'> etc. And then in when footer callback I've tried to remove if this column total is ZERO then this $("col_"+i).remove(); this code removed table headers only so I've tried again with $("col_"+i).empty() but again it's just empty. <th> only
Then I've tried to hide the columns by creating dynamic but I don't get any values.
"footerCallback": function ( row, data, start, end, display )
{
var api = this.api(), data;
var intVal = function ( i ) { return typeof i === 'string' ? i.replace(/[\$,]/g, '')*1 : typeof i === 'number' ? i : 0;};
var col_gonna_invis = '[';
for(i=1;i<length_of_coloumns;i++)
{
total_salary = api.column( i ).data().reduce( function (a, b) {return intVal(a) + intVal(b);},0 );
$('#total_cont_'+i).html(total_salary);
if(total_salary == 0)
{
col_gonna_invis += '{"targets": [ '+i+' ], "visible": false, "searchable": false },';
}
}
col_gonna_invis += ']';alert(col_gonna_invis);
},
"aoColumnDefs": col_gonna_invis;
Please someone help me fix this issue or please someone tell me how to hide or remove columns which footer total is 0.
Thank you in advance.
I will suggest you use the visible() API method along with the sum() plugin :
Enhance the API with a column().sum() method :
jQuery.fn.dataTable.Api.register( 'sum()', function ( ) {
return this.flatten().reduce( function ( a, b ) {
if ( typeof a === 'string' ) {
a = a.replace(/[^\d.-]/g, '') * 1;
}
if ( typeof b === 'string' ) {
b = b.replace(/[^\d.-]/g, '') * 1;
}
return a + b;
}, 0 );
} );
now, in initComplete() you can very easy hide columns which have a total or sum() of 0 :
var table = $('#example').dataTable({
//...
initComplete : function() {
var api = this.api(),
colCount = api.row(0).data().length;
for (var i=0; i<colCount; i++) {
if (api.column(i).data().sum() == 0) {
api.column(i).visible(false);
}
}
}
});
demo -> http://jsfiddle.net/qer7e5os/