Extjs values not submitted - forms

When submitting a form with Extjs I can see the form items have values with this code just before the submit:
var itemsForm = '';
function mostraItems(item, index, length) { itemsForm += item.id + ':' + item.name + ':' + item.value + ':' + index + '\n'; }
myForm.form.items.each(mostraItems);
alert (itemsForm);
myForm.form.submit({...
But when the request arrives at the handling page the form items are not there. I can see the request details with Firebug.
One of the form items is a ComboBox:
var myCombo = new Ext.form.ComboBox({
//autoWidth: true,
width: 250,
displayField: 'theFieldText',
editable: false,
emptyText: 'Select something ...',
fieldLabel: 'Some text',
listeners: { 'select': { fn: theOnSelect, scope: this} },
mode: 'local',
selectOnFocus: true,
store: theStore,
triggerAction: 'all',
typeAhead: true,
valueField: 'theFieldValue'
});
This is Extjs 2.1

You need to specify the "name" property in order to map the control to a form name-value pair.

Related

AG-Grid Concat fields

I'm trying to concat multiple fields in AG Grid. This is working but when the field is blank the grid shows undefined.
See my code below. I have a grid that has a students First, Middle and Last Name. However, when the Middle name is blank, the 'Student' field, where the values are concatenated it shows the middle name as undefined.
this.state = {
modules: AllCommunityModules,
columnDefs: [
{
field:"FirstName",
headerName: "FirstName",
},
{
field: "MiddleName",
header: "MiddleName",
},
{
field: "LastName",
header: "LastName",
},
{
field: "Student",
header: "Student",
valueGetter: studentValueGetter,
},
function studentValueGetter(params) {
return params.data.FirstName + params.data.MiddleName + params.data.LastName;
}
A header
Another header
A header
Another header
John
Pete
Smith
JohnPeteSmith
Sarah
Jane
SarahunderfinedJane
Just add a condition on the middle name:
return params.data.FirstName + ' ' +
(params.data.MiddleName ? params.data.MiddleName + ' ' : '') +
params.data.LastName;
Or the same thing with more advanced syntax:
const { FirstName, MiddleName, LastName } = params.data;
return [FirstName, MiddleName, LastName].filter(n => !!n).join(' ');
Not an ag-grid specific thing though; this is JavaScript generally.

CKEditor Link dialog modification

I am trying to add a drop down to CKEditor's link dialog. When selected, the drop down should insert corresponding class name to the link.
CKEDITOR.on( 'dialogDefinition', function( ev ) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if ( dialogName == 'link' ) {
var infoTab = dialogDefinition.getContents( 'info' );
infoTab.add({
type: 'select',
label: 'Display link as a button',
id: 'buttonType',
'default': '',
items: [
['- Not button -', ''],
['Button one', 'btn-primary'],
['Button two', 'btn-success'],
['Button three', 'btn-danger']
],
commit: function(data) {
data.className = this.getValue();
}
});
}
});
I have a feeling commit function is not doing the job, but cannot figure out how to make it work. I saw a code that almost does the same thing as I want at http://www.lxg.de/code/simplify-ckeditors-link-dialog. I tried it and it does not work either.
I am using CKEditor 4.3.2.
I appreciate your help in advance.
If you console.log the data object in link dialog's onOk, you'll find quite a different hierarchy. Element classes are in data.advanced.advCSSClasses. But even if you decide to override (or extend) the value of this property in your commit, your string will be nuked by the original commit of advCSSClasses input field ("Advanced" tab) anyway. So the approach got to be a little bit different:
Always store the value of the select in data.
Override commit of advCSSClasses input field to consider stored value.
Remember to execute the original commit of advCSSClasses input.
Here we go:
CKEDITOR.on( 'dialogDefinition', function( ev ) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if ( dialogName == 'link' ) {
var infoTab = dialogDefinition.getContents( 'info' ),
advTab = dialogDefinition.getContents( 'advanced' ),
advCSSClasses = advTab.get( 'advCSSClasses' );
infoTab.add( {
type: 'select',
label: 'Display link as a button',
id: 'buttonType',
'default': '',
items: [
['- Not button -', ''],
['Button one', 'btn-primary'],
['Button two', 'btn-success'],
['Button three', 'btn-danger']
],
commit: function( data ) {
data.buttonType = this.getValue();
}
});
var orgAdvCSSClassesCommit = advCSSClasses.commit;
advCSSClasses.commit = function( data ) {
orgAdvCSSClassesCommit.apply( this, arguments );
if ( data.buttonType && data.advanced.advCSSClasses.indexOf( data.buttonType ) == -1 )
data.advanced.advCSSClasses += ' ' + data.buttonType;
};
}
});
Now you got to only write a setup function which will detect whether one of your button classes is present to set a proper value of your select field once the dialog is open.

Extjs - autocomplete filter 2 properties

By following this example http://dev.sencha.com/deploy/ext-4.1.0-gpl/examples/form/forum-search.html
I could apply the auto-complete feature on my combo box, using php/postgresql query retrieves the names then:
{
xtype: 'combo',
store: ds,
hideTrigger:true,
typeAhead: false,
id: 'search_input_text',
width: 187,
queryMode: 'remote',
hideLabel: true,
queryParam: 'query',
displayField: 'first_name',
valueField: 'first_name',
listConfig: {
loadingText: 'Loading...',
getInnerTpl: function() {
return '{first_name}';
}}
listeners: {
buffer: 50,
change: function() {
var store = this.store;
store.clearFilter();
store.filter({
property: 'first_name',
anyMatch: true,
value : this.getValue()
});
}
}
}
Now, I need to edit this to let user enter either the first or last name of the student, and then each name entered (first or last) will be shown in the combo box.
So, I edited the query to make it retrieve the names :
SELECT first_name, last_name FROM students WHERE first_name ILIKE '%$query%' OR last_name ILIKE '%$query%' ";
and:
displayField: 'first_name'+'last_name',
valueField: 'first_name'+'last_name',
return '{first_name}'+'{last_name}';
store.filter({
property: 'first_name',
anyMatch: true,
value : this.getValue()
},
{
property: 'last_name',
anyMatch: true,
value : this.getValue()
}
but still, it retrieves only first names according to what user types,
Note that if I use this alone:
store.filter({
property: 'last_name',
anyMatch: true,
value : this.getValue()
});
it works fine with last names only.
You can apply multiple filters to data store like this:
var filters = [
new Ext.util.Filter({
filterFn: function(item){return item.get('first_name') == this.getValue() || item.get('last_name') == this.getValue();
}
})
];
store.filter(filters);
The above code block is just an idea on how to apply multiple filters in the same field. Notice the double-pipe "||". You can use "&&" as per your needs. It is like SQL query.

ExtJS combo load and disable

I summarize the issue like this.
I use a form to edit user information which is loaded from the DB (I get these values through a JSONStore)
I want to enable/disable a combo depending on the loaded value of another combo.
Example: disable combo2 if the loaded value into combo1 = 0
if I load combo1 = 1, combo2 = 12 :
Everything fine
if I load combo1 = 0, combo2 = 15 : Disable combo2
Any ideas? Thanks
A listener like this should do the job:
formEditUser.getForm().on('actioncomplete',function(form,action) {
if(combo1.getValue() == 0) {
combo2.disable();
} else if (combo1.getValue() == 1) {
combo2.enable();
}
})
working code segment:
enter code here
{xtype: 'fieldset',
items: [{xtype: 'combo',
hiddenName: 'category[line]',
fieldLabel: 'Category',
store: categories,
emptyText: 'Select',
triggerAction: 'all',
mode: 'local',
displayField: 'category_name',
valueField: 'id',
anchor: '50%',
listeners:{
select:{fn:function(thisCombo, value) {
var combo = Ext.getCmp('combo-subcats');
combo.enable();
//combo.clearValue();
/* category is part of the json data inside the subcat. So the first select choose the category - then filter out only that bit and populate the subcat combo. Make sense? */ combo.store.filter('category', values.data['category']);
}}
}
},
{xtype: 'combo',
hiddenName: 'subcats[line]',
disabled: true,
id: 'combo-subcats',
fieldLabel: 'Sub Cat',
store: getSubcatsStore(),
emptyText: 'Select',
triggerAction: 'all',
mode: 'local',
displayField: 'name',
valueField: 'id',
anchor: '50%',
lastQuery: '' //<-- this is what makes it work.
},

cakePHP + extjs row editor and REST

I've implemented REST routing in cakePHP to properly route REST style requests to the proper methods in my controller.
This is what I've added to my routes.php
Router::mapResources(array('object_fields'));
This properly routes the REST requests to my index/add/edit/delete methods inside my controller.
In my EXTJS grid I am using the row editor with a restful store to achieve CRUD behavior.
Here is the code for my grid
myapp.object_field_grid = Ext.extend(Ext.grid.GridPanel, {
closable: true,
stripeRows: true,
frame: true,
viewConfig: {
forceFit: true
},
editor: new Ext.ux.grid.RowEditor({
saveText: 'Update',
}),
onAdd : function(btn, ev){
var u = new this.store.recordType({
name : '',
type: '',
});
this.editor.stopEditing();
this.store.insert(0, u);
this.editor.startEditing(0);
},
onDelete : function(){
},
initComponent: function() {
var proxy = new Ext.data.HttpProxy({
url: 'object_fields/',
});
var reader = new Ext.data.JsonReader({
totalProperty: 'totalCount',
successProperty: 'success',
idProperty: 'id',
root: 'data',
messageProperty: 'message'
}, [
{name: 'id'},
{name: 'name', allowBlank: false},
{name: 'type', allowBlank: false},
]);
var writer = new Ext.data.JsonWriter({
encode: false,
});
var store = new Ext.data.Store({
baseParams: {id: this.object_id},
id: 'object_fields',
restful: true,
proxy: proxy,
reader: reader,
writer: writer,
});
store.load();
var object_field_columns = [
// {header: "id", width: 250, sortable: true, dataIndex: 'id', editor: new Ext.form.TextField({})},
{header: "name", width: 250, sortable: true, dataIndex: 'name', editor: new Ext.form.TextField({})},
{header: "type", width: 250, sortable: true, dataIndex: 'type', editor: new Ext.form.ComboBox({editable: false, store:['STRING', 'NUMBER']})},
];
var config = {
columns: object_field_columns,
store: store,
plugins: [this.editor],
//autoHeight: true,
height: 200,
tbar: [{
text: 'Add',
iconCls: 'silk-add',
handler: this.onAdd,
scope: this,
}, '-', {
text: 'Delete',
iconCls: 'silk-delete',
handler: this.onDelete,
scope: this,
}, '-'],
}
Ext.apply(this, Ext.apply(this.initialConfig, config));
myapp.object_field_grid.superclass.initComponent.apply(this, arguments);
},
onRender: function() {
this.store.load();
myapp.object_field_grid.superclass.onRender.apply(this, arguments);
}
});
Ext.reg('object_field_grid', myapp.object_field_grid); // register xtype
My GET/POST requests are being properly routed to my index/add methods inside my controller and I am able to easily retrieve the paramaters that I pass it in the request.
My problem is with the update functionality PUT request. The PUT request does get successfully routed to my edit method inside the controller.
This is what the request looks like in firebug
http://server.local/object_fields/20
JSON
data
Object { name="test7777777777", more...}
id
"18"
Source
{"id":"18","data":{"name":"test7777777777","id":"20"}}
Inside my edit method I'm not receiving my array that I passed through the PUT request.
When I dump $this->params inside my edit method this is what is in the array.
([id] => 20
[named] => Array
(
)
[pass] => Array
(
[0] => 20
)
[controller] => object_fields
[action] => edit
[[method]] => PUT
[plugin] =>
[url] => Array
(
[ext] => html
[url] => object_fields/20
)
[form] => Array
(
)
[isAjax] => 1
)
How can I properly receive my array through the PUT request inside my edit method?
UPDATE:
I am able to retrieve my array using the following code inside the edit method
function edit($id){
$this->autoRender = false;
echo 'edit';
$raw = '';
$httpContent = fopen('php://input', 'r');
while ($kb = fread($httpContent, 1024)) {
$raw .= $kb;
}
fclose($httpContent);
$params = array();
parse_str($raw, $params);
print_r($params);
}
The question is now why does cakePHP not do this automaticly?
put this in your app_controller.php:
public function beforeFilter() {
if (
isset($this->RequestHandler) &&
$this->RequestHandler->requestedWith('json') &&
(
$this->RequestHandler->isPost() ||
$this->RequestHandler->isPut()
)
) {
$jsonData = json_decode(utf8_encode(trim(file_get_contents('php://input'))), true);
if (is_array($jsonData)) {
$this->data = $jsonData;
unset($jsonData);
}
}
}