Beispiel #1
0
 def _render(self, form, field, renderer):
     entity = form.edited_entity
     domid = field.dom_id(form).replace(':', r'\\:')
     if callable(self.autocomplete_initfunc):
         data = self.autocomplete_initfunc(form, field)
     else:
         data = xml_escape(self._get_url(entity, field))
     form._cw.add_onload(
         u'$("#%s").cwautocomplete(%s, %s);' %
         (domid, json_dumps(data), json_dumps(self.autocomplete_settings)))
     return super(AutoCompletionWidget, self)._render(form, field, renderer)
Beispiel #2
0
 def call(self, rset=None, tab_id=None, jsbind=None, renderer=None, options=None,
          divid=None, legend=None, colors=None,
          width=450, height=300, displayfilter=False, mainvar=None, title=None,
          displayactions=False, actions=None):
     # Refefine the call() function to allow to pass an rset
     if self._cw.ie_browser():
         self._cw.add_js('excanvas.js')
     self._cw.add_js(('jquery.jqplot.js', 'cubes.jqplot.js', 'cubes.jqplot.ext.js'))
     self._cw.add_css('jquery.jqplot.min.css')
     data, ticks = self.get_data(rset)
     if legend is None:
         legend = self.default_legend
     if divid is None:
         divid = u'figure%s' % self._cw.varmaker.next()
     if renderer is None:
         renderer = self.default_renderer
     serie_options = {'renderer': self.renderer(self.renderers, renderer)}
     if options is None:
         options = self.default_options
     serie_options['rendererOptions']= options
     options = {'series': [serie_options],
                'legend': legend,
                'title': title,
                }
     if ticks:
         self._cw.html_headers.add_onload('ticks = %s' % json_dumps(ticks))
         options['axes'] = {'xaxis': {'ticks': JSString('ticks'),
                                      'renderer': JSString('$.jqplot.CategoryAxisRenderer')}}
         self._cw.add_js('plugins/jqplot.categoryAxisRenderer.min.js')
     if colors is not None:
         options['seriesColors'] = colors
     self.set_custom_options(options)
     # Allow an onload on tab/pill show
     js_onload  = self.onload % {'id': divid, 'data': json_dumps([data]),
                                 'options': js_dumps(options)}
     if not tab_id:
         self._cw.html_headers.add_onload(js_onload)
     else:
         self._cw.html_headers.add_onload("""$('a[data-toggle="%s"]').on('shown',
         function (e) {%s})""" % (tab_id, js_onload))
     self.div_holder(divid, width, height)
     if displayfilter and not 'fromformfilter' in self._cw.form:
         self.form_filter(divid, mainvar)
     if displayactions and not 'fromformfilter' in self._cw.form:
         self.display_actions(divid, actions)
     # Add a js bind function
     if jsbind:
         self._cw.html_headers.add_onload("""$('#%s').bind('jqplotDataClick',%s)"""
                                          % (divid, jsbind))
Beispiel #3
0
 def wdata(self, data):
     if '_indent' in self._cw.form:
         indent = int(self._cw.form['_indent'])
     else:
         indent = None
     # python's json.dumps escapes non-ascii characters
     self.w(json_dumps(data, indent=indent).encode('ascii'))
Beispiel #4
0
def wdata(self, udata):
    """ Mixin class for json views.

    Handles the following optional request parameters:

    - '_indent': must be an integer. If found, it is used to pretty print
      json output.
    - '_binary': must be an integer. If found, it will decode binary fields.
    """
    # Select indentation
    if "_indent" in self._cw.form:
        indent = int(self._cw.form["_indent"])
    else:
        indent = None

    # Convert binary if requested
    if "_binary" in self._cw.form:
        data = []
        for row in udata:
            for index, item in enumerate(row):
                if isinstance(item, Binary):
                    row[index] = json.loads(item.getvalue())
            data.append(row)
    else:
        data = udata

    # Dump in html page
    self.w(json_dumps(data, indent=indent))
Beispiel #5
0
    def build_unrelated_select_div(self,
                                   entity,
                                   rschema,
                                   role,
                                   is_cell=False,
                                   hidden=True):
        options = []
        divid = 'div%s_%s_%s' % (rschema.type, role, entity.eid)
        selectid = 'select%s_%s_%s' % (rschema.type, role, entity.eid)
        if rschema.symmetric or role == 'subject':
            targettypes = rschema.objects(entity.e_schema)
            etypes = '/'.join(
                sorted(etype.display_name(self._cw) for etype in targettypes))
        else:
            targettypes = rschema.subjects(entity.e_schema)
            etypes = '/'.join(
                sorted(etype.display_name(self._cw) for etype in targettypes))
        etypes = uilib.cut(
            etypes, self._cw.property_value('navigation.short-line-size'))
        options.append('<option>%s %s</option>' %
                       (self._cw._('select a'), etypes))
        options += self._get_select_options(entity, rschema, role)
        options += self._get_search_options(entity, rschema, role, targettypes)
        relname, role = self._cw.form.get('relation').rsplit('_', 1)
        return u"""\
<div class="%s" id="%s">
  <select id="%s"
          onchange="javascript: addPendingInsert(this.options[this.selectedIndex], %s, %s, '%s');">
    %s
  </select>
</div>
""" % (hidden and 'hidden' or '', divid, selectid,
        xml_escape(json_dumps(entity.eid)), is_cell and 'true'
        or 'null', relname, '\n'.join(options))
Beispiel #6
0
 def _render_fields(self, fields, w, form):
     if form.parent_form is not None:
         entity = form.edited_entity
         values = form.form_previous_values
         qeid = eid_param('eid', entity.eid)
         cbsetstate = "setCheckboxesState('eid', %s, 'checked')" % \
                      xml_escape(json_dumps(entity.eid))
         w(u'<tr class="%s">' % (entity.cw_row % 2 and u'even' or u'odd'))
         # XXX turn this into a widget used on the eid field
         w(u'<td>%s</td>' % checkbox('eid', entity.eid,
                                     checked=qeid in values))
         for field in fields:
             error = form.field_error(field)
             if error:
                 w(u'<td class="error">')
                 self.render_error(w, error)
             else:
                 w(u'<td>')
             if isinstance(field.widget, (fwdgs.Select, fwdgs.CheckBox,
                                          fwdgs.Radio)):
                 field.widget.attrs['onchange'] = cbsetstate
             elif isinstance(field.widget, fwdgs.Input):
                 field.widget.attrs['onkeypress'] = cbsetstate
             # XXX else
             w(u'<div>%s</div>' % field.render(form, self))
             w(u'</td>\n')
         w(u'</tr>')
     else:
         self._main_display_fields = fields
Beispiel #7
0
 def render(self, form, field, renderer):
     stream = []
     w = stream.append
     req = form._cw
     _ = req._
     eid = form.edited_entity.eid
     w(u'<table id="relatedEntities">')
     for rschema, role, related in field.relations_table(form):
         # already linked entities
         if related:
             label = rschema.display_name(
                 req, role, context=form.edited_entity.cw_etype)
             w(u'<tr><th class="labelCol">%s</th>' % label)
             w(u'<td>')
             w(u'<ul class="list-unstyled">')
             for viewparams in related:
                 w(u'<li>%s<span id="span%s" class="%s">%s</span></li>' %
                   (viewparams[1], viewparams[0], viewparams[2],
                    viewparams[3]))
             if not form.force_display and form.maxrelitems < len(related):
                 link = (
                     u'<span>[<a '
                     'href="javascript: window.location.href+=\'&amp;__force_display=1\'"'
                     '>%s</a>]</span>' % _('view all'))
                 w(u'<li>%s</li>' % link)
             w(u'</ul>')
             w(u'</td>')
             w(u'</tr>')
     pendings = list(field.restore_pending_inserts(form))
     if not pendings:
         w(u'<tr><th>&#160;</th><td>&#160;</td></tr>')
     else:
         for row in pendings:
             # soon to be linked to entities
             w(u'<tr id="tr%s">' % row[1])
             w(u'<th>%s</th>' % row[3])
             w(u'<td>')
             w(u'<a class="handle" title="%s" href="%s">[x]</a>' %
               (_('cancel this insert'), row[2]))
             w(u'<a id="a%s" class="editionPending" href="%s">%s</a>' %
               (row[1], row[4], xml_escape(row[5])))
             w(u'</td>')
             w(u'</tr>')
     w(u'<tr id="relationSelectorRow_%s" class="separator">' % eid)
     w(u'<th class="labelCol">')
     w(u'<select id="relationSelector_%s" '
       'onchange="javascript:showMatchingSelect(this.options[this.selectedIndex].value,%s);">'
       % (eid, xml_escape(json_dumps(eid))))
     w(u'<option value="">%s</option>' % _('select a relation'))
     for i18nrtype, rschema, role in field.relations:
         # more entities to link to
         w(u'<option value="%s_%s">%s</option>' %
           (rschema, role, i18nrtype))
     w(u'</select>')
     w(u'</th>')
     w(u'<td id="unrelatedDivs_%s"></td>' % eid)
     w(u'</tr>')
     w(u'</table>')
     return '\n'.join(stream)
Beispiel #8
0
def toggleable_relation_link(eid, nodeid, label='x'):
    """return javascript snippet to delete/undelete a relation between two
    entities
    """
    js = u"javascript: togglePendingDelete('%s', %s);" % (
        nodeid, xml_escape(json_dumps(eid)))
    return u'[<a class="handle" href="%s" id="handle%s">%s</a>]' % (js, nodeid,
                                                                    label)
Beispiel #9
0
    def response(self, domid, status, args, entity):
        callback = str(self._cw.form.get('__onsuccess', 'null'))
        errback = str(self._cw.form.get('__onfailure', 'null'))
        cbargs = str(self._cw.form.get('__cbargs', 'null'))
        self._cw.set_content_type('text/html')
        jsargs = json_dumps((status, args, entity))
        return """<script type="text/javascript">
 window.parent.handleFormValidationResponse('%s', %s, %s, %s, %s);
</script>""" % (domid, callback, errback, jsargs, cbargs)
Beispiel #10
0
 def serialize(self, content):
     if self.output_type is None:
         return content
     elif self.output_type == 'xhtml':
         self._cw.set_content_type(self._cw.html_content_type())
         return ''.join((u'<div>', content.strip(), u'</div>'))
     elif self.output_type == 'json':
         self._cw.set_content_type('application/json')
         return json_dumps(content)
     raise RemoteCallFailed('no serializer found for output type %s' %
                            self.output_type)
Beispiel #11
0
 def _render(self, form, field, renderer):
     req = form._cw
     if req.lang != 'en':
         req.add_js('jquery.ui.datepicker-%s.js' % req.lang)
     domid = field.dom_id(form, self.suffix)
     # XXX find a way to understand every format
     fmt = req.property_value('ui.date-format')
     picker_fmt = fmt.replace('%Y', 'yy').replace('%m',
                                                  'mm').replace('%d', 'dd')
     max_date = min_date = None
     if self.min_of:
         current = getattr(form.edited_entity, self.min_of)
         if current is not None:
             max_date = current.strftime(fmt)
     if self.max_of:
         current = getattr(form.edited_entity, self.max_of)
         if current is not None:
             min_date = current.strftime(fmt)
     req.add_onload(u'renderJQueryDatePicker("%s", "%s", "%s", %s, %s);' %
                    (domid, req.uiprops['CALENDAR_ICON'], picker_fmt,
                     json_dumps(min_date), json_dumps(max_date)))
     return self._render_input(form, field)
Beispiel #12
0
 def add_onload(self):
     fullcalendar_options = self.fullcalendar_options.copy()
     fullcalendar_options['events'] = self.get_events()
     # i18n
     # js callback to add a tooltip and to put html in event's title
     js = """
     var options = $.fullCalendar.regional('%s', %s);
     options.eventRender = function(event, $element) {
       // add a tooltip for each event
       var div = '<div class="tooltip">'+ event.description+ '</div>';
       $element.append(div);
       // allow to have html tags in event's title
       $element.find('span.fc-event-title').html($element.find('span.fc-event-title').text());
     };
     $("#%s").fullCalendar(options);
     """ #"
     self._cw.add_onload(js % (self._cw.lang, json_dumps(fullcalendar_options), self.calendar_id))
Beispiel #13
0
 def lazy_view_holder(self, w, entity, oid, registry='views'):
     """add a holder and return a URL that may be used to replace this
     holder by the html generate by the view specified by registry and
     identifier. Registry defaults to 'views'.
     """
     holderid = '%sHolder' % self.domid
     w(u'<div id="%s"></div>' % holderid)
     params = self.cw_extra_kwargs.copy()
     params.pop('view', None)
     params.pop('entity', None)
     form = params.pop('formparams', {})
     if entity.has_eid():
         eid = entity.eid
     else:
         eid = None
         form['etype'] = entity.cw_etype
         form['tempEid'] = entity.eid
     args = [json_dumps(x) for x in (registry, oid, eid, params)]
     return self._cw.ajax_replace_url(holderid,
                                      fname='render',
                                      arg=args,
                                      **form)
Beispiel #14
0
 def _build_args(self,
                 entity,
                 rtype,
                 role,
                 formid,
                 reload,
                 action,
                 extradata=None):
     divid = self._build_divid(rtype, role, entity.eid)
     event_args = {
         'divid': divid,
         'eid': entity.eid,
         'rtype': rtype,
         'formid': formid,
         'reload': json_dumps(reload),
         'action': action,
         'role': role,
         'vid': u''
     }
     if extradata:
         event_args.update(extradata)
     return event_args
Beispiel #15
0
    def render(self, form, field, renderer):
        stream = []
        w = stream.append
        req = form._cw
        _ = req._
        __ = _
        entity = form.edited_entity
        eid = entity.eid
        etype = entity.e_schema
        relative_url = '%s' % eid
        w(u'<div class="accordion form-relation" id="accordion_%s">' % eid)
        w_num_rel = 0
        for label, rschema, role in field.relations:
            # FIXME should be a more optimized way to get the name of
            # the target entity.
            targets = rschema.targets(etype, role)

            #----
            #    Agregar ciclo sobre targets
            #----
            for target in targets:
                if req.vreg.schema.eschema(target).has_perm(req, 'read'):
                    if w_num_rel == 0:
                        w(u'<div class="row-fluid">')
                    w_num_rel = w_num_rel + 1

                    linkto = '%s:%s:%s' % (rschema, eid, neg_role(role))
                    link_label = u'%s %s' % (req._('add'), req._(target))
                    lsearch = u'%s %s' % (req._('search'), req._(target))

                    relate_entity = (
                        u'<div class="relate-entity">%(relate_entity)s</div>' %
                        {
                            'relate_entity':
                            entity.view('autocomplete-edition-view',
                                        relation=rschema,
                                        role=role,
                                        etype_search=target,
                                        showname="E")
                        })

                    search_url = (
                        '<a href="?__mode=%(role)s:%(eid)s:%(rschema)s:'
                        '%(target)s&vid=search-associate"'
                        'class="btn btn-micro btn-link">'
                        '%(link_label)s'
                        '</a>' % {
                            'role': role,
                            'rschema': rschema,
                            'eid': eid,
                            'link_label': lsearch,
                            'target': target
                        })

                    add_new = (
                        '<a href="/add/%(target)s?__linkto=%(linkto)s'
                        '&__redirectpath=%(url)s&__redirectvid=edition "'
                        'class="btn btn-micro btn-link">'
                        '%(link_label)s'
                        '</a>' % {
                            'linkto': linkto,
                            'url': relative_url,
                            'link_label': link_label,
                            'target': target
                        })

                    w(
                        u'<div class="span4"><div class="accordion-group">'
                        u'<div class="accordion-heading container-fluid">'
                        u'    <div id="RDR_%(relation_name)s_%(role)s_%(target)s">'
                        u'        <a class="accordion-toggle" data-toggle="collapse" '
                        u'            data-parent="# accordion_%(eid)s" '
                        u'             href="#collapse_%(relation_name)s">'
                        u'             %(label)s'
                        u'        </a>'
                        u'    </div>'  # </div> de id_RDR..
                        u'    <div id="add-relation-combo">%(search)s %(add_new)s</div>'
                        u'</div>'  # </div> de accordion-heading
                        % {
                            'eid': eid,
                            'relation_name': rschema,
                            'target': target,
                            'label': label,
                            'search': search_url,
                            'add_new': add_new,
                            'role': role,
                            'relate-entity': relate_entity
                        })
                    w(u'<div id="collapse_%(relation)s" class="accordion-body collapse in">'
                      u'    <div class="accordion-inner">'
                      u'        <ul class="thumbnails">%(relate-entity)s' % {
                          'relation': rschema,
                          'relate-entity': relate_entity
                      })
                    #----
                    # Reemplazar los widgets desordenados de la vid=edition por tablas tipo any_rset
                    #----
                    if role == "subject":
                        subject_eid = eid
                        target_eid = 'eid-objeto'
                        rql = ('Any X,X WHERE X is %(target)s,Y is %(entity)s,'
                               ' Y %(relate)s X, Y eid %(eid)s ' % {
                                   'relate': rschema,
                                   'target': target,
                                   'entity': etype,
                                   'eid': eid
                               })
                    else:
                        subject_eid = 'eid-objeto'
                        target_eid = eid
                        rql = ('Any X,X WHERE X is %(target)s,Y is %(entity)s,'
                               ' X %(relate)s Y, Y eid %(eid)s' % {
                                   'relate': rschema,
                                   'target': target,
                                   'entity': etype,
                                   'eid': eid
                               })
                    rset = form._cw.execute(rql)
                    #----
                    #    Incluir el activador ([x]) de borrado de relaciones en la tabla preentada.
                    #        + cellvid redf-del-rel para el activador de borrado
                    #        + cellvid pending_del para que las relaciones seleccionadas se marquen  visualmente
                    #----
                    pending_deletes = get_pending_deletes(form._cw, eid)
                    ea_relation = rschema.type
                    param_but = '%s|%s|%s|%s|%s' % ('Y', eid, ea_relation,
                                                    role, str(pending_deletes))

                    kwargs = {
                        'ea_rel_entity': target,
                        'ea_relation': rschema,
                        'role': role,
                        'headers': (' '),
                        'cellvids': {
                            0: 'rdef-del-rel',
                            '_0': param_but
                        },
                        'limit': 10,
                        'rdefkwargs': {},
                        'title': u'no-widget-title',
                    }

                    w(form._cw.view('w-table', rset, 'null', **kwargs))
                    #----
                    w(u'    </div>'  # </div> de accordion-inner
                      u'</div></div>'  # </div> de accordion-body-collapse  -- </div> accordion-group
                      u'</div>')  # </div> de span4

                    if w_num_rel == 3:  # controlar el cambio de row de los widgets
                        w(u'</div>')
                        w_num_rel = 0
        if w_num_rel > 0:
            w(u'</div>')
        w(u'</div>' u'</div>')

        # FIXME try to change this table with a fancy html code.

        pendings = list(field.restore_pending_inserts(form))

        w(u'<table id="relatedEntities">')
        if not pendings:
            w(u'<tr><th>&#160;</th><td>&#160;</td></tr>')
        else:
            for row in pendings:
                # soon to be linked to entities
                w(u'<tr id="tr%s">' % row[1])
                w(u'<th>%s</th>' % row[3])
                w(u'<td>')
                w(u'<a class="handle" title="%s" href="%s">[x]</a>' %
                  (_('cancel this insert'), row[2]))
                w(u'<a id="a%s" class="editionPending" href="%s">%s</a>' %
                  (row[1], row[4], xml_escape(row[5])))
                w(u'</td>')
                w(u'</tr>')
        w(u'<tr id="relationSelectorRow_%s" class="separator">' % eid)
        w(u'<th class="labelCol">')
        w(u'<select id="relationSelector_%s" tabindex="%s" '
          u'onchange="javascript:showMatchingSelect'
          u'(this.options[this.selectedIndex].value,%s);">' %
          (eid, req.next_tabindex(), xml_escape(json_dumps(eid))))
        w(u'<option value="">%s</option>' % _('select a relation'))
        for i18nrtype, rschema, role in field.relations:
            # more entities to link to
            w(u'<option value="%s_%s">%s</option>' %
              (rschema, role, i18nrtype))
        w(u'</select>')
        w(u'</th>')
        w(u'<td id="unrelatedDivs_%s"></td>' % eid)
        w(u'</tr>')
        w(u'</table>')
        return '\n'.join(stream)
Beispiel #16
0
    def generate_form(self,
                      w,
                      rset,
                      divid,
                      vid,
                      mainvar=None,
                      paginate=False,
                      cssclass='',
                      hiddens=None,
                      **kwargs):
        """display a form to filter some view's content

        :param w:        Write function

        :param rset:     ResultSet to be filtered

        :param divid:    Dom ID of the div where the rendering of the view is done.
        :type divid:     string

        :param vid:      ID of the view display in the div
        :type vid:       string

        :param paginate: Is the view paginated?
        :type paginate:  boolean

        :param cssclass: Additional css classes to put on the form.
        :type cssclass:  string

        :param hiddens:  other hidden parametters to include in the forms.
        :type hiddens:   dict from extra keyword argument
        """
        # XXX Facet.context property hijacks an otherwise well-behaved
        #     vocabulary with its own notions
        #     Hence we whack here to avoid a clash
        kwargs.pop('context', None)
        baserql, wdgs = facets(self._cw,
                               rset,
                               context=self.__regid__,
                               mainvar=mainvar,
                               **kwargs)
        assert wdgs
        self._cw.add_js(self.needs_js)
        self._cw.add_css(self.needs_css)
        self._cw.html_headers.define_var('facetLoadingMsg',
                                         self._cw._('facet-loading-msg'))
        vidargs = {}
        facetargs = xml_escape(json_dumps([divid, vid, paginate, vidargs]))
        w(u'<form id="%sForm" class="%s" method="post" action="" '
          'cubicweb:facetargs="%s" >' % (divid, cssclass, facetargs))
        w(u'<fieldset>')
        if hiddens is None:
            hiddens = {}
        if mainvar:
            hiddens['mainvar'] = mainvar
        filter_hiddens(w, baserql, wdgs, **hiddens)
        self.layout_widgets(w, self.sorted_widgets(wdgs))

        # <Enter> is supposed to submit the form only if there is a single
        # input:text field. However most browsers will submit the form
        # on <Enter> anyway if there is an input:submit field.
        #
        # see: http://www.w3.org/MarkUp/html-spec/html-spec_8.html#SEC8.2
        #
        # Firefox 7.0.1 does not submit form on <Enter> if there is more than a
        # input:text field and not input:submit but does it if there is an
        # input:submit.
        #
        # IE 6 or Firefox 2 behave the same way.
        w(u'<input type="submit" class="hidden" />')
        #
        w(u'</fieldset>\n')
        w(u'</form>\n')
Beispiel #17
0
 def ajax_page_url(self, **params):
     divid = params.setdefault('divid', 'contentmain')
     params['rql'] = self.cw_rset.printable_rql()
     return js_href(
         "$(%s).loadxhtml(AJAX_PREFIX_URL, %s, 'get', 'swap')" %
         (json_dumps('#' + divid), js.ajaxFuncArgs('view', params)))
Beispiel #18
0
 def dumps(self):
     return json_dumps({'reason': self.reason})
Beispiel #19
0
 def newfunc(*args, **kwargs):
     value = function(*args, **kwargs)
     try:
         return json_dumps(value)
     except TypeError:
         return json_dumps(repr(value))