Need to bind my form elements separately for different buttons. Using allowBlank in elements for sending binding conditions and formBind in buttons for binding the buttons. Need to do this like in this simplest way. (ExtJs 4.2.1 Classic)
Example
Ext.create('Ext.form.Panel', {
......
items: [
Ext.create('Ext.form.field.Date', {
.....,
allowBlank: false, //bind for both search & download button.
.....
}),
......, //// All rest elements bind for both search & download button.
Ext.create('Ext.form.ComboBox', {
......,
allowBlank: false, //bind for only download button.
......
})
],
buttons: [
{
text: 'Search',
formBind: true, /// Need to bind for specific field only.
},
{
text: 'Download',
formBind: true, /// Need to bind for all.
},
............
});
If any other data or details is necessary then please don't hesitate to ask.
I created a fiddle here that I think should accomplish what you're trying to do. The idea to use an event listener on the combobox, instead of the formBind config of the Download button:
https://fiddle.sencha.com/#view/editor&fiddle/289a
Ext.create('Ext.form.Panel', {
renderTo: Ext.getBody(),
itemId: 'exampleForm',
items: [Ext.create('Ext.form.field.Date', {
allowBlank: false, //bind for both search & download button.
}),
Ext.create('Ext.form.ComboBox', {
allowBlank: false, //bind for only download button.
listeners: {
change: function (thisCombo, newValue, oldValue, eOpts) {
if (Ext.isEmpty(newValue)) {
thisCombo.up('#exampleForm').down('#btnDownload').setDisabled(true);
} else {
thisCombo.up('#exampleForm').down('#btnDownload').setDisabled(false);
}
}
},
store: ['item1', 'item2']
})
],
buttons: [{
text: 'Search',
formBind: true, /// Need to bind for specific field only.
}, {
itemId: 'btnDownload',
text: 'Download',
disabled: true
//formBind: true, /// Need to bind for all.
}]
});
There is no standard quick way to do this, you might want to write a plugin for this. I've put together one:
Ext.define('App.plugin.MultiDisableBind', {
extend: 'Ext.AbstractPlugin',
alias: 'plugin.multidisablebind',
/**
* #cfg
* Reference to the fields that this button depends on.
* Can contain either direct references, or a query selectors that will be
* executed with the button as the root
*/
depFields: null,
/**
* #property
* A map object with field ids as key, and field values as value
*/
valuesMap: null,
init: function (cmp) {
this.setCmp(cmp);
cmp.on('render', this.setup, this);
},
setup: function () {
var cmp = this.getCmp(),
depFields = this.depFields,
valuesMap = {};
if (!Ext.isArray(depFields)) {
depFields = [depFields];
}
Ext.Array.forEach(depFields, function (field) {
if (Ext.isString(field)) {
field = cmp.query(field)[0];
}
cmp.mon(
field,
'change',
Ext.Function.createThrottled(this.updateValuesMap, 300, this),
this
);
valuesMap[field.getId()] = field.getValue();
}, this);
this.valuesMap = valuesMap;
this.updateCmpDisabled();
},
updateValuesMap: function (depField, newValue) {
this.valuesMap[depField.getId()] = newValue;
this.updateCmpDisabled();
},
updateCmpDisabled: function () {
var cmp = this.getCmp(),
toDisable = true;
Ext.Object.each(this.valuesMap, function (fieldId, fieldValue) {
if (!Ext.isEmpty(fieldValue)) {
toDisable = false;
return false
}
});
cmp.setDisabled(toDisable);
}
});
You can use this plugin in your buttons like so:
xtype: 'button',
text: 'My button',
plugins: {
ptype: 'multidisablebind',
depFields: ['^form #fieldQuery', fieldVar]
}
In the depFields config you specify references to the fields that button's disabled state depends on, and the plugin will monitor these fields, so that on each field value change it will update the disabled state.
Here is a working fiddle: https://fiddle.sencha.com/#view/editor&fiddle/28cm
I have created a fiddle for you. The code uses bind and formBind respectively for the two different buttons. May be you want something like this.
Related
I have some Froala Editor inputs and I want to use generic propierties for all of them and then add some custom properties according to the current input.
For assign the froala object I use this code:
new FroalaEditor('.froala-editor-inline-horari', {
toolbarInline: true,
placeholderText: 'Editar',
toolbarButtons: [
['bold', 'italic'],
['textColor', 'backgroundColor']
],
events: {
contentChanged: function () {
guardarFila(this);
}
},
spellcheck: false
});
I want to use some generic properties as a constant like:
const FROALA_PROPERTIES = {
toolbarInline: true,
placeholderText: 'Editar',
toolbarButtons: [
['bold', 'italic'],
['textColor', 'backgroundColor']
],
events: {
contentChanged: function () {
guardarFila(this);
}
},
spellcheck: false
});
and then add to this object some modification like:
events: {
initialized: function () {
this.html.set('some value');
}
so, in this example I want to obtain the first object FROALA_PROPERTIES plus the new events: {...} key.
Is it this possible?
I answer myself because I found the solution. I can add this keys and values or functions by the next code:
FROALA_PROPERTIES.events.initialized = function () {
this.html.set('some value');
}
But if events key doesnt exist, then I need to create it first.
I based my andwer by this web research: http://researchhubs.com/post/computing/javascript/add-a-key-value-pair-to-a-javascript-object.html
I am using angular-silkgrid with angular 7. I am using inline editing feature. I am using single select editor for inline edit. Currently I want to achieve this functionality:
As soon as user click on the editable field , the select drop down will be visible.On select any option from select dropdown the inline mode should exist and column value should be updated.
currently I need to click on other field to exit from inline mode(I want to achieve this on select option select)
editor: {
// display checkmark icon when True
enableRenderHtml: true,
// tslint:disable-next-line:max-line-length
collection: [{
value: 1,
label: 'Sucessful'
}, {
value: 2,
label: 'Unsucessful'
}],
model: Editors.singleSelect, // CustomSelectEditor
elementOptions: {
autoAdjustDropPosition: false,
onClick: (event, rr) => {
// here i want to write some code which can trigger to grid to start update
}
}
}
Thanks All for the answers. I have solved my issue as below:
editor: {
enableRenderHtml: true,
collection: [{ value: CCLStaus.Sucessfull, label: 'Sucessful' }, { value: CCLStaus.UnSucessfull, label: 'Unsucessful' }],
model: Editors.singleSelect,// CustomSelectEditor
elementOptions: {
onClick: (event) => {
const updateItem = this.angularSilkGrid.gridService.getDataItemByRowIndex(this.rowInEditMode);
updateItem.status = +event.value;
this.angularSilkGrid.gridService.updateItem(updateItem, { highlightRow: false });
this.angularSilkGrid.gridService.renderGrid();
}
}
}
Generally,
grid.getEditorLock().commitCurrentEdit()
will commit and close the editor.
Also, any of
grid.navigateRight()
grid.navigateLeft()
grid.navigateDown()
grid.navigateUp()
grid.navigateNext()
grid.navigatePrev()
will commit and exit gracefully. In the select2 editor, you'll notice:
this.init = function () {
...
// Set focus back to select2 element on closing.
$input.on('select2:close', function (e) {
if ((e.params.originalSelect2Event && e.params.originalSelect2Event.data)
|| e.params.key === 9) {
// item was selected with ENTER or no selection with TAB
args.grid.navigateNext();
} else {
// closed with no selection
setTimeout(function () {
$input.select2('focus');
}, 100);
}
});
};
this.destroy = function () {
$input.select2('destroy');
$input.remove();
};
, noting that args.grid.navigateNext() will commit and close the editor, including calling the destroy() method at the appropriate time.
From the Angular-Slickgrid Editor Example there's a checkbox in the example to auto commit and that is a setting to you need to enable in your Grid Options
this.gridOptions = {
autoEdit: true,
autoCommitEdit: true,
}
The lib will internally call grid.getEditorLock().commitCurrentEdit() like Ben wrote in his answer, in Angular-Slickgrid you can just set the autoCommitEdit flag that I added.
Hello stackoverflow community,
i just built a Codemirror Editor into an ExtJSProject like so:
addCodeMirrorPanel: function() {
this.getAixmFormarea().add(Ext.widget({
xtype: 'textarea',
fieldLabel: 'AIXM',
autoScroll: true,
name: 'aixm',
id: 'codearea',
width: 800,
height: 300,
resizable: true,
resizeHandles: 's se e',
listeners: {
afterrender: function () {
var textarea = Ext.getCmp('codearea');
var codemirror = CodeMirror.fromTextArea(textarea.inputEl.dom,{
lineNumbers: true,
content: '',
matchBrackets: true,
electricChars:true,
autoClearEmptyLines: true,
extraKeys: {"Enter": "newlineAndIndentContinueComment"}
});
}
}
}));
}
Now what i want to do is access the codemirror editor from a different Controller function
and im not quite sure about how to do that.
no getinstance() , geteditorbyID() or similar methods are specified in the codemirror manual and i cant seem to access it from the now hidden textfield either.
Well why are you discarding the instance after you are creating it? Perhaps you could simply store it on the widget?
this.codeMirror = CodeMirror.fromTextArea(...);
I ran into a similar issue and was originally using the answer provided by plalx. However, if you are in need of creating instances of codemirror's dynamically this can get tricky.
I used the following code and created a method on the parent component to getValue(), setValue(), and getCodeMirror()
So in use you can get the codemirror instance similar to this:
var codeMirror = Ext.ComponentQuery.query('#parentFld')[0].getCodeMirror();
Here is the component code:
{
fieldLabel: 'Code Instance',
itemId: 'parentFld',
border: 1,
html: '<textarea></textarea>',
/* Overriding getValue function of the field to pull value from the codemirror text area*/
getValue: function (value) {
return this.getCodeMirror().getValue();
},
/*Overriding setValue function of the field to put the value in the code mirror window*/
setValue: function (value) {
this.getCodeMirror().setValue(value);
},
getCodeMirror: function () {
return this.getEl().query('.CodeMirror')[0].CodeMirror;
},
listeners: {
//on render of the component convert the textarea into a codemirror.
render: function () {
var codeMirror = CodeMirror.fromTextArea(this.getEl().down('textarea').dom, {
mode: {
name: "text/x-sql", globalVars: true
},
//theme: theme,
lineNumbers: true,
readOnly: false,
extraKeys: {"Ctrl-Space":"autocomplete"}
});
codeMirror.setSize(700, 370);
}
}
}
Hi I have the code below my my enter event is never triggering, any help will be appreciated.
items: [{
xtype: 'textfield',
id: 'idhere',
name: 'namehere',
fieldLabel: 'lablehere:',
width: 500,
handler: {
key:13,
fn : function () {
if (e.getKey() == e.ENTER) {
alert("You pressed an enter button in text field.");
}
}
}
},{
xtype: 'button',
text: 'texttodisplay',
handler: function() {
//my function.
}
}]
I actually solved this by using:
listeners: {
specialkey: function (f,e) {
if (e.getKey() == e.ENTER) {
loadData();
}
}
}
I am not sure why Sencha never included Ext.ux.form.SearchField in the API docs but the component has been included in all versions of the framework I've used. It is set-up to fire a submit and a cancel event and includes the appropriate search and cancel buttons attached to the field.
You can find it in your framework files at: [extjs-root]\examples\ux\form\SearchField.js
I would recommend using that component instead of trying to create your own searchfield. I usually override the default search function to fit my own needs but there have been a few scenarios where I did not need to also.
If you add a requires statement at the top of your component JS you can create it like any other (non-UX) component:
E.g:
Requires statement:
Ext.define('MyApp.view.SomeComponent', {
extend: 'Ext.grid.Panel',
alias: 'widget.mycomponent',
requires: [
'Ext.ux.form.SearchField'
],
...
Creating a search field in the panel's bottom toolbar:
bbar: {
items: [{
text: 'A Button'
}, {
text: 'Another Button'
}, '-', {
xtype: 'searchfield', // <- can use this xtype with requires stmt
itemId: 'search',
width: 250,
emptyText: 'Enter first and last name to search...'
}]
},
...
If you have trouble with the requires statement you could also just create it like this:
var search = Ext.create('Ext.ux.form.SearchField', {
itemId: 'search',
width: 250,
emptyText: 'Enter first and last name to search...'
});
Just to supply how to add such a listener. There is a specialkey event that can be used for such a case
fieldinstance.on('specialkey', function(f, e){
if (e.getKey() == e.ENTER) {
// your action
}
});
Anyway I recommend to use the ux component that #Geronimo mentioned
I am extending GridPanel with Ext.define() (Ext v4).
I need to get the row data when a grid row is double clicked. At this point I cannot even get the event listener working:
Ext.define('Application.usersGrid', {
extend: 'Ext.grid.GridPanel',
alias: 'widget.usersgrid',
viewConfig: {
listeners: {
dblclick: function(dataview, index, item, e) {
alert('dblclick');
}
}
},
...
What is wrong here?
If anyone needs the answer- this is the right way:
Ext.define('Application.usersGrid', {
extend: 'Ext.grid.Panel',
alias: 'widget.usersgrid',
viewConfig: {
listeners: {
itemdblclick: function(dataview, record, item, index, e) {
alert('itemdblclick');
}
}
},
...
http://dev.sencha.com/new/ext-js/4-0/api/Ext.grid.GridView#event-itemdblclick
You don't need to put the listener in the viewconfig. Here is my working configuration:
listeners : {
itemdblclick: function(dv, record, item, index, e) {
alert('working');
}
},
Another thing is, you seems to have used Ext.grid.GridPanel in the extend property. But in documentation it's Ext.grid.Panel. But even with gridpanel, everything seems to work fine.
I would suggest to use the Ext JS 4 terms as it might cause to application breakage later in other 4.x versions.
Now, if you are using the new MVC architecture, you will want to move these actions to the controller rather than the view. You can refer to the MVC Architecture guide for details.
With the MVC approach in ExtJS 4 there's another smart way too to define such handlers. Some example code:
Ext.define('App.controller.Documents', {
extend: 'Ext.app.Controller',
stores: ['Documents'],
models: ['Document'],
views: [
'document.List',
'document.Edit',
'document.Preview'
],
init: function() {
this.control({
/*
* a cool way to select stuff in ExtJS 4
*/
'documentlist': {
itemdblclick: this.editDocument
},
/*
* simple access to components
*/
'documentedit button[action=save]': {
click: this.updateDocument
},
});
},
editDocument: function(grid, record) {
var view = Ext.widget('documentedit');
view.down('form').loadRecord(record);
},
updateDocument: function(button) {
var win = button.up('window'), // new selection API
form = win.down('form'), // in ExtJS 4
record = form.getRecord(),
values = form.getValues();
record.set(values);
win.close();
}
});
listeners: {
select: 'xxxx',
itemdblclick: function (dv, record, item, index, e) {
var myBtn = Ext.getCmp('btnEdit');
myBtn.onClick();
}
},