67 |
67 |
68 TRANSITIONAL_DOCTYPE = u'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" %s>\n' |
68 TRANSITIONAL_DOCTYPE = u'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" %s>\n' |
69 |
69 |
70 STRICT_DOCTYPE = u'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" %s>\n' |
70 STRICT_DOCTYPE = u'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" %s>\n' |
71 |
71 |
|
72 # base view object ############################################################ |
|
73 |
72 class View(AppRsetObject): |
74 class View(AppRsetObject): |
73 """abstract view class, used as base for every renderable object such |
75 """abstract view class, used as base for every renderable object such |
74 as views, templates, some components...web |
76 as views, templates, some components...web |
75 |
77 |
76 A view is instantiated to render a [part of a] result set. View |
78 A view is instantiated to render a [part of a] result set. View |
464 def write_doctype(self, xmldecl=True): |
466 def write_doctype(self, xmldecl=True): |
465 assert isinstance(self._stream, HTMLStream) |
467 assert isinstance(self._stream, HTMLStream) |
466 self._stream.doctype = self.doctype |
468 self._stream.doctype = self.doctype |
467 if not xmldecl: |
469 if not xmldecl: |
468 self._stream.xmldecl = u'' |
470 self._stream.xmldecl = u'' |
|
471 |
|
472 # concrete component base classes ############################################# |
|
473 |
|
474 class ReloadableMixIn(object): |
|
475 """simple mixin for reloadable parts of UI""" |
|
476 |
|
477 def user_callback(self, cb, args, msg=None, nonify=False): |
|
478 """register the given user callback and return an url to call it ready to be |
|
479 inserted in html |
|
480 """ |
|
481 self.req.add_js('cubicweb.ajax.js') |
|
482 if nonify: |
|
483 _cb = cb |
|
484 def cb(*args): |
|
485 _cb(*args) |
|
486 cbname = self.req.register_onetime_callback(cb, *args) |
|
487 return self.build_js(cbname, html_escape(msg or '')) |
|
488 |
|
489 def build_update_js_call(self, cbname, msg): |
|
490 rql = html_escape(self.rset.printable_rql()) |
|
491 return "javascript:userCallbackThenUpdateUI('%s', '%s', '%s', '%s', '%s', '%s')" % ( |
|
492 cbname, self.id, rql, msg, self.__registry__, self.div_id()) |
|
493 |
|
494 def build_reload_js_call(self, cbname, msg): |
|
495 return "javascript:userCallbackThenReloadPage('%s', '%s')" % (cbname, msg) |
|
496 |
|
497 build_js = build_update_js_call # expect updatable component by default |
|
498 |
|
499 def div_id(self): |
|
500 return '' |
|
501 |
|
502 |
|
503 class Component(ReloadableMixIn, View): |
|
504 """base class for components""" |
|
505 __registry__ = 'components' |
|
506 __registerer__ = yes_registerer |
|
507 __selectors__ = (yes,) |
|
508 property_defs = { |
|
509 _('visible'): dict(type='Boolean', default=True, |
|
510 help=_('display the box or not')), |
|
511 } |
|
512 |
|
513 def div_class(self): |
|
514 return '%s %s' % (self.propval('htmlclass'), self.id) |
|
515 |
|
516 def div_id(self): |
|
517 return '%sComponent' % self.id |