How to set length of a combo box to only allow one of two values - extjs

I have the combobox minLength set to 5. I want the combobox to require the length to be 5. If it is longer than 5, I want the minLength to be set to 10. So the outcome should be: the min length can be either 5 or 10, nothing else. (The ComboBox will not accept an input with a length of less than 5 or greater than 10, it also will not accept a length equal to 6, 7, 8, or 9).
Here is my code for example:
xtype: 'combobox',
minLength: 5,
maxLength: 10,
maskRe: /[0-9.-]/,
validator: function(v) {
//this only allows numbers and a hyphen to be entered into the combo box,
//while also requiring 4 digits to be entered after the hyphen
//(only if a hyphen is present)
return /^[0-9]*(-?[0-9]{4})?$/.test(v)? true : 'A Postal Code should only include a hyphen if there are four digits after the hyphen!';
},

As far as I know there is no built-in solution for that, but you can do it. Check the code below and this fiddle, this is for ExtJS 7.5 Classic Material, but it can likely be adopted to other version / toolkit.
Some notes:
You have to set a store, even if it's empty, otherwise the change listener will not be called. (I don't know if it is a bug or a feature.)
The solution uses a ViewModel and binds the minLength to this. The reason you need setMinLength and setMaxLength is that ExtJS doesn't provide it and getter / setter is required for binding.
Important: since this is not an 'official' solution there is no guarantee it will always work.
Ext.application({
name: 'MyApp',
launch: function () {
Ext.create('Ext.form.Panel', {
renderTo: Ext.getBody(),
items: [{
xtype: 'combo',
minLength: 5,
maxLength: 10,
maskRe: /[0-9.-]/,
viewModel: {
data: {
minLength: 5
}
},
store: [],
bind: {
minLength: '{minLength}'
},
setMinLength: function (v) {
this.minLength = v;
},
getMinLength: function () {
return this.minLength;
},
validator: function (v) {
return /^[0-9]*(-?[0-9]{4})?$/.test(v) ? true : 'A Postal Code should only include a hyphen if there are four digits after the hyphen!';
},
listeners: {
change: function (combo, newValue, oldValue, eOpts) {
const newMinLength = newValue == null ? 5 : newValue.length >= 5 ? 10 : 5;
console.log('New min length will be: ' + newMinLength);
combo.getViewModel().set('minLength', newMinLength);
}
}
}]
});
}
});

Related

Format formly form field

I want to format a field when the data finally updates the model. The number usually comes back with a decimal point so what I want to be able to do is format it to no decimal point number (parseNumber function does that).
e.g. vm.model.total = 34.54
I want to format this number to 34 on the fly.
I can't make it work...
vm.fields = [
{
className: 'row',
fieldGroup: [
{
className: 'col-xs-12',
key: 'total',
type: 'input',
templateOptions: {
wrapperClass: 'row',
labelClass: 'col-xs-9 col-sm-3',
dataClass: 'col-xs-3 col-sm-2 col-sm-offset-right-7',
label: 'Total',
disabled: true
},
formatters: [parseNumber(vm.model.total, 0)]
}
]
}
];
Your example does not match the examples in the documentation
Your argument to formatters field is incorrect. That field is expecting a function, NOT THE RESULT of the function, which is what you have defined here.
You should either use an anonymous function or a named function:
formatters: [function(value){ return parseNumber(value, 0); }]
or
formatters: [removeDecimal]
//...
function removeDecimal(value) {
return parseNumber(value, 0)
}
This is a working example from their own documentation which I have added a formatter to the first name field: https://jsbin.com/hapuyefico/1/edit?html,js,output

Bitmask to boolean conversion in the model

I have a model that receives int bitmasks from the backend:
{"user": 7, "group":5, "other":1}
and I now want to show a form with checkboxes like this:
user: [X] read [X] write [X] execute
group: [X] read [ ] write [X] execute
other: [ ] read [ ] write [X] execute
where user can toggle on or off and then the updated bitmask is sent back to the server in a store.sync operation.
I know how to make and align the checkboxes, but ExtJS checkboxes in a form bind to boolean values through a correlation between the checkbox name and the model field name, and not to parts of bitmask.
So I have to convert back and forth between the bitmask int and a bunch of booleans. How would I implement that in a reusable manner?
I think the checkbox group component is a good candidate to render your checkboxes and also to implement the conversion logic.
Here is a reusable component to do the two-way conversion of bitmasks:
Ext.define('Fiddle.Bitmask', {
extend: 'Ext.form.CheckboxGroup',
xtype: 'fiddlebitmask',
isFormField: true,
columns: 3,
items: [{
boxLabel: 'Read',
name: 'read',
inputValue: 1,
excludeForm: true,
uncheckedValue: 0
}, {
boxLabel: 'Write',
name: 'write',
inputValue: 1,
excludeForm: true,
uncheckedValue: 0
}, {
boxLabel: 'Execute',
name: 'exec',
inputValue: 1,
excludeForm: true,
uncheckedValue: 0
}],
getModelData: function () {
let obj = {};
obj[this.name] = this.getValue();
return obj;
},
setValue: function (value) {
if (value) {
var binary = Ext.String.leftPad((value).toString(2), 3, '0');
value = {
read: Number(binary[0]),
write: Number(binary[1]),
exec: Number(binary[2])
};
}
this.callParent([value]);
},
getValue: function () {
var value = this.callParent();
var binary = `${value['read']||0}${value['write']||0}${value['exec']||0}`
return parseInt(binary, 2);
}
});
And the working fiddle: https://fiddle.sencha.com/#view/editor&fiddle/2clg
edit Component completed with getModelData implementation to support usage with form.getValues/form.updateRecord.
What version of Ext are you using? If your version supports ViewModels then I would do the conversion in the ViewModel and bind it to the view.
There is the convert and calculate config on fields as well but they are converting in one way only.

Ionic 2 / 3: Number Input from Alert

I'm using Ionic 3.x on macOS.
I have the following issue:
I have an array containing a number and an array of names.
table: { number: number, names: string[] } = {
number: 0,
names: ['']
};
I want to set the number of the array using an input for the user. I stumbled upon the AlertController.
I have written the following function thing to add a number:
addTable(){
let prompt = this.alertCtrl.create({
title: 'Add Table',
subTitle: 'Enter the table number',
inputs: [{
name: 'tableNumber',
placeholder: 'Number',
type: 'number'
}],
buttons: [
{
text: 'Cancel'
},
{
text: 'Add',
handler: data => {
//this.tables.push(data);
this.table.number = data;
}
}
]
});
prompt.present();
}
But this always sets table.number to object [object]. If I write it as this.table.number = +data; it has the value NaN. The push version also doesn't work.
How do I set table.number to a number that the user put in?
The name of the input
name: 'tableNumber'
gets added as a property name to the resulting object. You can access it like this:
handler: data => {
this.table.number = data.tableNumber;
}

How to filter each row dropdown values in Angular Ui Grid

I started to work with ui-grid a few time ago so i'm having some problems.
I would like to filter the options in dropdown of every row of the grid.
I can filter the values and show it in the dropdown field but when i click in dropdown only appear undefined values. What can i do to solve this problem?
I've tried so many things but i can't find the solution.
Here is the plunker
http://embed.plnkr.co/HMsq4OasNs50ywJuI3DS/
Thanks
I forked your plunker.
In summary, I changed up the column definition to use editDropdownOptionsFunction instead of the combination of editDropdownOptionsArray and cellFilter. According to the documentation,
cellFilter is a filter to apply to the content of each cell
... so that doesn't seem like what you were trying to achieve.
Also, changed the periodos definition for rowEntity.sindicato === 1 to be an array rather than an object.
editDropdownOptionsFunction: function(rowEntity, colDef) {
console.log(rowEntity);
if (rowEntity.sindicato === 1) {
periodos = [{
id: 1,
value: 'teste1'
}];
} else if (rowEntity.sindicato === 2) {
periodos = [{
id: 2,
value: 'test2'
}, {
id: 5,
value: 'test5'
}];
} else {
periodos = [{
id: 3,
value: 'test3'
}, {
id: 6,
value: 'test6'
}, {
id: 4,
value: 'test4'
}];
}
return periodos;
}

Extjs linked combos - let parent values have same child values

I have linked combos that work if the parent value has a unique identifier.
However, I have 4 options in the parent combo that should have the same value for the child combo. I've given these the same identifier in the store, yet the value in the combo doesn't change when I choose any of them.
Is there anyway to do this without duplicating all values?
Stores
var fields = [
["s","Name"],
["s","ID"],
["cc","City"],
["s","Cost"],
["r","Status"]
];
var operators =[
[1, "s","begins with"],
[2, "s","equals"],
[3, "s","contains"],
[4, "s","ends with"],
[5, "cc", "equals"],
[6, "r", "equals"]
];
Combo
xtype:'combo',
id: 'fieldSelecCmb1',
width: 125,
displayField: 'field',
valueField: 'fid',
hideLabel: true,
store: storeField ,
triggerAction: 'all',
mode: 'local',
value: "Choose a field",
listeners:{
select: {
fn:function(combo, value){
var id = combo.id;
var rowNo = id.charAt(id.length-1);
var opCombo = Ext.getCmp("optionSelectCmb"+rowNo);
opCombo.clearValue();
opCombo.store.filter("fid", combo.getValue());
}
}
You can use the filterBy function instead. Here's how:
opCombo.store.filterBy( function(record, id) {
if((record.data.id == 1 || record.data.id == 2) && (this.id == 1 || this.id == 2)) {
// specify index that you want to exclude when getting say parent combo value 1 or 2
return false; // excludes the record in the store
} else {
return true; // includes the record in the store.
}
} , combo );

Resources