[gen] Highlight keywords in query results.

This commit is contained in:
Gaetan Delannay 2014-12-30 11:23:03 +01:00
parent 92d1276ffb
commit cf2cbc52d6
4 changed files with 35 additions and 10 deletions

View file

@ -446,8 +446,8 @@ class String(Field):
elif format == String.TEXT: self.maxChars = 9999 elif format == String.TEXT: self.maxChars = 9999
elif format == String.XHTML: self.maxChars = 99999 elif format == String.XHTML: self.maxChars = 99999
elif format == String.PASSWORD: self.maxChars = 20 elif format == String.PASSWORD: self.maxChars = 20
self.filterable = self.indexed and (self.format == String.LINE) and \ self.filterable = self.indexed and not self.isSelect and \
not self.isSelect (self.format in (String.LINE, String.TEXT))
self.swidth = self.swidth or self.width self.swidth = self.swidth or self.width
self.sheight = self.sheight or self.height self.sheight = self.sheight or self.height
self.checkParameters() self.checkParameters()

View file

@ -923,6 +923,24 @@ class BaseMixin:
return return
return res return res
def highlight(self, text):
'''This method highlights parts of p_value if we are in the context of
a query whose keywords must be highlighted.'''
# Must we highlight something?
criteria = self.REQUEST.SESSION.get('searchCriteria')
if not criteria or ('SearchableText' not in criteria): return text
# Highlight every variant of every keyword
for word in criteria['SearchableText'].strip().split():
sWord = word.strip(' *').lower()
for variant in (sWord, sWord.capitalize(), sWord.upper()):
text = text.replace(variant, '***+%s-***' % variant)
# If I replace immediately with the opening and ending "span"
# tag (see below), I will have problems if the next keyword is
# included in the tag, ie "la" (in 'class', or "spa" (in
# 'span').
text = text.replace('***+', '<span class="highlight">')
return text.replace('-***', '</span>')
def getSupTitle(self, navInfo=''): def getSupTitle(self, navInfo=''):
'''Gets the html code (icons,...) that can be shown besides the title '''Gets the html code (icons,...) that can be shown besides the title
of an object.''' of an object.'''
@ -951,7 +969,7 @@ class BaseMixin:
return '' return ''
def getListTitle(self, mode='link', nav='', target=None, page='main', def getListTitle(self, mode='link', nav='', target=None, page='main',
inPopup=False, selectJs=None): inPopup=False, selectJs=None, highlight=False):
'''Gets the title as it must appear in lists of objects (ie in lists of '''Gets the title as it must appear in lists of objects (ie in lists of
tied objects in a Ref, in query results...). tied objects in a Ref, in query results...).
@ -970,10 +988,15 @@ class BaseMixin:
The last p_mode is "text". In this case, we simply show the object The last p_mode is "text". In this case, we simply show the object
title but with no tied action (link, select). title but with no tied action (link, select).
If p_highlight is True, keywords will be highlighted if we are in the
context of a query with keywords.
''' '''
# Compute common parts # Compute common parts
cssClass = self.getCssFor('title') cssClass = self.getCssFor('title')
# Get the title, with highlighted parts when relevant
title = self.getShownValue('title') title = self.getShownValue('title')
if highlight: title = self.highlight(title)
if mode == 'link': if mode == 'link':
inPopup = inPopup or (target.target != '_self') inPopup = inPopup or (target.target != '_self')
url = self.getUrl(page=page, nav=nav, inPopup=inPopup) url = self.getUrl(page=page, nav=nav, inPopup=inPopup)

View file

@ -177,3 +177,4 @@ td.search { padding-top: 8px }
font-weight: bold} font-weight: bold}
.language {color: grey; font-size: 7pt; border: grey 1px solid; padding: 2px; .language {color: grey; font-size: 7pt; border: grey 1px solid; padding: 2px;
margin: 0 2px 0 4px; font-family: monospace } margin: 0 2px 0 4px; font-family: monospace }
.highlight { background-color: yellow }

View file

@ -161,10 +161,10 @@ class ToolWrapper(AbstractWrapper):
zobjects=ztool.executeQuery(className, search=search, \ zobjects=ztool.executeQuery(className, search=search, \
maxResults=10).objects"> maxResults=10).objects">
<p if="not zobjects" class="lsNoResult">:_('query_no_result')</p> <p if="not zobjects" class="lsNoResult">:_('query_no_result')</p>
<div for="ztied in zobjects" style="padding: 3px 5px"> <div for="zobj in zobjects" style="padding: 3px 5px">
<a href=":ztied.absolute_url()" <a href=":zobj.absolute_url()"
var="content=ztool.truncateValue(ztied.Title(), width=80)" var="content=ztool.truncateValue(zobj.Title(), width=80)"
title=":ztied.Title()">:content</a> title=":zobj.Title()">:content</a>
</div> </div>
<!-- Go to the page showing all results --> <!-- Go to the page showing all results -->
<div if="zobjects" align=":dright" style="padding: 3px"> <div if="zobjects" align=":dright" style="padding: 3px">
@ -359,9 +359,10 @@ class ToolWrapper(AbstractWrapper):
q(rootHookId), q(uiSearch.initiator.url))"> q(rootHookId), q(uiSearch.initiator.url))">
<x var="sup=zobj.getSupTitle(navInfo)" if="sup">::sup</x> <x var="sup=zobj.getSupTitle(navInfo)" if="sup">::sup</x>
<x>::zobj.getListTitle(mode=titleMode, nav=navInfo, target=target, \ <x>::zobj.getListTitle(mode=titleMode, nav=navInfo, target=target, \
page=pageName, inPopup=inPopup, selectJs=selectJs)</x> page=pageName, inPopup=inPopup, selectJs=selectJs, highlight=True)</x>
<span style=":showSubTitles and 'display:inline' or 'display:none'" <span style=":showSubTitles and 'display:inline' or 'display:none'"
name="subTitle" var="sub=zobj.getSubTitle()" if="sub">::sub</span> name="subTitle" var="sub=zobj.getSubTitle()"
if="sub">::zobj.highlight(sub)</span>
<!-- Actions --> <!-- Actions -->
<table class="noStyle" if="not inPopup and zobj.mayAct()"> <table class="noStyle" if="not inPopup and zobj.mayAct()">
@ -421,7 +422,7 @@ class ToolWrapper(AbstractWrapper):
filterable=field.filterable" filterable=field.filterable"
width=":column.width" align=":column.align"> width=":column.width" align=":column.align">
<x>::ztool.truncateText(_(field.labelId))</x> <x>::ztool.truncateText(_(field.labelId))</x>
<x if="totalNumber &gt; 1">:tool.pxSortAndFilter</x> <x if="(totalNumber &gt; 1) or filterValue">:tool.pxSortAndFilter</x>
<x>:tool.pxShowDetails</x> <x>:tool.pxShowDetails</x>
</th> </th>
</tr> </tr>