From: Radim N. <svn...@pl...> - 2010-08-25 12:55:05
|
Author: naro Date: Wed Aug 25 12:54:56 2010 New Revision: 13021 Modified: MoreFieldsAndWidgets/Products.MasterSelectWidget/branches/radio/Products/MasterSelectWidget/MasterSelectDemo.py MoreFieldsAndWidgets/Products.MasterSelectWidget/branches/radio/Products/MasterSelectWidget/browser.py MoreFieldsAndWidgets/Products.MasterSelectWidget/branches/radio/Products/MasterSelectWidget/masterselect.js MoreFieldsAndWidgets/Products.MasterSelectWidget/branches/radio/Products/MasterSelectWidget/profiles/demo/types/MasterSelectDemo.xml Log: fixed javascript, most of situations works, but radio field without default does not work yet Modified: MoreFieldsAndWidgets/Products.MasterSelectWidget/branches/radio/Products/MasterSelectWidget/MasterSelectDemo.py ============================================================================== --- MoreFieldsAndWidgets/Products.MasterSelectWidget/branches/radio/Products/MasterSelectWidget/MasterSelectDemo.py (original) +++ MoreFieldsAndWidgets/Products.MasterSelectWidget/branches/radio/Products/MasterSelectWidget/MasterSelectDemo.py Wed Aug 25 12:54:56 2010 @@ -109,6 +109,22 @@ "radio controls instead a dropdown.", ), ), + StringField( + name='masterRadioNoDefaultField', + searchable=0, + vocabulary=['YES', 'NO'], + widget=MasterSelectWidget( + format="radio", + slave_fields=( + dict(name='slaveField1', action='show', hide_values=('NO',)), + dict(name='slaveField2', action='show', hide_values=('YES',)), + ), + description="This field has no default. If YES is selected, " + "slaveField1 is visible and slaveField2 hidden. " + "If NO is selected, slaveField1 is hidden and " + "slaveField2 is visible.", + ), + ), LinesField( name='slaveField1', Modified: MoreFieldsAndWidgets/Products.MasterSelectWidget/branches/radio/Products/MasterSelectWidget/browser.py ============================================================================== --- MoreFieldsAndWidgets/Products.MasterSelectWidget/branches/radio/Products/MasterSelectWidget/browser.py (original) +++ MoreFieldsAndWidgets/Products.MasterSelectWidget/branches/radio/Products/MasterSelectWidget/browser.py Wed Aug 25 12:54:56 2010 @@ -4,7 +4,7 @@ from Products.Archetypes import DisplayList from Products.Five import BrowserView -SELECT = "$('#archetypes-fieldname-%(master)s')" +SELECT = "$('[id=archetypes-fieldname-%(master)s]')" BINDERS = dict( vocabulary=SELECT + ".bindMasterSlaveVocabulary('%(name)s', " Modified: MoreFieldsAndWidgets/Products.MasterSelectWidget/branches/radio/Products/MasterSelectWidget/masterselect.js ============================================================================== --- MoreFieldsAndWidgets/Products.MasterSelectWidget/branches/radio/Products/MasterSelectWidget/masterselect.js (original) +++ MoreFieldsAndWidgets/Products.MasterSelectWidget/branches/radio/Products/MasterSelectWidget/masterselect.js Wed Aug 25 12:54:56 2010 @@ -2,20 +2,20 @@ var cache = {}; // Cache AJAX results var guid = 0; // Used to give each handler binding a unique name // Anonymizer so we can bind the same handler multiple times per eventtype - function _anon(f) { return function() { f.apply(this, arguments); }; }; + function _anon(f) { return function() { f.apply(this, arguments); }; } function justValue(el, master, multivalued) { master = typeof(master) != 'undefined' ? master : null; multivalued = typeof(multivalued) != 'undefined' ? multivalued : false; var $el = $(el); if ($el.is('select')) { - return $el.val() + return $el.val(); } else if ($el.is('input:radio')) { - return $el.val() + return $el.val(); } else if ($el.is('input:checkbox')) { - if (master != null && multivalued) { + if (master !== null && multivalued) { // return all checked values of the field with name set in 'master' - var result = new Array(); + var result = []; $el.closest('[id='+master+']').find('[name^='+master+']').each(function() { if($(this).attr('checked')) { result.push($(this).val()); @@ -29,7 +29,7 @@ } function typeAndValue(el) { // Returns type of widget and it's value - var result = new Object(); + var result = {}; var $items = $(el).find('select'); if ($items.length == 1) { result.type = 'select'; @@ -41,10 +41,10 @@ result.value = $($items[0]).attr('checked'); } else if ($items.length > 1) { result.type = 'multicheckbox'; - result.value = new Array(); + result.value = []; $items.each(function() { if (this.checked) { - result.value.push($(this).val()) + result.value.push($(this).val()); } }); } else { @@ -70,54 +70,57 @@ // AJAX vocabulary handling function updateSelect(field, data) { var values = {}; // Remember current selections; reselect afterwards - $('#archetypes-fieldname-' + field).find('select') - .each(function() { values[this] = $(this).val() }) + $('[id=archetypes-fieldname-' + field+']').find('select') + .each(function() { values[this] = $(this).val(); }) .empty().html( // Replace all options with new ones $.map(data, function(entry) { return '<option value="' + entry.value + '" '+ entry.selected +' >' + entry.label + '</option>'; }).join('') - ).each(function(){if (!(this.selectedIndex)) - $(this).val(values[this])} + ).each(function(){if (!(this.selectedIndex)) { + $(this).val(values[this]);}} ).change(); - }; + } function handleMasterVocabularyChange(event) { var value = justValue(this); var slave = event.data.slaveid; var name = cleanedName(this.name); var cachekey = [name, slave, value].join(':'); - if (cache[cachekey] == undefined) + if (cache[cachekey] === undefined) { $.getJSON(event.data.url, { field: name, slave: slave, value: value }, function(data) { cache[cachekey] = data; updateSelect(slave, data); }); - else updateSelect(slave, cache[cachekey]); - }; + } else { + updateSelect(slave, cache[cachekey]); + } + } $.fn.bindMasterSlaveVocabulary = function(slaveid, url) { var data = { slaveid: slaveid, url: url }; var val = typeAndValue(this); + var $items; if (val.type == 'select') { - var $items = $(this).find('select'); + $items = $(this).find('select'); $items.bind('change.masterslavevocabulary' + ++guid, data, _anon(handleMasterVocabularyChange)) .trigger('change.masterslavevocabulary' + guid); } if (val.type == 'checkbox') { - var $items = $(this).find('input:checkbox'); + $items = $(this).find('input:checkbox'); $items.bind('click.masterslavevocabulary' + ++guid, data, _anon(handleMasterVocabularyChange)) .trigger('click.masterslavevocabulary' + guid); } if (val.type == 'multicheckbox') { - var $items = $(this).find('input:checkbox'); + $items = $(this).find('input:checkbox'); // data.multivalued = true; alert('Master slave vocabulary for multicheckbox field is not yet implemented'); } if (val.type == 'radio') { - var $items = $(this).find('input:radio'); - var $bound = $items.bind('click.masterslavevocabulary' + ++guid, + $items = $(this).find('input:radio'); + $items.bind('click.masterslavevocabulary' + ++guid, data, _anon(handleMasterVocabularyChange)); } }; @@ -126,46 +129,48 @@ function updateValue(field, data) { field = $('#archetypes-fieldname-' + field + ' #' + field); field.val(data).change(); - if (field.is('.kupu-editor-textarea')) // update kupu editor too + if (field.is('.kupu-editor-textarea')) {// update kupu editor too field.siblings('iframe:first').contents().find('body').html(data); + } } function handleMasterValueChange(event) { var value = justValue(this); var slave = event.data.slaveid; var name = cleanedName(this.name); var cachekey = [name, slave, value].join(':'); - if (cache[cachekey] == undefined) + if (cache[cachekey] === undefined) { $.getJSON(event.data.url, { field: name, slave: slave, value: value }, function(data) { cache[cachekey] = data; updateValue(slave, data); }); - else updateValue(slave, cache[cachekey]); - }; + } else { updateValue(slave, cache[cachekey]); } + } $.fn.bindMasterSlaveValue = function(slaveid, url) { var data = { slaveid: slaveid, url: url }; var val = typeAndValue(this); + var $items; if (val.type == 'select') { - var $items = $(this).find('select'); + $items = $(this).find('select'); $items.bind('change.masterslavevalue' + ++guid, data, _anon(handleMasterValueChange)) .trigger('change.masterslavevalue' + guid); } if (val.type == 'checkbox') { - var $items = $(this).find('input:checkbox'); + $items = $(this).find('input:checkbox'); $items.bind('click.masterslavevalue' + ++guid, data, _anon(handleMasterValueChange)) .trigger('click.masterslavevalue' + guid); } if (val.type == 'multicheckbox') { - var $items = $(this).find('input:checkbox'); + $items = $(this).find('input:checkbox'); // data.multivalued = true; alert('Master slave value for multicheckbox field is not yet implemented'); } if (val.type == 'radio') { - var $items = $(this).find('input:radio'); - var $bound = $items.bind('click.masterslavevalue' + ++guid, + $items = $(this).find('input:radio'); + $items.bind('click.masterslavevalue' + ++guid, data, _anon(handleMasterValueChange)); } }; @@ -173,7 +178,7 @@ // Field status/visibility toggles function handleMasterToggle(event) { var action = event.data.action; - var slave = $('#archetypes-fieldname-' + event.data.slaveid); + var slave = $('[id=archetypes-fieldname-' + event.data.slaveid+']'); var val = justValue(this, event.data.master, event.data.multivalued); if (!jq.isArray(val)) { val = $.inArray(val, event.data.values) > -1; @@ -182,7 +187,7 @@ $.each(val, function(idx, name) { if ($.inArray(name, event.data.values) > -1){ result = true; - return false + return false; } }); val = result; @@ -191,10 +196,11 @@ val = !val; action = action == 'hide' ? 'show' : 'enable'; } - if (action == 'show') + if (action == 'show') { slave.each(function() { $(this)[ val ? "show" : "hide" ](); }); - else + } else { slave.find(':input').attr('disabled', val ? '' : 'disabled'); + } } $.fn.bindMasterSlaveToggle = function(slaveid, action, values, master) { var data = { slaveid: slaveid, @@ -202,15 +208,18 @@ values: values, multivalued: false, master: master }; + console.log('Binding to: ' + this.attr('id') ); + console.log(data); var val = typeAndValue(this); + var $bound, $items; if (val.type == 'select') { - var $items = $(this).find('select'); + $items = $(this).find('select'); $items.bind('change.masterslavetoggle' + ++guid, data, _anon(handleMasterToggle)) .trigger('change.masterslavetoggle' + guid); } if (val.type == 'checkbox') { - var $items = $(this).find('input:checkbox'); + $items = $(this).find('input:checkbox'); $items.bind('click.masterslavetoggle' + ++guid, data, _anon(handleMasterToggle)) .trigger('click.masterslavetoggle' + guid); @@ -218,28 +227,56 @@ $items.attr('checked', val.value); } if (val.type == 'multicheckbox') { - var $items = $(this).find('input:checkbox'); + $items = $(this).find('input:checkbox'); data.multivalued = true; - var $bound = $items.bind('click.masterslavetoggle' + ++guid, + $bound = $items.bind('click.masterslavetoggle' + ++guid, data, _anon(handleMasterToggle)) .trigger('click.masterslavetoggle' + guid); $bound.each(function() { $item = $(this); - $item.attr('checked', $.inArray($item.val(), val.value) == -1 ? null : 'checked') - }) + $item.attr('checked', $.inArray($item.val(), val.value) == -1 ? null : 'checked'); + }); } if (val.type == 'radio') { - var $items = $(this).find('input:radio'); - var $bound = $items.bind('click.masterslavetoggle' + ++guid, - data, _anon(handleMasterToggle)); - if (val.value != null) { + $items = $(this).find('input:radio'); + $bound = $items.bind('click.masterslavetoggle' + ++guid, + data, _anon(handleMasterToggle)) + .trigger('click.masterslavetoggle' + guid); + if (val.value !== null) { // click at default value $bound.each(function() { if ($(this).val() == val.value) { $(this).trigger('click'); return false; } - }) + }); + } else { + // clear all values + $bound.each(function() { + $(this).attr('checked', false); + }); + // we must reverse the operation on last item, because it was + // "clicked", but shouldn't be. + $last = $bound.last(); + $.each($last.data('events').click, function() { + // search for masterslavetoggle namespaced event + if (this.namespace.substr(0,17) == 'masterslavetoggle') { + // found the event - issue reverse operation + val = false; // not checked + var action = this.data.action; + var slave = $('[id=archetypes-fieldname-' + this.data.slaveid+']'); + if ($.inArray(action, ['hide', 'disable']) > -1) { + val = !val; + action = action == 'hide' ? 'show' : 'enable'; + } + if (action == 'show') { + slave.each(function() { $(this)[ val ? "show" : "hide" ](); }); + } else { + slave.find(':input').attr('disabled', val ? '' : 'disabled'); + } + return false; + } + }); } } }; Modified: MoreFieldsAndWidgets/Products.MasterSelectWidget/branches/radio/Products/MasterSelectWidget/profiles/demo/types/MasterSelectDemo.xml ============================================================================== --- MoreFieldsAndWidgets/Products.MasterSelectWidget/branches/radio/Products/MasterSelectWidget/profiles/demo/types/MasterSelectDemo.xml (original) +++ MoreFieldsAndWidgets/Products.MasterSelectWidget/branches/radio/Products/MasterSelectWidget/profiles/demo/types/MasterSelectDemo.xml Wed Aug 25 12:54:56 2010 @@ -1,6 +1,6 @@ <?xml version="1.0"?> <object name="MasterSelectDemo" meta_type="Factory-based Type Information" - xmlns:i18n="http://xml.zope.org/namespaces/i18n"> + xmlns:i18n="http://xml.zope.org/namespaces/i18n" i18n_domain="plone"> <property name="title">Master Select Demo</property> <property name="description">Demo from MasterSelectWidget.</property> <property name="content_icon">document_icon.gif</property> |