edit: search in custom queries: better solution /topic/3620-custom-queries-with-pagination-sorting-and-searching/#entry14192
Hello!
I am new here but I have found this forum very helpful in many cases, therefore it is time to share my 2 cents workaround to search issue, even if it is not solid enough to be used in production environment with complex custom queries.
in class Custom_query_model add the following
private $search_info = null;
/**
* NOTE:
* this works only in very simple cases where $query_str accepts appending where, order by to its end
* this does NOT work in changed field types @see My_extension::set_ajax_list_queries()
* @see Grocery_crud_model::get_list()
*/
function get_list() {
if(!isset($this->search_info) || $this->search_info == null) {
return $this->db->query($this->query_str)->result();
}
$sql = $this->query_str;
$conditions = $this->search_info;
if(isset($conditions->search) && $conditions->search != null && is_array($conditions->search) && count($conditions->search) > 0) {
foreach($conditions->search as $key => $value) {
$sql .= ' AND `'.$key.'` LIKE '%'.@mysql_real_escape_string($value).'%' ';
}
}
if(isset($conditions->order_by) && $conditions->order_by != null && is_array($conditions->order_by) && count($conditions->order_by) > 0) {
$sql .= ' order by `'.$conditions->order_by[0].'` '.$conditions->order_by[1];
}
return $this->db->query($sql)->result();
}
public function set_search_info($search_info) {
$this->search_info = $search_info;
}
then extend Grocery_CRUD class (such us it is described -> /topic/90-how-to-create-an-extension-for-grocery-crud-real-example-included/ ) and override set_ajax_list_queries method:
/**
* Override to fix search in true_false and dropdown fields
* @see grocery_CRUD_Model_Driver::set_ajax_list_queries()
*/
public function set_ajax_list_queries($state_info = null)
{
if (!isset($state_info) || $state_info == null || empty($state_info)
|| !isset($state_info->search) || $state_info->search == null || empty($state_info->search)
|| !is_array($state_info->search)
|| !isset($this->change_field_type) || $this->change_field_type == null || empty($this->change_field_type)
|| !is_array($this->change_field_type)
) {
if (is_a($this->basic_model, 'Custom_query_model') && method_exists($this->basic_model, 'set_search_info' )) {
$this->basic_model->set_search_info($state_info);
}
parent::set_ajax_list_queries($state_info);
return;
}
$changeFields = $this->change_field_type;
foreach ($state_info->search as $search_field => $search_text) {
if (array_key_exists($search_field, $changeFields)
&& isset($changeFields[$search_field]->extras)
&& is_array($changeFields[$search_field]->extras)
&& count($changeFields[$search_field]->extras) > 0
) {
$extraArr = $changeFields[$search_field]->extras;
if ($changeFields[$search_field]->type == 'true_false') {
foreach ($extraArr as $extraKey => $extraVal) {
if (strval(intval($search_text)) === $search_text) {
if (intval($search_text) == intval($extraKey)) {
$state_info->search[$search_field] = $extraKey;
}
}
else if(stripos($extraVal, $search_text) > -1) {
$state_info->search[$search_field] = $extraKey;
}
}
}
else if ($changeFields[$search_field]->type == 'dropdown') {
$conditionAdded = 0;
foreach ($extraArr as $extraKey => $extraVal) {
if (strval(intval($search_text)) === $search_text) {
if (intval($search_text) == intval($extraKey)) {
$this->where($search_field.' =' , intval($extraKey));
unset($state_info->search[$search_field]);
$conditionAdded++;
}
}
else if(stripos($extraVal, $search_text) > -1) {
unset($state_info->search[$search_field]);
$this->or_like($search_field , $extraKey);
}
}
if(strval(intval($search_text)) === $search_text && $conditionAdded == 0) {
// add a condition in order not to match with special value "-1"
$this->where($search_field.' !=', '-1');
}
}
}
}
if (is_a($this->basic_model, 'Custom_query_model') && method_exists($this->basic_model, 'set_search_info' )) {
$this->basic_model->set_search_info($state_info);
}
parent::set_ajax_list_queries($state_info);
}
Actually important part for this topic is only:
if (is_a($this->basic_model, 'Custom_query_model') && method_exists($this->basic_model, 'set_search_info' )) {
$this->basic_model->set_search_info($state_info);
}
all the rest try to handle search problem in:
- 'dropdown' define such as array keys correspond to DB real values: $crud->field_type('column','dropdown',array("dbVal1" => "Label1","dbVal2" => "Label2"))
- 'true_false' fields (in this case assuming you use it in this way in your controller: $crud->field_type('column','true_false', array('No','Yes'));
This is still in development and I cannot assure it is bug free of course but I think it is a starting point to more expert people here.
If you found errors or improvements please share them with the community.
bye,
G.
EDIT: I have workaround another bug (search does not work properly when input == '0') => /topic/3548-bootstrap-theme-search-in-list-with-value-0-on-tinyint1-fields-problem/#entry14232