diff --git a/invenio/templates/page.html b/invenio/templates/page.html index 5fea41a13e..f7abc13093 100644 --- a/invenio/templates/page.html +++ b/invenio/templates/page.html @@ -34,6 +34,7 @@ {# Global CSS #} {%- css 'css/bootstrap.css', '00-invenio' -%} {%- css 'css/bootstrap-responsive.min.css', '00-invenio' -%} +{%- css 'css/bootstrap-multiselect.css', '00-invenio' -%} {%- css 'css/token-input.css', '00-invenio' -%} {%- css 'css/token-input-facebook.css', '00-invenio' -%} {%- css 'css/b2s-common.css', '00-invenio' -%} @@ -42,6 +43,7 @@ {# Global Javascript files #} {%- js 'js/jquery.min.js', '00-invenio' -%} {%- js 'js/bootstrap.js', '00-invenio' -%} +{%- js 'js/bootstrap-multiselect.js', '00-invenio' -%} {%- js 'js/jquery.tokeninput.js', '00-invenio' -%} {%- js 'js/invenio.js', '00-invenio' -%} diff --git a/simplestore/lib/simplestore_marc_handler.py b/simplestore/lib/simplestore_marc_handler.py index a8e56337f6..26b6025727 100644 --- a/simplestore/lib/simplestore_marc_handler.py +++ b/simplestore/lib/simplestore_marc_handler.py @@ -42,11 +42,12 @@ def add_basic_fields(rec, form, email): if form['title']: record_add_field(rec, '245', subfields=[('a', remove_html_markup(form['title']))]) - if form['creator']: - for kw in form['creator'].split(';'): - if kw and not kw.isspace(): - record_add_field(rec, '100', subfields=[('a', remove_html_markup(kw.strip()))]) - + if form['creator']: + fields = form.getlist('creator') + for f in fields: + if f and not f.isspace(): + record_add_field(rec, '100', subfields=[('a', remove_html_markup(f.strip()))]) + if form['domain']: record_add_field(rec, '980', subfields=[('a', remove_html_markup(form['domain']))]) pubfields = [] @@ -75,14 +76,18 @@ def add_basic_fields(rec, form, email): subfields=[('a', remove_html_markup(kw.strip()))]) if form['contributors']: - for kw in form['contributors'].split(';'): - record_add_field(rec, '700', subfields=[('a', remove_html_markup(kw.strip()))]) + fields = form.getlist('contributors') + for f in fields: + if f and not f.isspace(): + record_add_field(rec, '700', subfields=[('a', remove_html_markup(f.strip()))]) record_add_field(rec, '546', subfields=[('a', remove_html_markup(form['language']))]) # copying zenodo here, but I don't think 980 is the right MARC field if form['resource_type']: - record_add_field(rec, '980', subfields=[('a', remove_html_markup(form['resource_type']))]) + fields = form.getlist('resource_type') + for f in fields: + record_add_field(rec, '980', subfields=[('a', remove_html_markup(form['resource_type']))]) if form['alternate_identifier']: record_add_field(rec, '024', @@ -166,9 +171,12 @@ def add_domain_fields(rec, form): if fs.name != 'Generic': # TODO: this is brittle; get from somewhere for k in (fs.optional_fields + fs.basic_fields): if form[k]: - record_add_field(rec, '690', - subfields=[('a', k), ('b', form[k])]) - + fields = form.getlist(k) + for f in fields: + if f and not f.isspace(): + record_add_field(rec, '690', + subfields=[('a', k), ('b', f)]) + def add_epic_pid(rec, recid, checksum): """ Adds EPIC PID to the record. If registration fails, can diff --git a/simplestore/lib/simplestore_model/HTML5ModelConverter.py b/simplestore/lib/simplestore_model/HTML5ModelConverter.py index e7e2687f00..06d2eeeb9d 100644 --- a/simplestore/lib/simplestore_model/HTML5ModelConverter.py +++ b/simplestore/lib/simplestore_model/HTML5ModelConverter.py @@ -180,11 +180,17 @@ def __init__(self, placeholder="", **kwargs): class SelectWithInput(Select): def __call__(self, field, **kwargs): kwargs.setdefault('id', field.id) - html = [' 1: + html.append('class="multiselect" multiple="multiple" ') + html.append('%s>' % html_params(name=field.name, **kwargs)) + for val, label, selected in field.iter_choices(): html.append(self.render_option(val, label, selected)) html.append('') - html.append('' + if field.other: + html.append('' .format(html_params(name=field.name+"_input"), html_params(id=field.name+"_input"))) return HTMLString(''.join(html)) @@ -192,14 +198,46 @@ def __call__(self, field, **kwargs): class SelectFieldWithInput(SelectField): widget = SelectWithInput() + cardinality = "" + filtering = "" + other = "" - def __init__(self, other="", **field_args): - self.field_args = field_args + def __init__(self, other="", filtering="", cardinality="1", + data_provide="", data_source="", **field_args): # make list of tuples for SelectField (only once) - if isinstance(self.field_args['choices'][0], basestring): - self.field_args['choices'] = [(x,x) for x in field_args['choices']] - self.field_args['choices'].append(('other', other)) + self.cardinality = cardinality + self.other = other + self.filtering = filtering + if isinstance(data_source[0], basestring): + field_args['choices'] = [(x,x) for x in data_source] + field_args['choices'].append(('other', other)) super(SelectFieldWithInput, self).__init__(**field_args) + + +class AddFieldInput(Input): + input_type = "text" + + def __call__(self, field, **kwargs): + kwargs.setdefault('id', field.id) + html = ['
'] + html.append('
') + html.append('' + .format(field.placeholder, self.html_params(name=field.name, **kwargs))) + html.append('
' + .format(field.placeholder, field.cardinality, field.name)) + html.append('
') + html.append('
') + return HTMLString(''.join(html)) + +class AddField(StringField): + widget = AddFieldInput() + placeholder = "" + cardinality = "" + + def __init__(self, cardinality="n", placeholder="", **field_args): + self.placeholder = placeholder + self.cardinality = cardinality + super(AddField, self).__init__(**field_args) class HiddenInput(Input): @@ -269,19 +307,17 @@ def conv_String(self, field_args, **extra): if hidden: return hidden - if 'placeholder' in field_args: - return PlaceholderStringField(**field_args) - if 'data_provide' in field_args: - return TypeAheadStringField(**field_args) - - # SelectField - if 'choices' in field_args: - if 'other' in field_args: + if field_args['data_provide'] == 'typeahead': + return TypeAheadStringField(**field_args) + + if field_args['data_provide'] == 'select': return SelectFieldWithInput(**field_args) + + if 'cardinality' in field_args: + return AddField(**field_args) - if isinstance(field_args['choices'][0], basestring): - field_args['choices'] = [(x,x) for x in field_args['choices']] - return SelectField(**field_args) + if 'placeholder' in field_args: + return PlaceholderStringField(**field_args) return StringField(**field_args) diff --git a/simplestore/lib/simplestore_model/model.py b/simplestore/lib/simplestore_model/model.py index 82d19823f9..d601351c11 100644 --- a/simplestore/lib/simplestore_model/model.py +++ b/simplestore/lib/simplestore_model/model.py @@ -44,7 +44,7 @@ class SubmissionMetadata(db.Model): id = db.Column(db.Integer, primary_key=True) description = db.Column(db.Text(), nullable=False) - creator = db.Column(db.String(256)) # split on ; + creator = db.Column(db.String(256)) title = db.Column(db.String(256), nullable=False) open_access = db.Column(db.Boolean(), default=True) @@ -55,7 +55,7 @@ class SubmissionMetadata(db.Model): keywords = db.Column(db.String(256)) # split on , # optional - contributors = db.Column(db.String(256)) # split on ; + contributors = db.Column(db.String(256)) #language = db.Column(db.Enum(*babel.core.LOCALE_ALIASES.keys())) language = db.Column(db.String(128), default=language_default) resource_type = db.Column(db.String(256)) # XXX should be extracted to a separate class @@ -63,7 +63,7 @@ class SubmissionMetadata(db.Model): version = db.Column(db.String(128)) basic_fields = ['title', 'description', 'creator', 'open_access', - 'licence', 'publisher', 'publication_date','language', 'keywords'] + 'licence', 'publisher', 'publication_date', 'language', 'keywords'] optional_fields = ['contributors', 'resource_type', 'alternate_identifier', 'version'] @@ -137,7 +137,8 @@ def __init__(self): 'will not be public, however the metadata will be.' } self.field_args['contributors'] = { - 'placeholder': 'contributor 1; contributor 2; ...', + 'placeholder': 'contributor', + 'cardinality': 'n', 'description': 'A semicolon separated list of all other ' +\ 'contributors. Mention all ' +\ @@ -145,13 +146,14 @@ def __init__(self): } self.field_args['language'] = { 'hidden': True, - 'value': self.language_default + 'value': self.language_default, # 'description': # 'The name of the language the document is written in.' } self.field_args['resource_type'] = { - 'choices': ['Text', 'Image', 'Video'], # choices -> SelectField - 'other': 'Other...', # other -> dynamic input text field + 'data_provide': 'select', + 'cardinality': 'n', + 'data_source': ['Text', 'Image', 'Video', 'Other'], 'description': 'Select the type of the resource.' } @@ -161,7 +163,8 @@ def __init__(self): 'Any kind of other reference such as a URN, URI or an ISBN number.' } self.field_args['creator'] = { - 'placeholder': 'author 1; author 2; ... ', + 'placeholder': 'author', + 'cardinality': 'n', 'description': 'A semicolon separated list of authors of the resource.' } @@ -244,4 +247,9 @@ def is_external_attr(n): args['field_args'][f['name']]['placeholder'] = f.get('placeholder') if 'value' in f: args['field_args'][f['name']]['value'] = f.get('value') + if 'other' in f: + args['field_args'][f['name']]['other'] = f.get('other') + if 'cardinality' in f: + args['field_args'][f['name']]['cardinality'] = f.get('cardinality') + return type(clsname, (SubmissionMetadata,), args)