How I can get search form value in Drupal 7 - content-management-system

I've tried to implement a new module that catches the keys written in the default search form and displays other results than the default search result page. With these other results I will make an external query, which is put in a special block.
Any idea on how to do this?
I've tried to use a custom module making a "hook_alter_form " with no success.
In other words :
I have a function like this:
function my_function_name_form_alter(&$form,&$form_state,$form_id){
switch($form_id){
case 'search-block-form':
//Here i want to catch the text that i wrote in the search box
break;
}
}
Thank u!

You can alter the search query in order to show other results:
function mymodule_query_alter(QueryAlterableInterface $query){
$is_search = FALSE;
foreach ($query->getTables() as $table) {
if ($table['table'] == 'search_index') {
$is_search = TRUE;
}
}
if ($is_search) {
global $language;
$db_or = db_or();
$db_or->condition('n.type', 'event', '=');
$db_or->condition('n.type', 'real_sitio', '=');
$query->condition($db_or);
$query->condition('n.language' , $language->language, '=');
}
}
This is a bit performance killer so there's a patch for drupal at http://drupal.org/node/1435834 that adds a hook for making the alter directly in the search query:
So finally it would look like:
function mymodule_search_query_search_node_alter(&$query) {
$query->condition('n.type', 'article', '=');
}

Related

Assign mongo selectors in find() dynamically

I have the following problem: I have an interface where a user can filter stuff out based on several inputs. There are 5 inputs. When an input is filled out I want to add it's value to the helper returning the collection. The problem I can't solve is how to do this dynamically. Sometimes the user might fill out one input, sometimes three, sometimes all 5. Within the find() method you can only write down meteor's syntax:
mongoSelector: fieldName,
This means you can only hardcode stuff within find(). But just adding all 5 selectors doesn't work, since if one of the values is empty, the find searches for an empty string instead of nothing.
I thought of doing conditionals or variables but both don't work within find because of the required syntax. What could I do to solve this?
var visitorName;
var visitorAge;
Session.set('visitorName', visitorName);
Session.set('visitorAge', visitorAgee);
Template.web.helpers({
visitors: function() {
return Visitors.find({ visitor_name: Session.get('visitorName'), visitor_age: Session.get('visitorAge') });
}
});
Template.web.events({
"change #visitor_name": function (event, template) {
visitorName = $(event.currentTarget).val();
}
});
Template.web.events({
"click #reset_filter": function (event, template) {
return Visitors.find();
$(input).val('');
}
});
http://jsfiddle.net/m5qxoh3b/
This one works
Template.web.helpers({
visitors: function() {
var query = {};
var visitorName = (Session.get('visitorName') || "").trim();
if (visitorName) {
query["visitor_name"] = visitorName;
}
//same thing for other fields
return Visitors.find(query);
}
});
Template.web.events({
"change #visitor_name": function (event, template) {
var visitorName = $(event.currentTarget).val();
Session.set('visitorName', visitorName);
}
});

Codemirror adding keywords on the fly for syntax highlight

I am currently adding a new language mode in CodeMirror for my current project. This is a proprietary language in which user can create a new keyword. Basically I am trying to update existing keyword list at the runtime and my syntax highlighter can pick this new keyword.
var mode = editor.doc.modeOption;
if(mode === "dmsrl") mode = "text/dmsrl";
var keyWords = CodeMirror.resolveMode(mode).keywords;
keyWords[x]=true;
I am currently trying to add new keyword like above, but somehow the list is not getting updated and new keyword is unavailable in my tokebase() method.
Any help would be appreciated.
You can try to redefine hintOptions object, that pass to Codemirror's init function and than building hints in your specific hint addon with this data. Just try this
cm.setOption("hintOptions", { "keywords" : ["k1", "k2"] });
Look at first in sql-hint for example (link):
cm.setOption("hintOptions", { "tables" : ["k1", "k2"] });
For sql-mode this is not heavy operation
I wanted to reach the same goal as yours but with some more degree of freedom, consisting in inputting a container, which I can re-define along the run.
1) Put the following code into a file custom.mode.js, to be loaded from your web page
var _glob_keywords = [ [ "key1", "keyword1" ],
[ "key2", "keyword2" ]
] ;
var cm_custom_check_stream_fn = function( stream )
{
for( var _i = 0 ; _i < _glob_keywords.length ; _i++ )
{
if ( stream.match( _glob_keywords[_i][0] ) ) return _glob_keywords[_i][1] ;
}
return "" ;
}
CodeMirror.defineMode("custom.mode", function()
{
return {
token: function(stream,state)
{
var _ret = cm_custom_check_stream_fn( stream ) ;
if ( _ret.length > 0 ) return _ret ;
else { stream.next(); return null; }
}
};
});
This code will be automatically embedded into the Codemirror object to dynamically handle the input in the textbox.
Example: if "key1" is found, then "keyword1" is returned.
We assume that "keyword1", "keyword2" refer to entries inside a custom css definitions file, as explained in the codemirror documentation, that is,
.cm-keyword1 { color:#8BA8C4; }
.cm-keyword2 { color:lime; }
Hope it helps!

Populate select in jqgrid filter toolbar

I've tried to populate a dropdownlist with values from my database. I've got the following code in my .js file:
function getDropdowndata() {
var sHTML;
var filter;
var url = "dropdown.json";
jQuery.getJSON(url, function (dddata) {
if (dddata.rows.length > 0) {
sHTML = "";
for (x = 0; x < dddata.rows.length; x++) {
sHTML += (dddata.rows[x].Type + ":" + dddata.rows[x].Type + ";");
}
filter = sHTML.substring(0, sHTML.length - 1);
}
});
return filter;
}
And in my Jqgrid list I've got the following:
editoptions: { value: ":All;" + getDropdowndata() }
The problem I've got with this code is that it seems that the function is being executed too early and because of that the dropdownlist contains nothing.
The reason for my assumption is that if I put an alert inside of the javascript function before the return, the dropdownlist is filled with the values and everything seems to work.
Any suggestions?
Instead of getting the data with a custom function using JSON, you might want to try using the built-in functionality for dynamic select fields (see documentation: select edittype ). All you do is specify a url where the code for the select element is generated.
colModel:[
{name:'colName',
editable:true,
edittype:'select',
formatter:'select',
editoptions:{dataUrl:'/path/to/generated/html/select'}
]
Then you just need to make sure that /path/to/generated/html/select returns all the right HTML code for a select element.

StandardAnalyzer seems to not being involved when indexing data, NHibernate.Search

Im building a search function for an application with Lucene.NET and NHibernate.Search. To index the existing data I am using this method:
public void SynchronizeIndexForAllUsers()
{
var fullTextSession = Search.CreateFullTextSession(m_session);
var users = GetAll();
foreach (var user in users)
{
if (!user.IsDeleted)
{
fullTextSession.Index(user);
}
}
}
Where I have marked the fields I want to index with following attribute:
[Field(Index.Tokenized, Store = Store.Yes, Analyzer = typeof(StandardAnalyzer))]
public virtual string FirstName
{
get { return m_firstName; }
set { m_firstName = value; }
}
But when I then inspect the indicies in Luke the fields still have uppercases, commas etc. which should have been removed by the StandardAnalyzer.
Does anyone have know what I am doing wrong?
I had similiar problem to yours, but I've been trying to use WhitespaceAnalyzer. Setting it in Field attribute didn't work for me either.
I've ended up setting it globally. I am using FluentNHibernate for configuration and it looks like that:
this._sessionFactory =
Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2005
.ConnectionString(cs => cs
// cut
.ShowSql()
)
.Mappings(m => m.FluentMappings
// cut
)
.ExposeConfiguration(cfg =>
{
// important part: lucene.net and nhibernate.search
cfg.SetProperty("hibernate.search.default.directory_provider", typeof(NHibernate.Search.Store.FSDirectoryProvider).AssemblyQualifiedName);
cfg.SetProperty("hibernate.search.default.indexBase", #"~\Lucene");
cfg.SetProperty("hibernate.search.indexing_strategy", "event");
cfg.SetProperty(NHibernate.Search.Environment.AnalyzerClass, typeof(WhitespaceAnalyzer).AssemblyQualifiedName);
cfg.SetListener(NHibernate.Event.ListenerType.PostUpdate, new FullTextIndexEventListener());
cfg.SetListener(NHibernate.Event.ListenerType.PostInsert, new FullTextIndexEventListener());
cfg.SetListener(NHibernate.Event.ListenerType.PostDelete, new FullTextIndexCollectionEventListener());
})
.BuildSessionFactory();
Take a look at NHibernate.Search.Environment.AnalyzerClass. Funny thing is that it won't work for generic fulltext queries (i think that Lucene will use StandardAnalyzer), but that's another story :).
Hope this helps.

Zend Dojo FilteringSelect from joined tables How can this be done with Doctrine

I have a number of FilteringSelect elements within my Zend Framework application that are working fine but they are based on simple queries.
I now need to create a FilteringSelect that will allow me to select the id of one table while displaying the text of field in a related table, i.e. I have two tables groomservices and groomprocedures which are related (i.e. groomprocedures.groomProceduresID has many groomservices.procedure).
The form I'm trying to create is for an appointments table which has many groomservices.groomServicesID values. I want the user to be able to see the name of the procedure while saving the value of the groomservices.groomServicesID using the FilteringSelect.
So far I've not been able to do this in that my FilteringSelect displays nothing, I'm sure this can be done just that the fault is with my inexperience with Zend,Doctrine and Dojo
I'm not sure if my problem is with my autocomplete action(including the query) or with the FilteringSelect element.
Can anyone spot where I've gone wrong in the code sections below, I need to get this working.
My autocomplete action within my controller
public function gserviceAction()
{
// disable layout and view rendering
$this->_helper->layout->disableLayout();
$this->getHelper('viewRenderer')->setNoRender(true);
// get a list of all grooming services IDs and related procedures
$qry= Doctrine_Query::create()
->select('g.groomServicesID,p.groomProcedure')
->from('PetManager_Model_Groomservices g')
->leftJoin('g.PetManager_Model_Groomprocedures p');
$result=$qry->fetchArray();
//generate and return JSON string
$data = new Zend_Dojo_Data('g.groomServicesID',$result);
echo $data->toJson();
}
My FilteringSelect element code
// Create a autocomplete select input for the service
$gservice = new Zend_Dojo_Form_Element_FilteringSelect('gapmtService');
$gservice->setLabel('Proceedure');
$gservice->setOptions(array(
'autocomplete' => true,
'storeID' => 'gserviceStore',
'storeType' => 'dojo.data.ItemFileReadStore',
'storeParams' => array('url' => "/groomappointments/appointment/gservice"),
'dijitParams' => array('searchAttr' => 'groomProcedure')))
->setRequired(true)
->addValidator('NotEmpty', true)
->addFilter('HTMLEntities')
->addFilter('StringToLower')
->addFilter('StringTrim');
Many thanks in advance,
Graham
P.S. orgot to mention I tried the following query in mysql and I gave me what I'm looking for I believe the Doctine query evaluates to the same.
select groomservices.groomservicesID,groomprocedures.groomprocedure from groomprocedures left join groomservices on groomprocedures.groomproceduresID =groomservices.groomProcedure
But I'm not sure if I formatted the query correctly in Doctrine.
EDIT in relation to the flammon's comments
Ok I've set the code to the following but I'm still not getting anything to display.
public function gserviceAction()
{
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContexts(array(
'gservice' => 'json'
));
// get a list of all grooming services IDs and related procedures
$qry= Doctrine_Query::create()
->select('g.groomServicesID AS id,p.groomprocedure AS name')
->from('PetManager_Model_Groomservices g')
->leftJoin('g.PetManager_Model_Groomprocedures p');
$this->view->model = (object) array();
$this->view->model->identifier = 'id';
$this->view->model->label = 'name';
$this->view->model->items = array();
$tableRows = $this->dbTable->fetchAll($qry);
foreach ($tableRows as $row) {
$this->view->model->items[] = $row->toArray();
}
}
I'm sure the fault lies with me.
It looks like there's a problem with the data that you're putting in the ItemFileReadStore.
Here are a few pointers.
Consider extending Zend_Rest_Controller for your services. It'll be easier to manage your contexts and your views. You'll be able to do something like this:
public function init()
{
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContexts(array(
'gservice' => 'json'
));
}
And it will eliminate the need for the following in each of you service actions.
// disable layout and view rendering
$this->_helper->layout->disableLayout();
$this->getHelper('viewRenderer')->setNoRender(true);
You'll need to either pass the format parameter or use the following plugin to help with the context switch. Passing the format parameter is simpler but it pollutes the url with ?format=json. Here's the Zend documentation on AjaxContext.
Here's a plugin that you can use if you don't want to pass the format parameter.
class Application_Plugin_AcceptHandler extends Zend_Controller_Plugin_Abstract
{
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{
if (!$request instanceof Zend_Controller_Request_Http) {
return;
}
$header = $request->getHeader('Accept');
switch (true) {
case (strstr($header, 'application/json')):
Zend_Registry::get('logger')->log('Setting format to json', Zend_Log::INFO);
$request->setParam('format', 'json');
break;
case (strstr($header, 'application/xml')
&& (!strstr($header, 'html'))):
Zend_Registry::get('logger')->log('Setting format to xml', Zend_Log::INFO);
$request->setParam('format', 'xml');
break;
default:
Zend_Registry::get('logger')->log('Setting format to html', Zend_Log::INFO);
break;
}
}
}
In your controller, instead of echoing the data, create view variables that dojo expects. See this document for the format.
$this->view->model = (object) array();
$this->view->model->identifier = 'id';
$this->view->model->label = 'name';
$this->view->model->items = array();
In your controller, fetch your table rows:
$tableRows = $this->dbTable->fetchAll($select);
or, if you've put model code in a function, it might look more like:
$tableRows = $this->dbTable->fetchGroomProcedures();
Put your row data in the model->items[] array:
foreach ($tableRows as $row) {
$this->view->model->items[] = $row->toArray();
}
Create a view, view/scripts/appointment/gservice.json.phtml and in it put
Zend_Json::encode($this->model)
Use Firebug to see what is returned from your service.