diff --git a/fields/__init__.py b/fields/__init__.py index c650f85..431d89b 100644 --- a/fields/__init__.py +++ b/fields/__init__.py @@ -76,6 +76,26 @@ class Field: tagName=field.master and 'slave' or ''; layoutTarget=field">:tool.pxLayoutedObject''') + def doRender(self, layoutType, request, context=None, name=None): + '''Allows to call pxRender from code, to display the content of this + field in some specific context, for example in a Computed field.''' + if context == None: context = {} + context['layoutType'] = layoutType + context['field'] = self + context['name'] = name or self.name + # We may be executing a PX on a given object or on a given object tied + # through a Ref. + ctx = request.pxContext + if 'obj' not in context: + context['obj'] = ('tied' in ctx) and ctx['tied'] or ctx['obj'] + context['zobj'] = context['obj'].o + # Copy some keys from the context of the currently executed PX. + for k in ('tool', 'ztool', 'req', '_', 'q', 'url', 'dright', 'dleft', \ + 'inPopup'): + if k in context: continue + context[k] = ctx[k] + return self.pxRender(context).encode('utf-8') + # Displays a field label. pxLabel = Px('''''') diff --git a/fields/string.py b/fields/string.py index 9653f70..f7d599b 100644 --- a/fields/string.py +++ b/fields/string.py @@ -113,9 +113,11 @@ class String(Field): # pxView part for format String.XHTML. pxViewRich = Px('''
::value or '-'
-
::value or '-'
- ''') + +
::value or '-'
+ +
''') # PX displaying the language code and name besides the part of the # multilingual field storing content in this language. @@ -618,7 +620,6 @@ class String(Field): def getIndexValue(self, obj, forSearch=False): '''Pure text must be extracted from rich content; multilingual content must be concatenated.''' - print 'INDEX value computing...', self.name, obj.title isXhtml = self.format == String.XHTML if self.isMultilingual(): res = self.getValue(obj) @@ -639,7 +640,6 @@ class String(Field): # Ugly catalog: if value is an empty string or None, it keeps the # previous index value. if res in self.emptyValuesCatalogIgnored: res = ' ' - print 'INDEX value for', self.name, 'is', res return res def getPossibleValues(self, obj, withTranslations=False, @@ -815,8 +815,18 @@ class String(Field): '''Stores the new field value from an Ajax request, or do nothing if the action was canceled.''' rq = obj.REQUEST - if rq.get('cancel') != 'True': - self.store(obj, self.getStorableValue(rq['fieldContent'])) + if rq.get('cancel') == 'True': return + requestValue = rq['fieldContent'] + if self.isMultilingual(): + # We get a partial value, for one language only. + language = rq['languageOnly'] + v = self.getUnilingualStorableValue(requestValue) + getattr(obj.aq_base, self.name)[language] = v + part = ' (%s)' % language + else: + self.store(obj, self.getStorableValue(requestValue)) + part = '' + obj.log('Ajax-edited %s%s on %s.' % (self.name, part, obj.id)) def getIndexType(self): '''Index type varies depending on String parameters.''' @@ -893,18 +903,20 @@ class String(Field): return 'CKEDITOR.replace("%s", {%s})' % \ (name, self.getCkParams(obj, language)) - def getJsInlineInit(self, obj, language): + def getJsInlineInit(self, obj, name, language): '''Gets the Javascript init code for enabling inline edition of this field (rich text only). If the field is multilingual, the current - p_language is given. Else, p_language is None.''' + p_language is given and p_name includes it. Else, p_language is + None.''' uid = obj.id - name = not language and self.name or ('%s_%s' % (self.name, language)) + fieldName = language and name.rsplit('_',1)[0] or name + lg = language or '' return "CKEDITOR.disableAutoInline = true;\n" \ "CKEDITOR.inline('%s_%s_ck', {%s, on: {blur: " \ "function( event ) { var content = event.editor.getData(); " \ - "doInlineSave('%s', '%s', '%s', content)}}})" % \ - (uid, name, self.getCkParams(obj, language), uid, name, - obj.absolute_url()) + "doInlineSave('%s','%s','%s',content,'%s')}}})" % \ + (uid, name, self.getCkParams(obj, language), uid, fieldName, + obj.absolute_url(), lg) def isSelected(self, obj, fieldName, vocabValue, dbValue): '''When displaying a selection box (only for fields with a validator diff --git a/gen/ui/appy.js b/gen/ui/appy.js index 01a10a2..cdedcf8 100644 --- a/gen/ui/appy.js +++ b/gen/ui/appy.js @@ -110,6 +110,7 @@ function getAjaxHook(hookId) { for the result of an ajax request. If p_hookId starts with ':', we search the element in the top browser window, not in the current one that can be an iframe.*/ + if (!hookId) return; var container = window.document; var startIndex = 0; if (hookId[0] == ':') { @@ -126,7 +127,7 @@ function getAjaxChunk(pos) { if ( (typeof(xhrObjects[pos]) != 'undefined') && (xhrObjects[pos].freed == 0)) { var hook = xhrObjects[pos].hook; - if (xhrObjects[pos].xhr.readyState == 1) { + if (hook && (xhrObjects[pos].xhr.readyState == 1)) { // The request has been initialized: display the waiting radar var hookElem = getAjaxHook(hook); if (hookElem) @@ -135,7 +136,8 @@ function getAjaxChunk(pos) { if (xhrObjects[pos].xhr.readyState == 4) { // We have received the HTML chunk var hookElem = getAjaxHook(hook); - if (hookElem && (xhrObjects[pos].xhr.status == 200)) { + var responseOk = (xhrObjects[pos].xhr.status == 200); + if (hookElem && responseOk) { injectChunk(hookElem, xhrObjects[pos].xhr.responseText); // Call a custom Javascript function if required if (xhrObjects[pos].onGet) { @@ -146,8 +148,8 @@ function getAjaxChunk(pos) { for (var i=0; i