# HG changeset patch # User Sylvain Thénault # Date 1242732089 -7200 # Node ID b2fe73a558995393863cad8bfe42c4fa388349a3 # Parent 94dc8ccd320ba7bfdfe089b4d994d87674b7a89a# Parent 118c7528d08f6d96eaad3b397d044ad4ca7bfcd4 merge diff -r 94dc8ccd320b -r b2fe73a55899 web/data/cubicweb.edition.js --- a/web/data/cubicweb.edition.js Tue May 19 13:08:51 2009 +0200 +++ b/web/data/cubicweb.edition.js Tue May 19 13:21:29 2009 +0200 @@ -342,11 +342,11 @@ } -function handleFormValidationResponse(formid, onsuccess, result) { +function handleFormValidationResponse(formid, onsuccess, onfailure, result) { // Success if (result[0]) { if (onsuccess) { - return onsuccess(result[1]); + return onsuccess(result[1], formid); } else { document.location.href = result[1]; return ; @@ -365,6 +365,9 @@ _displayValidationerrors(formid, descr[0], descr[1]); updateMessage(_("please correct errors below")); document.location.hash = '#header'; + if (onfailure){ + onfailure(formid); + } return false; } @@ -426,7 +429,7 @@ * to the appropriate URL. Otherwise, the validation errors are displayed * around the corresponding input fields. */ -function validateForm(formid, action, onsuccess) { +function validateForm(formid, action, onsuccess, onfailure) { try { var zipped = formContents(formid); var d = asyncRemoteExec('validate_form', action, zipped[0], zipped[1]); @@ -435,7 +438,7 @@ return false; } function _callback(result, req) { - handleFormValidationResponse(formid, onsuccess, result); + handleFormValidationResponse(formid, onsuccess, onfailure, result); } d.addCallback(_callback); return false; diff -r 94dc8ccd320b -r b2fe73a55899 web/data/cubicweb.preferences.css --- a/web/data/cubicweb.preferences.css Tue May 19 13:08:51 2009 +0200 +++ b/web/data/cubicweb.preferences.css Tue May 19 13:21:29 2009 +0200 @@ -6,28 +6,14 @@ */ -table.preferences td{ - padding: 0 0.5em 1em; +.preferences .validateButton{ + margin-top:0px; } fieldset.preferences{ border : 1px solid #CFCEB7; - margin:1em 0; - padding:0 1em 1em; -} - -div.preffield { - margin-bottom: 0.8em ; -} - -/* -div.preffield label{ - font-size:110% - } -*/ - -div.prefinput{ - margin:.3em 0; + margin:7px 1em 0; + padding:2px 6px 6px; } div.componentLink{ @@ -36,35 +22,49 @@ a.componentTitle{ font-weight:bold; - color: #000; + color: #000/*#0083AB;*/ } a.componentTitle:visited{ color: #000; } - - h2.propertiesform a{ display:block; margin: 10px 0px 6px 0px; font-weight: bold; - color: #222211; + color: #000; padding: 0.2em 0.2em 0.2em 16px; background:#eeedd9 url("puce_down.png") 3px center no-repeat; - font-size:76%; + font-size:89%; +} + +h2.propertiesform a:hover{ + background-color:#cfceb7; } -h2.propertiesform a:hover{ - color:#000; - background-color:#cfceb7; +h2.propertiesform a:hover, +h2.propertiesform a:visited{ text-decoration:none; + color: #000; } +div.preffield { + margin-bottom: 5px; + padding:2px 5px; + background:#eeedd9; +} + +div.prefinput{ + margin:.3em; +} + + div.prefinput select.changed, div.prefinput input.changed{ - background:#eeedd9; - border: 1px solid #eeedd9; + border: 1px solid #000; + font-weight:bold; + } div.prefinput select, @@ -74,23 +74,26 @@ } .prefinput input.error { - background:transparent url(error.png) no-repeat scroll 100% 50% !important; + /* background:#fff url(error.png) no-repeat scroll 100% 50% !important; */ + border:1px solid red !important; + color:red; + padding-right:1em; } div.formsg{ font-weight:bold; margin:0.5em 0px; - } +} -div.formsg .critical{ +div.critical{ color:red; padding-left:20px; background:#fff url(critical.png) no-repeat; } -div.formsg .message{ +div.formsg .msg{ color : green; } @@ -105,11 +108,6 @@ cursor: default; } -.error{ - color:red; - padding-right:1em; - } - div.openlink{ display:inline; - } \ No newline at end of file + } diff -r 94dc8ccd320b -r b2fe73a55899 web/data/cubicweb.preferences.js --- a/web/data/cubicweb.preferences.js Tue May 19 13:08:51 2009 +0200 +++ b/web/data/cubicweb.preferences.js Tue May 19 13:21:29 2009 +0200 @@ -4,11 +4,9 @@ * move me in a more appropriate place */ -function toggleVisibility(elemId, cookiename) { - _clearPreviousMessages(); - jqNode(elemId).toggleClass('hidden'); - asyncRemoteExec('set_cookie', cookiename, - jQuery('#' + elemId).attr('class')); +function togglePrefVisibility(elemId) { + clearPreviousMessages(); + jQuery('#' + elemId).toggleClass('hidden'); } function closeFieldset(fieldsetid){ @@ -43,44 +41,25 @@ } function validatePrefsForm(formid){ - var form = getNode(formid); freezeFormButtons(formid); - try { - var d = _sendForm(formid, null); - } catch (ex) { - log('got exception', ex); - return false; - } - function _callback(result, req) { - _clearPreviousMessages(); - _clearPreviousErrors(formid); - // success - if(result[0]){ - return submitSucces(formid) - } - // Failures - unfreezeFormButtons(formid); - var descr = result[1]; - if (!isArrayLike(descr) || descr.length != 2) { - log('got strange error :', descr); - updateMessage(descr); - return ; - } - _displayValidationerrors(formid, descr[0], descr[1]); - var dom = DIV({'class':'critical'}, - _("please correct errors below")); - jQuery(form).find('div.formsg').empty().append(dom); - updateMessage(_("")); - return false; - } - d.addCallback(_callback); - return false; + clearPreviousMessages(); + clearPreviousErrors(formid); + return validateForm(formid, null, submitSucces, submitFailure); } -function submitSucces(formid){ +function submitFailure(formid){ + var form = jQuery('#'+formid); + var dom = DIV({'class':'critical'}, + _("please correct errors below")); + jQuery(form).find('div.formsg').empty().append(dom); + // clearPreviousMessages() + jQuery(form).find('span.error').next().focus(); +} + +function submitSucces(url, formid){ var form = jQuery('#'+formid); setCurrentValues(form); - var dom = DIV({'class':'message'}, + var dom = DIV({'class':'msg'}, _("changes applied")); jQuery(form).find('div.formsg').empty().append(dom); jQuery(form).find('input').removeClass('changed'); @@ -88,13 +67,13 @@ return; } -function _clearPreviousMessages() { +function clearPreviousMessages() { jQuery('div#appMsg').addClass('hidden'); jQuery('div.formsg').empty(); } -function _clearPreviousErrors(formid) { - jQuery('#' + formid + ' span.error').remove(); +function clearPreviousErrors(formid) { + jQuery('#err-value:' + formid).remove(); } @@ -111,20 +90,20 @@ unfreezeButtons = _checkValue(jQuery(this), unfreezeButtons); } }); - + if (unfreezeButtons){ unfreezeFormButtons(form.attr('id')); }else{ if (!success){ - _clearPreviousMessages(); + clearPreviousMessages(); } - _clearPreviousErrors(form.attr('id')); + clearPreviousErrors(form.attr('id')); freezeFormButtons(form.attr('id')); } } function _checkValue(input, unfreezeButtons){ - var currentValueInput = jQuery("input[id=current-" + input.attr('name') + "]"); + var currentValueInput = jQuery("input[name=current-" + input.attr('name') + "]"); if (currentValueInput.attr('value') != input.attr('value')){ input.addClass('changed'); unfreezeButtons = true; @@ -138,14 +117,13 @@ function setCurrentValues(form){ - jQuery(form).find('input[id^=current-value]').each(function () { + jQuery(form).find('input[name^=current-value]').each(function () { var currentValueInput = jQuery(this); - var name = currentValueInput.attr('id').split('-')[1]; + var name = currentValueInput.attr('name').split('-')[1]; jQuery(form).find("[name=" + name + "]").each(function (){ var input = jQuery(this); if(input.attr('type')=='radio'){ if(input.attr('checked')){ - log(input.attr('value')); currentValueInput.attr('value', input.attr('value')); } }else{ @@ -155,7 +133,6 @@ }); } - function initEvents(){ jQuery('form').each(function() { var form = jQuery(this); @@ -169,6 +146,7 @@ form.find('select').change(function(){ checkValues(form); }); + setCurrentValues(form); }); } diff -r 94dc8ccd320b -r b2fe73a55899 web/formrenderers.py --- a/web/formrenderers.py Tue May 19 13:08:51 2009 +0200 +++ b/web/formrenderers.py Tue May 19 13:21:29 2009 +0200 @@ -83,13 +83,13 @@ return tags.label(label, **attrs) def render_help(self, form, field): - help = [ u'
' ] + help = [] descr = field.help if descr: - help.append('%s' % form.req._(descr)) + help.append('
%s
' % form.req._(descr)) example = field.example_format(form.req) if example: - help.append('(%s: %s)' + help.append('
(%s: %s)
' % (form.req._('sample format'), example)) return u' '.join(help) diff -r 94dc8ccd320b -r b2fe73a55899 web/views/cwproperties.py --- a/web/views/cwproperties.py Tue May 19 13:08:51 2009 +0200 +++ b/web/views/cwproperties.py Tue May 19 13:21:29 2009 +0200 @@ -17,6 +17,7 @@ from cubicweb.view import StartupView from cubicweb.web import uicfg, stdmsgs from cubicweb.web.form import CompositeForm, EntityFieldsForm, FormViewMixIn +from cubicweb.web.formrenderers import FormRenderer from cubicweb.web.formfields import FIELDS, StringField from cubicweb.web.formwidgets import Select, Button, SubmitButton from cubicweb.web.views import primary @@ -48,10 +49,9 @@ _('category') -def make_togglable_link(nodeid, label, cookiename): +def make_togglable_link(nodeid, label): """builds a HTML link that switches the visibility & remembers it""" - action = u"javascript: toggleVisibility('%s', '%s')" % \ - (nodeid, cookiename) + action = u"javascript: togglePrefVisibility('%s')" % nodeid return u'%s' % (action, label) def css_class(someclass): @@ -95,7 +95,7 @@ def call(self, **kwargs): """The default view representing the application's index""" - self.req.add_js('cubicweb.preferences.js') + self.req.add_js(('cubicweb.edition.js', 'cubicweb.preferences.js', 'cubicweb.ajax.js')) self.req.add_css('cubicweb.preferences.css') vreg = self.vreg values = self.defined_keys @@ -113,41 +113,51 @@ mainopts.setdefault(parts[0], []).append(key) # precompute form to consume error message for group, keys in mainopts.items(): - mainopts[group] = self.form(keys, True) + mainopts[group] = self.form(group, keys, False) + for group, objects in groupedopts.items(): for oid, keys in objects.items(): - groupedopts[group][oid] = self.form(keys, True) + groupedopts[group][oid] = self.form(group + '-' + oid, keys, True) + w = self.w req = self.req _ = req._ w(u'

%s

\n' % _(self.title)) - # we don't want this in each sub-forms + # we don't want this in each sub-forms XXX w(u'
%s
' % self.req._('validating...')) for label, group, form in sorted((_(g), g, f) for g, f in mainopts.iteritems()): status = css_class(self._group_status(group)) w(u'

%s

\n' % - (make_togglable_link('fieldset_' + group, label, - self._cookie_name(group)))) + (make_togglable_link('fieldset_' + group, label.capitalize()))) w(u'
' % (group, status)) + w(u'
') w(form) - w(u'
') + w(u'') + for label, group, objects in sorted((_(g), g, o) for g, o in groupedopts.iteritems()): status = css_class(self._group_status(group)) w(u'

%s

\n' % - (make_togglable_link('fieldset_' + group, label, - self._cookie_name(group)))) + (make_togglable_link('fieldset_' + group, label.capitalize()))) w(u'
' % (group, status)) - for label, oid, form in sorted((self.req.__('%s_%s' % (group, o)), o, f) - for o, f in objects.iteritems()): - w(u'
') - w(u'%s\n' % label) + + # create selection + sorted_objects = sorted((self.req.__('%s_%s' % (group, o)), o, f) + for o, f in objects.iteritems()) + for label, oid, form in sorted_objects: + w(u'''') docmsgid = '%s_%s_description' % (group, oid) doc = _(docmsgid) if doc != docmsgid: - w(u'

%s

' % html_escape(doc)) - w(form) + w(u'
%s
' % html_escape(doc).capitalize()) + + w(u'
' + % {'oid':oid, 'group':group}) + w(form) w(u'
') w(u'
') @@ -175,20 +185,22 @@ entity['value'] = self.vreg.property_value(key) return entity - def form(self, keys, splitlabel=False): - buttons = [SubmitButton(), - Button(stdmsgs.BUTTON_CANCEL, cwaction='cancel')] - form = CompositeForm(self.req, domid=None, action=self.build_url(), - form_buttons=buttons, + def form(self, formid, keys, splitlabel=False): + buttons = [SubmitButton()] + form = CompositeForm(self.req, domid=formid, action=self.build_url(), + form_buttons=buttons, + onsubmit="return validatePrefsForm('%s')" % formid, submitmsg=self.req._('changes applied')) - path = self.req.relative_path() + path = self.req.relative_path() if '?' in path: path, params = path.split('?', 1) form.form_add_hidden('__redirectparams', params) form.form_add_hidden('__redirectpath', path) for key in keys: self.form_row(form, key, splitlabel) - return form.form_render(display_progress_div=False) + renderer = EPropertiesFormRenderer() + return form.form_render(display_progress_div=False, + renderer=renderer) def form_row(self, form, key, splitlabel): entity = self.entity_for_key(key) @@ -196,15 +208,16 @@ label = key.split('.')[-1] else: label = key - subform = EntityFieldsForm(self.req, entity=entity, set_error_url=False) + subform = EntityFieldsForm(self.req, entity=entity, set_error_url=False) + subform.append_field(PropertyValueField(name='value', label=label, eidparam=True)) subform.vreg = self.vreg subform.form_add_hidden('pkey', key, eidparam=True) + subform.form_add_hidden("current-value:%s" % entity.eid,) form.form_add_subform(subform) return subform - - + def is_user_prefs(cls, req, rset, row=None, col=0, **kwargs): return req.user.eid == rset[row or 0][col] @@ -326,7 +339,7 @@ if vocab is not None: if callable(vocab): # list() just in case its a generator function - self.choices = list(vocab(form.req)) + self.choices = list(vocab(form.req)) else: self.choices = vocab wdg = Select() @@ -338,6 +351,30 @@ wdg.attrs.setdefault('size', 3) self.widget = wdg +class EPropertiesFormRenderer(FormRenderer): + """specific renderer for cwproperties""" + + def open_form(self, form, values): + err = '
' + return super(EPropertiesFormRenderer, self).open_form(form, values) + err + + def _render_fields(self, fields, w, form): + for field in fields: + w(u'
\n') + if self.display_label: + w(u'%s' % self.render_label(form, field)) + error = form.form_field_error(field) + w(u'%s' % self.render_help(form, field)) + w(u'
') + w(field.render(form, self)) + w(u'
') + w(u'
') + + def render_buttons(self, w, form): + w(u'
\n') + for button in form.form_buttons: + w(u'%s\n' % button.render(form)) + w(u'
') uicfg.autoform_field.tag_attribute(('CWProperty', 'pkey'), PropertyKeyField) uicfg.autoform_field.tag_attribute(('CWProperty', 'value'), PropertyValueField)