PDA

View Full Version : Extjs 4.2 combobox, how to disable use of store filters ?



maneljn
11 Apr 2013, 7:40 AM
In new version extjs 4.2 the combobox uses by default the store "filter"
Is it possible to disable the uses of filters in combobox , and use only the "query" param ?

The problem is that in php POST variables, i cannot distinguish what filters are added by combobox, and what filters are added in other parts of source code, like in store config.

Manel

slemmon
15 Apr 2013, 9:33 AM
I'm not following. What are you seeing being sent as filters? Do you have a simple test case to show what you mean?

maneljn
15 Apr 2013, 11:27 PM
slemmon, in my code i use some fixed filters in store to get data , for example, of the selected company.
In all my "get data" methods of the php server side, i add all the "filter" received by the POST

For example this is my example code:

The model:


//@charset UTF-8

// Modelo de datos para las areas
Ext.define('esiacademia.model.area', {
extend: 'Ext.data.Model',

idProperty: 'area_id',
fields: [
{ name: 'area_id', type: 'integer' },
{ name: 'area_guid', type: 'string' },
{ name: 'area_empresa_id', type: 'integer' },
{ name: 'area_nombre', type: 'string' },
{ name: 'area_jefe_contacto_id', type: 'integer' },
{ name: 'area_descripcion', type: 'string' },
{ name: 'area_observaciones', type: 'string' },
{ name: 'area_activo', type: 'boolean' },

// Jefe area - Contacto asociado
{ name: 'area_jefe_cto_nombre_fiscal', type: 'string', persist: false },

// Empresa
{ name: 'empresa_emp_nombre', type: 'string', persist: false },
{ name: 'empresa_cto_nombre_fiscal', type: 'string', persist: false },

{ name: 'area_usralta_id', type: 'integer', persist: false },
{ name: 'area_fechaalta', type: 'date', dateFormat: 'Y-m-d H:i:s', persist: false },
{ name: 'area_usrmod_id', type: 'integer', persist: false },
{ name: 'area_fechamod', type: 'date', dateFormat: 'Y-m-d H:i:s' }, // Este campo se usará para el aviso de sobreescritura en concurrencia (2 usuarios grabando en el mismo registro a la vez)
{ name: 'area_usralta_nombre', type: 'string', persist: false },
{ name: 'area_usrmod_nombre', type: 'string', persist: false }
]

});


The store:


//@charset UTF-8

// Store para las areas
Ext.define('esiacademia.store.areas', {
extend: 'Ext.data.Store',

requires: [
'esiacademia.model.area'
],

constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
autoLoad: false,
autoSync: false,
buffered: false,
model: 'esiacademia.model.area',
remoteSort: true,
remoteFilter: true,
pageSize: 50,
proxy: {
type: 'direct',
batchActions: false,
paramAsHash: true,
extraParams: {
buscar: null
},
api: {
read: Ext.esiacademiaDirect.esiacademia_areas.getAreas,
create: Ext.esiacademiaDirect.esiacademia_areas.createArea,
update: Ext.esiacademiaDirect.esiacademia_areas.updateArea,
destroy: Ext.esiacademiaDirect.esiacademia_areas.destroyArea
},
reader: {
type: 'json',
root: 'data',
idProperty: 'area_id',
totalProperty: 'total',
successProperty: 'success',
messageProperty : 'message'
}
}
}, cfg)]);
}

});


The store creation


// ---------------------------------------------------------------
// Asignar el store para poder tener las areas disponibles y asignar a asignaturas (Forzamos la creación de un objeto nuevo)
// ---------------------------------------------------------------
me.storeAreasDisponibles = Ext.create('esiacademia.store.areas', {
storeId: Ext.id(),
autoLoad: false,
pageSize: -1
});
// Hay que filtrar la información por la empresa seleccionada (ejecutara el load automaticamente)
// Filtrar solo queremos las areas activas (ejecutara el load automaticamente)
me.storeAreasDisponibles.filter([{
id: 'area_activo',
property: 'area_activo',
value: true
},{
id: 'area_empresa_id',
property: 'area_empresa_id',
value: esiacademiaApp.empresaActualId
}]);



The combobox:



// Area asignada a la asignatura
name: 'asig_area_id',
xtype: 'combobox',
fieldLabel: gt.dgettext('esicontactos','Area'),
store: me.storeAreasDisponibles ,
queryMode: 'remote',
displayField: 'area_nombre',
valueField: 'area_id',
forceSelection: true,
typeAhead: true,
editable: true,
anchor: '70%',
fieldCls: 'campo_obligatorio',
allowBlank: false



The php server side


/**
* Obtener todos los areas
* @remotable
*/
public static function getAreas($_parametros)
{

// Si se recibe el parametro por ExtDirect con paramAsHash=true viene como un objeto
if (is_object($_parametros)) {
if (isset($_parametros->buscar)) {
$_buscar = trim($_parametros->buscar);
}
if (isset($_parametros->query)) {
// Això ho passa un boxselect si demanes filtratge de la llista (Cadena que escriu l'usuari al combo)
$_query = trim($_parametros->query);
$_buscar = (empty($_buscar) ? "" : " ") . $_query;
}
if (isset($_parametros->group[0])) {
$_agruparPor = $_parametros->group[0]->property;
$_agruparDir = $_parametros->group[0]->direction;
}
if (isset($_parametros->sort[0])) {
$_ordenarPor = $_parametros->sort[0]->property;
$_ordenarDir = $_parametros->sort[0]->direction;
}
if (isset($_parametros->filter)) {
$_filter = $_parametros->filter;
}
$_offset = $_parametros->start;
$_limit = $_parametros->limit;
}

// conexion a la base de datos
$esiacademiaConexionBD = esiacademia_conexion::getInstancia()->conexionBD;
$esiacademiaPrefijoTablas = esiacademia_conexion::esiacademiaPrefijoTablas;
$esinubePrefijoTablas = esinube_conexion::esinubePrefijoTablas;
$esicontactosPrefijoTablas = esicontactos_conexion::esicontactosPrefijoTablas;

if (!$esiacademiaConexionBD) {
$respuesta['success'] = true;
$respuesta['data'] = NULL;
return $respuesta;
}

// Orden por defecto
$campo_ordenar = 'area_nombre';
$sentido_ordenar = 'asc';
// Orden pedido por usuario
if (isset($_ordenarPor) && isset($_ordenarDir)) {
switch ($_ordenarPor) {
case 'area_usralta_nombre':
$campo_ordenar = 'x.cto_nombre_fiscal';
break;
case 'area_usrmod_nombre':
$campo_ordenar = 'x.cto_nombre_fiscal';
break;
default:
$campo_ordenar = $_ordenarPor;
}
$sentido_ordenar = $_ordenarDir;
}

// Condicion Where
$condWhere = null;

// Campos de filtro del store-proxy
if (isset($_filter)) {
$_filtrar = get_magic_quotes_gpc() ? stripslashes($_filter) : $_filter;
if ( is_array($_filtrar) ) {
$condWhere .= "";
foreach ($_filtrar as $_filtro) {
$condWhere .= " AND ".$_filtro->property."='".$_filtro->value."' ";
}
}
}

// Filtro libre por palabras
if (isset($_buscar)) {
if (!empty($_buscar)) {
$condBuscar = "";
$_buscar = mb_strtolower($_buscar);
$palabras = explode(" ",$_buscar);
foreach ($palabras as $palabra) {
if ( !empty($palabra) ) {
$condBuscarPalabra = " ( LOWER(a.area_guid)='".mysql_real_escape_string( $palabra ,$esiacademiaConexionBD)."' )";
$condBuscarPalabra .= " OR ( LOWER(a.area_nombre) LIKE '%".mysql_real_escape_string( $palabra ,$esiacademiaConexionBD)."%' )";
$condBuscarPalabra .= " OR ( LOWER(a.area_descripcion) LIKE '%".mysql_real_escape_string( $palabra ,$esiacademiaConexionBD)."%' )";
// En campos BLOB no funciona el LOWER directamente hay que hacer primero el CONVERT
$condBuscarPalabra .= " OR ( LOWER(CONVERT(a.area_observaciones USING utf8)) LIKE '%".mysql_real_escape_string( $palabra ,$esiacademiaConexionBD)."%' )";
$condBuscarPalabra .= " OR ( LOWER(b.cto_nombre_fiscal) LIKE '%".mysql_real_escape_string( $palabra ,$esiacademiaConexionBD)."%' )";
// Campos numericos
if (is_numeric($palabra)) {
$condBuscarPalabra .= " OR ( a.area_id='".mysql_real_escape_string( $palabra ,$esiacademiaConexionBD)."' )";
}
$condBuscar .= (!empty($condBuscar) ? " AND " : "" ) . " ( ".$condBuscarPalabra." ) ";
}
}
$condWhere .= "";
$condWhere .= " AND ( ".$condBuscar." )";
}
}

// Filtro obligatorio solo deja pasar registros de empresas permitidas
// Si se desean los registros de una sola empresa se envia como parametro del filter adicional
$cadenaidsEmpresasPermitidas = $_SESSION[_APP_INDEX_SESSION]['usuario']['empresas_permitidas']['esiacademia'];
$condWhere .= "";
$condWhere .= " AND a.area_empresa_id IN (" .(mb_strlen($cadenaidsEmpresasPermitidas)>0 ? $cadenaidsEmpresasPermitidas : "-1"). ") ";

// Contar todos los registros
$sqlContarTotal = "SELECT count(*) FROM ".$esiacademiaPrefijoTablas."Areas a ";
$sqlContarTotal .= " LEFT JOIN ".$esicontactosPrefijoTablas."Contactos b ON a.area_jefe_contacto_id=b.cto_id ";
if ($condWhere) {
$sqlContarTotal .= " WHERE true ";
$sqlContarTotal .= $condWhere;
}
$resultadoContarTotal = mysql_query($sqlContarTotal, $esiacademiaConexionBD);
$filaContarTotal= mysql_fetch_row($resultadoContarTotal);

// Seleccionar pagina de registros
$sqlRegistros = "SELECT a.* ";
$sqlRegistros .= " ,b.cto_nombre_fiscal as area_jefe_cto_nombre_fiscal ";
$sqlRegistros .= " ,y.emp_nombre as empresa_emp_nombre ";
$sqlRegistros .= " ,y.cto_nombre_fiscal as empresa_cto_nombre_fiscal ";
$sqlRegistros .= " ,x.cto_nombre_fiscal as area_usralta_nombre ";
$sqlRegistros .= " ,w.cto_nombre_fiscal as area_usrmod_nombre ";
$sqlRegistros .= " FROM ".$esiacademiaPrefijoTablas."Areas a ";
$sqlRegistros .= " LEFT JOIN ".$esicontactosPrefijoTablas."Contactos b ON a.area_jefe_contacto_id=b.cto_id ";
$sqlRegistros .= " LEFT JOIN (SELECT emp_id, emp_nombre, cto_nombre_fiscal FROM ".$esinubePrefijoTablas."Empresas LEFT JOIN ".$esicontactosPrefijoTablas."Contactos ON emp_contacto_id=cto_id) y ON a.area_empresa_id=y.emp_id ";
$sqlRegistros .= " LEFT JOIN (SELECT usr_id, cto_nombre_fiscal FROM ".$esinubePrefijoTablas."Usuarios LEFT JOIN ".$esicontactosPrefijoTablas."Contactos ON usr_contacto_id=cto_id) x ON a.area_usralta_id=x.usr_id ";
$sqlRegistros .= " LEFT JOIN (SELECT usr_id, cto_nombre_fiscal FROM ".$esinubePrefijoTablas."Usuarios LEFT JOIN ".$esicontactosPrefijoTablas."Contactos ON usr_contacto_id=cto_id) w ON a.area_usrmod_id=w.usr_id ";
if ($condWhere) {
$sqlRegistros .= " WHERE true ";
$sqlRegistros .= $condWhere;
}
$sqlRegistros .= " ORDER BY ".$campo_ordenar." ".$sentido_ordenar." ";
if ($_limit>0) {
$sqlRegistros .= " LIMIT ".$_offset.",".$_limit." ";
}
$resultadoRegistros = mysql_query($sqlRegistros, $esiacademiaConexionBD);
$sqlError=mysql_error($esiacademiaConexionBD); // Captura texto error si hay
$sqlErrorNum=mysql_errno($esiacademiaConexionBD); // Captura num error si hay
if (($resultadoRegistros===false) || $sqlErrorNum>0 )
{
$respuesta['success'] = true;
$respuesta['data'] = NULL;
return $respuesta;
} else {
$registros = array();
while($fila = mysql_fetch_object($resultadoRegistros)){
array_push($registros, $fila);
}
}
$respuesta['success'] = true;
$respuesta['data'] = $registros;
$respuesta['total'] = $filaContarTotal[0];
return $respuesta;
}



The first POST to server


{"action":"esiacademia_areas","method":"getAreas","data":[{"buscar":null,"page":1,"start":0,"limit":-1,"filter":[{"property":"area_activo","value":true},{"property":"area_empresa_id","value":3},{"property":"area_nombre"}]}],"type":"rpc","tid":6}


As you can see i have not typed anything, and there is a new "property" named "area_nombre" created by combobox, without "value" setting. (bug ?)

The first response from server

{"type":"rpc","tid":6,"action":"esiacademia_areas","method":"getAreas","result":{"success":true,"data":[],"total":"0"}}



It returns no data because of the presence of the "automatically created filter"

The post when i type "inform" in combobox.


{"action":"esiacademia_areas","method":"getAreas","data":[{"buscar":null,"query":"inform","page":1,"start":0,"limit":-1,"filter":[{"property":"area_activo","value":true},{"property":"area_empresa_id","value":3},{"property":"area_nombre"}]}],"type":"rpc","tid":7}


As you can see , it continues without the "value" setting in property "area_nombre" (this could be a bug ?)

the returned values



{"type":"rpc","tid":7,"action":"esiacademia_areas","method":"getAreas","result":{"success":true,"data":[],"total":"0"}}


Nothing returned because of the presence of this combobox "filter"


I think that, when sencha adds new features to components, they have to think in existing code from developers of earlier version.
The new versions have to work, if it's possible, with earlier versions. When you add new features i think allways is possible to be retro compatible.
It's very simple to add a config option to "enable/disable" new features, but let it disabled by default.
It will be some good in adition to add a param that tells to server side that this filter is automatically generated by combo, to distinguish from other created hardcoded. (for example the filter id value)

Now i have to reprogram all my sever side coding or disable in some way the filters feature in combobox, when my code works very well with extjs 4.1.1a version.

slemmon
16 Apr 2013, 7:47 AM
I see.
I tested with 4.2 and saw the issue and tested with 4.2.1 Beta and it looks like that issue is fixed in Beta now.

maneljn
16 Apr 2013, 8:05 AM
Thanks Slemmon, another questions:

Do you know if in v4.2.1:
- Use of combo filters will be configurable (enable/disable)
- Combo filter POST will have something to distinguish from other harcoded filters ?

Manel

slemmon
16 Apr 2013, 9:19 AM
Yeah, the query is being looks like:



_dc=1366132624071&buscar=&query=myquery&page=1&start=0&limit=-1&filter=%5B%7B%22property%22%3A%22area_activo%22%2C%22value%22%3Atrue%7D%2C%7B%22property%22%3A%22area_empresa_id%22%2C%22value%22%3A1%7D%5D


parsed:


_dc:1366132624071
buscar:
query:myquery
page:1
start:0
limit:-1
filter:[{"property":"area_activo","value":true},{"property":"area_empresa_id","value":1}]

maneljn
16 Apr 2013, 11:24 PM
sorry slemmon, but i don't understand what you mean with the last post.

Manel

slemmon
17 Apr 2013, 10:42 AM
Oh, sorry. To answer your question it looks like the query and the filters are being sent separately as two different params. The query is using the 'query' param and the filters are using the 'filter' param. Below is what I'm seeing sent from the proxy in 4.2.1 Beta


_dc:1366132624071
buscar:
query:myquery
page:1
start:0
limit:-1
filter:[{"property":"area_activo","value":true},{"property":"area_empresa_id","value":1}]

maneljn
17 Apr 2013, 11:26 PM
Now I understand your answer. But, if in my store are two filters hardcoded, and the combobox added another filter automatically when typing a text, when i get in the filters array received in php with the 3 filters, how can i distinguish, which of the 3 filters is the one added the combobox??

Or, do you mean , that with 4.2.1 beta, you can disable the use of filters from combobox (not sending it in post), and use only the query param ??

slemmon
18 Apr 2013, 2:13 PM
In 4.2.1 filters are sent with the 'filter' param
and what is typed in the field is sent with the 'query' param so that you can distinguish it from the filters in your server script.

maneljn
18 Apr 2013, 11:26 PM
Slemmon, tell me if i have understood well:

In v4.2.1 will go like this in the 2 examples :

Example A. If i have an store without any filter, when i type "somewords" in combobox, in php i will receive empty array "filters" param, and "somewords" in "query" param.

Example B. If i have an store with ,for example 1 filter hardcoded (Field1) in store class definition using a field, that isn't the combobox displayfield (Field2), when i type "somewords" in combobox, in php i will receive an array "filters" param with just 1 member (only the hardcoded Field1), and "somewords" in "query" param. The presence of (Field2 - combo displayfield) does not appear in received "filters" param anymore.

Sorry about this confusing post , but for me is important to difference between hardcoded filters (in php i check it with equals SQL (field = filtervalue), and the query combobox i check it with like SQL (field LIKE %filtervalue%). Is for this, that i need to avoid the combobox to use filters, or if it uses, i need to distinguish in php side which "filters" array members are the automatically created by the combobox.

slemmon
19 Apr 2013, 10:26 AM
Scenario B is correct. So, your script should, going forward, see the query from the field as a distinct parameter from any filters.

maneljn
21 Apr 2013, 12:52 AM
slemmon, v4.2.1 beta is yet downloadable, to test this changes ? Can you post me the download link ?

slemmon
22 Apr 2013, 8:04 AM
4.2.1 Beta 1 is available for download. The link is posted here:
http://www.sencha.com/forum/showthread.php?261008-Ext-JS-4.2.1-Beta-1-Now-Available