Author: jriboux
Date: Fri Mar 14 11:55:55 2008
New Revision: 9438
Added:
MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/
- copied from r9435, MoreFieldsAndWidgets/AutocompleteWidget/branches/displaylist_support/
Modified:
MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/AutocompleteWidget.py
MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/Extensions/Install.py
MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/__init__.py
MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/config.py
MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/history.txt
MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/skins/actb_widget/actb_widget.css.dtml
MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/skins/actb_widget/actb_widget.js
MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/skins/actb_widget/autocomplete.pt
MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/todo.txt
MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/version.txt
Log:
Add branch based on AutocompleteWidget v1.2.1 (fork based on the displaylist_support branch of AutocompleteWidget of Archetypes' third party widgets). The goal is to improve the way multivalued fields are managed and make it more userfriendly.
Modified: MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/AutocompleteWidget.py
==============================================================================
--- MoreFieldsAndWidgets/AutocompleteWidget/branches/displaylist_support/AutocompleteWidget.py (original)
+++ MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/AutocompleteWidget.py Fri Mar 14 11:55:55 2008
@@ -1,73 +1,66 @@
-from AccessControl import ClassSecurityInfo
-from Products.Archetypes.public import StringWidget
-
-class AutocompleteWidget(StringWidget):
- security = ClassSecurityInfo()
-
- _properties = StringWidget._properties.copy()
- _properties.update({
- 'macro' : "autocomplete",
- 'helper_js': ('actb_widget.js',),
- 'helper_css': ('actb_widget.css',),
- 'actb_timeout': 2250, #How long (ms) before the autocomplete times out
- 'actb_lim': 5, #How many choices to show at a time
- 'actb_firsttext': 0, #Should the auto complete be limited to the
- #beginning of keyword?
- 'actb_filter_bogus': 0, # 1: removes items not in the vocabulary
- 'actb_expand_onfocus': 1, # expands the dropdown on field focus
- 'actb_complete_on_tab': 1, # when set to 0, pressing tab moves the focus to the next widget
- })
-
- security.declarePublic('process_form')
- def process_form(self, instance, field, form, empty_marker=None, emptyReturnsMarker=False):
- """ process the string into a list """
-
- # first preprocess if necessary
- value = form.get(field.getName(), empty_marker)
-
- vocab = field.Vocabulary(instance)
-
-
- if self.actb_filter_bogus==1:
-
- # make delimiters uniform
- value = value.replace(',', ';')
-
- keywords = value.split(';');
- keywords = [k.strip() for k in keywords]
- result = []
-
- # now check if the keywords are in the vocab
- for keyword in keywords:
- if keyword in vocab and keyword not in result:
- result.append(keyword)
-
- if field.type!='lines':
- # make it a string again
- result= ';'.join(result)
- else:
- # don't filter out non-vocab keywords
- if field.type=='lines':
- # make delimiters uniform
- value = value.replace(',', ';')
-
- keywords = value.split(';');
- keywords = [k.strip() for k in keywords]
- result = []
- # simply remove redunant keywords
- for keyword in keywords:
- if keyword not in result:
- result.append(keyword)
-
- else:
- result = value
-
- return result,{}
-
-from Products.Archetypes.Registry import registerWidget
-
-registerWidget(AutocompleteWidget,
- title='Autocomplete',
- description="Text field with vocabulary based autocomplete.",
- used_for=('Products.Archetypes.public.StringField',)
- )
\ No newline at end of file
+from AccessControl import ClassSecurityInfo
+from Products.Archetypes.public import StringWidget
+
+class AutocompleteWidget(StringWidget):
+ security = ClassSecurityInfo()
+
+ _properties = StringWidget._properties.copy()
+ _properties.update({
+ 'macro' : "autocomplete",
+ 'helper_js': ('actb_widget.js',),
+ 'helper_css': ('actb_widget.css',),
+ 'actb_timeout': 2250, #How long (ms) before the autocomplete times out
+ 'actb_lim': 5, #How many choices to show at a time
+ 'actb_firsttext': 0, #Should the auto complete be limited to the
+ #beginning of keyword?
+ 'actb_filter_bogus': 1, # 1: removes items not in the vocabulary
+ 'actb_expand_onfocus': 1, # expands the dropdown on field focus
+ 'actb_complete_on_tab': 1, # when set to 0, pressing tab moves the focus to the next widget
+ })
+
+ security.declarePrivate('keyword_from_value')
+ def keyword_from_value(self, value, instance, field):
+ vocab = field.Vocabulary(instance)
+ if self.actb_filter_bogus: # delete bogus keywords
+ return vocab.getKey(value.strip(), None)
+ else: # keep bogus keywords
+ return vocab.getKey(value.strip(), value.strip()) # if no keyword, use value
+
+ security.declarePublic('process_form')
+ def process_form(self, instance, field, form, empty_marker=None, emptyReturnsMarker=False):
+ """ process the string into a list """
+
+ value = form.get(field.getName(), None)
+
+ # no value!
+ if not value:
+ return field.type=='lines' and [] or '', {}
+
+ if field.multiValued:
+ # make delimiters uniform
+ value = value.replace(',', ';')
+
+ # get keywords from values
+ values = value.split(';');
+ result = []
+ for value in values:
+ keyword = self.keyword_from_value(value, instance, field)
+ if keyword and keyword not in result:
+ result.append(keyword)
+
+ if field.type!='lines':
+ result= ';'.join(result) # make it a string again
+ else:
+ keyword = self.keyword_from_value(value, instance, field)
+ result = keyword and keyword or ''
+
+ return result, {}
+
+
+from Products.Archetypes.Registry import registerWidget
+
+registerWidget(AutocompleteWidget,
+ title='Autocomplete',
+ description="Text field with vocabulary based autocomplete.",
+ used_for=('Products.Archetypes.public.StringField',)
+ )
Modified: MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/Extensions/Install.py
==============================================================================
--- MoreFieldsAndWidgets/AutocompleteWidget/branches/displaylist_support/Extensions/Install.py (original)
+++ MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/Extensions/Install.py Fri Mar 14 11:55:55 2008
@@ -1,11 +1,11 @@
-from StringIO import StringIO
-from Products.Archetypes.Extensions.utils \
- import install_subskin
-from Products.AutocompleteWidget.config import *
-
-
-def install(self):
- out = StringIO()
- install_subskin(self, out, GLOBALS)
- out.write("Successfully installed %s." % PROJECTNAME)
+from StringIO import StringIO
+from Products.Archetypes.Extensions.utils \
+ import install_subskin
+from Products.AutocompleteWidget.config import *
+
+
+def install(self):
+ out = StringIO()
+ install_subskin(self, out, GLOBALS)
+ out.write("Successfully installed %s." % PROJECTNAME)
return out.getvalue()
\ No newline at end of file
Modified: MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/__init__.py
==============================================================================
--- MoreFieldsAndWidgets/AutocompleteWidget/branches/displaylist_support/__init__.py (original)
+++ MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/__init__.py Fri Mar 14 11:55:55 2008
@@ -1,4 +1,4 @@
-from config import *
-from Products.CMFCore.DirectoryView import registerDirectory
-
+from config import *
+from Products.CMFCore.DirectoryView import registerDirectory
+
registerDirectory(SKINS_DIR, GLOBALS)
\ No newline at end of file
Modified: MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/config.py
==============================================================================
--- MoreFieldsAndWidgets/AutocompleteWidget/branches/displaylist_support/config.py (original)
+++ MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/config.py Fri Mar 14 11:55:55 2008
@@ -1,3 +1,3 @@
-PROJECTNAME = "AutocompleteWidget"
-SKINS_DIR = 'skins'
+PROJECTNAME = "AutocompleteWidget"
+SKINS_DIR = 'skins'
GLOBALS = globals()
\ No newline at end of file
Modified: MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/history.txt
==============================================================================
--- MoreFieldsAndWidgets/AutocompleteWidget/branches/displaylist_support/history.txt (original)
+++ MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/history.txt Fri Mar 14 11:55:55 2008
@@ -1,3 +1,37 @@
+14-03-2008 - v1.2.1 : Jonathan Riboux
+
+ * integrated Ak Sorpa's fix to prevent &, < and > to appear in the input box after selecting a value in the drop-down list
+
+
+12-03-2008 - v1.2 : Jonathan Riboux
+
+ * corrected i18n attributes so AutocompleteWidget can be used in English
+
+ * added tooltips and button labels
+
+ * better look
+
+ * added CSS classes to buttons
+
+
+25-02-2008 - v1.1 : Nicolas Geissel
+
+ * using fieldName var instead of field.getName for better flexibility (widget can now be used as a search widget)
+
+ * added i18n
+
+
+07-02-2008 - v1.0 : Jonathan Riboux
+
+ * improvement of display list support (display value, but register key)
+
+ * widget shows a list of current values next to the input field for multivalued fields
+
+ * arrows navigation in menu now works on Internet Explorer
+
+ * cleanup of process_form code
+
+
09-02-2005: Danny Bloemendaal
* ESC shows the dropdown list
@@ -8,7 +42,7 @@
* renamed filter_bogus to actb_filter_bogus to have a consistent naming
-08-02-2005: Danny Bloemendaal
+08-02-2005: Danny Bloemendaal
* replaced the javascript factory with the latets version from the original author
Modified: MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/skins/actb_widget/actb_widget.css.dtml
==============================================================================
--- MoreFieldsAndWidgets/AutocompleteWidget/branches/displaylist_support/skins/actb_widget/actb_widget.css.dtml (original)
+++ MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/skins/actb_widget/actb_widget.css.dtml Fri Mar 14 11:55:55 2008
@@ -10,6 +10,8 @@
color:black;
font-size:110%;
//background-color: &dtml-contentViewBackgroundColor;;
+ /*QUADRA : so it is visible when using thickbox*/
+ z-index: 5000;
}
.actb_active { background-color: &dtml-globalBorderColor;;
@@ -42,6 +44,61 @@
margin: 0 1em 0 0;
}
-
+.autocomplete .add_button {
+ background:transparent url(<dtml-var portal_url>/add_icon.gif) 0 0 no-repeat;
+ cursor: pointer;
+ font-size: &dtml-fontSmallSize;;
+ padding: 1px 1px 1px 15px;
+ text-transform: &dtml-textTransform;;
+ overflow: visible;
+}
+
+.autocomplete .clear_button {
+ background: transparent url(<dtml-var portal_url>/undo_icon.gif) 0 0 no-repeat;
+ cursor: pointer;
+ font-size: &dtml-fontSmallSize;;
+ padding: 1px 1px 1px 15px;
+ text-transform: &dtml-textTransform;;
+ overflow: visible;
+}
+
+.autocomplete .delete_button {
+ background: transparent url(<dtml-var portal_url>/delete_small_icon.gif) 0px -2px no-repeat;
+ cursor: pointer;
+ font-size: &dtml-fontSmallSize;;
+ padding: 1px 1px 1px 15px;
+ text-transform: &dtml-textTransform;;
+ overflow: visible;
+ border-bottom: none;
+}
+.autocomplete .delete_button span {
+ display: none;
+}
+
+.autocomplete .empty_info {
+ font-size: &dtml-fontSmallSize;;
+ text-transform: &dtml-textTransform;;
+}
+
+.autocomplete ul {
+ font-size: 90%;
+ margin: 0px;
+ padding: 0px 3px;
+ border-left: &dtml-borderWidth; &dtml-borderStyle; &dtml-globalBorderColor;;
+}
+
+.autocomplete ul li {
+ font-size: 90%;
+ margin: 0px;
+ padding: 0px;
+ list-style: none;
+ list-style-image: none;
+}
+
+.autocomplete .empty_info {
+ padding: 0px 3px;
+ border-left: &dtml-borderWidth; &dtml-borderStyle; &dtml-globalBorderColor;;
+}
+
/* </dtml-with> */
\ No newline at end of file
Modified: MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/skins/actb_widget/actb_widget.js
==============================================================================
--- MoreFieldsAndWidgets/AutocompleteWidget/branches/displaylist_support/skins/actb_widget/actb_widget.js (original)
+++ MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/skins/actb_widget/actb_widget.js Fri Mar 14 11:55:55 2008
@@ -32,7 +32,7 @@
if (obj.setSelectionRange){
obj.setSelectionRange(l,l);
}else if(obj.createTextRange){
- m = obj.createTextRange();
+ m = obj.createTextRange();
m.moveStart('character',l);
m.collapse();
m.select();
@@ -47,6 +47,35 @@
String.prototype.trim = function () {
return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1");
};
+function actb_convert_escape_chars(str) {
+ // Thanks to Ak Sorpa for this function
+ // When a string is assigned to innerHTML, it will be converted
+ // to contain escape sequences. For example,
+ // word1 & word2 is converted into word1 & word2
+ // The following string
+ // ~!@#$%^&*()_+=-{}][:;'/><|
+ // is converted into
+ // ~!@#$%^&*()_+=-{}][:;'/><|
+ // Based on this test, only conversion of & < > signs is supported
+ // by this function. Improve more if necessary.
+
+ if (!str) {
+ return str;
+ }
+
+ var escape_sequences = new Object();
+
+ escape_sequences["<"] = "<";
+ escape_sequences[">"] = ">";
+ escape_sequences["&"] = "&";
+
+ var converted = str;
+ for (var esc in escape_sequences) {
+ converted = converted.replace(esc, escape_sequences[esc]);
+ }
+
+ return converted;
+}
function actb(obj,evt,ca, time_out, limit, first_text, expand_onfocus, complete_on_tab){
@@ -98,9 +127,9 @@
var oldkeydownhandler = document.onkeydown;
var oldblurhandler = obj.onblur;
- var oldkeypresshandler = obj.onkeypress;
+ var oldkeyuphandler = obj.onkeyup;
- document.onkeypress = actb_checkkey;
+ document.onkeydown = actb_checkkey;
obj.onblur = actb_clear;
obj.onkeyup = actb_keypress;
@@ -111,7 +140,7 @@
if (!evt) evt = event;
document.onkeydown = oldkeydownhandler;
actb_curr.onblur = oldblurhandler;
- actb_curr.onkeypress = oldkeypresshandler;
+ actb_curr.onkeyup = oldkeyuphandler;
actb_removedisp();
}
function actb_parse(n){
@@ -176,6 +205,21 @@
}
function actb_generate(){
+
+ /*if (document.getElementById('tat_rm_link')) document.body.removeChild(document.getElementById('tat_rm_link'));
+ l = document.createElement('a');
+ l.style.position='absolute';
+ l.style.top = eval(curTop() + 1) + "px";
+ l.innerHTML = 'vider';
+ l.style.left = eval(curLeft() + actb_curr.offsetWidth + 3) + "px";
+ l.id = 'tat_rm_link';
+ l.onclick = function () {
+ actb_curr.value="";
+ setTimeout("document.getElementById('"+actb_curr.id+"').focus()", 250);
+ };
+
+ document.body.appendChild(l);*/
+
if (document.getElementById('tat_table')){ actb_display = false;document.body.removeChild(document.getElementById('tat_table')); }
if (actb_kwcount == 0){
@@ -265,6 +309,7 @@
}
function actb_remake(){
document.body.removeChild(document.getElementById('tat_table'));
+
a = document.createElement('table');
a.className='actb_table';
a.cellSpacing='1px';
@@ -352,7 +397,7 @@
c.align='center';
c.innerHTML=' ';
c.className='actb_arrow_placeholder';
- }
+ }
}
function actb_goup(){
if (!actb_display) return;
@@ -464,11 +509,16 @@
str += actb_delimchar[i];
}
}
+ // Ak Sorpa's fix to prevent &, < and > to appear in the input box
+ str = actb_convert_escape_chars(str);
actb_curr.value = str;
setCaret(actb_curr,l);
}else{
actb_curr.value = a;
}
+ if (actb_curr.onchange) {
+ actb_curr.onchange()
+ }
actb_mouse_on_list = 0;
actb_removedisp();
}
@@ -492,6 +542,9 @@
if (document.getElementById('tat_table')){
document.body.removeChild(document.getElementById('tat_table'));
}
+ /*if (document.getElementById('tat_rm_link')){
+ setTimeout("document.body.removeChild(document.getElementById('tat_rm_link'))", 250);
+ }*/
if (actb_toid) clearTimeout(actb_toid);
}
}
@@ -617,4 +670,97 @@
if (actb_timeOut > 0) actb_toid = setTimeout(function(){actb_mouse_on_list = 0;actb_removedisp();},actb_timeOut);
actb_generate();
}
-}
\ No newline at end of file
+}
+
+
+function actb_addValue(id) {
+ var value = document.getElementById(id+'_toadd_widget').value;
+ var obj = document.getElementById(id+'_widget_list');
+
+ var value_tab = value.split(new RegExp("[;]+", "g"));
+ for (var i = 0; i < value_tab.length; i++) {
+ _actb_addValue(obj, value_tab[i], id);
+ }
+
+ actb_updateWidgetValue(id);
+ actb_resetWidget(id);
+}
+
+function _actb_addValue(obj, value, id) {
+ var model = document.getElementById(id+'_widget_delete');
+ if (value=='') {
+ return;
+ }
+ var nodes = obj.childNodes;
+ for (var i = 0; i < nodes.length; i++) {
+ node = nodes[i].firstChild;
+ if (node && node.data == value) {
+ return;
+ }
+ }
+
+ var li = document.createElement('li');
+ li.appendChild(document.createTextNode(value));
+ var a = document.createElement('a');
+ a.appendChild(document.createTextNode(' '));
+ var sp = document.createElement('span');
+ sp.appendChild(document.createTextNode(model.childNodes[0].nodeValue));
+ a.title = model.title;
+ a.appendChild(sp);
+ a.onclick = actb_remove;
+ a.className = 'delete_button';
+ li.appendChild(a);
+ obj.appendChild(li);
+}
+
+function actb_remove(e) {
+ if (!e) {
+ e = window.event;
+ }
+ var obj = (e.srcElement?e.srcElement:e.target).parentNode;
+ var list = obj.parentNode;
+ list.removeChild(obj);
+ actb_updateWidgetValue(list.id.substr(0, list.id.length-12));
+}
+
+function actb_updateWidgetValue(id) {
+ var list = document.getElementById(id+'_widget_list');
+ var widget = document.getElementById(id+'_widget');
+ var empty = document.getElementById(id+'_widget_empty');
+ var value='';
+ var nodes = list.childNodes;
+ var has_items = false;
+ for (var i = 0; i < nodes.length; i++) {
+ if (nodes[i] && nodes[i].firstChild) {
+ value = value + nodes[i].firstChild.data + ';';
+ has_items = true;
+ }
+ }
+ if (has_items) {
+ empty.style.display='none';
+ } else {
+ empty.style.display='block';
+ }
+ if (value.length > 0) {
+ value = value.substring(0, value.length - 1);
+ }
+ widget.value = value;
+}
+
+function actb_updateListFromValue(id) {
+ var list = document.getElementById(id+'_widget_list');
+ var widget = document.getElementById(id+'_widget');
+ if (widget.value.length == 0) {
+ return;
+ }
+ var value_tab = widget.value.split(new RegExp("[;]+", "g"));
+ for (var i=0; i<value_tab.length; i++) {
+ _actb_addValue(list, value_tab[i], id);
+ }
+ actb_updateWidgetValue(id);
+}
+
+function actb_resetWidget(id) {
+ var obj = document.getElementById(id+'_toadd_widget');
+ obj.value="";
+}
Modified: MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/skins/actb_widget/autocomplete.pt
==============================================================================
--- MoreFieldsAndWidgets/AutocompleteWidget/branches/displaylist_support/skins/actb_widget/autocomplete.pt (original)
+++ MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/skins/actb_widget/autocomplete.pt Fri Mar 14 11:55:55 2008
@@ -1,65 +1,102 @@
<html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:tal="http://xml.zope.org/namespaces/tal"
- xmlns:metal="http://xml.zope.org/namespaces/metal"
- xmlns:i18n="http://xml.zope.org/namespaces/i18n"
- i18n:domain="plone">
+ xmlns:tal="http://xml.zope.org/namespaces/tal"
+ xmlns:metal="http://xml.zope.org/namespaces/metal"
+ xmlns:i18n="http://xml.zope.org/namespaces/i18n" i18n:domain="autocompletewidget">
<head>
- <title></title>
+<title></title>
</head>
<body>
- <!-- Selection Widgets -->
+<!-- Selection Widgets -->
- <metal:view_macro define-macro="view"
- tal:define="vocab python:field.Vocabulary(here);
+<metal:view_macro define-macro="view"
+ tal:define="vocab python:field.Vocabulary(here);
value python:accessor();
- display python:here.displayValue(vocab, value)">
- <span tal:replace="display" />
- </metal:view_macro>
-
- <metal:define define-macro="edit">
-
- <metal:use use-macro="field_macro | here/widgets/field/macros/edit">
-
- <metal:fill fill-slot="widget_body"
- tal:define="vocab python:field.Vocabulary(here);
- widget_value python:test(field.type=='lines', ','.join(value), value)">
- <script type="text/javascript"
- tal:define="esc_vocab python: [v.replace('\'','\\\'') for v in vocab];
+ display python:same_type(value, ()) and ', '.join([here.displayValue(vocab, x) or x for x in value]) or here.displayValue(vocab, value) or '';">
+ <span tal:condition="display" tal:replace="display" />
+</metal:view_macro>
+
+<metal:define define-macro="edit">
+
+ <metal:use use-macro="field_macro | here/widgets/field/macros/edit">
+ <tal:comment replace="nothing">
+ <!--
+ QUADRA: change definition of widget_value because on error
+ we have a weird behaviour with , , , , , ,
+ -->
+ </tal:comment>
+ <metal:fill fill-slot="widget_body"
+ tal:define="vocab python:field.Vocabulary(here);
+ widget_multi field/multiValued;
+ widget_multi_str python:widget_multi and 'true' or 'false';
+ value python:value!=None and value or '';
+ widget_value python:same_type(value, ()) and ';;'.join([here.displayValue(vocab, x) or x for x in value]) or here.displayValue(vocab, value) or '';
+ widget_id python:fieldName + (widget_multi and '_toadd_widget' or '_widget');
+ widget_name python:(not widget_multi) and fieldName or nothing;">
+
+ <script type="text/javascript"
+ tal:define="esc_vocab python: [v.replace('\'','\\\'') for v in vocab.values()];
vocab_list python: '\'' + '\',\''.join(esc_vocab) + '\''"
- tal:content="string:
- var array_${fieldName}=new Array(${vocab_list});
- ">
- </script>
-
- <input onfocus='actb(this,event,customarray, timeout, limit, firsttext);'
- type='text'
- value=''
- id=''
- autocomplete="off"
- tal:attributes="name fieldName;
- value widget_value;
- size widget/size;
- maxlength widget/maxlength;
- tabindex tabindex/next;
- id python:field.getName() + '_widget';
- onfocus string:actb(this, event, array_${fieldName}, ${widget/actb_timeout},${widget/actb_lim},${widget/actb_firsttext}, ${widget/actb_expand_onfocus})"
-
- />
-
-
- </metal:fill>
-
- </metal:use>
-
- </metal:define>
-
- <div metal:define-macro="search">
- <div metal:use-macro="here/widgets/selection/macros/edit" />
- </div>
+ tal:content="string:var array_${fieldName}=new Array(${vocab_list});">
+ </script>
+ <div id="" tal:attributes="id python:fieldName" class="autocomplete">
+ <input
+ onfocus='actb(this,event,customarray, timeout, limit, firsttext);'
+ type='text' value='' id='' autocomplete="off"
+ tal:attributes="name widget_name;
+ value python:(not widget_multi) and widget_value or '';
+ size widget/size;
+ maxlength widget/maxlength;
+ tabindex tabindex/next;
+ id widget_id;
+ onfocus string:actb(this, event, array_${fieldName}, ${widget/actb_timeout},${widget/actb_lim},${widget/actb_firsttext}, ${widget/actb_expand_onfocus})" />
+ <tal:multi tal:condition="widget_multi">
+ <a class="inline_button add_button" tal:attributes="onclick python:'actb_addValue(\''+fieldName+'\')'"
+ i18n:attributes="title action_add_title;"
+ title="Add the value to the list">
+ <span i18n:translate="action_add">Add</span>
+ </a>
+ </tal:multi>
+ <a class="clear_button"
+ tal:attributes="onclick python:'document.getElementById(\'%s\').value=\'\';;document.getElementById(\'%s\').focus()'%(widget_id, widget_id);
+ id python:fieldName + '_clear';"
+ i18n:attributes="title action_clear_title;"
+ title="Clear the input field">
+ <span i18n:translate="action_clear">Clear</span>
+ </a>
+ <tal:multi tal:condition="widget_multi">
+ <input type='hidden' value='' id='' autocomplete="off"
+ tal:attributes="name fieldName;
+ value python:same_type(widget_value, ()) and ','.join(widget_value) or widget_value;
+ id python:fieldName + '_widget';" />
+ <div class="empty_info"
+ title="The list is empty, type a value and click the Add button"
+ tal:attributes="id python:fieldName + '_widget_empty';"
+ i18n:attributes="title empty_list_title;"
+ i18n:translate="empty_list">The list is empty</div>
+ <ul id="widget_list"
+ tal:attributes="id python:fieldName + '_widget_list';">
+ </ul>
+ <span tal:attributes="id python:fieldName + '_widget_delete';"
+ i18n:translate="action_delete"
+ i18n:attributes="title action_delete_title;"
+ style="display:none;"
+ title="Delete from the list">Delete</span>
+ <script type="text/javascript" charset="iso-8859-1"
+ tal:content="string:actb_updateListFromValue('${fieldName}');" />
+ </tal:multi>
+ </div>
+
+ </metal:fill>
+
+ </metal:use>
+
+</metal:define>
+<div metal:define-macro="search">
+<div metal:use-macro="here/widgets/autocomplete/macros/edit" /></div>
</body>
</html>
Modified: MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/todo.txt
==============================================================================
--- MoreFieldsAndWidgets/AutocompleteWidget/branches/displaylist_support/todo.txt (original)
+++ MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/todo.txt Fri Mar 14 11:55:55 2008
@@ -1,2 +1,4 @@
+* submit form or trigger a custom function on enter key press when menu is hidden
+* replace the javascript factory with the latest version from the original author
* use a div with scrollbar instead of a table and some
obscure way of dealing with scrolling
\ No newline at end of file
Modified: MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/version.txt
==============================================================================
--- MoreFieldsAndWidgets/AutocompleteWidget/branches/displaylist_support/version.txt (original)
+++ MoreFieldsAndWidgets/AutocompleteWidget/branches/improved_multivalued_fields_management/version.txt Fri Mar 14 11:55:55 2008
@@ -1 +1 @@
-0.9.1 (svn/unreleased)
\ No newline at end of file
+1.2.1
\ No newline at end of file
|