Update: Dec 17 2009:

My 5$ bounty for anyone providing a solution to this issue.

Paypal payment,.

==============================================================================
can we send word to view's filter condition as a parameter?

i have a view, created along with a block and page view at www.mysite.com/myview

the view uses a condition 'filter' that filters and displays all those article that have the word "someword" in the title

it works fine and when i open www.mysite.com/myview the view lists all nodes with "myword" in their title.

NOW THe THING IS

i use the filter agagin and again. instead of creating a separate view for "myword2" and "myword3"

so i want to pass "myword" as an "argument" to the view and then use that "myword" in the condition

how can i do that?
will it work if i just edit my view and replace the "myword" in the filter condition with "%1" and call www.mysite.com/myview/myword ?

thanks in advance to any one who helps

Comments

saitanay’s picture

any help?

elkin_taharon’s picture

Hi, i think that something like this will do the job :


  $view = views_get_view('my_view');
  $view->exposed_input['my_filter']= 'the word or var with the word';
  
// the type of display for the view
  $result = $view->preview('default');
 
  print $result;

If the word is in the url you can get it with arg() or $_GET[' ']

saitanay’s picture

still waiting..

saitanay’s picture

any one can help?

a_lawry’s picture

Hi,

I think you should be using an argument condition not a filter condition.

Change your filter to an argument.

Andrew

saitanay’s picture

i dont find any argument filter in views filters,

do i have to add an argument first?

what type of arguments shud i add?

thansk for the help

saitanay’s picture

or should i add something to the argument handling code also code?

saitanay’s picture

help..

a_lawry’s picture

Add an argument instead of a filter.

A views argument acts as a variable filter. It is generally read from within the URL so the URL entered will be something like www.mysite.com/myview/titleword.

Have a look at the documentation on views arguments. You may need to use PHP code if the avaqilable argument options don't give you what you want.

saitanay’s picture

after i add an argument, how do i make the argument be checked in the title and display the results? i shud use a ilter rite?

saitanay’s picture

i am still searching for a solution to this..

mittalpatel’s picture

Hello there,
To give a solution to your problem, I created a view and used arguments. Please follow the steps below :
1. Create a new view
2. Add Page display
3. Give path to page "myview/%"
4. Select appropriate fields you want to show.
5. Click + of arguments (To add an argument)
6. Select Node : Title and add
7. Give some title
8. Select "Display empty text" (You'll have to give some value in Empty field)
9. Case in path : Lower case
10. Check : Transform spaces to dashes in URL
11. Update
11. Save the view

Now go to "www.yoursite.com/myview/test node" and you will see if you have any node named "Test Node".
Now the limitation I saw is that it will perform exact match and return only single node.
It will not display anything if you will simply give "www.yoursite.com/myview/node"

I am not pretty sure how to make it search part of the title. For example, if I give "/myview/test" then it should display all the nodes with the word test in title rather then single node with title Test.

Can anyone put some light on this? It will be enlightening me as well.

Thanks in advanced.

saitanay’s picture

thanks for the try,. anyone with a solution?

saitanay’s picture

can anyone suggest a solution for this for a prize say $5?

saitanay’s picture

any solution possible?

saitanay’s picture

bump

saitanay’s picture

My 5$ bounty for anyone providing a solution to this issue.

Paypal payment,.

saitanay’s picture

bump.,.

tpainton’s picture

This is a view that will display nodes with a keyword in the url if you go to node/% where % is the keyword you want to filter on. So if you go to www.mysite.com/node/test it will only list nodes with 'test' included in the title. If you need to change the url architecture to something like node/mine/cars/test, then you will need to modify the arg() function in the code.. See arg() in the handbook.

$view = new view;
$view->name = 'test';
$view->description = 'test';
$view->tag = '';
$view->view_php = '';
$view->base_table = 'node';
$view->is_cacheable = FALSE;
$view->api_version = 2;
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
$handler = $view->new_display('default', 'Defaults', 'default');
$handler->override_option('fields', array(
'title' => array(
'label' => 'Title',
'alter' => array(
'alter_text' => 0,
'text' => '',
'make_link' => 0,
'path' => '',
'link_class' => '',
'alt' => '',
'prefix' => '',
'suffix' => '',
'target' => '',
'help' => '',
'trim' => 0,
'max_length' => '',
'word_boundary' => 1,
'ellipsis' => 1,
'strip_tags' => 0,
'html' => 0,
),
'empty' => '',
'hide_empty' => 0,
'empty_zero' => 0,
'link_to_node' => 1,
'exclude' => 0,
'id' => 'title',
'table' => 'node',
'field' => 'title',
'relationship' => 'none',
),
));
$handler->override_option('arguments', array(
'title' => array(
'default_action' => 'default',
'style_plugin' => 'default_summary',
'style_options' => array(),
'wildcard' => 'all',
'wildcard_substitution' => 'All',
'title' => '',
'breadcrumb' => '',
'default_argument_type' => 'php',
'default_argument' => '',
'validate_type' => 'none',
'validate_fail' => 'not found',
'glossary' => 0,
'limit' => '0',
'case' => 'none',
'path_case' => 'none',
'transform_dash' => 0,
'id' => 'title',
'table' => 'node',
'field' => 'title',
'validate_user_argument_type' => 'uid',
'validate_user_roles' => array(
'2' => 0,
'3' => 0,
'4' => 0,
),
'relationship' => 'none',
'default_options_div_prefix' => '',
'default_argument_user' => 0,
'default_argument_fixed' => 'test',
'default_argument_php' => '$keyword = arg(1);
return $keyword;
',
'validate_argument_node_type' => array(
'product' => 0,
'seminar' => 0,
'ucnc_document' => 0,
'anytime_seminar' => 0,
'credit_letter' => 0,
'infoblock' => 0,
'page' => 0,
'question' => 0,
'story' => 0,
),
'validate_argument_node_access' => 0,
'validate_argument_nid_type' => 'nid',
'validate_argument_vocabulary' => array(
'2' => 0,
'1' => 0,
),
'validate_argument_type' => 'tid',
'validate_argument_transform' => 0,
'validate_user_restrict_roles' => 0,
'validate_argument_php' => '',
),
));
$handler->override_option('access', array(
'type' => 'none',
));
$handler->override_option('cache', array(
'type' => 'none',
));
$handler = $view->new_display('page', 'Page', 'page_1');
$handler->override_option('path', 'node/%');
$handler->override_option('menu', array(
'type' => 'none',
'title' => '',
'description' => '',
'weight' => 0,
'name' => 'navigation',
));
$handler->override_option('tab_options', array(
'type' => 'none',
'title' => '',
'description' => '',
'weight' => 0,
));

Just copy the above code and import it into a view. Keep the $5.

tpainton’s picture

I forgot the substr aspect. The above will display node with exactly title 'test'.. Like I said, it's early. I'll fix it.. give me a little time. Need coffee.

I would do this by using a node:nid as the argument.
First take the keyword from the url using arg()

Do a database query and return all nids that have $keyword in the title.

Then return the nids as an array to include.

tpainton’s picture

almost there, but one of my biggest problems is matching, wildcards, preg etc.

If I can get your sql query fixed, then I can export your view for you. I am stuck here..and I could figure it out, but I am an hour late for work and it's more than $5/hour :)

This only returns one node with keyword "test" in the title. My matching/wildcard is wrong. If someone can help here, then I can do the rest. Later, I really need to work on my project.

<?php
$keyword = 'test';
$result = db_query("SELECT n.nid FROM {node} n WHERE n.title LIKE '$keyword'");
?>

For my own good, if someone has some good tutorials on sql LIKE statement, that would be great, the stripping of the %% and all that just confuses me. Sorry I could not quickly complete it for you.

ah and also, I forgot you have to take the final array and implode it to a string with glue of '+' for views... array wont work for a return value. I can do that too later..

tpainton’s picture

I actually have some interest in this thread now out of pure curiosity. The problem seems to be that nodes with titles like 'The big Test', and Test one, are bing missed. Of course the case is an issue, but my big question is, will LIKE 'test' catch 'test one'?

m_z’s picture

No, it won't. You have to put a % after your keyword. (Often you have to escape the "%" by another "%".)
A very flexible where condition would be "WHERE LOWER('my_fieldname_goes_here') LIKE LOWER('%%%s%%')" and putting your keyword instead of %s.

ussher’s picture

here is the solution: (total credit to Deciphered and LittleViking on IRC)

What you want to do is not use the filters, but instead use arguments. The problem with the arguments is that they will output with
AND (sometable.somecolumn = '%s') but what you need is
AND (sometable.somecolumn LIKE '%%s%') //the %s will be replaced by your 'myview' and the % on either side is a wildcard search

so now create a module that has this code in it

function MODULENAME_views_query_alter(&$view, &$query) {
    if($view->name == 'aiueo'){
     $query->where[0]['clauses'][1] = " node_data_field_furigana.field_furigana_value LIKE '%s%' ";
    }
}

for me my module name was 'aiueo' but yours will be whatever you choose.

Start out by putting

function MODULENAME_views_query_alter(&$view, &$query) {
    if($view->name == 'aiueo'){
       print_r($query);
    }
}

and open your view in a browser. when you look at the source code, locate the AND query row. its that row that your going to want to change. match up the [0]'s and 'clauses' so that that row is selected and change it from there.

mmrtnt’s picture

Okay. This is the way to go. ussher nailed it.

I had put off learning to make a module and that was a mistake. It's drop-dead simple.

This solution is the bomb. Ignore all of my blathering in the succeeding posts.

I followed the module building tutorial for Drupal 6 here and below is the contents of the two files necessary to implement the fix.

view_query.info

<?php
name = View Query
description = Customize View queries
core = 6.x
dependencies[] = views 
version = "6.x-1.0"
?>

view_query.module

<?php
/**
* Display help and module information
* @param path which path of the site we're displaying help
* @param arg array that holds the current path as would be returned from arg() function
* @return help text for the path
*/
function view_query_help($path, $arg) {
  $output = '';  //declare your output variable
  switch ($path) {
    case "admin/help#view_query":
      $output = '<p>'.  t("Supplies modified queries to Views") .'</p>';
      break;
  }
  return $output;
} // function view_query_help

/**
* Valid permissions for this module
* @return array An array of valid permissions for the view_query module
*/
function view_query_perm() {
 return array('access view_query', 'create view_query', 'administer view_query');
} // function view_query_perm()

/* DEBUG */
/*
function view_query_views_query_alter(&$view, &$query) {
    if($view->name == 'title_search'){
       print_r($query);
    }
}
*/

function view_query_views_query_alter(&$view, &$query) {
    if($view->name == 'title_search'){
     $query->where[0]['clauses'][0] = "node.status = 1";
     $query->where[0]['clauses'][2] = "node.type in ('comic', 'blog')";
     $query->where[0]['clauses'][1] = "LOWER(node.title) LIKE LOWER('%%%s%')";
    }
}
?>
mmrtnt’s picture

(I know the OP is pretty old, but I did get this to work with a minimum of customization)

[Edit - 02/01/2013]

Never mind. This doesn't work either... feh

I had a problem with this solution in that someone could monkey with the url and get all published items.

In other words, the normal path to this, as constructed by the HTML in my search form was,

myhost.com/titlesearch?title=<partialstring>

If someone modified the url and left off everything following "titlesearch", they would get all published items on my site, restricted to 10-at-a-time by the view.

I found a VERY simple way to get around this.

First, remove the "Argument" field in the View - it's not needed any more.

Then, in the exposed Field block under "Filters", supply a default value for the "title".

I set mine to "clown"

This way, if someone uses a mangled URL, they get a list of all of my posts with the word "clown" in the title.

Pretty sweet!

[/Edit]

I modified a plain node list View and added an Argument, then set "Action to take if argument is not present:" to "Display all values"

Added a Filter to filter by partial keyword by selecting "Node: Title", "Operator: Contains", leaving the "Value" blank , [Edit - set the "Value" to "clown", set the "Filter identifier" to "title"] and set the Filter to exposed.

I set the Page:Path to the View as "titlesearch".

So, going to http://www.myhost.com/titlesearch?title=partialstring results in all nodes being returned and then filtered by %partialstring%.

WHERE (node.promote <> 0) AND (node.status = 1) AND ((node.title) LIKE ('%partialstring%'))

I hid the exposed parameter "Apply" widget with CSS in my theme:

#views-exposed-form-title-search-page {

    visibility:hidden;

 }

(I don't care if people want to monkey with the query string, I just didn't want another form showing up in the results) [Edit - Guess I do care!]

I then builit a tiny search block and added it to the sidebar:

<?php

      $post_title = $_POST[ 'title' ];
      $post_title = substr( $post_title, 0, 127 );
      if( strlen( $post_title ) > 0 ) 
      {   
         ob_start(); // ensures anything dumped out will be caught
         $url = "/titlesearch&title=$post_title";
         while (ob_get_status()) 
            { ob_end_clean(); }
         header( "Location: $url" );
         return;
         }
      }  

print "
<b>Look for droids</b><br>
<form name='TitleSearch' method='post' action=''>
<input type='textbox' name='title' value='' id='titleval' size=10>
<input type='submit' value='Go' >
</form>";
?>

I used a bit of PHP to handle the "Empty text" field:

<?php

   $qstr = $_SERVER[ 'QUERY_STRING' ];

   $title = preg_replace( '/.*title=(.*)/', '$1', $qstr );

   $title =  htmlspecialchars_decode ( urldecode($title) );

   print "<h2>No droids by the name of \"$title\" found</h2><br>";

?>