label inside combobox and conditional multiselect - javascript

I am building a pretty combobox with checkboxes and conditional entries. Everything works out alright, except for two features that I cannot figure out how to implement.
1) I would like to move the label inside the combobox, make it shift the values to the right, and appear in a slightly gray color.
2) I would like the value to ignore certain entries (group headers) selected. Those entries are there for functionality only - to select/unselect groups of other entries.
The entire project is in the zip file. You don't need a server, it's a client base app. Just download the archive, unpack, and launch app.html in your browser.
http://filesave.me/file/30586/project-zip.html
And here's a snapshot of what I would like to achieve.

Regarding your second issue, the best way I see is to override combobox onListSelectionChange to filter the values you don't want:
onListSelectionChange: function(list, selectedRecords) {
//Add the following line
selectedRecords = Ext.Array.filter(selectedRecords, function(rec){
return rec.data.parent!=0;
});
//Original code unchanged from here
var me = this,
isMulti = me.multiSelect,
hasRecords = selectedRecords.length > 0;
// Only react to selection if it is not called from setValue, and if our list is
// expanded (ignores changes to the selection model triggered elsewhere)
if (!me.ignoreSelection && me.isExpanded) {
if (!isMulti) {
Ext.defer(me.collapse, 1, me);
}
/*
* Only set the value here if we're in multi selection mode or we have
* a selection. Otherwise setValue will be called with an empty value
* which will cause the change event to fire twice.
*/
if (isMulti || hasRecords) {
me.setValue(selectedRecords, false);
}
if (hasRecords) {
me.fireEvent('select', me, selectedRecords);
}
me.inputEl.focus();
}
},
And change your onBoundlistItemClick to only select and deselect items in the boundlist not to setValue of the combo:
onBoundlistItemClick: function(dataview, record, item, index, e, eOpts) {
var chk = item.className.toString().indexOf('x-boundlist-selected') == -1;
if ( ! record.data.parent) {
var d = dataview.dataSource.data.items;
for (var i in d) {
var s = d[i].data;
if (s.parent == record.data.id) {
if (chk) { // select
dataview.getSelectionModel().select(d[i],true);
} else { // deselect
dataview.getSelectionModel().deselect(d[i]);
}
}
}
}
},
Regarding your first issue, it is easy to add the label using the displayTpl config option. But this will only add the text you need, without any style (grey color, etc). The combo is using a text input, which does not accept html tags. If you don't need the user to type text, than you may want to change the combo basic behavior and use another element instead of the text input.

Related

Angular: Tabkey Press not Populating fields

I'm new to Angular, I have a component which contains some basic fields and dropdown menu.When I select anything from dropdown using tab key the other related field are not getting populated,But it works with mouse click.
receipt-creation.component.ts
populateItems(event: any, obj) {
this.receiptForm.valueChanges.subscribe(() => {
const dirty = this.isFormDirty(this.receiptForm);
if (dirty) {
this.unsavedChanges = true;
}
});
this.receiptLineItems = obj.itemList; // obj.itemList contain the values related to selected item
this.changeDetectorRef.detectChanges();
this.updateSubtotal(); // this function caluclate the total based on the item selected from the dropdown
}
receipt-creation.component.html
<add-new-row
[addNewText]="INVOICE_CONSTS.ADD_LINE_ITEM"
[canAutoAddNewRow]="false"
[checkPristine]="true"
[type]="'receipt'"
[data]="lineItemsMetaData"
[form]="receiptCreationForm"
[triggerExtraAddNewKey]="true"
[itemList]="receiptLineItems"
(changeItemEvent)="populateItems($event, receiptCreationForm)"
(keydown.enter)="preventFormSubmission($event)"
></add-new-row>
With event.preventDefault() the fields gets populated, but I want the default behaviour of tab key to be working.

Kendo Combo box always selecting first item on Tab

I have the following code in my Kendo Combo Box:
.Events(events =>
{
events.Select("carUpdate");
events.DataBound("dropDownBind");
})
My carUpdate js method is then as below:
function carUpdate(e) {
debugger;
var rowData = getRowData(e, this);
//If enough data is given to identify unique technology autocomplete the row
var grid = $grid.data('kendoGrid');
if (isUniqueManufacturerDataProvided(rowData)) {
rowData.CarName = this.dataItem(e.selectedIndex).Name;
rowData.CarId = this.dataItem(e.selectedIndex).Id;
return;
}
if (this.selectedIndex === null || this.selectedIndex === -1
|| e.sender._last === kendo.keys.TAB) {
rowData.CarName = pleaseSelect;
rowData.CarId = null;
//$("#Car").data("kendoComboBox").value(pleaseSelect);
//$("#Car").data("kendoComboBox").trigger("close");
return;
} else {
rowData.CarName = this.dataItem(e.selectedIndex).Name;
rowData.CarId = this.dataItem(e.selectedIndex).Id;
}
}
If my ComboBox Contains AB, ABC, ABCD, ABCDE
If I enter A and press the Tab Key I want the combo box to revert to my Please Select Option and move to the next Field in the grid. However what I am finding is the if I just Enter A and press Tab the AB option is getting selected in the box. The other behaviour I want is that ABCDE is entered (i.e - enough data so the combox is filtered to only 1 option) and the Tab key is pressed this option is selected and the cursor moves to the next field in the grid. Is there something I have missed in my js to make this work

How to reflect change made in a component's variable to the view in Angular 2?

I have (n) check boxes and a button in my angular2 view . When I click on one of them a function is called. When I click on the button every checkbox must be unchecked. How to do it?? (n) may vary dynamically.
enter image description here
I will give you an example from a table, since I have no idea what your code actually looks like, but it should work for what you need.
You need some object defined for all of your checkboxes. They likely all have certain properties in common, like labels. Here is an example of such an object:
myData = {
content: [
{
some_string: '',
some_number: 0,
type: '',
selected: false
}
]
};
With this object you can create checkbox instances and push each one to an array, which will hold all of your checkbox objects.
Create your checkboxes in your html in a loop using the objects you have defined above. In your html have your checkboxes call a function. In the case below the checkToggle() function is called.
<input id='{{row.id}}' class='bx--checkbox bx--checkbox--svg'
type='checkbox' name='checkbox' (change)="checkToggle($event,
row.id)" [checked]="row.selected">
checkToggle() has been defined as follows:
//select or deselect this check box
checkToggle(event, nodeId) {
const id = this.findNode(nodeId);
this.myData.content[id].selected = !this.myData[id].selected;
}
Your button should end up calling a function to check all of the boxes
<button (click)="checkToggleAll($event)">Your Button Title</button>
Finally, have your checkToggleAll() function go through the entire array of checkboxes and set them. Here is an example:
//select or deselect all the check boxes
checkToggleAll(event) {
for (let i = 0; i < this.myData.content.length; i++) {
if (this.controls[this.myData.content[i].type]) {
this.myData.content[i].selected = event.target.checked;
}
}
}
This is not something you can plug into your code but it should give you some idea of how to accomplish what you're after.

Gxt: How to disable the checkbox of CheckBoxSelectionModel

We have been using the CheckBoxSelectionModel in a Grid of GXT. We want to have a particularly checkbox of some row to be checked and disabled, that is, the checkbox of CheckBoxSelectionModel will be selected and grayed-out, and user couldn't select or deselect it.
CheckBoxSelectionModel sm = new CheckBoxSelectionModel<ModelData>();
ColumnConfig checkBoxColumn = sm.getColumn();
checkBoxColumn.setStyle("vertical-align: middle;");
checkBoxColumn.setRenderer(new GridCellRenderer<ModelData>()
{
#Override
public Object render(ModelData model, String property, ColumnData config, int rowIndex, int colIndex, ListStore<ModelData> store, Grid<ModelData> grid)
{
// if the code property of model is 1 then select and disable it
if (model.get("code").equals(1))
{
sm.select((BaseModel) model, true);
return "<div> </div>";
} else { // others case
return "<div class=\"x-grid3-row-checker\"> </div>";
}
}
});
columnConfigs.add(checkBoxColumn);
We have tried the above code from this link suggested, but this will hide the checkbox which is not what we needed.
Don't know if there has any other more properly way to disable the checkbox of the CheckBoxSelectionModel?
Any help is appreciated.
CheckBoxSelectionModel sm has boolean locked property which takes one argument. So in renderer set either value you want;
DOC:
True to lock the selection model. When locked, all selection changes are disabled.
#param locked true to lock
sm.setLocked(true) or sm.setLocked(false)

ExtJS display RowExpander on condition only

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;
}
}
}
});

Categories