grid flickering with checkbox and edit method - checkbox

My purpose is to translate interactively a checkbox action into a couple of values "0001" or "".
I placed this method on a table whose name is Notification.
// BP Deviation Documented
edit NoYesId provenWarranty (boolean _set = false, NoYesId _provenWarranty = NoYes::No)
{
NoYesId provenWarr;
;
// set value
if (_set)
{
if (_provenWarranty)
this.Func_Status = '0001';
else
this.Func_Status = '';
return _provenWarranty;
}
// read value
if (this.Func_Status == '0001')
return NoYes::Yes;
else
return NoYes::No;
}
This method is used by a Checkbox in a Form with this Table as a Datasource.
This method has been cached in the Notification datasource init() method.
Notification_ds.cacheAddMethod(tablemethodstr(Notification, provenWarranty));
My problem is that the Checkbox is constantly flickering, is there a way to avoid that ?
Update
The flickering appears inside the Checkbox design, but without
toggling it between checked or not.
This problem appears even if the Checkbox is connected to a basic
datasource field, not only if connected to an edit method.
It seems that the more fields there are in the datasource, the more
flickering I get.

Related

Angular FormControl's material-checkboxes.component has selected values but this.controlValue is an empty array

I have an Angular form I've built that consists of a single material-checkboxes component. I have two copies of this component, one is static and one is dynamic. The only difference is that the dynamic version gets its control values from an API call. Both of these examples have one or more options defaulted as checked when the controls initialize.
The issue I have is that the dynamic one's model is out of sync with its view as long as its left unchanged (ie, if I don't click on any of the checkbox controls to select or unselect them). Once I click on one of the checkboxes, the model updates to sync with the view.
I can tell this because I can submit the static version and get expected results (the defaulted items are posted as values as expected). However, when I submit the dynamic one, I get an empty post.
Here is what the component looks like with the defaulted values before I submit it to see the submitted form data:
And here is the resulted submitted values (as expected):
By way of comparison, here is the same control (material-checkboxes.component.ts) but built using an external datasource to feed in the titleMap and also has defaulted values.
And here is the result after submit of the above form:
So, as the screencaps indicate, The manually created one works as expected and submits the form containing the defaulted values. However, the component with the dynamically generated values, even though the view shows it to have selected default options, submits as EMPTY.
Expected: this.controlValue = ['12', 'd4']
Actual:
onInit > this.controlValue = ['12', 'd4']
After updateValue method > this.controlValue = undefined // But the view is unchanged from the init
However, I can get it to submit data as expected, if I manually change any of the values, even if i set them exactly as they were defaulted. Its as if the form data is not being set until manually clicking on the options.
Here is a snippet from the template that holds the component:
<mat-checkbox
type="checkbox"
[class.mat-checkboxes-invalid]="showError && touched"
[class.mat-checkbox-readonly]="options?.readonly"
[checked]="allChecked"
[disabled]="(controlDisabled$ | async) || options?.readonly"
[color]="options?.color || 'primary'"
[indeterminate]="someChecked"
[name]="options?.name"
(focusout)="onFocusOut()"
(change)="updateAllValues($event)"
[required]="required"
[value]="controlValue">
Update: I found that the issue was that the form control's value is not updated before leaving the syncCurrentValues() method called just after the setTitleMap hostlistener. Adding a call to this.updateValue() in syncCurrentValues() resolves it and the model and view are back in sync. However, there is a problem, but first, here is the code that resolves the issue when there is a default value set in the this.options data:
#HostListener('document:setTitleMap', ['$event'])
setTitleMap(event: CustomEvent) {
if (event.detail.eventName === this.options.wruxDynamicHook && isRequester(this.componentId, event.detail.params)) {
this.checkboxList = buildTitleMap(event.detail.titleMap, this.options.enum, true, true, this.options.allowUnselect || false);
// Data coming in after ngInit. So if this is the first time the list is provided, then use the defaultValues from the options.
const value = this.setDefaultValueComplete ?
this.jsf.getFormControl(this)?.value || [] :
[].concat(this.options?.defaultValue || []);
this.syncCurrentValues(value);
// Set flag to true so we ignore future calls and not overwrite potential user edits
this.setDefaultValueComplete = true;
}
}
updateValue(event: any = {}) {
this.options.showErrors = true;
// this.jsf.updateArrayCheckboxList(this, this.options.readonly ? this.checkboxListInitValues : this.checkboxList);
this.jsf.updateArrayCheckboxList(this, this.checkboxList);
this.onCustomAction(this.checkboxList);
this.onCustomEvent(this.checkboxList);
this.jsf.forceUpdates();
if (this.jsf.mode === 'builder-properties') {
this.jsf.elementBlurred();
}
}
syncCurrentValues(newValues: Array<any>): void {
for (const checkboxItem of this.checkboxList) {
checkboxItem.checked = newValues.includes(checkboxItem.value);
}
this.updateValue(); // Fixed it. Otherwise, the checked items in titlemap never get synced to the model
}
The call to updateData() above fixes the issue in that case. However, when there are no default values in the options data and the checkbox data is loaded externally from an API call that executes after the ngOnInit has fired, I have the same issue. this.controlValue is empty after ngOnInit despite that the view has updated to show checked checkboxes. The model has made that happen through the setTitleMap() method but the controlValue still logs as an empty array.

drupal7 Filter content type based on session in view

I have created a custom type with multiple fields.
1 field is a checkbox to "show for all people"
2nd field is a textfield ( you can add multiple textfields ) for adding a code.
I created a view where all those content types are being shown in a page. ( this works )
But now:
When a person enters the site, he has to insert a code. This code is saved into a cookie because it needs to be remembered for about 2 weeks.
So I can't use the contextual filters.
If the checkbox "show for all people" is checked, this block is shown.
if the checkbox "show for all people" is unchecked, this block is hidden, except for people who came in without a code, or if the code is one of the values that was inserted in the 2nd field.
I don't wan't to use views php_filter. But I have no clue how to proceed with this problem.
I tried some solutions on the web to create a custom filter, but the problem here is, that we can't access the form values.
I found a solution, but I'm not sure if this is the correct drupal way.
I used the hook_node_view function to get all nodes that are printed on that page. I check if the code that was inserted into a cookie with the codes that are allowed ( created in the text fields of the content type )
function code_node_view($node, $view_mode, $langcode) {
if ($node->type == 'winning_codes') {
$code = _code_read_cookie('code');
$winning_codes = (!empty($node->field_winning_codes['und'])) ? $node->field_winning_codes['und'] : array();
$winning_codes = array_map(function ($ar) {
return $ar['value'];
}, $winning_codes);
if (!empty($code) && (!in_array($code, $winning_codes))) {
hide($node->content);
}
}
}

ExtJS setting one element in propertyGrid sourceConfig as hidden dynamically

I'm working with an ExtJS 4 propertygrid that can list three different kinds of items that display when clicked on in another grid. One kind of item has to have a particular field hidden, so that it is't shown but any updates caused by editing other fields aren't affected by potentially missing information.
Attempts of using hidden/isHidden/visible/isVisible, with quoted and unquoted true/false values, haven't worked, and show the ShapeLength field in the propertyGrid.
Is there a "hidden: true" setting within the sourceConfig that I can apply somehow?
Example code:
var lengthDisplayName = '';
if(record.data.Type_ID == 'Circle(s)'){
lengthDisplayName = 'Radius (mm)';
}
if(record.data.Type_ID == 'Triangle(s)'){
lengthDisplayName = 'Side Length (mm)';
}
detailsGrid.sourceConfig['ShapeLength'] = {displayName: lengthDisplayName, type: 'number'};
if(record.data.Item_No == '-1'){
detailsGrid.sourceConfig['ShapeLength'] = {
displayName: lengthDisplayName,
type: 'number'
//, hidden/isVisible/visible value set here
}
};
No there is no hidden property for sourceConfig. But one possibility is to remove the property from the sourceConfig and reinsert it if it should be visible again.
delete detailsGrid.sourceConfig['ShapeLength'];
Was directed to an answer by a colleague - I can getRowClass within the propertyGrid and apply a hidden style on source data for an identifying property and the row name to hide, or else return out:
detailsGrid.getView().getRowClass = function(row) {
if(detailsGrid.source['Item_No'] == '-1' && row.data.name == 'ShapeLength')
return 'x-hidden';
return;
};

NatTable - need checkbox only when editable

I am new to NatTable. I have gone thorough the NatTable examples and its source code but am not getting a solution to one of my problems.
In the NatTable I have a column that should provide a checkbox for selection depending on the value of another column.
I have used Checkboxpainter, checkboxcelleditor, the defaultbooleanconverter and IEditableRule. This renders a checkbox irrespective of whether the cell is editable or not though it allows me to mark the checkbox only if it is enabled.
However as per our requirement user should not see the checkbox if the row is not selectable. or in worst case a disabledcheckbox should be rendered for rows that are not selectable.
Can someone please help me out?
Thanks and regards,
Pradyumna
Got a solution for this.
I had to write a custom checkboxpainter (inheriting from the one that is available OOTB) and override its getImage method to return null for appropriate cells
There is a better solution which I have just applied to a similar case in my work.
I did it by adding the following configuration to the table:
// make checkbox cells editable
configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITABLE_RULE, IEditableRule.ALWAYS_EDITABLE, DisplayMode.EDIT, CONFIG_LABEL_CHECKBOX);
// register the checkbox editor for DisplayMode.EDIT
configRegistry.registerConfigAttribute(EditConfigAttributes.CELL_EDITOR, new CheckBoxCellEditor(), DisplayMode.EDIT, CONFIG_LABEL_CHECKBOX);
// register the checkbox painter for DisplayMode.NORMAL
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER, new CheckBoxPainter(), DisplayMode.NORMAL, CONFIG_LABEL_CHECKBOX);
// register the painter for empty cells in DisplayMode.NORMAL
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER, new BackgroundPainter(), DisplayMode.NORMAL, CONFIG_LABEL_EMPTY);
Basically, this introduces the configuration labels CONFIG_LABEL_CHECKBOX for an editable checkbox, and CONFIG_LABEL_EMPTY for an empty cell.
Now all you have to do is to attach an IConfigLabelAccumulator to your bodyDataLayer:
bodyDataLayer.setConfigLabelAccumulator(new IConfigLabelAccumulator()
{
public void accumulateConfigLabels(LabelStack configLabels, int columnPosition, int rowPosition)
{
if(columnPosition == CHECKBOX_COLUMN_INDEX)
{
if(someCodeToCheckIfRowIsEditable(rowPosition))
{
configLabels.add(CONFIG_LABEL_CHECKBOX);
}
else
{
configLabels.add(CONFIG_LABEL_EMPTY);
}
}
}
}

ExtJS: Added grid rows wont de-highlight

When adding a rows to a grid, and then clicking on it, it gets selected (and highlighted). Then, clicking elsewhere but the new row remains highlighted (so now there are to highlighted rows).
Please, does anyone know what the problem could be? How to make it behave normally, i.e. clicking a row deselects (de-highlights) the other one?
After I reload the page (so the new row is not new anymore), everything works as expected.
Edit: Here's the code for adding rows:
var rec = new store.recordType({
test: 'test'
});
store.add(rec);
Edit 2: The problem seems to be listful: true. If false, it works! But I need it to be true so I'm looking at this further... It looks like as if the IDs went somehow wrong... If the ID would change (I first create the record and then the server returns proper ID, that would also confuse the row selector, no?)
(Note, correct as ExtJS 3.3.1)
First of all, this is my quick and dirty hack. Coincidentally I have my CheckboxSelectionModel extended in my system:-
Kore.ux.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.CheckboxSelectionModel, {
clearSelections : function(fast){
if(this.isLocked()){
return;
}
if(fast !== true){
var ds = this.grid.store,
s = this.selections;
s.each(function(r){
//Hack, ds.indexOfId(r.id) is not correct.
//Inherited problem from Store.reader.realize function
this.deselectRow(ds.indexOf(r));
//this.deselectRow(ds.indexOfId(r.id));
}, this);
s.clear();
}else{
this.selections.clear();
}
this.last = false;
}
});
And this is the place where the clearSelections fails. They try to deselect rows by using ds.indexOfId(r.id) and it will returns -1 because we do not have the index defined remapped.
And this is why we can't find the id:-
http://imageshack.us/photo/my-images/864/ssstore.gif/
Note that the first item in the image is not properly "remapped". This is because we have a problem in the "reMap" function in our Ext.data.Store, read as follow:-
// remap record ids in MixedCollection after records have been realized. #see Store#onCreateRecords, #see DataReader#realize
reMap : function(record) {
if (Ext.isArray(record)) {
for (var i = 0, len = record.length; i < len; i++) {
this.reMap(record[i]);
}
} else {
delete this.data.map[record._phid];
this.data.map[record.id] = record;
var index = this.data.keys.indexOf(record._phid);
this.data.keys.splice(index, 1, record.id);
delete record._phid;
}
}
Apparently, this method fails to get fired (or buggy). Traced further up, this method is called by Ext.data.Store.onCreateRecords
....
this.reader.realize(rs, data);
this.reMap(rs);
....
It does look fine on the first look, but when I trace rs and data, these data magically set to undefined after this.reader.realize function, and hence reMap could not map the phantom record back to the normal record.
I don't know what is wrong with this function, and I don't know how should I overwrite this function in my JsonReader. If any of you happen to be free, do help us trace up further for the culprit that causes this problem
Cheers
Lionel
Looks like to have multi select enabled for you grid. You can configure the selection model of the grid by using the Ext.grid.RowSelectionModel.
Set your selection model to single select by configuring the sm (selection model) in grid panel as show below:
sm: new Ext.grid.RowSelectionModel({singleSelect:true})
Update:
Try reloading the grid using the load method or loadData method of the grid's store. Are you updating the grid on the client side? then maybe you can use loadData method. If you are using to get data from remote.. you can use load method. I use load method to update my grid with new records (after some user actions like add,refresh etc). Or you could simply reload as follows:
grid.getStore().reload();

Resources