I am trying to implement row selection functionalty to svelte component I am developing. I am creating component using svelte-table component where I list items from database and the component should allow selection of only two items and remove first row when third is added. Row id's are then recorded in svelte store and passed to an other component. This all works in program level, that is not a problem. The problem is to highlight correct rows in the table so that user is on map which rows are selected. I can get the highlighting working using classNameRowSelected property on svelte-table but the problem is removing the highlighting from the first selected row when that third row is selected. I seem to fail find any example or reference how to do this from Javasctipt...
Here is my SvelteTable element:
<SvelteTable
columns="{COLUMNS}"
rows="{rows}"
rowKey="key"
selectOnClick="{true}"
on:clickRow="{rowSelected}"
classNameTable={['table table-striped']}
classNameThead={['table-primary']}
classNameRowSelected="row-selected"
/>
<style>
:global(.row-selected) {
background-color: #f8c;
}
</style>
and the rowSelected function then row is clicked:
function rowSelected(event)
{
let found = false;
compare_tests.forEach((test,index, compare_tests) => {
console.log(test);
if (test == event.detail.row.key)
{
found = true;
event.detail.row.selected = false;
compare_tests[index] = "";
}
});
if (!found)
{
compare_tests.shift();
compare_tests.push(event.detail.row.key);
event.detail.row.selected = true;
found = false;
}
$testids = compare_tests;
}
Ideally there is some function/property on "row" parameter that I can use to de-select the row based on row.key before I shift it away from the array.
I am relatively new to JavaScript and Svelte so any help where to find information on how to accomplish this would be appreciated.
By using selected (‡ optional array of key values of selected rows) instead of selectOnClick this would be a way >> REPL
<script>
import SvelteTable from "svelte-table";
import {rows, columns} from './data'
let selectedRowIds = []
function handleRowClick(event) {
const rowId = event.detail.row.id
if(selectedRowIds.includes(rowId)) {
selectedRowIds = selectedRowIds.filter(id => id !== rowId)
} else {
selectedRowIds = [rowId, ...selectedRowIds].slice(0,2)
}
}
</script>
<SvelteTable columns="{columns}"
rows="{rows}"
rowKey="id"
on:clickRow={handleRowClick}
selected={selectedRowIds}
classNameRowSelected="row-selected"
>
</SvelteTable>
<style>
:global(.row-selected) {
background-color: #f8c;
}
</style>
I'm now trying to hide clicked row after changing status in angularjs. Here is my coding and please let me know how to do it?
table.table
tr(data-ng-repeat="application in job.applications", ng-hide="application.hideApplication")
td.status
div.bold #{getMessage('Change Status:')}
div.normal
a(ng-class="app_status === 'shortlist' ? 'admin_edit_bold' : 'admin_edit_normal'", ng-click="changeApplicationStatus(application.id, 'shortlist', application)") #{getMessage('Shortlist')}
td.rating
div(ng-init='rating = application.app_rating')
.star-rating(star-rating='', rating-value='rating', data-max='5', on-rating-selected='rateFunction(application.id, rating)')
Here is controllerjs.
$scope.changeApplicationStatus = function (appId, app_status, application) {
return jobsService.changeApplicationStatus(appId, app_status).then(
function () {
application.hideApplication = false;
}
);
};
Put this attribute on whichever element you're wanting to show/hide
ng-hide="application.hideApplication"
Edit subsequent to comment:
That attribute wouldn't work on the same element as the ng-repeat, I don't think the application variable would be in scope...
Instead, you could change your repeat to:
application in job.applications | filter: { hideApplication : false }
I'm trying to change the selected row of an ng-table. Using this code I can select the first row of the ng-table however on the initial call the data-ng-class does not seem to be triggering because the style is not being applied to the selected row. However on the second call to the function the style is applied.
This is our selection function:
function changeSelection(agreement) {
if (agreementNumberService.isSelectable === true) {
agreementVM.isSelectable = true;
if (agreement.$selected) {
agreement.$selected = !agreement.$selected;
} else {
agreement.$selected = true;
}
//agreement.$selected = !agreement.$selected;
if (agreementVM.selectedItem && agreementVM.selectedItem !== agreement) {
agreementVM.selectedItem.$selected = false;
}
agreementVM.selectedItem = agreement;
}
}
This is the table row:
<tr data-ng-repeat="agreement in $data" data-ng-click="vm.changeSelection(agreement, $event)"
data-ng-class="{'active': agreement.$selected}">
Do you have any idea why the style is not being applied on the first call to the function but is on subsequent calls? Thanks in advance.
The following change to the view fixed the problem. There was a problem with the previous expression.
<tr data-ng-repeat="agreement in $data" data-ng-click="vm.changeSelection(agreement)"
data-ng-class="{'active': (agreement.agreementNumber == vm.selectedItem.agreementNumber)}">
I currently have a rather big Grid and am successfully using the RowExpander plugin to display complementary informations on certain rows. My problem is that it's not all rows that contain the aforementioned complementary informations and I do not wish the RowExpander to be active nor to show it's "+" icon if a particular data store's entry is empty. I tried using the conventional "renderer" property on the RowExpander object, but it did not work.
So basically, how can you have the RowExpander's icon and double click shown and activated only if a certain data store's field != ""?
Thanks in advance! =)
EDIT: I found a solution
As e-zinc stated it, part of the solution (for me at least) was to provide a custom renderer that would check my conditional field. Here is my RowExpander:
this.rowExpander = new Ext.ux.grid.RowExpander({
tpl: ...
renderer: function(v, p, record) {
if (record.get('listeRetourChaqueJour') != "") {
p.cellAttr = 'rowspan="2"';
return '<div class="x-grid3-row-expander"></div>';
} else {
p.id = '';
return ' ';
}
},
expandOnEnter: false,
expandOnDblClick: false
});
Now, the trick here is that for this particular Grid, I chose not to allow the expandOnEnter and expanOnDblClick since the RowExpander will sometimes not be rendered. Also, the CSS class of the grid cell that will hold the "+" icon is 'x-grid3-td-expander'. This is caused by the fact that the CSS class is automatically set to x-grid3-td-[id-of-column]. So, by setting the id to '' only when I'm not rendering the rowExpander, I'm also removing the gray background of the un-rendered cells. So, no double click, no enter, no icon, no gray-background. It really becomes as if there is strictly no RowExpander involved for the columns where my data store field is empty (when I want no RowExpander).
That did the trick for me. For someone that wishes to preserve the ID of the cell, or that wishes to keep the double click and enter events working, there is nothing else to do other than extending the class I guess. Hope this can help other people stuck in the position I was!
As e-zinc stated it, part of the solution (for me at least) was to provide a custom renderer that would check my conditional field. Here is my RowExpander:
this.rowExpander = new Ext.ux.grid.RowExpander({
tpl: ...
renderer: function(v, p, record) {
if (record.get('listeRetourChaqueJour') != "") {
p.cellAttr = 'rowspan="2"';
return '<div class="x-grid3-row-expander"></div>';
} else {
p.id = '';
return ' ';
}
},
expandOnEnter: false,
expandOnDblClick: false
});
Now, the trick here is that for this particular Grid, I chose not to allow the expandOnEnter and expandOnDblClick specifically since the RowExpander will sometimes not be rendered. Also, the CSS class of the grid cell that will hold the "+" icon is 'x-grid3-td-expander'. This is caused by the fact that the CSS class is automatically set to x-grid3-td-[id-of-column]. So, by setting the id to an empty string only when I'm not rendering the rowExpander, I'm also removing the gray background of the cells that won't offer any expanding. So, no double click, no enter, no icon, no gray-background. It really becomes as if there is strictly no RowExpander involved for the columns where my data store field is empty (when I want no RowExpander).
That did the trick for me. For someone that wishes to preserve the ID of the cell, or that wishes to keep the double click and enter events working, there is nothing else to do other than extending the RowExpander class in my opinion. Of course, one could also use Ext.override(), but then all instances of RowExpander would be hit by the override.
I have the same task, there is my solution
var rowExpander = new Ext.ux.grid.RowExpander({
renderer : function(v, p, record){
return record.get('relatedPageCount') > 0 ? '<div class="x-grid3-row-expander"> </div>' : ' ';
}
});
I have overridden render method which test relatedPageCount field in store and render + or white space.
I think I've found a cleaner solution.Give me a feedback pls :)
I extend the toggleRow method of RowExpander and if I match a condition avoid to toggle the row.Otherwise the standard flow continues
Ext.create('customplugins.grid.plugin.ClickRowExpander',{
pluginId : 'rowexpander',
rowBodyTpl : new Ext.XTemplate(
'<p><b>Last Modified By:</b> {usermodify}</p>',
'<p><b>User data:</b> {userdata}</p>',
'<p><b>Correlation ID:</b> {correlationid}</p>',
'<p><b>Description:</b> {descr}</p>'
),
toggleRow : function(rowIdx, record) {
if(record.get('directory')) return false;
customplugins.grid.plugin.ClickRowExpander.prototype.toggleRow.apply(this, arguments);
}
})
This version works in Ext JS 5 and 6 (classic)
One thing is to remove the +/- icon, which can be done via grid viewConfig:
getRowClass: function (record, rowIndex, rowParams, store) {
var yourFieldofChoice = record.get('yourFieldofChoice');
if (yourFieldofChoice == null) {
return 'hide-row-expander';
}
},
Define css for hide-row-expander:
.hide-row-expander .x-grid-row-expander {
visibility: hidden;
}
Now you disable expanding on enter key ('expandOnEnter' config is no longer supported in Ext JS 6) or double click by overriding toggleRow, or if you do not wish the override you create your custom rowexpander built on existing plugin:
Ext.define('RowExpander', {
extend: 'Ext.grid.plugin.RowExpander',
alias: 'plugin.myExpander',
init: function (grid) {
var me = this;
me.grid = grid;
me.callParent(arguments);
},
requiredFields: ['yourFieldofChoice'],
hasRequiredFields: function (rec) {
var valid = false;
Ext.each(this.requiredFields, function (field) {
if (!Ext.isEmpty(rec.get(field))) {
valid = true;
}
});
return valid;
},
toggleRow: function (rowIdx, record) {
var me = this, rec;
rec = Ext.isNumeric(rowIdx)? me.view.getStore().getAt(rowIdx) : me.view.getRecord(rowIdx);
if (me.hasRequiredFields(rec)) {
me.callParent(arguments);
}
}
});
I have handled the beforeexpand event inside the listeners of Ext.ux.grid.RowExpander. beforeexpand method got the whole row data injected. Checking the data conditionally we can return true or false. If we return false it wont expand otherwise it will do.
var expander = new Ext.ux.grid.RowExpander({
tpl: '<div class="ux-row-expander"></div>',
listeners: {
beforeexpand : function(expander, record, body, rowIndex){
var gpdata = record.data.GROUP_VALUES[1].COLUMN_VALUE
if(gpdata == null){
return false;
}
else{
return true;
}
}
}
});
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.