Limit the input entered in ExtJs textfield/numberfield - extjs4

I have requirement where the textfield/numberfield present should only allow values between 0 to 99999.99 i.e. 5 digits with 2 decimal places.
The user should be restricted to use any invalid number.
I'm bad at regular expression but will that solve my problem ?
Any pointer to solve this issue will be appreciated.
I need to restrict user to enter any values beyond 5 digit. after 5 digit only a decimal can be placed and beyond that 2 digits
Any suggestions ?

You need to add a custom validation type VTypes.
addCustomVtypes : function() {
var mRegex = /^\d{0,5}(\.\d{0,2})?$/;
Ext.apply(Ext.form.field.VTypes, {
mRegex : function(val, field) {
return ralphaNumHyphen.test(val);
},
mRegexText : 'Invalid input. Message here.',
mRegexMask : /\d{0,5}(\.\d{0,2})?$/i
});
}
You could call this on application launch.
Then, on your textfield, add vtype: mRegex.

Ext.create('Ext.form.Panel', {
title: 'On The Wall',
width: 300,
bodyPadding: 10,
renderTo: Ext.getBody(),
items: [{
xtype: 'numberfield',
anchor: '100%',
name: 'bottles',
fieldLabel: 'Bottles of Beer',
value: 0,
maxValue: 99999.99,
minValue: 0
}],
buttons: [{
text: 'Take one down, pass it around',
handler: function() {
this.up('form').down('[name=bottles]').spinDown();
}
}]
});
from:http://docs-origin.sencha.com/extjs/4.0.7/#!/api/Ext.form.field.Number

Related

VueJS - How to have a custom headerName of columnDefs in ag-grid-vue

I am trying to display my header name in a new line, but i am unable to do it.
Version of ag-grid-vue: 6.12.0
Here is what i tried but it did not work out:
defaultColDef: {
sortable: true,
editable: true,
resizable: true,
suppressMenu: true
},
columnDefs: [
{
headerName: 'Average low ', // This value is displayed in a single line
field: 'average_low',
width: 200,
},
{
headerName: 'Average high ', // Even this value is displayed in a single line
field: 'average_high',
width: 200,
},
...
}
I tried something like this to display the headerName in new line:
{
headerName: 'Avg. \n low ', // This value is displayed in a single line
field: 'average_low',
width: 200,
},
{
headerName: 'Avg. </br> high ', // Even this value is displayed in a single line
field: 'average_high',
width: 200,
},
I want to display something like this:
Please tell me how i can do this. Here is the officially documentation:
https://www.ag-grid.com/documentation/vue/component-header/
and here is the plunker which shows the example and can be used to workout:
https://plnkr.co/edit/QGopxrvIoTPu2vkZ
EDIT: here is a working solution >> https://plnkr.co/edit/Lr6cneCFiT91lCOD
Adapt it to your liking with the according theme (alpine, balham and so on) and the height that you wish or any other CSS structure that you have.
As told below, this inspired by this guy's work.
A working solution can be done with the script below
const MIN_HEIGHT = 80; // this line is the one you're looking for !
function autosizeHeaders(event) {
if (event.finished !== false) {
event.api.setHeaderHeight(MIN_HEIGHT);
const headerCells = document.querySelectorAll('#myGrid .ag-header-cell-label');
let minHeight = MIN_HEIGHT;
headerCells.forEach(cell => {
minHeight = Math.max(minHeight, cell.scrollHeight);
});
event.api.setHeaderHeight(minHeight);
}
}
(function() {
document.addEventListener('DOMContentLoaded', function() {
var gridDiv = document.querySelector('#myGrid');
var gridOptions = {
enableColResize: true,
enableSorting: true,
onColumnResized: autosizeHeaders,
onGridReady: autosizeHeaders,
columnDefs: [
{
headerName: 'Header with a very long description',
field: 'name',
headerClass: 'multiline'
},
{
headerName: 'Another long header title',
field: 'role',
headerClass: 'multiline'
}
],
rowData: [
{name: 'Niall', role: 'Developer'},
{name: 'Eamon', role: 'Manager'},
{name: 'Brian', role: 'Musician'},
{name: 'Kevin', role: 'Manager'}
]
};
new agGrid.Grid(gridDiv, gridOptions);
});
})();
There is a github issue here with a Stackoverflow thread with a lot of hacky (but working) solutions. It looks like there is no official support for this, so your best bet would be to check there and try out the various CSS solutions.
If you have a hosted example that we can play with, I may help more but right now, I can only recommend reading the various comments and try to tinker the CSS with your dev tools ! :)

Using PortfolioItem/Feature model on custom store

I'm creating an overview of features and their feature dependencies (not user stories).
I'm fetching the wsapi store filtered on release in step 1 and in step 2 I'm fetching the predecessor and successor collections in order to display their values.
I would like to use this wsapi store directly in a grid, but when performing an onScopeChange (release filtered app) the rendering of the grid happens before my loading of predecessor + successor collections. Thus, I'm trying to store the data in a custom.store to use in the grid - so far so good.
My issue is that I need to do all (most) formatting in the grid on my own. I'm setting the custom store model to PortfolioItem/Feature and would expect this to be used on the grid, but it just doesn't. Is this possible? If so, what am I doing wrong?
Custom store
_getViewStore: function () {
var me = this;
/*
Extract data from featureStore
*/
var records = me.myFeatureStore.getRecords();
/*
Create new, update, store for adding into grid
*/
if (!me.myViewStore) {
me.myViewStore = Ext.create('Rally.data.custom.Store', {
model: 'PortfolioItem/Feature',
data: records,
});
} else {
me.myViewStore.removeAll();
me.myViewStore.add(records);
}
},
Grid
_createGrid: function () {
var me = this;
me.myGrid = Ext.create('Ext.Container', {
items: [{
xtype: 'rallygrid',
store: me.myViewStore,
columnCfgs: [{
xtype: 'gridcolumn',
align: 'left',
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate'),
text: 'Predecessors',
dataIndex: 'Predecessors',
width: 200,
renderer: function (value, metaData, record) {
var mFieldOutputPre = '';
var records = record.predecessorStore.getRecords();
_.each(records, function (feature) {
mFieldOutputPre += Rally.nav.DetailLink.getLink({
record: feature,
text: feature.get('FormattedID'),
showTooltip: true
});
// Add the feature name and a line break.
mFieldOutputPre += ' - ' + feature.get('Name') + '<br>';
}); //_.each
return mFieldOutputPre;
},
},
{
text: 'FormattedID',
dataIndex: 'FormattedID',
xtype: 'templatecolumn',
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate')
},
{
text: 'Name',
dataIndex: 'Name',
flex: 1
},
{
text: 'Release',
dataIndex: 'Release',
flex: 1
},
{
text: 'State',
dataIndex: 'State',
flex: 1
},
{ // Column 'Successors'
xtype: 'templatecolumn',
align: 'left',
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate'),
text: 'Successors',
dataIndex: 'Successors',
width: 200,
renderer: function (value, metaData, record) {
var mFieldOutputSuc = '';
var records = record.successorStore.getRecords();
_.each(records, function (feature) {
//console.log('feature = ', feature);
mFieldOutputSuc += Rally.nav.DetailLink.getLink({
record: feature,
text: feature.get('FormattedID'),
showTooltip: true
});
// Add the feature name and a line break.
mFieldOutputSuc += ' - ' + feature.get('Name') + '<br>';
});
return mFieldOutputSuc;
},
}
]
}],
renderTo: Ext.getBody()
});
me.add(me.myGrid);
}
The Release + State fields does not display data correct when using my custom store, but if I use my wsapi (feature) store that are formatted correctly.
Thank you in advance
I'd probably load all the stores first and then add the rallygrid configured with your already loaded feature store. Then you don't have to worry about the timing issues. I'm guessing you already found this example in the docs for loading the child collections?
https://help.rallydev.com/apps/2.1/doc/#!/guide/collections_in_v2-section-collection-fetching
This example is also pretty helpful, as it shows how to load hierarchical data much like you're doing, and uses promises to help manage all of that and then do something when everything has finished loading:
https://help.rallydev.com/apps/2.1/doc/#!/guide/promises-section-retrieving-hierarchical-data

Date range vtype, cannot understand how it works, extjs 4

i have a form with two date fields, they have to define a date range, so the end cannot be before the start; and they both are made by two datepicker, which should disable the dates before the "start" in the "end". I've found this manual page with some code to be pasted, but i cannot paste this code in my page without getting an error. Maybe my page is too complicated but i don't think so, i think it's only me who cannot figure out where to paste the codewithout making all the other code fail. The following is the code of my page:
Ext.define('MyDesktop.count', {
extend: 'Ext.ux.desktop.Module',
requires: [
'Ext.ux.desktop.DatabaseModel',
//'Ext.ux.desktop.UserModel',
'Ext.data.TreeStore',
'Ext.layout.container.Accordion',
'Ext.toolbar.Spacer',
'Ext.tree.Panel'
],
id:'count',
init : function(){
this.launcher = {
text: 'count',
iconCls:'accordion'
};
},
createWindow : function(){
var App = this.app;
var desktop = this.app.getDesktop();
var win = desktop.getWindow('count-win');
if (!win) {
win = desktop.createWindow({
id: 'count-win',
title: 'count',
width: 350,
height: 200,
animCollapse: false,
maximizable: false,
resizable: false,
//constrainHeader: true,
//bodyBorder: true,
layout : 'anchor',
items:[
{
xtype : 'fieldset',
border: false,
defaultType: 'textfield',
items: [
{
xtype: 'datefield',
fieldLabel: 'Start date',
format: 'Ymd',
id:"start",
//altFormats: 'Ymd',
vtype: 'daterange',
endDateField: 'end'
},
{
xtype: 'datefield',
fieldLabel: 'End date',
format: 'Ymd',
id: "end",
//minValue: Ext.getCmp('start').getValue(),
//altFormats: 'm/d/Y',
vtype: 'daterange',
startDateField: 'start'
},
{
xtype: 'combo',
fieldLabel: 'Client',
id:"client",
hiddenName: 'client',
store: new Ext.data.SimpleStore({
data: [
['applix', 'applix'],
['banzai', 'banzai'],
['banzai-cooking', 'banzai - cooking'],
['integralAS', 'integralAS'],
['LinkSmart', 'LinkSmart'],
['nbcuniversal', 'nbcuniversal'],
['primenetwork', 'primenetwork'],
['quag', 'quag'],
['turnEU', 'turnEU'],
['turnUS', 'turnUS']
],
id: 0,
fields: ['value', 'text']
}),
valueField: 'value',
displayField: 'text',
triggerAction: 'all',
editable: false
}
]
}
],
buttons: [{
text: 'Submit',
handler: function() {
console.log(this);
start= Ext.util.Format.date(Ext.getCmp('start').getValue(),'Ymd');
end= Ext.util.Format.date(Ext.getCmp('end').getValue(),'Ymd');
//period = Ext.getCmp('period').value;
client = Ext.getCmp('client').value;
Ext.Ajax.request({
method : "GET",
url : 'http://whatever.com/count?client='+client+'&start='+start+'&end='+end,
timeout : 30000,
success :
function (response) {
//console.log(Ext.getCmp('to_add'))
Ext.Msg.alert(response.responseText);
desktop.getWindow('count-win').doClose();
}//handler
,
failure :
function(response) {
alert("Wrong request");
}
});
}
}]
});
}
return win;
}
});
The vtypes are already there, where should i put the listener and/or the function to handle the daterage property without cutting away all the rest of the code?Should i use a listener as in some examples here on stackoverflow (but i tryed and the window of the form wasn't working any more) or should i use the code from the manual? Anyone has any experience with this issue?
Ok then, the answer is more simple then it seems at first sight You have to leave the solution with vtype (which is difficult and it doesn't work). Then you have to add a listener to yours:
xtype: "datefield",
the code is here:
{
xtype: 'datefield',
fieldLabel: 'Start date',
format: 'Ymd',
id:"start",
//altFormats: 'Ymd',
vtype: 'daterange',
endDateField: 'end',
listeners:{
'change': function(th,a){
Ext.getCmp('end').setMinValue(a);
}
}},
It changes the minValue of the second datefield when the first datefield is changed.
It is simple, it worked for me.

sencha touch dynamic chart

in Sencha Touch 2.1 how can I load the chart dynamically from json, also with dynamic fields store, chart axes, and chart series,
I know maybe this is too much, but I need to display many kind of data, If I create 1 chart component for each display means I have to create more than 15 chart component, I'm afraid it get bloated
I did not complete this dynamically, but I made it seem dynamic.
I first request a user to fill out a form.
I also have multiple panels that holds charts with empty stores, in the form of several different layouts.
Based on the user's form, I show and hide panels, or chart when they need to be displayed only after loading the store with the required data.
yes it is bulky, and they are static, but I found it slightly easier to handle than dynamically loading.
EDIT
After thinking,
have you tried a function like
function dynamiccharts(var1, var2, var3){
return Ext.chart.Chart({
....
})
}
variables would include things like data, url, store or etc.
This is my example creating a chart on controller inside a panel: axis, series, store fields, url are became parameters, PAR_FORM is global variable showing the difference between views, I'm using this code for another chart (Column, Pie)
Ext.define("Geis.controller.app", {
extend: "Ext.app.Controller",
config: {
refs: {
mainview: 'mainview',
barchartview: 'barchartview',
btnShowChartAnggaran: '#btnShowChartAnggaran'
},
control: {
'btnShowChartAnggaran': {
tap: 'onShowChartAnggaran'
}
}
}
createBarChart: function(fields, series_xfield, series_yfield, url) {
this.getBarchartview().add(new Ext.chart.CartesianChart({
id: 'barchartgenerateview',
store: {
fields: fields,
proxy: {
type: 'jsonp',
url: url
}
},
background: 'white',
flipXY: true,
colors: Geis.view.ColorPatterns.getBaseColors(),
interactions: [
{
type: 'panzoom',
axes: {
"left": {
allowPan: true,
allowZoom: true
},
"bottom": {
allowPan: true,
allowZoom: true
}
}
},
'itemhighlight'
],
series: [{
type: 'bar',
xField: series_xfield,
yField: series_yfield,
highlightCfg: {
strokeStyle: 'red',
lineWidth: 3
},
style: {
stroke: 'rgb(40,40,40)',
maxBarWidth: 30
}
}],
axes: [{
type: 'numeric',
position: 'bottom',
fields: series_yfield,
grid: {
odd: {
fill: '#e8e8e8'
}
},
label: {
rotate: {
degrees: -30
}
},
maxZoom: 1
},
{
type: 'category',
position: 'left',
fields: series_xfield,
maxZoom: 4
}]
}));
Ext.getCmp('barchartgenerateview').getStore().load();
},
onShowChartAnggaran: function() {
this.getBarchartview().remove(Ext.getCmp('barchartgenerateview'), true);
if (PAR_FORM == 'Dana Anggaran') {
this.createBarChart(['kode', 'keterangan', 'nilai'], 'keterangan', 'nilai',
Geis.util.Config.getBaseUrl() + 'anggaran/laporan/json/get_dana_anggaran_json/');
} else if (PAR_FORM == 'Alokasi Anggaran') {
this.createBarChart(['kode', 'keterangan', 'belanja_pegawai', 'belanja_barang', 'belanja_modal'],
'keterangan', ['belanja_pegawai', 'belanja_barang', 'belanja_modal'],
Geis.util.Config.getBaseUrl() + 'anggaran/laporan/json/get_alokasi_json/');
}
this.getMainview().animateActiveItem(1, {type:'slide', direction:'left'});
}
});
base on my experiment if you want to activate the interactions features you need to set the chart id dynamically too, for example by creating Global Counter Variable

How to get password value in sencha touch?

I have a sencha touch password field like below:
xtype : 'passwordfield',
id : 'password',
name: 'password',
label : 'Password',
labelWidth : '40%',
I want to get the value of this field. I tried using getValue() method. But it is returning me null value.
In controller:
merchantPwd : '#password',
And then like this:
var pwd = this.getMerchantPwd().getValue();
alert("password:" +pwd);
Please help..
The only different between passwordfield and other input fields is its value is hidden by showing just meaningless characters, e.g dots or stars. Except this, it's just like other input field.
For example, try this in the Sencha Touch documentation code editor & live preview, it works.
Ext.create('Ext.form.Panel', {
fullscreen: true,
items: [
{
xtype: 'fieldset',
title: 'Register',
items: [
{
xtype: 'emailfield',
label: 'Email',
name: 'email'
},
{
xtype: 'passwordfield',
label: 'Password',
name: 'password',
id: 'abc',
value: 'abc',
}
]
}
]
});
Ext.Msg.alert(Ext.getCmp('abc').getValue());
So I think there might be some issues such as:
The password field is blank (actually in this case it shows nothing but not null value)
There're some problems with your controller code. Pay attention to this pointer.