Change AG grid previous cellStyle dynamically based on condition of other nodes or row value - angular5

I can able to change current cellStyle based on some condition of current node. But I have to change the immediate previous cellStyle based on some condition in current node.
columnDefs = [
{ headerName: "TripStatus", field: "TripStatusCode",cellStyle: this.cellStyling},
]
Call following method to change the style dynamically
cellStyling(params:any){
// This will change the current cell style only. But I need to change the style of immediate previous cell style.
if(params.node.TripStatusCode==='CO')
return {'background-color': 'red'};
}

Check out cellClassRules
cellClassRules = {
'your-css-class': params => {
if (params.colDef.field === "myCurrentField" &&
params.data["previousField"] === "value") {
return true;
} else {
return false;
}
},
'your-other-css-class': params => {return false}
}
You can define as many class rules as you need, just separate by comma and the function should return true/false.

Related

Prepopulate the text box for dataTables individual column searching

this should be easy but all the examples I can find are specific to the "general search" text box.
I'm trying to prepopulate an individual column search box, for example the "Name" field.
I don't need the code to do the search, just code to put a value in that "Search Name" text field.
There are 2 steps you can take to achieve this.
Step 1:
Use the searchCols option to set up your initial search terms. For example:
"searchCols": [
{ "search": "sat" }
]
This will cause column 1 to be filtered on the string sat.
If you want to use additional or different column filters, you can use null to skip columns - for example:
"searchCols": [
null,
{ "search": "foo" }
null,
{ "search": "bar" }
]
The above example will filter the 2nd and 4th columns.
Step 2:
You can take the existing code which creates the input fields in the table's footer cells, and modify that code to (a) use an index, and then (b) use the index to target the specific column(s) you want to pre-populate:
$('#example tfoot th').each(function ( idx ) {
var title = $(this).text();
$(this).html('<input type="text" placeholder="Search ' + title + '" />');
if ( idx === 0 ) {
$(this).find( 'input' ).val( 'sat' );
}
});
In the above fragment, I took the code linked to in the question and added the idx variable, and then used that to target the first input field, and populate it with "sat".
Without step 2, the DataTable will not show you the values being used to perform filtering.
initComplete: function () {
this.api().columns().every( function () {
var column = this;
if ($(column.header()).hasClass('datatable_search')) {
var that = this;
//player var taken from url
if (column.header().innerText.includes('Players') && players.length){
//prepopulate the input field
$( 'input', this.header() ).val(players)
//use the url.players arg in the search and redraw
this.search( players ).draw();
}
$( 'input', this.header() ).on( 'keyup change clear', function () {
if ( that.search() !== this.value ) {
that
.search( this.value )
.draw();
}
} );

How to making sure at least one checkbox is checked using vuejs

I would like to guarantee that at least one checkboxes are checked and the price are correct calculated.
https://jsfiddle.net/snoke/1xrzy57u/1/
methods: {
calc: function (item) {
item.isChecked = !item.isChecked
this.total = 0;
for (i = 0; i < this.items.length; i++) {
if(this.items[i].isChecked === true) {
this.total += this.items[i].price;
}
}
// fullPackagePrice
if(this.items[0].isChecked === true && this.items[1].isChecked === true && this.items[2].isChecked === true) {
this.total = this.fullPackagePrice;
}
// Trying to guarantee that have at least one checkbox checked
if(this.items[0].isChecked === false && this.items[1].isChecked === false && this.items[2].isChecked === false) {
this.total = this.items[0].price;
this.items[0].isChecked = true;
}
}
}
A good fit for this would be using computed properties instead of a method.
Read more about these here: https://v2.vuejs.org/v2/guide/computed.html#Computed-Properties
A computed property observes all referenced data and when one piece changes, the function is re-run and re-evaluated.
What you could do is first create a allowCheckout computed property like this:
allowCheckout() {
return this.items[0].isChecked || this.items[1].isChecked || this.items[2].isChecked;
}
You will then use it within the button like this:
<button :disabled="allowCheckout"...
This will disable the button when no items are checked.
Next, you'll also want to create a second computed property for the total price
totalPrice() {
// Perform similar checking here to update this.total
}
Lastly, you'll want to change your checkboxes to no longer use v-on:change but to instead use v-model for the relevant parameter for each.
This way your checkbox status will be bound to the true/falseness of the variables.
If you still want to go with your method, you can implement at like shown in this updated fiddle and set a variable atLeastOneItemIsChecked like this:
this.atLeastOneItemIsChecked = this.items.find(item => item.isChecked) !== undefined
Do not force the user to always check a checkbox. Instead, display a hint and disable the button using :disable and tailwind css resulting in this:

In ag grid drop down, how to show name once selected and on save set value instead of name.?

Using this reference, I had worked ag grid drop down.
Issue : once I selected a drop down value, then getvalue() returns value instead of name. Hence it shows the number on the column and it should be text.
If I change that to name, while saving, its bind to name . But here it should be value.
Required : getValue should return name & saving the array should contain value.
agInit(params: any): void {
this.params = params;
this.value = this.params.value;
this.name = this.params.name;
this.options = params.options;
}
getValue(): any {
return this.value;
}
ngAfterViewInit() {
window.setTimeout(() => {
this.input.element.nativeElement.focus();
})
}
stackbltiz here
here
How can I achieve this.
You don't have to create new cellRenderer and cellEditor for it, ag-grid provides inbuilt select for it. **
When you using objects (for dropdown\combobox) inside single cell - you have to implement value handlers: valueParser and valueFormatter:
Value parser: After editing cells in the grid you have the opportunity to parse the value before inserting it into your data. This is done using Value Parsers.
colDef.valueParser = (params) => {
return this.lookupKey(mapping, params.newValue);
}
Value formatter: Value formatters allow you to format values for display. This is useful when data is one type (e.g. numeric) but needs to be converted for human reading (e.g. putting in currency symbols and number formatting).
colDef.valueFormatter = (params) => {
return this.lookupValue(mapping, params.newValue);
}
*where mapping represents your object and inside each of those functions you are just extracting key or value.
Original solution:
lookupValue(mappings, key) {
return mappings[key];
}
lookupKey(mappings, name) {
var keys = Object.keys(mappings);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (mappings[key] === name) {
return key;
}
}
}
and here my little bit modified:
lookupValue(mappings, key:string) {
if(!mappings || !mappings.find(item => item.Id == key)) return null;
else
return mappings.find(item => item.Id == key).Value;
}
lookupKey(mappings, name) {
let key: any;
for (key in mappings) {
if (mappings.hasOwnProperty(key)) {
if (name === mappings[key]) {
return key.Id;
}
}
}
}
UPDATE
To populate dropdown you need yo use cellEditorParams:
colDef.cellEditor = 'selectCellEditor';
colDef.cellEditorParams = {
values: yourList,
},
** But in case when it could be required you still need to have both of renderers and store object inside, and then you would be able to choose what would be displayed on every stage.

Always first filtered selected on Quasar Select

I am using Quasar Framework and using the Q-Select with filter.
I would like to the first filtered option always be already marked, because then if I hit enter, the first will selected.
After some research I found out how to achieve this in a generic way.
The second parameter on the function update received at filterFn is the instance of QSelect itself.
Hence, we can use
ref.setOptionIndex(-1);
ref.moveOptionSelection(1, true);
To keep the focus on the first filtered element, regardless of multiselect or not.
The final code is something like
filterFn(val, update) {
update(
() => {
const needle = val.toLocaleLowerCase();
this.selectOptions = this.qSelectOptions.filter(v => v.toLocaleLowerCase().indexOf(needle) > -1);
},
ref => {
ref.setOptionIndex(-1);
ref.moveOptionSelection(1, true);
});
}
There is one option to achieve this is set model value in the filter method if filtered options length is >0.
filterFn (val, update, abort) {
update(() => {
const needle = val.toLowerCase()
this.options = stringOptions.filter(v => v.toLowerCase().indexOf(needle) > -1)
if(this.options.length>0 && this.model!=''){
this.model = this.options[0];
}
})
}
Codepen - https://codepen.io/Pratik__007/pen/QWjYoNo

Filter Data Separately in Two Different DataTables

Here is what I am trying to do:
I have two DataTables on the same page with different data. One is 'sell_orders' and the other is 'buy_orders'. I want to filter the data in each table separately based on checkboxes at the top of each table. So far I have gotten that to work using the following code:
$("#sell_vis_cit").change(function() {
var checked = this.checked;
var allowFilter = ['sell-orders'];
if (!checked) {
$.fn.dataTable.ext.search.push (
function(settings, data, dataIndex) {
// check if current table is part of the allow list
if ( $.inArray( settings.nTable.getAttribute('id'), allowFilter ) == -1 ) {
// if not table should be ignored
return true;
}
return $(sell_table.row(dataIndex).node()).attr('sell-data-sec') != 'x';
}
);
sell_table.draw();
} else {
$.fn.dataTable.ext.search.pop();
sell_table.draw();
}
});
$("#buy_vis_cit").change(function() {
var checked = this.checked;
var allowFilter = ['buy-orders'];
if (!checked) {
$.fn.dataTable.ext.search.push (
function(settings, data, dataIndex) {
// check if current table is part of the allow list
if ( $.inArray( settings.nTable.getAttribute('id'), allowFilter ) == -1 ) {
// if not table should be ignored
return true;
}
return $(buy_table.row(dataIndex).node()).attr('buy-data-sec') != 'x';
}
);
buy_table.draw();
} else {
$.fn.dataTable.ext.search.pop();
buy_table.draw();
}
});
The problem I am having is when it comes time to remove the filter. If filters have been applied to each table, the removal of the filter using the pop() function becomes unreliable because there is no way to verify that it is removing the filter from the right table.
So my question is: is there a way to verify that pop() is running on the right table like I did with push()? Alternatively, is there a better way to achieve my goal?
Why push() and pop() in the first place? It seems to me you have some static filters which is turned on and off by checkboxes. You could declare a filter once globally and do the "math" inside the filter :
$.fn.dataTable.ext.search.push(function(settings, data, dataIndex) {
if ((settings.sTableId == 'sell-orders' && $("#sell_vis_cit").is(':checked')) ||
(settings.sTableId == 'buy-orders' && $("#buy_vis_cit").is(':checked'))) {
//filter code
} else {
return true
}
})
and then simply activate the filters in the click handlers :
$("#sell_vis_cit, #buy_vis_cit").change(function() {
buy_table.draw();
sell_table.draw();
})