diff --git a/frappe/public/js/frappe/form/dashboard.js b/frappe/public/js/frappe/form/dashboard.js index b2fbe2e915..1b18eef783 100644 --- a/frappe/public/js/frappe/form/dashboard.js +++ b/frappe/public/js/frappe/form/dashboard.js @@ -12,6 +12,7 @@ frappe.ui.form.Dashboard = Class.extend({ this.heatmap_area = this.wrapper.find('.form-heatmap'); this.chart_area = this.wrapper.find('.form-chart'); this.stats_area = this.wrapper.find('.form-stats'); + this.stats_area_row = this.stats_area.find('.row'); this.links_area = this.wrapper.find('.form-links'); this.transactions_area = this.links_area.find('.transactions'); @@ -28,7 +29,8 @@ frappe.ui.form.Dashboard = Class.extend({ this.links_area.find('.count, .open-notification').addClass('hidden'); // clear stats - this.stats_area.empty().addClass('hidden'); + this.stats_area.addClass('hidden') + this.stats_area_row.empty(); // clear custom this.wrapper.find('.custom').remove(); @@ -345,8 +347,9 @@ frappe.ui.form.Dashboard = Class.extend({ this.show(); this.stats_area.removeClass('hidden'); + // set colspan - var indicators = this.stats_area.find('.indicator-column'); + var indicators = this.stats_area_row.find('.indicator-column'); var n_indicators = indicators.length + 1; if(n_indicators > 4) { colspan = 3 } else { colspan = 12 / n_indicators; } @@ -357,7 +360,7 @@ frappe.ui.form.Dashboard = Class.extend({ } var indicator = $('
' - +label+'
').appendTo(this.stats_area); + +label+'').appendTo(this.stats_area_row); return indicator; }, diff --git a/frappe/public/js/frappe/form/templates/form_dashboard.html b/frappe/public/js/frappe/form/templates/form_dashboard.html index bc7352cebd..2c6e5b4342 100644 --- a/frappe/public/js/frappe/form/templates/form_dashboard.html +++ b/frappe/public/js/frappe/form/templates/form_dashboard.html @@ -8,7 +8,9 @@ - + diff --git a/frappe/templates/generators/web_form.html b/frappe/templates/generators/web_form.html index 3f1d0790fe..eafa76424e 100644 --- a/frappe/templates/generators/web_form.html +++ b/frappe/templates/generators/web_form.html @@ -58,7 +58,7 @@ data-label="{{ _(field.label) }}" data-fieldtype="{{ field.fieldtype }}" data-doctype="{{ field.parent }}" data-default="{{ field.default or "" }}" {{ (field.reqd and field.fieldtype!="Attach") and "data-reqd=1" or "" }} - {{ field.read_only and "disabled" or "" }} + {{ (read_only or field.read_only) and "disabled" or "" }} {% endmacro -%} {%- macro value(field, _doc) -%} @@ -96,7 +96,6 @@ class="form-control" {{ properties(field) }} value="{{ value(field, _doc) }}" {%- if field.fieldtype=="Int" %} pattern="[0-9]*"{% endif %} - {%- if field.max_value %} max={{ field.max_value }}{% endif %} {%- if field.max_length %} maxlength={{ field.max_length }}{% endif %}> {{ help(field) }} @@ -264,7 +263,7 @@
{{ payment_button_help }}
{% endif %} - + {{ payment_button_label }} {% else %}
{{ _("Payment Complete") }}
@@ -321,6 +320,7 @@ frappe.ready(function() { frappe.form_dirty = false; frappe.max_attachment_size = {{ max_attachment_size }}; moment.defaultFormat = "{{ frappe.date_format.upper() }}"; + {% if row_template %}frappe.web_form_row_template = "{{ row_template }}";{% endif %} var $form = $("form[data-web-form='{{ name }}']"); @@ -370,6 +370,12 @@ frappe.ready(function() { set_mandatory_class(this); }).on('keypress', function() { set_mandatory_class(this); + + // validate maxlength + var maxlength = parseInt($(this).attr('maxlength')); + if(maxlength && (($(this).val() || '') + '').length > maxlength-1) { + $(this).val($(this).val().substr(0, maxlength-1)); + }; }).each(function() { set_mandatory_class(this); }); // if changed, set dirty flag @@ -377,6 +383,16 @@ frappe.ready(function() { frappe.form_dirty = true; }); + // allow payment only if + $('.btn-payment').on('click', function() { + var data = get_data(); + if(frappe.mandatory_missing.length) { + frappe.msgprint(__('Payment can only be made after filling the following mandatory fields: {0}', + ['

  1. ' + frappe.mandatory_missing.join('
  2. ') + '
'])); + return false; + } + }); + // change attach $form.on("click", ".change-attach", function() { $(this).parent().addClass("hide") diff --git a/frappe/templates/includes/list/list.js b/frappe/templates/includes/list/list.js index b42ab4d7aa..09cde04307 100644 --- a/frappe/templates/includes/list/list.js +++ b/frappe/templates/includes/list/list.js @@ -10,9 +10,10 @@ frappe.ready(function() { txt: "{{ txt or '' }}", limit_start: next_start, pathname: location.pathname, - is_web_form: "{{ is_web_form }}" }); + data.web_form_name = frappe.web_form_name; + btn.prop("disabled", true); return $.ajax({ url:"/api/method/frappe.www.list.get", @@ -37,7 +38,7 @@ frappe.ready(function() { $(".website-list .more-block").addClass("hide"); } }; - + if($('.navbar-header .navbar-toggle:visible').length === 1) { $('.page-head h1').addClass('list-head').click(function(){ diff --git a/frappe/templates/includes/web_sidebar.html b/frappe/templates/includes/web_sidebar.html index a3128fb40a..2ad6d201b4 100644 --- a/frappe/templates/includes/web_sidebar.html +++ b/frappe/templates/includes/web_sidebar.html @@ -16,22 +16,21 @@ diff --git a/frappe/utils/jinja.py b/frappe/utils/jinja.py index 62affcd440..a43312deb1 100644 --- a/frappe/utils/jinja.py +++ b/frappe/utils/jinja.py @@ -61,7 +61,10 @@ def get_allowed_functions_for_jenv(): import mimetypes datautils = {} - date_format = frappe.db.get_default("date_format") or "yyyy-mm-dd" + if frappe.db: + date_format = frappe.db.get_default("date_format") or "yyyy-mm-dd" + else: + date_format = 'yyyy-mm-dd' for key, obj in frappe.utils.data.__dict__.items(): if key.startswith("_"): diff --git a/frappe/website/context.py b/frappe/website/context.py index 4e3ef3501e..ff04264157 100644 --- a/frappe/website/context.py +++ b/frappe/website/context.py @@ -114,7 +114,6 @@ def add_sidebar_data(context): if not context.sidebar_items: sidebar_items = frappe.cache().hget('portal_menu_items', frappe.session.user) - print sidebar_items if sidebar_items == None: sidebar_items = [] roles = frappe.get_roles() diff --git a/frappe/website/doctype/web_form/web_form.py b/frappe/website/doctype/web_form/web_form.py index 365d47d4e0..4d28d5ee3e 100644 --- a/frappe/website/doctype/web_form/web_form.py +++ b/frappe/website/doctype/web_form/web_form.py @@ -95,9 +95,9 @@ def get_context(context): """) def get_context(self, context): - from frappe.www.list import get_context as get_list_context + '''Build context to render the `web_form.html` template''' + self.set_web_form_module() - frappe.form_dict.is_web_form = 1 logged_in = frappe.session.user != "Guest" doc, delimeter = make_route_string(frappe.form_dict) @@ -120,9 +120,7 @@ def get_context(context): if self.allow_edit: if self.allow_multiple: if not frappe.form_dict.name and not frappe.form_dict.new: - frappe.form_dict.doctype = self.doc_type - get_list_context(context) - context.is_list = True + self.build_as_list(context) else: name = frappe.db.get_value(self.doc_type, {"owner": frappe.session.user}, "name") if name: @@ -135,6 +133,25 @@ def get_context(context): if not self.login_required or not self.allow_edit: frappe.form_dict.new = 1 + self.load_document(context) + context.parents = self.get_parents(context) + + if self.breadcrumbs: + context.parents = eval(self.breadcrumbs) + + context.has_header = ((frappe.form_dict.name or frappe.form_dict.new) + and (frappe.session.user!="Guest" or not self.login_required)) + + if context.success_message: + context.success_message = context.success_message.replace("\n", + "
").replace("'", "\'") + + self.add_custom_context_and_script(context) + self.add_payment_gateway_url(context) + context.max_attachment_size = get_max_file_size() + + def load_document(self, context): + '''Load document `doc` and `layout` properties for template''' if frappe.form_dict.name or frappe.form_dict.new: context.layout = self.get_layout() context.parents = [{"route": self.route, "title": self.title }] @@ -147,25 +164,27 @@ def get_context(context): context.reference_doctype = context.doc.doctype context.reference_name = context.doc.name - if self.allow_comments and frappe.form_dict.name: - context.comment_list = get_comment_list(context.doc.doctype, - context.doc.name) + if self.allow_comments: + context.comment_list = get_comment_list(context.doc.doctype, + context.doc.name) - context.parents = self.get_parents(context) + def build_as_list(self, context): + '''Web form is a list, show render as list.html''' + from frappe.www.list import get_context as get_list_context - if self.breadcrumbs: - context.parents = eval(self.breadcrumbs) + # set some flags to make list.py/list.html happy + frappe.form_dict.web_form_name = self.name + frappe.form_dict.doctype = self.doc_type + frappe.flags.web_form = self - context.has_header = ((frappe.form_dict.name or frappe.form_dict.new) - and (frappe.session.user!="Guest" or not self.login_required)) + self.update_list_context(context) + get_list_context(context) + context.is_list = True - if context.success_message: - context.success_message = context.success_message.replace("\n", - "
").replace("'", "\'") - - self.add_custom_context_and_script(context) - self.add_payment_gateway_url(context) - context.max_attachment_size = get_max_file_size() + def update_list_context(self, context): + '''update list context for stanard modules''' + if self.web_form_module and hasattr(self.web_form_module, 'get_list_context'): + self.web_form_module.get_list_context(context) def add_payment_gateway_url(self, context): if context.doc and self.accept_payment: @@ -191,23 +210,17 @@ def get_context(context): def add_custom_context_and_script(self, context): '''Update context from module if standard and append script''' - if self.is_standard: - module_name = "{app}.{module}.web_form.{name}.{name}".format( - app = frappe.local.module_app[scrub(self.module)], - module = scrub(self.module), - name = scrub(self.name) - ) - module = frappe.get_module(module_name) - new_context = module.get_context(context) + if self.web_form_module: + new_context = self.web_form_module.get_context(context) if new_context: context.update(new_context) - js_path = os.path.join(os.path.dirname(module.__file__), scrub(self.name) + '.js') + js_path = os.path.join(os.path.dirname(self.web_form_module.__file__), scrub(self.name) + '.js') if os.path.exists(js_path): context.script = open(js_path, 'r').read() - css_path = os.path.join(os.path.dirname(module.__file__), scrub(self.name) + '.css') + css_path = os.path.join(os.path.dirname(self.web_form_module.__file__), scrub(self.name) + '.css') if os.path.exists(css_path): context.style = open(css_path, 'r').read() @@ -267,13 +280,26 @@ def get_context(context): def get_parents(self, context): parents = None - if context.is_list: + if context.is_list and not context.parents: parents = [{"title": _("My Account"), "name": "me"}] elif context.parents: parents = context.parents return parents + def set_web_form_module(self): + '''Get custom web form module if exists''' + if self.is_standard: + module_name = "{app}.{module}.web_form.{name}.{name}".format( + app = frappe.local.module_app[scrub(self.module)], + module = scrub(self.module), + name = scrub(self.name) + ) + self.web_form_module = frappe.get_module(module_name) + else: + self.web_form_module = None + + @frappe.whitelist(allow_guest=True) def accept(web_form, data): data = frappe._dict(json.loads(data)) @@ -388,7 +414,7 @@ def make_route_string(parameters): delimeter = '?' if isinstance(parameters, dict): for key in parameters: - if key != "is_web_form": + if key != "web_form_name": route_string += route_string + delimeter + key + "=" + cstr(parameters[key]) delimeter = '&' return (route_string, delimeter) \ No newline at end of file diff --git a/frappe/www/list.py b/frappe/www/list.py index 981fc6f673..343c28d4d3 100644 --- a/frappe/www/list.py +++ b/frappe/www/list.py @@ -73,7 +73,7 @@ def get(doctype, txt=None, limit_start=0, limit=20, **kwargs): def set_route(context): '''Set link for the list item''' - if context.is_web_form: + if context.web_form_name: context.route = "{0}?name={1}".format(context.pathname, quoted(context.doc.name)) elif context.doc and getattr(context.doc, 'route', None): context.route = context.doc.route @@ -89,7 +89,7 @@ def prepare_filters(doctype, kwargs): # resolve additional filters from path resolve_path(filters.pathname) for key, val in frappe.local.form_dict.items(): - if key not in filters: + if key not in filters and key != 'flags': filters[key] = val # filter the filters to include valid fields only @@ -97,9 +97,6 @@ def prepare_filters(doctype, kwargs): if not meta.has_field(fieldname): del filters[fieldname] - if "is_web_form" in filters: - del filters["is_web_form"] - return filters def get_list_context(context, doctype): @@ -111,12 +108,20 @@ def get_list_context(context, doctype): if hasattr(module, "get_list_context"): list_context = frappe._dict(module.get_list_context(context) or {}) - # is web form - if cint(frappe.local.form_dict.is_web_form): - list_context.is_web_form = 1 + # is web form, show the default web form filters + # which is only the owner + if frappe.form_dict.web_form_name: + list_context.web_form_name = frappe.form_dict.web_form_name if not list_context.get("get_list"): list_context.get_list = get_web_form_list + if not frappe.flags.web_form: + # update list context from web_form + frappe.flags.web_form = frappe.get_doc('Web Form', frappe.form_dict.web_form_name) + + if frappe.flags.web_form.is_standard: + frappe.flags.web_form.update_list_context(list_context) + return list_context def get_list(doctype, txt, filters, limit_start, limit_page_length=20, ignore_permissions=False,