Please check this fiddle. I have a simple textareafield. If user try to paste data into the textarea which contains more than 5 lines, I want to show error message by turning the border of the textareafield red & showing some message.
Ext.onReady(function () {
Ext.create('Ext.window.Window', {
height: 60,
layout: 'anchor',
minHeight: 60,
width: 200,
items: [{
grow: true,
anchor: '100%',
flex: 1,
enableKeyEvents: true,
xtype: 'textareafield',
id: 'txtFld',
listeners: {
keydown: function (txtArea, e, eOpts) {
//console.log(e.getKey());
if (e.keyCode == 13 && txtArea.value.split("\n").length >= 5) {
console.log('unable to stop :( ');
e.stopEvent();
return false;
}
},
paste: {
element: 'inputEl',
delay: 1,
fn: function (event, inputEl) {
if (event.type == "paste") {
if (inputEl.value.split("\n").length > 5) {
var enteredValues = inputEl.value.split("\n");
var modifiedText = inputEl.value.split("\n").slice(0, 5);
inputEl.value = modifiedText.join("\n");
// How to show Show error message stating some of the values are ignored ????
}
}
}
}
}
}]
}).show();
});
You can use the markInvalid function on the textarea to achieve the behaviour which applies for regular validation and which basically is what you described as the desired behaviour.
Ext.getCmp('txtFld').markInvalid('Some content was removed');
I've updated your fiddle so you can have a look at it.
Related
I am using the below code -
afterListeners: function(thisEl, eOpts) {
sliderSprite = Ext.create('Ext.draw.sprite.Rect', {
width: spriteWidth, // half year width height : 20, x : 16, y : 0, draggable : true, floatable : true, 'stroke-width' : 2, fill : '#FCE5C5', stroke : '#C6B395' });
sliderSprite.show(true);
thisEl.getSurface().add(sliderSprite);
alert("before source");
new Ext.drag.Source({
element: sliderSprite,
constrain: {
// Drag only horizontal in 30px increments
horizontal: true, // snap: { // y: 30 // }
},
onDragMove: function() {
alert("inside source");
spriteHighlighter.remove();
me.onDragSprite(e, this, chartWidth, spriteWidth);
},
onDragEnd: function() {
me.refreshCharts(xPlots, bigChart, sliderSprite, firstYear, lastYear, chartWidth);
}
});
alert("outside source");
},
}
}
Now, the issue is, control doesn't go inside the Ext.drag.Source(). I get 2 alert messages ,before source and outside source. and because it doesn't go inside Ext.drag.Source().
The drag-able functionality of the element is not working. What should I do ?
First you need to be clear on which component you want to use. After that you need to put afterrender event on that component and inside of that event you can use Ext.drag.Source.
In this FIDDLE, I have created a demo using button and Ext.drag.Source.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
var buttons = [],
rendomColor = () => {
return "#" + ((1 << 24) * Math.random() | 0).toString(16);
};
for (var i = 0; i < 10; i++) {
buttons.push({
text: `Button ${i+1}`,
margin: 10,
style: `background:${rendomColor()}`
});
}
Ext.create({
xtype: 'panel',
height: window.innerHeight,
title: 'Ext.drag.Source Example',
defaults: {
xtype: 'button'
},
items: buttons,
renderTo: Ext.getBody(),
listeners: {
afterrender: function (panel) {
panel.items.items.forEach(item => {
new Ext.drag.Source({
element: item.el,
constrain: {
// Drag only vertically in 30px increments
//vertical: true,
snap: {
y: 1,
x: 1
}
}
})
})
}
}
});
}
});
I'm trying to make a grid editor that will automatically advance to the next column after 5 characters are typed in the first column. I've put together what I think is the right code for this, but the selected column keeps jumping back to the first one and clears the data that was entered.
Here is the grid that I'm using:
Ext.create('Ext.grid.Panel', {
title: 'idNumbers',
store: Ext.data.StoreManager.lookup('priceStore'),
plugins: [Ext.create('Ext.grid.plugin.RowEditing',
{
clicksToEdit: 1,
pluginId: 'idNumberGridEditor'
})],
columns: [
{
header: 'Name',
dataIndex: 'idNumber',
editor: {
allowBlank: false,
xtype: 'combobox',
store: Ext.data.StoreManager.lookup('idNumberStore'),
displayField: 'idNumber',
valueField: 'idNumber',
typeAhead: true,
allowBlank: false,
forceSelection: true,
enableKeyEvents: true,
listeners: {
keyup: function(combo, e, eOpts) {
if(combo.getValue().length==5)
{
//move to next control
if(!this.nowFive)
{
editPlugin = this.up().editingPlugin;
curRow = editPlugin.context.rowIdx;
curCol = editPlugin.context.colIdx;
editPlugin.startEdit(curRow, curCol + 1);
this.nowFive = true;
}
}
else
{
this.nowFive = false;
}
}
}
}
},
{
header: 'Phone',
dataIndex: 'price',
editor: {
allowBlank: false,
xtype: 'numberfield'
}
}
],
height: 200,
width: 400,
renderTo: Ext.getBody(),
listeners: {
afterrender: function() {
console.log(this);
//this.editor.startEdit(1,1);
}
}
});
Here is the full example: http://jsfiddle.net/cFD9W/5/
startEdit will reset the edit state (it is intended to be used in conjunction with completeEdit or cancelEdit. What you want here is just to focus the next field, this way the edit state will be handled correctly by the plugin.
Here's a rewrite of your listener in that spirit (updated fiddle):
keyup: function(combo, e, eOpts) {
if(combo.getValue().length==5) {
//move to next control
if(!this.nowFive) {
var editPlugin = this.up().editingPlugin,
editor = editPlugin.getEditor(), // Ext.grid.RowEditor
curCol = editPlugin.context.colIdx,
currentField = editor.getEditor(curCol),
nextField = editor.getEditor(curCol + 1);
if (currentField) {
// ensure the combo is collapsed when the field is blurred
currentField.triggerBlur();
}
if (nextField) {
// startEdit will reset the edit state... What we need
// is simply to focus the field, the value will be
// updated when the user clicks the "update" button.
nextField.focus();
}
this.nowFive = true;
}
} else {
this.nowFive = false;
}
}
Finally, as already said by Akori, if you set forceSelection to true, the combo value will be forced to one that already exists in the store, which is probably not what you want.
My aim is simple, for some needs, I have to test the "pop-up function" in ExtJS via the widget.window.
I've created a button in HTML and a pop-u in a JS file, when I click it, everything works fine, the pop-up is well displayed.
The HTML button is coded this way :
<input type="button" id="popup-map" value="Pop Up"/>
And the JS refers to the button this way :
Ext.application({
name: 'popup',
launch: function() {
var popup,
button = Ext.get('popup-map');
button.on('click', function(){
if (!popup) {
popup = Ext.create('widget.window', {
title: 'Pop-Up',
header: {
titlePosition: 2,
titleAlign: 'center'
},
border: false,
closable: true,
closeAction: 'hide',
width: 800,
minWidth: 400,
maxWidth: 1200,
height: 500,
minHeight: 550,
maxHeight: 800,
tools: [{type: 'help'}],
layout: {
type: 'border',
padding: 2
},
items: [
{
region: 'center',
xtype: 'tabpanel',
items: [
mappanel,
{
title: 'Description',
html: 'Attributs de l\'objet sous forme de tableau'
}
]
}
]
});
}
button.dom.disabled = true;
if (popup.isVisible()) {
popup.hide(this, function() {
button.dom.disabled = false;
});
} else {
popup.show(this, function() {
button.dom.disabled = false;
});
}
});
Problem, if I have two buttons that contains the id "popup-map", only the first one declared is working. I guess it's pretty normal the way I've coded it.
How can I call the popup contains in the JS file by clicking several buttons in HTML ?
Thanks :-)
Use a CSS class instead of a duplicated id. Duplicated ids are bad, you know that... Then use Ext.query instead of Ext.get. Your code should look something like this:
Ext.onReady(function() {
var popup;
function handler(button) {
if (!popup) {
// ...
}
// you've got button and popup, do your things
}
// adds the handler to every button with class 'popup-map' on the page
Ext.query('button.popup-map', function(button) {
button.on('click', handler);
});
});
I'm using Ext.onReady to wait for the DOM to be ready before searching for buttons on the page. That also gives us a closure for our local variables popup and handler.
Thanks to #rixo, here's the code working.
I've created a empty css class called customizer.
Ext.onReady(function() {
var popup, popup_visible;
function popup_constructor() {
//alert(this.getAttribute('pwet'));
if (!popup) {
popup = Ext.create('widget.window', {
title: 'Pop-Up',
id: 'popup',
header: {
titlePosition: 2,
titleAlign: 'center',
height: 30
},
border: false,
closable: true,
closeAction: 'hide',
width: 800,
minWidth: 400,
maxWidth: 1200,
height: 500,
minHeight: 550,
maxHeight: 800,
tools: [{type: 'help'}],
layout: {
type: 'border',
padding: 10
},
items: [
{
region: 'center',
xtype: 'tabpanel',
plain: true,
items: [
{
title: 'Carte',
html: 'On mettra la carte ici',
border: false,
},
{
title: 'Description',
html: 'Attributs de l\'objet sous forme de tableau',
border: false,
}
]
}
]
});
}
popup_visible = true;
if (popup.isVisible())
{
popup.hide(this, function() {
popup_visible = false;
});
}
else
{
popup.show(this, function() {
popup_visible = false;
});
}
}
var popup_show = Ext.query('.customizer');
Ext.each(popup_show, function (item) {
item = Ext.get(item);
item.on('click', popup_constructor);
}, this);
});
I have added an input field to Window's title bar (header). On Chrome selecting and editing the input field works, and I can still drag the window around. On Firefox I can drag the window around the viewport, but I am unable to select the input field and edit it. How should I correct this code so that it would work on both browsers?
Quick'n'dirty demonstration of the problem:
Ext.define('Demo.DemoWindow', {
extend: 'Ext.window.Window',
xtype: 'demowindow',
height: 300,
width: 400,
title: 'Window',
autoShow: true,
items: [{
xtype: 'button',
text : 'Press!',
listeners: {
click: function() {
var win = this.up('window');
var header = win.getHeader();
header.setTitle('');
var killDrag = false;
var dragEvent = win.dd.on({
beforedragstart: function(dd, e) {
if (killDrag) {
return false;
}
}
});
var field = Ext.create('Ext.form.field.Text', {
name: 'Title',
allowBlank: false,
value: 'Type here something!',
listeners: {
el: {
delegate: 'input',
mouseout: function() {
killDrag = false;
},
mouseenter: function() {
killDrag = true;
}
}
}
});
header.insert(0, field);
}
}
}]
});
Ext.application({
name: 'Demo',
launch: function() {
Ext.create('Ext.container.Viewport', {
layout: 'absolute',
items: [
{
xtype: 'demowindow',
x: 20,
y: 20,
}
]
});
}
});
Using the mouseover event instead of mouseenter seems to work well with both.
I want to add buttons in one of columns in the grid. I try this code
listeners: {
render: {
fn: function(kad_tab){
var view = kad_tab.getView();
for (var i = 0; i < store.getCount(); i++) {
var cell = Ext.fly(view.getCell(i, 2));
new Ext.Button({
handler: function(){
alert('Suppression')
},
renderTo: cell.child(".btn"),
text: 'Supprimer'
});
}
},
// delay: 200
}
}
{header: "", width: 70, dataIndex: '', renderer: function(){ return '<div class="btn" style="height: 11px; width: 60px"></div>';}}
But firebug says that he see error here Ext.fly(this.getRow(c)) is null.
if i use delay: 200. There is no errors in firebug but dont see a buttons in column.
What im doing wrong?
I found a simple way...
{
xtype: 'actioncolumn',
width: 50,
items: [{
icon : url_servlet+'externals/gxp/src/theme/img/pencil.png',
tooltip: 'Button click',
handler: function(grid, rowIndex, colIndex) {
alert("DAMACIA!!!!!");
}
}]
}