I want to return matching records when user search with a key, I am building an online shopping site so if user search for xyz then it should return all records that contain xyz in a particular column in database. Right now it will return if and only if an exact match found in the column and the current code
if(isset($_GET['search']))
{
$search=$_GET['search'];
$criteria=new CDbCriteria;
$criteria->compare('name',$search,true);
$items=Item::model()->findAll($criteria);
}
right now it will return the records(name) that match xyz=name but my requirement is if user search for xy then also it should return xyz(name)
There is a method \CDbCriteria::addSearchCondition(), here is it's signature:
public static addSearchCondition(string $column, string $keyword, boolean $escape=true, string $operator='AND', string $like='LIKE')
In you example you have to use it like:
if(isset($_GET['search']))
{
$search=$_GET['search'];
$criteria=new CDbCriteria;
$criteria->addSearchCondition('name', $search);
$items=Item::model()->findAll($criteria);
}
You can find more information in the official Yii API:
https://www.yiiframework.com/doc/api/1.1/CDbCriteria#addSearchCondition-detail
Related
Using Grails (or hibernate), I was wanting to know if there is a specific design pattern or method we should be using when implementing a SEARCH of our domain.
For example, on my website, I want to be able to filter(or search) by multiple properties in the domain.
EG: For I have a page which displays a list of HOTELS. When I submit a search form, or if a user clicks "filter by name='blah'", when I enter the controller I get the following:
Domain
String name
String location
Controller
if(params.name && params.reference) {
// Find name/reference
} else if(params.name) {
// Find name
} else if(params.reference) {
// Find reference
} else {
// Find all
}
As you can understand, if there are more properties in the domain to search/filter, the longer the controller gets.
Any help. Please note, I do not want to use the 'searchable' plugin, as this is too complex for my needs.
I would embed these in a named query in the Domain class itself. For example:
Class Hotel {
String name
String city
String country
boolean isNice
static namedQueries = {
customSearch { p ->
if (p?.name) eq('name', p.name)
if (p?.city) eq('name', p.city)
if (p?.country) eq('name', p.country)
if (p?.isNice != null) eq('isNice', p.isNice)
}
}
}
Then later in a controller somewhere ...
def results = Hotel.customSearch(params)
Of course this is a very simple example, but you can expand on it using the same named query or even adding others and chaining them together.
I'm using play framework 1.2.7 to create a simple page to search some data on a database.
I already have one of the listing pages with CRUD module. The problem is that the search is a text field that searches in all text columns. I want to customize this.
The default is:
#{crud.search /}
I imagine I should be able to do something like:
#{crud.search }
... search fields...
#{/crud.search}
But I can't find any documentation about it.
How can I define the fields to search and how to use them?
What it worked for me was to overwrite the list method in the controller that extends from CRUD.
For example:
public static void list(int page, String search, String searchFields,
String orderBy, String order) {
ObjectType type = ObjectType.get(getControllerClass());
notFoundIfNull(type);
if (page < 1) {
page = 1;
}
List<YourObject> yourObjects;
List<Model> objects;
yourObjects = YourObject.yourSearch(search);
/* I also wanted to keep the standard search
so from here I also kept the standard code */
....
}
I'm doin a simple query linq to retrieve a label from an optionSet. Looks like the formatted value for the option set is missing. Someone knows why is not getting generated?
Best Regards
Sorry for the unclear post. I discovered the problem, and the reason of the missing key as formattedvalue.
The issue is with the way you retrieve the property. With this query:
var invoiceDetails = from d in xrmService.InvoiceSet
where d.InvoiceId.Value.Equals(invId)
select new
{
name = d.Name,
paymenttermscode = d.PaymentTermsCode
}
I was retrieving the correct int value for the option set, but what i needed was only the text. I changed the query this way:
var invoiceDetails = from d in xrmService.InvoiceSet
where d.InvoiceId.Value.Equals(invId)
select new
{
name = d.Name,
paymenttermscode = d.FormattedValues["paymenttermscode"]
}
In this case I had an error stating that the key was not present. After many attempts, i tried to pass both the key value and the option set text, and that attempt worked just fine.
var invoiceDetails = from d in xrmService.InvoiceSet
where d.InvoiceId.Value.Equals(invId)
select new
{
name = d.Name,
paymenttermscode = d.PaymentTermsCode,
paymenttermscodeValue = d.FormattedValues["paymenttermscode"]
}
My guess is that to retrieve the correct text associated to that option set, in that specific entity, you need to retrieve the int value too.
I hope this will be helpful.
Best Regards
You're question is rather confusing for a couple reasons. I'm going to assume that what you mean when you say you're trying to "retrieve a label from an OptionSet" is that you're attempting to get the Text Value of a particular OptionSetValue and you're not querying the OptionSetMetadata directly to retrieve the actual LocalizedLabels text value. I'm also assuming "formatted value for the option set is missing" is referring to the FormattedValues collection. If these assumptions are correct, I refer you to this: CRM 2011 - Retrieving FormattedValues from joined entity
The option set metadata has to be queried.
Here is an extension method that I wrote:
public static class OrganizationServiceHelper
{
public static string GetOptionSetLabel(this IOrganizationService service, string optionSetName, int optionSetValue)
{
RetrieveOptionSetRequest retrieve = new RetrieveOptionSetRequest
{
Name = optionSetName
};
try
{
RetrieveOptionSetResponse response = (RetrieveOptionSetResponse)service.Execute(retrieve);
OptionSetMetadata metaData = (OptionSetMetadata)response.OptionSetMetadata;
return metaData.Options
.Where(o => o.Value == optionSetValue)
.Select(o => o.Label.UserLocalizedLabel.Label)
.FirstOrDefault();
}
catch { }
return null;
}
}
RetrieveOptionSetRequest and RetrieveOptionSetResponse are on Microsoft.Xrm.Sdk.Messages.
Call it like this:
string label = service.GetOptionSetLabel("wim_continent", 102730000);
If you are going to be querying the same option set multiple times, I recommend that you write a method that returns the OptionSetMetadata instead of the label; then query the OptionSetMetadata locally. Calling the above extension method multiple times will result in the same query being executed over and over.
In a Model_Page class, extending the Kohana ORM class, I have this rules definition :
public function rules() {
return array(
'url' => array(
array('Model_Page::unique_url', array($this)),
),
);
}
To simplify here, I will just return false from this function, so it should never validate when I try to save/update a page :
public static function unique_url($page) {
return false;
}
This works as expected, if the value for url is not NULL or not an empty string.
But if I already have a page with an empty url, and that I try to add a new page with an empty url, the unique_url function is ignored, even when forcing a return false.
This could be a bug, but maybe I missed something...? In the Kohana docs, for the unique example, they use a username as an example, but the username also has a not_empty rule, which does not apply here.
Any help/suggestion appreciated!
I believe the rule is applied once you set the value, not when you're saving it.
I had a similar issue - the filter wasn't working if I didn't assign any value to the field. I've written my own save method:
public function save(Validation $validation = NULL)
{
if (!$this->loaded())
{
$this->ordering = 0;
}
return parent::save($validation);
}
this way the ordering would always be assigned for newly created objects and my filter would work.
And that's how I built another model. It's a company model that has a unique company name. Rules for the field are defined like this:
'name' => array(
array('not_empty'),
array('max_length', array(':value', 255)),
array(array($this, 'unique_name'))
)
And I have a method:
public function unique_name($value)
{
$exists = (bool) DB::select(array(DB::expr('COUNT(*)'), 'total_count'))
->from($this->_table_name)
->where('name', '=', $value)
->where($this->_primary_key, '!=', $this->pk())
->execute($this->_db)
->get('total_count');
return !$exists;
}
It basically checks if there are any other companies with the same name as the current one. Maybe this will give you the idea of what could be wrong with your solution.
I have a property in my index (using the Advanced Database Crawler) for an archive date.
I want to find all items where the date is null or in the future....Date range search will accomplish the second part, but what about the first?
You can't do a null search against Lucene. What I've done in the past is to test for emtpy fields and insert the word "EMPTY" in the index. Then when querying the index you need to add a test that checks for the presence (or absence) of that term. It feels kind of dirty doing it that way but that is the only solution I've been able to find or come up with in the 3 years I've been working with Sitecore and Lucene.
In the DateFieldCrawler class, we modified the following code:
public override string GetValue()
{
if (String.IsNullOrEmpty(_field.Value))
{
return DateTools.DateToString(DateTime.MinValue, DateTools.Resolution.DAY);
}
if (FieldTypeManager.GetField(_field) is DateField)
{
var dateField = new DateField(_field);
if(dateField.DateTime > DateTime.MinValue)
{
return DateTools.DateToString(dateField.DateTime, DateTools.Resolution.DAY);
}
}
return String.Empty;
}
By storing this value, we were able to perform the following queries to include null value dates:
DateRangeSearchParam.DateRange toFirstDate =
new DateRangeSearchParam.DateRange(EVENT_FIRST_DATE,
DateTime.MinValue, toDate.Value);
toFirstDate.InclusiveEnd = false;
eventDates.Add(toFirstDate);