def html(self, widget_id=None, formkey=None): """ Render the organizer container and instantiate the UI widget @param widget_id: the container's DOM ID """ T = current.T if not widget_id: widget_id = "organizer" # Parse resource configuration resources = self.resources if not isinstance(resources, (list, tuple)): resources = [resources] resource_configs = [] use_time = False for resource_config in resources: resource_use_time = resource_config.get("useTime") if resource_use_time: use_time = True resource_configs.append(resource_config) # Inject script and widget instantiation script_opts = { "resources": resource_configs, "useTime": use_time, "labelEdit": s3_str(T("Edit")), "labelDelete": s3_str(T("Delete")), "deleteConfirmation": s3_str(T("Do you want to delete this entry?")), } self.inject_script(widget_id, script_opts) # Add a datepicker to navigate to arbitrary dates picker = S3DateWidget()( Storage(name="date_select"), None, _type="hidden", _id="%s-date-picker" % widget_id, ) # Generate and return the HTML for the widget container return DIV( INPUT( _name="_formkey", _type="hidden", _value=str(formkey) if formkey else "", ), picker, _id=widget_id, _class="s3-organizer", )
def s3_datetime(name="date", **attr): """ Return a standard Datetime field Additional options to normal S3ResuableField: default = "now" (in addition to usual meanings) represent = "date" (in addition to usual meanings) widget = "date" (in addition to usual meanings) past = x hours future = x hours """ if "past" in attr: past = attr["past"] del attr["past"] else: past = None if "future" in attr: future = attr["future"] del attr["future"] else: future = None if "default" in attr and attr["default"] == "now": attr["default"] = current.request.utcnow if "label" not in attr: attr["label"] = current.T("Date") if "represent" not in attr: attr["represent"] = lambda dt: S3DateTime.datetime_represent(dt, utc=True) elif attr["represent"] == "date": attr["represent"] = lambda dt: S3DateTime.date_represent(dt, utc=True) if "widget" not in attr: if past is None and future is None: attr["widget"] = S3DateTimeWidget() elif past is None: attr["widget"] = S3DateTimeWidget(future=future) elif future is None: attr["widget"] = S3DateTimeWidget(past=past) else: attr["widget"] = S3DateTimeWidget(past=past, future=future) elif attr["widget"] == "date": if past is None and future is None: attr["widget"] = S3DateWidget() requires = IS_DATE( format=current.deployment_settings.get_L10n_date_format()) else: now = current.request.utcnow.date() current_month = now.month if past is None: future = int(round(future / 744.0, 0)) attr["widget"] = S3DateWidget(future=future) future_month = now.month + future if future_month <= 12: max = now.replace(month=future_month) else: current_year = now.year years = int(future_month / 12) future_year = current_year + years future_month = future_month - (years * 12) max = now.replace(year=future_year, month=future_month) requires = IS_DATE_IN_RANGE( format=current.deployment_settings.get_L10n_date_format(), maximum=max, error_message=current.T( "Date must be %(max)s or earlier!")) elif future is None: past = int(round(past / 744.0, 0)) attr["widget"] = S3DateWidget(past=past) if past < current_month: min = now.replace(month=current_month - past) else: current_year = now.year past_years = int(past / 12) past_months = past - (past_years * 12) min = now.replace(year=current_year - past_years, month=current_month - past_months) requires = IS_DATE_IN_RANGE( format=current.deployment_settings.get_L10n_date_format(), minimum=min, error_message=current.T("Date must be %(min)s or later!")) else: future = int(round(future / 744.0, 0)) past = int(round(past / 744.0, 0)) attr["widget"] = S3DateWidget(past=past, future=future) future_month = now.month + future if future_month < 13: max = now.replace(month=future_month) else: current_year = now.year years = int(future_month / 12) future_year = now.year + years future_month = future_month - (years * 12) max = now.replace(year=future_year, month=future_month) if past < current_month: min = now.replace(month=current_month - past) else: current_year = now.year past_years = int(past / 12) past_months = past - (past_years * 12) min = now.replace(year=current_year - past_years, month=current_month - past_months) requires = IS_DATE_IN_RANGE( format=current.deployment_settings.get_L10n_date_format(), maximum=max, minimum=min, error_message=current.T( "Date must be between %(min)s and %(max)s!")) if "empty" in attr: if attr["empty"] is False: attr["requires"] = requires else: attr["requires"] = IS_EMPTY_OR(requires) del attr["empty"] else: # Default attr["requires"] = IS_EMPTY_OR(requires) if "requires" not in attr: if past is None and future is None: requires = IS_UTC_DATETIME( format=current.deployment_settings.get_L10n_datetime_format()) else: now = current.request.utcnow if past is None: max = now + datetime.timedelta(hours=future) requires = IS_UTC_DATETIME( format=current.deployment_settings. get_L10n_datetime_format(), maximum=max, error_message=current.T( "Date must be %(max)s or earlier!")) elif future is None: min = now - datetime.timedelta(hours=past) requires = IS_UTC_DATETIME( format=current.deployment_settings. get_L10n_datetime_format(), minimum=min, error_message=current.T("Date must be %(min)s or later!")) else: min = now - datetime.timedelta(hours=past) max = now + datetime.timedelta(hours=future) requires = IS_UTC_DATETIME( format=current.deployment_settings. get_L10n_datetime_format(), maximum=max, minimum=min, error_message=current.T( "Date must be between %(min)s and %(max)s!")) if "empty" in attr: if attr["empty"] is False: attr["requires"] = requires else: attr["requires"] = IS_EMPTY_OR(requires) del attr["empty"] else: # Default attr["requires"] = IS_EMPTY_OR(requires) f = S3ReusableField(name, "datetime", **attr) return f()