[Checkins] SVN: jquery.livesearch/ Implemented JQuery based live
search
Roger Ineichen
roger at projekt01.ch
Fri May 25 02:11:38 EDT 2007
Log message for revision 75953:
Implemented JQuery based live search
Changed:
A jquery.livesearch/branches/
A jquery.livesearch/tags/
A jquery.livesearch/trunk/
A jquery.livesearch/trunk/src/
A jquery.livesearch/trunk/src/jquery/
A jquery.livesearch/trunk/src/jquery/livesearch/
A jquery.livesearch/trunk/src/jquery/livesearch/SETUP.cfg
A jquery.livesearch/trunk/src/jquery/livesearch/__init__.py
A jquery.livesearch/trunk/src/jquery/livesearch/browser.py
A jquery.livesearch/trunk/src/jquery/livesearch/configure.zcml
A jquery.livesearch/trunk/src/jquery/livesearch/interfaces.py
A jquery.livesearch/trunk/src/jquery/livesearch/jquery.livesearch-configure.zcml
A jquery.livesearch/trunk/src/jquery/livesearch/jquery.livesearch.css
A jquery.livesearch/trunk/src/jquery/livesearch/jquery.livesearch.js
A jquery.livesearch/trunk/src/jquery/livesearch/json.pt
A jquery.livesearch/trunk/src/jquery/livesearch/json.py
A jquery.livesearch/trunk/src/jquery/livesearch/json.zcml.sample
A jquery.livesearch/trunk/src/jquery/livesearch/result.py
A jquery.livesearch/trunk/src/jquery/livesearch/template.pt
-=-
Added: jquery.livesearch/trunk/src/jquery/livesearch/SETUP.cfg
===================================================================
--- jquery.livesearch/trunk/src/jquery/livesearch/SETUP.cfg (rev 0)
+++ jquery.livesearch/trunk/src/jquery/livesearch/SETUP.cfg 2007-05-25 06:11:38 UTC (rev 75953)
@@ -0,0 +1,3 @@
+<data-files zopeskel/etc/package-includes>
+ jquery.livesearch-*.zcml
+</data-files>
Added: jquery.livesearch/trunk/src/jquery/livesearch/__init__.py
===================================================================
--- jquery.livesearch/trunk/src/jquery/livesearch/__init__.py (rev 0)
+++ jquery.livesearch/trunk/src/jquery/livesearch/__init__.py 2007-05-25 06:11:38 UTC (rev 75953)
@@ -0,0 +1,16 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id: layer.py 197 2007-04-13 05:03:32Z rineichen $
+"""
Added: jquery.livesearch/trunk/src/jquery/livesearch/browser.py
===================================================================
--- jquery.livesearch/trunk/src/jquery/livesearch/browser.py (rev 0)
+++ jquery.livesearch/trunk/src/jquery/livesearch/browser.py 2007-05-25 06:11:38 UTC (rev 75953)
@@ -0,0 +1,23 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id: layer.py 197 2007-04-13 05:03:32Z rineichen $
+"""
+
+from zope.viewlet import viewlet
+
+
+LiveSearchJavaScriptViewlet = viewlet.JavaScriptViewlet('jquery.livesearch.js')
+
+LiveSearchCSSViewlet = viewlet.CSSViewlet('jquery.livesearch.css')
Added: jquery.livesearch/trunk/src/jquery/livesearch/configure.zcml
===================================================================
--- jquery.livesearch/trunk/src/jquery/livesearch/configure.zcml (rev 0)
+++ jquery.livesearch/trunk/src/jquery/livesearch/configure.zcml 2007-05-25 06:11:38 UTC (rev 75953)
@@ -0,0 +1,17 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:z3c="http://namespaces.zope.org/z3c"
+ i18n_domain="jquery">
+
+ <adapter
+ for="zope.interface.Interface"
+ factory="jquery.livesearch.result.LiveSearchResultItem"
+ />
+
+ <!-- page template for Live Search result -->
+ <z3c:template
+ template="json.pt"
+ for="jquery.livesearch.interfaces.IJSONLiveSearch"
+ />
+
+</configure>
Added: jquery.livesearch/trunk/src/jquery/livesearch/interfaces.py
===================================================================
--- jquery.livesearch/trunk/src/jquery/livesearch/interfaces.py (rev 0)
+++ jquery.livesearch/trunk/src/jquery/livesearch/interfaces.py 2007-05-25 06:11:38 UTC (rev 75953)
@@ -0,0 +1,47 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id: layer.py 197 2007-04-13 05:03:32Z rineichen $
+"""
+__docformat__ = "reStructuredText"
+
+import zope.interface
+
+
+class ILiveSearch(zope.interface.Interface):
+ """Live search interface."""
+
+ def getResults():
+ """Returns the catalog search result."""
+
+
+class IJSONLiveSearch(ILiveSearch):
+ """JSON live search interface."""
+
+ def getLiveSearchResult(searchString, searchId):
+ """Return a list of live search items."""
+
+
+class ILiveSearchResultItem(zope.interface.Interface):
+ """Live search result item is responsible for the presentation."""
+
+ def getURL(request):
+ """Returns the url used for rendering the link."""
+
+ def getText():
+ """Returns the test used for rendering the link text."""
+
+ def getScore(score):
+ """Returns the formatted score form the given catalog score."""
+
Added: jquery.livesearch/trunk/src/jquery/livesearch/jquery.livesearch-configure.zcml
===================================================================
--- jquery.livesearch/trunk/src/jquery/livesearch/jquery.livesearch-configure.zcml (rev 0)
+++ jquery.livesearch/trunk/src/jquery/livesearch/jquery.livesearch-configure.zcml 2007-05-25 06:11:38 UTC (rev 75953)
@@ -0,0 +1 @@
+<include package="jquery.livesearch" />
Added: jquery.livesearch/trunk/src/jquery/livesearch/jquery.livesearch.css
===================================================================
--- jquery.livesearch/trunk/src/jquery/livesearch/jquery.livesearch.css (rev 0)
+++ jquery.livesearch/trunk/src/jquery/livesearch/jquery.livesearch.css 2007-05-25 06:11:38 UTC (rev 75953)
@@ -0,0 +1,53 @@
+#liveSearch {
+ margin : 0;
+ padding : 0;
+}
+
+#liveSearchInput {
+ width: 200px;
+ vertical-align : middle;
+ border: #A7A78B solid 1px;
+}
+
+#liveSearchSubmit {
+ vertical-align : middle;
+}
+
+#liveSearchResult {
+ position: relative;
+ width: 200px;
+ border: #A7A78B solid 1px;
+ margin-top: 5px;
+}
+
+#liveSearchResult a {
+ color: #666;
+}
+
+#liveSearchResult .even {
+ background-color: #F3F3EE;
+ padding: 2px;
+}
+
+#liveSearchResult .odd {
+ background-color: #E4E4DA;
+ padding: 2px;
+}
+
+#liveSearchResult .left {
+ width: 140px;
+ text-align: left;
+ padding : 0;
+}
+
+#liveSearchResult .right {
+ float: right;
+ padding : 0;
+}
+
+div.hideLiveSearchResult {
+ height: 18px;
+ text-align: right;
+ background-color: #F3F3EE;
+ padding: 2px;
+}
Added: jquery.livesearch/trunk/src/jquery/livesearch/jquery.livesearch.js
===================================================================
--- jquery.livesearch/trunk/src/jquery/livesearch/jquery.livesearch.js (rev 0)
+++ jquery.livesearch/trunk/src/jquery/livesearch/jquery.livesearch.js 2007-05-25 06:11:38 UTC (rev 75953)
@@ -0,0 +1,66 @@
+//----------------------------------------------------------------------------
+/**
+ * @fileoverview JSON-RPC based live search implementation
+ * @author Roger Ineichen dev at projekt01 dot ch
+ * @version Initial, not documented
+ */
+//----------------------------------------------------------------------------
+
+function setLiveSearchResult(response) {
+ // we use a default element id, use a custom callback if this doesn't fit
+ ele = $('#liveSearchResultContainer');
+ if (response.content != null) {
+ $(ele).html(response.content)
+ $(ele).show('fast')
+ } else {
+ $(ele).hide('fast')
+ }
+}
+
+function closeLiveSearchResult(id) {
+ $('#'+id).hide();
+}
+
+//----------------------------------------------------------------------------
+// public API
+//----------------------------------------------------------------------------
+/**
+ * apply live search functionality. *
+ * @name jsonLiveSearch
+ * @name json live search with callback
+ * @param settings Hash with the following options:
+ * jsonURL The url where the json view getLiveSearchResult is available
+ * minQueryLenght The min length of the query string before we call json search
+ * resultElementExpression The xpath expresseion for get the result element
+ * requestId The is passed to the server via json, can be used for identify a search wquery
+ * searchMethodName The json search method name, can be used if you need to call different json views
+ * callback The callback function which get called within the response as argument
+ * @author Roger Ineichen dev - projekt01 - ch
+ * @example $("#myInputField").jsonLiveSearch();
+ * @example $("#myInputField").jsonLiveSearch({url:'http://localhost/page'});
+ * @example $("#myInputField").jsonLiveSearch({url:'http://localhost/page', callback:setLiveSearchResult});
+ */
+jQuery.fn.jsonLiveSearch = function(settings) {
+ settings = jQuery.extend({
+ jsonURL: contextURL,
+ minQueryLenght: 2,
+ resultElementExpression: '#liveSearchResultContainer',
+ requestId: 'jsonLiveSearch',
+ searchMethodName: 'getLiveSearchResult',
+ callback: setLiveSearchResult
+ }, settings);
+ return this.each(function(){
+ $(this).keyup(function(){
+ value = $(this).val();
+ if (value != '' && value.length >= settings.minQueryLenght) {
+ var proxy = getJSONRPCProxy(settings.jsonURL);
+ proxy.addMethod(settings.searchMethodName, settings.callback, settings.requestId);
+ proxy[settings.searchMethodName](value);
+ }else {
+ $(settings.resultElementExpression).hide();
+ }
+ });
+
+ });
+};
+
Added: jquery.livesearch/trunk/src/jquery/livesearch/json.pt
===================================================================
--- jquery.livesearch/trunk/src/jquery/livesearch/json.pt (rev 0)
+++ jquery.livesearch/trunk/src/jquery/livesearch/json.pt 2007-05-25 06:11:38 UTC (rev 75953)
@@ -0,0 +1,21 @@
+<div id="liveSearchResult">
+ <div class="hideLiveSearchResult">
+ <a href="javascript:closeLiveSearchResult('liveSearchResultContainer');">x</a>
+ </div>
+ <tal:block repeat="info view/results">
+ <div tal:define="oddrow repeat/info/odd;
+ url info/url"
+ tal:attributes="class python:oddrow and 'even' or 'odd'" >
+ <div class="right">
+ <a href=""
+ tal:attributes="href info/url"
+ tal:content="info/score" />
+ </div>
+ <div class="left">
+ <a href=""
+ tal:attributes="href string:${info/url}/@@SelectedManagementView.html"
+ tal:content="info/text" />
+ </div>
+ </div>
+ </tal:block>
+</div>
Added: jquery.livesearch/trunk/src/jquery/livesearch/json.py
===================================================================
--- jquery.livesearch/trunk/src/jquery/livesearch/json.py (rev 0)
+++ jquery.livesearch/trunk/src/jquery/livesearch/json.py 2007-05-25 06:11:38 UTC (rev 75953)
@@ -0,0 +1,85 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id: layer.py 197 2007-04-13 05:03:32Z rineichen $
+"""
+
+import zope.component
+import zope.interface
+from zope.pagetemplate.interfaces import IPageTemplate
+from zope.app.catalog.interfaces import ICatalog
+from zope.app.intid.interfaces import IIntIds
+
+from z3c.template.template import getPageTemplate
+from zif.jsonserver.jsonrpc import MethodPublisher
+from zif.jsonserver.interfaces import IJSONRPCRequest
+
+from jquery.livesearch import interfaces
+from jquery.livesearch.result import LiveSearchResult
+
+
+class JSONLiveSearch(MethodPublisher):
+ """JSON live search method with template for rendering the result."""
+
+ zope.interface.implements(interfaces.IJSONLiveSearch)
+ zope.component.adapts(zope.interface.Interface, IJSONRPCRequest)
+
+ # get the registered IPageTemplate template
+ template = getPageTemplate()
+ indexName = 'TextIndex'
+ jsonID = None # the json request id set in the javascript
+
+ def __init__(self, context, request):
+ super(JSONLiveSearch, self).__init__(context, request)
+ self.searchString = None
+ self.results = ()
+
+ def getCatalog(self):
+ """Returns the right catalog."""
+ return zope.component.getUtility(ICatalog)
+
+ def getLiveSearchResult(self, searchString):
+ """Returns JSON like dict/array containing a content attribute with the
+ search result.
+ """
+ self.jsonID = self.request.jsonID
+ self.doSearch(searchString)
+ # return None for content variable if no result was found. This will
+ # intepreted via JSON as null in javascript.
+ if len(self.results) == 0:
+ return {'content':None}
+ # render template only if result was found
+ else:
+ return {'content':self.render()}
+
+ def doSearch(self, searchString):
+ """Search the catalog for items and set the results."""
+ catResults = None
+ if searchString is not None:
+ catalog = self.getCatalog()
+ liveSearchString = searchString + '*'
+ if liveSearchString.strip('* ') != '':
+ catResults = catalog.apply({self.indexName:liveSearchString})
+ if catResults is not None:
+ uidutil = zope.component.getUtility(IIntIds)
+ self.results = LiveSearchResult(catResults, uidutil, self.request)
+
+ def getResults(self):
+ return self.results
+
+ def render(self):
+ # render live search results
+ template = zope.component.getMultiAdapter((self, self.request),
+ IPageTemplate)
+ return template(self)
Added: jquery.livesearch/trunk/src/jquery/livesearch/json.zcml.sample
===================================================================
--- jquery.livesearch/trunk/src/jquery/livesearch/json.zcml.sample (rev 0)
+++ jquery.livesearch/trunk/src/jquery/livesearch/json.zcml.sample 2007-05-25 06:11:38 UTC (rev 75953)
@@ -0,0 +1,13 @@
+<configure
+ xmlns:zope="http://namespaces.zope.org/zope"
+ xmlns:jsonrpc="http://namespaces.zope.org/jsonrpc"
+ i18n_domain="jquery">
+
+ <jsonrpc:view
+ for="*"
+ class="jquery.livesearch.json.JSONLiveSearch"
+ permission="zope.Public"
+ methods="getLiveSearchResult"
+ />
+
+</configure>
\ No newline at end of file
Added: jquery.livesearch/trunk/src/jquery/livesearch/result.py
===================================================================
--- jquery.livesearch/trunk/src/jquery/livesearch/result.py (rev 0)
+++ jquery.livesearch/trunk/src/jquery/livesearch/result.py 2007-05-25 06:11:38 UTC (rev 75953)
@@ -0,0 +1,83 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+$Id: layer.py 197 2007-04-13 05:03:32Z rineichen $
+"""
+
+import zope.interface
+from zope.traversing import api
+from zope.traversing.browser import absoluteURL
+from zope.security.interfaces import Unauthorized
+from zope.security.proxy import removeSecurityProxy
+
+from jquery.livesearch import interfaces
+
+
+class LiveSearchResultItem(object):
+ """Live search result item presentation."""
+
+ zope.interface.implements(interfaces.ILiveSearchResultItem)
+
+ def __init__(self, context):
+ """Adatps the object and offers live search result infos.
+
+ You need to implement this adapter for your searchable objects.
+ """
+ self.context = context
+
+ def getURL(self, request):
+ return absoluteURL(self.context, request)
+
+ def getText(self):
+ """Returns the test used for rendering the link text."""
+ try:
+ title = getattr(self.context, 'title', None)
+ except Unauthorized:
+ title = None
+
+ if title is None:
+ title = api.getName(self.context)
+
+ return title or u''
+
+ def getScore(self, score):
+ """Returns the score."""
+ return "%.4f" % score
+
+
+class LiveSearchResult:
+ """Lazily accessed set of object infos."""
+
+ def __init__(self, results, uidutil, request):
+ self.results = results
+ self.uidutil = uidutil
+ self.request = request
+
+ def __len__(self):
+ return len(self.results)
+
+ def __iter__(self):
+ for uid, score in self.results.items():
+ info = {}
+ obj = self.uidutil.getObject(uid)
+ obj = removeSecurityProxy(obj)
+ adapter = interfaces.ILiveSearchResultItem(obj)
+ info['obj'] = obj
+ info['text'] = adapter.getText()
+ info['score'] = adapter.getScore(score)
+ info['url'] = adapter.getURL(self.request)
+ yield info
+
+
+
Added: jquery.livesearch/trunk/src/jquery/livesearch/template.pt
===================================================================
--- jquery.livesearch/trunk/src/jquery/livesearch/template.pt (rev 0)
+++ jquery.livesearch/trunk/src/jquery/livesearch/template.pt 2007-05-25 06:11:38 UTC (rev 75953)
@@ -0,0 +1,24 @@
+<metal:block define-macro="livesearch">
+ <table class="navibox" width="100%" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <th nowrap>
+ <img class="icon" src="../../browser/img/navibox_edge.gif" border="0" width="17" height="22"
+ tal:attributes="src context/++resource++navibox_edge.gif" />
+ <div class="header">
+ <div class="title" i18n:translate="">Live Search</div>
+ </div>
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <div id="liveSearch">
+ <form id="liveSearchForm" name="liveSearchForm" action="livesearch_result.html" method="post">
+ <input id="liveSearchInput" type="text" name="searchableText" onKeyPress="startLiveSearch()" />
+ <input id="liveSearchSubmit" type="submit" name="SUBMIT_SEARCH" value="Search" />
+ </form>
+ <div id="liveSearchResult" style="display: none;"></div>
+ </div>
+ </td>
+ </tr>
+ </table>
+</metal:block>
More information about the Checkins
mailing list