* [wip] grid in web form * [complete] webform in grid * [minor] configurable sidebar items in web form * [fix] tests * [style]version-14
@@ -2,7 +2,7 @@ | |||||
"allow_copy": 0, | "allow_copy": 0, | ||||
"allow_import": 0, | "allow_import": 0, | ||||
"allow_rename": 1, | "allow_rename": 1, | ||||
"autoname": "field:subject", | |||||
"autoname": "", | |||||
"beta": 0, | "beta": 0, | ||||
"creation": "2013-01-10 16:34:31", | "creation": "2013-01-10 16:34:31", | ||||
"custom": 0, | "custom": 0, | ||||
@@ -16,6 +16,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "email_group", | "fieldname": "email_group", | ||||
"fieldtype": "Link", | "fieldtype": "Link", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -42,6 +43,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "subject", | "fieldname": "subject", | ||||
"fieldtype": "Small Text", | "fieldtype": "Small Text", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -66,6 +68,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"description": "", | "description": "", | ||||
"fieldname": "send_from", | "fieldname": "send_from", | ||||
"fieldtype": "Data", | "fieldtype": "Data", | ||||
@@ -91,6 +94,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "email_sent", | "fieldname": "email_sent", | ||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -115,6 +119,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "newsletter_content", | "fieldname": "newsletter_content", | ||||
"fieldtype": "Section Break", | "fieldtype": "Section Break", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -139,6 +144,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "message", | "fieldname": "message", | ||||
"fieldtype": "Text Editor", | "fieldtype": "Text Editor", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -163,6 +169,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"description": "", | "description": "", | ||||
"fieldname": "test_the_newsletter", | "fieldname": "test_the_newsletter", | ||||
"fieldtype": "Section Break", | "fieldtype": "Section Break", | ||||
@@ -188,6 +195,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"description": "A Lead with this email id should exist", | "description": "A Lead with this email id should exist", | ||||
"fieldname": "test_email_id", | "fieldname": "test_email_id", | ||||
"fieldtype": "Data", | "fieldtype": "Data", | ||||
@@ -213,6 +221,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "test_send", | "fieldname": "test_send", | ||||
"fieldtype": "Button", | "fieldtype": "Button", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -247,7 +256,7 @@ | |||||
"istable": 0, | "istable": 0, | ||||
"max_attachments": 0, | "max_attachments": 0, | ||||
"menu_index": 0, | "menu_index": 0, | ||||
"modified": "2016-08-05 06:26:58.705579", | |||||
"modified": "2016-09-13 11:33:47.892910", | |||||
"modified_by": "Administrator", | "modified_by": "Administrator", | ||||
"module": "Email", | "module": "Email", | ||||
"name": "Newsletter", | "name": "Newsletter", | ||||
@@ -15,6 +15,9 @@ from frappe.email.queue import send | |||||
from frappe.email.doctype.email_group.email_group import add_subscribers | from frappe.email.doctype.email_group.email_group import add_subscribers | ||||
class Newsletter(Document): | class Newsletter(Document): | ||||
def autoname(self): | |||||
self.name = self.subject | |||||
def onload(self): | def onload(self): | ||||
if self.email_sent: | if self.email_sent: | ||||
self.get("__onload").status_count = dict(frappe.db.sql("""select status, count(name) | self.get("__onload").status_count = dict(frappe.db.sql("""select status, count(name) | ||||
@@ -228,3 +228,10 @@ a.no-decoration:active { | |||||
-webkit-filter: grayscale(100%); | -webkit-filter: grayscale(100%); | ||||
filter: grayscale(100%); | filter: grayscale(100%); | ||||
} | } | ||||
.uppercase { | |||||
padding-bottom: 4px; | |||||
text-transform: uppercase; | |||||
font-size: 12px; | |||||
letter-spacing: 0.4px; | |||||
color: #8D99A6; | |||||
} |
@@ -228,6 +228,13 @@ a.no-decoration:active { | |||||
-webkit-filter: grayscale(100%); | -webkit-filter: grayscale(100%); | ||||
filter: grayscale(100%); | filter: grayscale(100%); | ||||
} | } | ||||
.uppercase { | |||||
padding-bottom: 4px; | |||||
text-transform: uppercase; | |||||
font-size: 12px; | |||||
letter-spacing: 0.4px; | |||||
color: #8D99A6; | |||||
} | |||||
.nav-pills a, | .nav-pills a, | ||||
.nav-pills a:hover { | .nav-pills a:hover { | ||||
border-bottom: none; | border-bottom: none; | ||||
@@ -228,6 +228,13 @@ a.no-decoration:active { | |||||
-webkit-filter: grayscale(100%); | -webkit-filter: grayscale(100%); | ||||
filter: grayscale(100%); | filter: grayscale(100%); | ||||
} | } | ||||
.uppercase { | |||||
padding-bottom: 4px; | |||||
text-transform: uppercase; | |||||
font-size: 12px; | |||||
letter-spacing: 0.4px; | |||||
color: #8D99A6; | |||||
} | |||||
.avatar { | .avatar { | ||||
display: inline-block; | display: inline-block; | ||||
vertical-align: middle; | vertical-align: middle; | ||||
@@ -263,3 +263,12 @@ a.no-decoration& { | |||||
-webkit-filter: grayscale(100%); | -webkit-filter: grayscale(100%); | ||||
filter: grayscale(100%); | filter: grayscale(100%); | ||||
} | } | ||||
.uppercase { | |||||
padding-bottom: 4px; | |||||
text-transform: uppercase; | |||||
font-size: 12px; | |||||
letter-spacing: 0.4px; | |||||
color: @text-muted; | |||||
} | |||||
@@ -18,7 +18,7 @@ | |||||
{{ _("Submit") if frappe.form_dict.new else _("Update") }}</button> | {{ _("Submit") if frappe.form_dict.new else _("Update") }}</button> | ||||
{% elif is_list %} | {% elif is_list %} | ||||
<div style="padding-bottom: 15px;"> | <div style="padding-bottom: 15px;"> | ||||
<a href="/{{ pathname + args }}{{ delimeter }}new=1" class="btn btn-primary btn-new btn-sm"> | |||||
<a href="/{{ pathname }}{{ delimeter }}new=1" class="btn btn-primary btn-new btn-sm"> | |||||
{{ _("New {0}").format(_(doc_type)) }} | {{ _("New {0}").format(_(doc_type)) }} | ||||
</a> | </a> | ||||
</div> | </div> | ||||
@@ -50,17 +50,22 @@ | |||||
<br> | <br> | ||||
{%- macro properties(field) %} | {%- macro properties(field) %} | ||||
name="{{ field.fieldname }}" id="{{ field.fieldname }}" | |||||
name="{{ field.fieldname }}" | |||||
{% if field.placeholder -%} placeholder="{{ _(field.placeholder) }}" {%- endif %} | {% if field.placeholder -%} placeholder="{{ _(field.placeholder) }}" {%- endif %} | ||||
data-label="{{ _(field.label) }}" data-fieldtype="{{ field.fieldtype }}" | data-label="{{ _(field.label) }}" data-fieldtype="{{ field.fieldtype }}" | ||||
data-doctype="{{ field.parent }}" data-default="{{ field.default or "" }}" | |||||
{{ (field.reqd and field.fieldtype!="Attach") and "required" or "" }} | {{ (field.reqd and field.fieldtype!="Attach") and "required" or "" }} | ||||
{{ field.read_only and "disabled" or "" }} | {{ field.read_only and "disabled" or "" }} | ||||
{% endmacro -%} | {% endmacro -%} | ||||
{%- macro value(field) -%}{% if doc %}{{ | |||||
doc.get(field.fieldname) or | |||||
field.default or | |||||
frappe.form_dict.get(field.fieldname) or "" }}{% else %}{{ getCookie(field.options) or field.default or "" }}{% endif %}{%- endmacro -%} | |||||
{%- macro value(field, _doc) -%} | |||||
{%- if _doc -%} | |||||
{{ _doc.get(field.fieldname) or field.default | |||||
or frappe.form_dict.get(field.fieldname) or "" }} | |||||
{%- else -%} | |||||
{{ field.default or "" }} | |||||
{%- endif -%} | |||||
{%- endmacro -%} | |||||
{%- macro help(field) -%} | {%- macro help(field) -%} | ||||
{% if field.description -%} | {% if field.description -%} | ||||
@@ -73,7 +78,7 @@ | |||||
{{ _(field.label) }}</label> | {{ _(field.label) }}</label> | ||||
{% endmacro %} | {% endmacro %} | ||||
{% macro render_field(field) %} | |||||
{% macro render_field(field, _doc=None, with_label=True) %} | |||||
{% if field.hidden %} | {% if field.hidden %} | ||||
<input type="hidden" | <input type="hidden" | ||||
name="{{ field.fieldname }}" {% if field.default -%} value="{{ field.default }}" {%- endif %}> | name="{{ field.fieldname }}" {% if field.default -%} value="{{ field.default }}" {%- endif %}> | ||||
@@ -83,18 +88,18 @@ | |||||
</div> | </div> | ||||
{% elif field.fieldtype in ("Data", "Date", "Datetime") %} | {% elif field.fieldtype in ("Data", "Date", "Datetime") %} | ||||
<div class="form-group"> | <div class="form-group"> | ||||
{{ label(field) }} | |||||
{% if with_label %}{{ label(field) }}{% endif %} | |||||
<input type="text" class="form-control" {{ properties(field) }} | <input type="text" class="form-control" {{ properties(field) }} | ||||
value="{{ value(field) }}"> | |||||
value="{{ value(field, _doc) }}"> | |||||
{{ help(field) }} | {{ help(field) }} | ||||
</div> | </div> | ||||
{% elif field.fieldtype=="Select" %} | {% elif field.fieldtype=="Select" %} | ||||
<div class="form-group"> | <div class="form-group"> | ||||
{{ label(field) }} | |||||
{% if with_label %}{{ label(field) }}{% endif %} | |||||
<select class="form-control" {{ properties(field) }}> | <select class="form-control" {{ properties(field) }}> | ||||
{% for option in field.options.split("\n") -%} | {% for option in field.options.split("\n") -%} | ||||
<option value="{{ option }}" | <option value="{{ option }}" | ||||
{{ 'selected="selected"' if value(field)==option else '' }}> | |||||
{{ 'selected="selected"' if value(field, _doc)==option else '' }}> | |||||
{{ option }}</option> | {{ option }}</option> | ||||
{%- endfor %} | {%- endfor %} | ||||
</select> | </select> | ||||
@@ -102,24 +107,24 @@ | |||||
</div> | </div> | ||||
{% elif field.fieldtype=="Text" %} | {% elif field.fieldtype=="Text" %} | ||||
<div class="form-group"> | <div class="form-group"> | ||||
{{ label(field) }} | |||||
{% if with_label %}{{ label(field) }}{% endif %} | |||||
{{ help(field) }} | {{ help(field) }} | ||||
<textarea class="form-control" style="height: 200px;" | <textarea class="form-control" style="height: 200px;" | ||||
{{ properties(field) }}>{{ value(field) }}</textarea> | |||||
{{ properties(field) }}>{{ value(field, _doc) }}</textarea> | |||||
</div> | </div> | ||||
{% elif field.fieldtype=="Attach" %} | {% elif field.fieldtype=="Attach" %} | ||||
<div class="form-group"> | <div class="form-group"> | ||||
{{ label(field) }} | |||||
{% if value(field) -%} | |||||
{% if with_label %}{{ label(field) }}{% endif %} | |||||
{% if value(field, _doc) -%} | |||||
<p class="small"> | <p class="small"> | ||||
<a href="{{ doc.get(field.fieldname) }}" target="blank"> | <a href="{{ doc.get(field.fieldname) }}" target="blank"> | ||||
{{ doc.get(field.fieldname) }} | |||||
{{ _doc.get(field.fieldname) }} | |||||
</a> | </a> | ||||
<br><button class="btn btn-small btn-default btn-xs | <br><button class="btn btn-small btn-default btn-xs | ||||
change-attach" style="margin-top: 5px;">Change</button> | change-attach" style="margin-top: 5px;">Change</button> | ||||
</p> | </p> | ||||
{%- endif %} | {%- endif %} | ||||
<p class="{{ value(field) and 'hide' or '' }} attach-input-wrap"> | |||||
<p class="{{ value(field, _doc) and 'hide' or '' }} attach-input-wrap"> | |||||
<input type="file" style="margin-top: 7px;" | <input type="file" style="margin-top: 7px;" | ||||
{{ properties(field) }}> | {{ properties(field) }}> | ||||
</p> | </p> | ||||
@@ -128,18 +133,65 @@ | |||||
{% elif field.fieldtype=="Check" %} | {% elif field.fieldtype=="Check" %} | ||||
<div class="form-group"> | <div class="form-group"> | ||||
<div class="checkbox"> | <div class="checkbox"> | ||||
{% if with_label %} | |||||
<label> | <label> | ||||
<input type="checkbox" id="{{ field.fieldname }}" | <input type="checkbox" id="{{ field.fieldname }}" | ||||
name="{{ field.fieldname }}" | name="{{ field.fieldname }}" | ||||
{{ doc and doc.get(field.fieldname) and 'checked' or '' }}> | {{ doc and doc.get(field.fieldname) and 'checked' or '' }}> | ||||
{{ _(field.label) }} | {{ _(field.label) }} | ||||
</label> | </label> | ||||
{% endif %} | |||||
{{ help(field) }} | {{ help(field) }} | ||||
</div> | </div> | ||||
</div> | </div> | ||||
{% endif %} | {% endif %} | ||||
{% endmacro %} | {% endmacro %} | ||||
{% macro render_row(field, d=None, hidden=False) %} | |||||
<tr class="web-form-grid-row {% if hidden %}hidden{% endif %}" | |||||
{% if d != None %}data-name="{{ d.name }}" data-child-row=1{% endif %}> | |||||
{% for df in frappe.get_meta(field.options).fields %} | |||||
{% if df.in_list_view %} | |||||
<{{ 'th' if d==None else 'td' }} style="width: {{ (field.columns or 2) * 8.3333 }}%;"> | |||||
{% if d!=None %} | |||||
{{ render_field(df, d, False) }} | |||||
{% else %} | |||||
<span class='text-muted small'>{{ df.label }}</span> | |||||
{% endif %} | |||||
</{{ 'th' if d.name==None else 'td' }}> | |||||
{% endif %} | |||||
{% endfor %} | |||||
<td style="width: 8.3333%"> | |||||
{% if d!=None %} | |||||
<button class='btn btn-default btn-sm btn-remove'><i class='icon-remove'></i></button> | |||||
{% endif %} | |||||
</td> | |||||
</tr> | |||||
{% endmacro %} | |||||
{% macro render_table(field) %} | |||||
<div class='web-form-grid' | |||||
data-fieldname='{{ field.fieldname }}' data-doctype='{{ field.options }}'> | |||||
<table class='table table-bordered'> | |||||
<thead> | |||||
{{ render_row(field) }} | |||||
</thead> | |||||
<tbody> | |||||
{{ render_row(field, {}, True) }} | |||||
{% if doc.get(field.fieldname) %} | |||||
{% for d in doc.get(field.fieldname) %} | |||||
{{ render_row(field, d) }} | |||||
{% endfor %} | |||||
{% else %} | |||||
{{ render_row(field, {}) }} | |||||
{% endif %} | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
<p><button class='btn btn-default btn-sm btn-add-row' | |||||
data-fieldname='{{ field.fieldname }}'>{{ _("Add Row") }}</button></p> | |||||
{% endmacro %} | |||||
<div class="form-message text-muted hide"></div> | <div class="form-message text-muted hide"></div> | ||||
<form role="form" | <form role="form" | ||||
data-web-form="{{ name }}" data-owner="{{ doc.owner }}"> | data-web-form="{{ name }}" data-owner="{{ doc.owner }}"> | ||||
@@ -153,23 +205,29 @@ | |||||
</div> | </div> | ||||
</div> | </div> | ||||
{% endif %} | {% endif %} | ||||
<input type="hidden" name="web_form" value="{{ name }}"> | |||||
<input type="hidden" name="doctype" value="{{ doc_type }}"> | |||||
{% if frappe.form_dict.name -%} | {% if frappe.form_dict.name -%} | ||||
<input type="hidden" name="name" value="{{ frappe.form_dict.name }}"> | |||||
<input type="hidden" name="name" value="{{ frappe.form_dict.name }}" | |||||
data-doctype="{{ doc_type }}"> | |||||
{%- endif %} | {%- endif %} | ||||
{% for section in layout %} | |||||
{% for section in layout %} | |||||
{% if section.label %} | |||||
<h5 class='uppercase'>{{ _(section.label) }}</h5> | |||||
{% endif %} | |||||
<div class="row"> | <div class="row"> | ||||
{% for column in section %} | |||||
<div class="col-sm-{{ (12 / (section|len))|int }}" style="max-width: 500px;"> | |||||
{% for column in section.columns %} | |||||
<div class="col-sm-{{ (12 / (section.columns|len))|int }}"> | |||||
{% for field in column %} | {% for field in column %} | ||||
{{ render_field(field) }} | |||||
{% if field.fieldtype=='Table' %} | |||||
{{ render_table(field) }} | |||||
{% else %} | |||||
{{ render_field(field, doc) }} | |||||
{% endif %} | |||||
{% endfor %} | {% endfor %} | ||||
</div> | </div> | ||||
{% endfor %} | {% endfor %} | ||||
</div> | </div> | ||||
{% endfor %} | |||||
{% endfor %} | |||||
</form> | </form> | ||||
{% if allow_comments and not frappe.form_dict.new -%} | {% if allow_comments and not frappe.form_dict.new -%} | ||||
<div class="comments"> | <div class="comments"> | ||||
@@ -186,8 +244,10 @@ | |||||
<script> | <script> | ||||
frappe.ready(function() { | frappe.ready(function() { | ||||
window.file_reading = false; | window.file_reading = false; | ||||
window.success_message = "{{ success_message or "" }}"; | |||||
window.success_message = "{{ success_message or "" }}"; | |||||
frappe.datepicker_format = "{{ frappe.date_format.replace('yyyy', 'yy') }}"; | frappe.datepicker_format = "{{ frappe.date_format.replace('yyyy', 'yy') }}"; | ||||
var web_form_doctype = "{{ doc_type }}"; | |||||
var web_form_name = "{{ name }}"; | |||||
var $form = $("form[data-web-form='{{ name }}']"); | var $form = $("form[data-web-form='{{ name }}']"); | ||||
// read file attachment | // read file attachment | ||||
@@ -223,20 +283,61 @@ frappe.ready(function() { | |||||
return false; | return false; | ||||
}); | }); | ||||
// submit | |||||
$(".btn-form-submit").on("click", function() { | |||||
var args = {}; | |||||
if(window.saving) | |||||
return; | |||||
window.saving = true; | |||||
// add row | |||||
$('.btn-add-row').on('click', function() { | |||||
var fieldname = $(this).attr('data-fieldname'); | |||||
var grid = $('.web-form-grid[data-fieldname="'+fieldname+'"]'); | |||||
var new_row = grid.find('.web-form-grid-row.hidden').clone() | |||||
.appendTo(grid.find('tbody')) | |||||
.attr('data-name', '') | |||||
.removeClass('hidden'); | |||||
new_row.find('input').each(function() { | |||||
$(this) | |||||
.val($(this).attr('data-default') || "") | |||||
.removeClass('hasDatepicker') | |||||
.attr('id', ''); | |||||
}); | |||||
setup_date_picker(new_row); | |||||
return false; | |||||
}); | |||||
if(window.file_reading) { | |||||
window.saving = false; | |||||
frappe.msgprint("Reading file, please retry."); | |||||
return; | |||||
} | |||||
// remove row | |||||
$('.web-form-grid').on('click', '.btn-remove', function() { | |||||
$(this).parents('.web-form-grid-row:first').remove(); | |||||
return false; | |||||
}); | |||||
// get document data | |||||
var get_data = function() { | |||||
var doc = get_data_for_doctype($form, web_form_doctype); | |||||
doc.doctype = web_form_doctype; | |||||
// get data from child tables | |||||
$('.web-form-grid').each(function() { | |||||
var fieldname = $(this).attr('data-fieldname'); | |||||
var doctype = $(this).attr('data-doctype'); | |||||
doc[fieldname] = []; | |||||
$form.find("[name]").each(function() { | |||||
// get data from each row | |||||
$(this).find('[data-child-row=1]:visible').each(function() { | |||||
var d = get_data_for_doctype($(this), doctype); | |||||
// set name of child record (if set) | |||||
var name = $(this).attr('data-name'); | |||||
if(name) { d.name = name; } | |||||
doc[fieldname].push(d); | |||||
}); | |||||
}); | |||||
return doc; | |||||
} | |||||
// get data from input elements | |||||
// for the given doctype | |||||
var get_data_for_doctype = function(parent, doctype) { | |||||
var out = {}; | |||||
parent.find("[name][data-doctype='"+ doctype +"']").each(function() { | |||||
var $input = $(this); | var $input = $(this); | ||||
var input_type = $input.attr("type"); | var input_type = $input.attr("type"); | ||||
if(input_type==="file") { | if(input_type==="file") { | ||||
@@ -257,13 +358,30 @@ frappe.ready(function() { | |||||
throw "mandatory missing"; | throw "mandatory missing"; | ||||
} | } | ||||
args[$input.attr("name")] = val; | |||||
out[$input.attr("name")] = val; | |||||
}); | }); | ||||
return out; | |||||
} | |||||
// submit | |||||
$(".btn-form-submit").on("click", function() { | |||||
if(window.saving) | |||||
return; | |||||
window.saving = true; | |||||
if(window.file_reading) { | |||||
window.saving = false; | |||||
frappe.msgprint("Reading file, please retry."); | |||||
return; | |||||
} | |||||
frappe.call({ | frappe.call({ | ||||
type: "POST", | type: "POST", | ||||
method: "frappe.website.doctype.web_form.web_form.accept", | method: "frappe.website.doctype.web_form.web_form.accept", | ||||
args: args, | |||||
args: { | |||||
data: get_data(), | |||||
web_form: web_form_name | |||||
}, | |||||
freeze: true, | freeze: true, | ||||
btn: $form.find("[type='submit']"), | btn: $form.find("[type='submit']"), | ||||
callback: function(data) { | callback: function(data) { | ||||
@@ -278,7 +396,7 @@ frappe.ready(function() { | |||||
} else { | } else { | ||||
frappe.msgprint(__('Successfully Updated')); | frappe.msgprint(__('Successfully Updated')); | ||||
setTimeout(function() { | setTimeout(function() { | ||||
window.location.href = "{{ success_url }}"; | |||||
//window.location.href = "{{ success_url }}"; | |||||
}, 3000); | }, 3000); | ||||
} | } | ||||
} | } | ||||
@@ -311,40 +429,49 @@ frappe.ready(function() { | |||||
} | } | ||||
}) | }) | ||||
// import date picker / timepicker if required | |||||
{% if "Date" in types %} | |||||
frappe.require("assets/frappe/js/lib/jquery/jquery-ui.min.js"); | |||||
frappe.require("assets/frappe/js/lib/jquery/bootstrap_theme/jquery-ui.selected.css"); | |||||
$form.find("[data-fieldtype='Date']").datepicker({ | |||||
altFormat:'yy-mm-dd', | |||||
changeYear: true, | |||||
yearRange: "-70Y:+10Y", | |||||
dateFormat: frappe.datepicker_format, | |||||
}); | |||||
// setup datepicker in all inputs within the given element | |||||
var setup_date_picker = function(ele) { | |||||
var $dates = ele.find("[data-fieldtype='Date']"); | |||||
var $date_times = ele.find("[data-fieldtype='Datetime']"); | |||||
// setup date | |||||
if($dates.length) { | |||||
frappe.require("assets/frappe/js/lib/jquery/jquery-ui.min.js"); | |||||
frappe.require("assets/frappe/js/lib/jquery/bootstrap_theme/jquery-ui.selected.css"); | |||||
$dates.datepicker({ | |||||
altFormat:'yy-mm-dd', | |||||
changeYear: true, | |||||
yearRange: "-70Y:+10Y", | |||||
dateFormat: frappe.datepicker_format, | |||||
}); | |||||
// convert dates to user format | |||||
$form.find("[data-fieldtype='Date']").each(function() { | |||||
var val = $(this).val(); | |||||
if(val) { | |||||
$(this).val($.datepicker.formatDate(frappe.datepicker_format, | |||||
$.datepicker.parseDate("yy-mm-dd", val))); | |||||
// convert dates to user format | |||||
$dates.each(function() { | |||||
var val = $(this).val(); | |||||
if(val) { | |||||
$(this).val($.datepicker.formatDate(frappe.datepicker_format, | |||||
$.datepicker.parseDate("yy-mm-dd", val))); | |||||
} | |||||
}); | |||||
} | } | ||||
}) | |||||
{% endif %} | |||||
// setup datetime | |||||
if($date_times.length) { | |||||
frappe.require("assets/frappe/js/lib/jquery/jquery.ui.slider.min.js"); | |||||
frappe.require("assets/frappe/js/lib/jquery/jquery.ui.sliderAccess.js"); | |||||
frappe.require("assets/frappe/js/lib/jquery/jquery.ui.timepicker-addon.css"); | |||||
frappe.require("assets/frappe/js/lib/jquery/jquery.ui.timepicker-addon.js"); | |||||
$date_times.datetimepicker({ | |||||
altFormat:'yy-mm-dd', | |||||
changeYear: true, | |||||
yearRange: "-70Y:+10Y", | |||||
dateFormat: frappe.datepicker_format, | |||||
}); | |||||
} | |||||
} | |||||
{% if "Datetime" in types %} | |||||
frappe.require("assets/frappe/js/lib/jquery/jquery.ui.slider.min.js"); | |||||
frappe.require("assets/frappe/js/lib/jquery/jquery.ui.sliderAccess.js"); | |||||
frappe.require("assets/frappe/js/lib/jquery/jquery.ui.timepicker-addon.css"); | |||||
frappe.require("assets/frappe/js/lib/jquery/jquery.ui.timepicker-addon.js"); | |||||
$form.find("[data-fieldtype='Datetime']").datetimepicker({ | |||||
altFormat:'yy-mm-dd', | |||||
changeYear: true, | |||||
yearRange: "-70Y:+10Y", | |||||
dateFormat: frappe.datepicker_format, | |||||
}) | |||||
{% endif %} | |||||
setup_date_picker($form); | |||||
}); | }); | ||||
{% if script is defined %} | {% if script is defined %} | ||||
@@ -355,5 +482,20 @@ frappe.ready(function() { | |||||
{% endblock %} | {% endblock %} | ||||
{% block style %} | {% block style %} | ||||
{% if style is defined %}<style>{{ style }}</style>{% endif %} | |||||
<style> | |||||
input, select { | |||||
max-width: 500px; | |||||
} | |||||
.web-form-grid-row input, .web-form-grid-row select { | |||||
border: 0px; | |||||
padding: 0px; | |||||
} | |||||
.web-form-grid-row input:focus, .web-form-grid-row select:focus { | |||||
box-shadow: none; | |||||
} | |||||
.web-form-grid-row .form-group { | |||||
margin: 0px; | |||||
} | |||||
{% if style is defined %}{{ style }}{% endif %} | |||||
</style> | |||||
{% endblock %} | {% endblock %} |
@@ -95,14 +95,15 @@ def add_sidebar_data(context): | |||||
from frappe.utils.user import get_fullname_and_avatar | from frappe.utils.user import get_fullname_and_avatar | ||||
import frappe.www.list | import frappe.www.list | ||||
sidebar_items = json.loads(frappe.cache().get('sidebar_items') or '[]') | |||||
if not sidebar_items: | |||||
sidebar_items = frappe.get_all('Portal Menu Item', | |||||
fields=['title', 'route', 'reference_doctype', 'show_always'], | |||||
filters={'enabled': 1}, order_by='idx asc') | |||||
frappe.cache().set('portal_menu_items', json.dumps(sidebar_items)) | |||||
if not context.sidebar_items: | if not context.sidebar_items: | ||||
sidebar_items = json.loads(frappe.cache().get_value('portal_menu_items') or '[]') | |||||
if not sidebar_items: | |||||
sidebar_items = frappe.get_all('Portal Menu Item', | |||||
fields=['title', 'route', 'reference_doctype', 'show_always'], | |||||
filters={'enabled': 1, 'parent': 'Portal Settings'}, order_by='idx asc') | |||||
frappe.cache().set_value('portal_menu_items', json.dumps(sidebar_items)) | |||||
context.sidebar_items = sidebar_items | context.sidebar_items = sidebar_items | ||||
info = get_fullname_and_avatar(frappe.session.user) | info = get_fullname_and_avatar(frappe.session.user) | ||||
@@ -14,6 +14,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "title", | "fieldname": "title", | ||||
"fieldtype": "Data", | "fieldtype": "Data", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -39,6 +40,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "enabled", | "fieldname": "enabled", | ||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -64,6 +66,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "route", | "fieldname": "route", | ||||
"fieldtype": "Data", | "fieldtype": "Data", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -78,7 +81,7 @@ | |||||
"precision": "", | "precision": "", | ||||
"print_hide": 0, | "print_hide": 0, | ||||
"print_hide_if_no_value": 0, | "print_hide_if_no_value": 0, | ||||
"read_only": 1, | |||||
"read_only": 0, | |||||
"report_hide": 0, | "report_hide": 0, | ||||
"reqd": 1, | "reqd": 1, | ||||
"search_index": 0, | "search_index": 0, | ||||
@@ -89,6 +92,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"description": "", | "description": "", | ||||
"fieldname": "reference_doctype", | "fieldname": "reference_doctype", | ||||
"fieldtype": "Link", | "fieldtype": "Link", | ||||
@@ -116,6 +120,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "target", | "fieldname": "target", | ||||
"fieldtype": "Data", | "fieldtype": "Data", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -141,6 +146,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "show_always", | "fieldname": "show_always", | ||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -173,7 +179,7 @@ | |||||
"issingle": 0, | "issingle": 0, | ||||
"istable": 1, | "istable": 1, | ||||
"max_attachments": 0, | "max_attachments": 0, | ||||
"modified": "2016-07-11 03:28:03.883801", | |||||
"modified": "2016-09-13 13:08:58.890253", | |||||
"modified_by": "Administrator", | "modified_by": "Administrator", | ||||
"module": "Website", | "module": "Website", | ||||
"name": "Portal Menu Item", | "name": "Portal Menu Item", | ||||
@@ -3,7 +3,7 @@ | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import frappe | import frappe | ||||
import unittest | |||||
import unittest, json | |||||
from frappe.website.render import build_page | from frappe.website.render import build_page | ||||
from frappe.website.doctype.web_form.web_form import accept | from frappe.website.doctype.web_form.web_form import accept | ||||
@@ -38,12 +38,12 @@ class TestWebForm(unittest.TestCase): | |||||
def test_accept(self): | def test_accept(self): | ||||
frappe.set_user("Administrator") | frappe.set_user("Administrator") | ||||
frappe.form_dict.web_form = "manage-events" | |||||
frappe.form_dict.doctype = "Event" | |||||
frappe.form_dict.subject = "_Test Event Web Form" | |||||
frappe.form_dict.description = "_Test Event Description" | |||||
frappe.form_dict.starts_on = "2014-09-09" | |||||
accept() | |||||
accept(web_form='manage-events', data=json.dumps({ | |||||
'doctype': 'Event', | |||||
'subject': '_Test Event Web Form', | |||||
'description': '_Test Event Description', | |||||
'starts_on': '2014-09-09' | |||||
})) | |||||
self.event_name = frappe.db.get_value("Event", | self.event_name = frappe.db.get_value("Event", | ||||
{"subject": "_Test Event Web Form"}) | {"subject": "_Test Event Web Form"}) | ||||
@@ -51,17 +51,18 @@ class TestWebForm(unittest.TestCase): | |||||
def test_edit(self): | def test_edit(self): | ||||
self.test_accept() | self.test_accept() | ||||
frappe.form_dict.web_form = "manage-events" | |||||
frappe.form_dict.doctype = "Event" | |||||
frappe.form_dict.name = self.event_name | |||||
frappe.form_dict.subject = "_Test Event Web Form" | |||||
frappe.form_dict.description = "_Test Event Description 1" | |||||
frappe.form_dict.starts_on = "2014-09-09" | |||||
doc={ | |||||
'doctype': 'Event', | |||||
'subject': '_Test Event Web Form', | |||||
'description': '_Test Event Description 1', | |||||
'starts_on': '2014-09-09', | |||||
'name': self.event_name | |||||
} | |||||
self.assertNotEquals(frappe.db.get_value("Event", | self.assertNotEquals(frappe.db.get_value("Event", | ||||
self.event_name, "description"), frappe.form_dict.description) | |||||
self.event_name, "description"), doc.get('description')) | |||||
accept() | |||||
accept(web_form='manage-events', data=json.dumps(doc)) | |||||
self.assertEquals(frappe.db.get_value("Event", | self.assertEquals(frappe.db.get_value("Event", | ||||
self.event_name, "description"), frappe.form_dict.description) | |||||
self.event_name, "description"), doc.get('description')) |
@@ -5,8 +5,12 @@ frappe.web_form = { | |||||
if(doc.doc_type) { | if(doc.doc_type) { | ||||
frappe.model.with_doctype(doc.doc_type, function() { | frappe.model.with_doctype(doc.doc_type, function() { | ||||
var fields = $.map(frappe.get_doc("DocType", frm.doc.doc_type).fields, function(d) { | var fields = $.map(frappe.get_doc("DocType", frm.doc.doc_type).fields, function(d) { | ||||
return frappe.model.no_value_type.indexOf(d.fieldtype)===-1 ? | |||||
d.fieldname : null; | |||||
if(frappe.model.no_value_type.indexOf(d.fieldtype)===-1 | |||||
|| d.fieldtype==='Table') { | |||||
return {label: d.label + ' ('+d.fieldtype+')', value:d.fieldname} | |||||
} else { | |||||
return null; | |||||
} | |||||
}) | }) | ||||
frappe.meta.get_docfield("Web Form Field", "fieldname", frm.doc.name).options | frappe.meta.get_docfield("Web Form Field", "fieldname", frm.doc.name).options | ||||
= [""].concat(fields); | = [""].concat(fields); | ||||
@@ -40,18 +44,26 @@ frappe.ui.form.on("Web Form", { | |||||
}); | }); | ||||
frappe.ui.form.on("Web Form Field", "fieldname", function(frm, doctype, name) { | |||||
var doc = frappe.get_doc(doctype, name); | |||||
var df = $.map(frappe.get_doc("DocType", frm.doc.doc_type).fields, function(d) { | |||||
return doc.fieldname==d.fieldname ? d : null; })[0]; | |||||
frappe.ui.form.on("Web Form Field", { | |||||
fieldtype: function(frm, doctype, name) { | |||||
var doc = frappe.get_doc(doctype, name); | |||||
if(fieldtype==='Section Break' || fieldtype==='Section Break') { | |||||
doc.fieldname = ''; | |||||
frm.refresh_field("web_form_fields"); | |||||
} | |||||
}, | |||||
fieldname: function(frm, doctype, name) { | |||||
var doc = frappe.get_doc(doctype, name); | |||||
var df = $.map(frappe.get_doc("DocType", frm.doc.doc_type).fields, function(d) { | |||||
return doc.fieldname==d.fieldname ? d : null; })[0]; | |||||
doc.label = df.label; | |||||
doc.reqd = df.reqd; | |||||
doc.options = df.options; | |||||
doc.fieldtype = frappe.meta.get_docfield("Web Form Field", "fieldtype") | |||||
.options.split("\n").indexOf(df.fieldtype)===-1 ? "Data" : df.fieldtype; | |||||
doc.description = df.description; | |||||
doc["default"] = df["default"]; | |||||
doc.label = df.label; | |||||
doc.reqd = df.reqd; | |||||
doc.options = df.options; | |||||
doc.fieldtype = frappe.meta.get_docfield("Web Form Field", "fieldtype") | |||||
.options.split("\n").indexOf(df.fieldtype)===-1 ? "Data" : df.fieldtype; | |||||
doc.description = df.description; | |||||
doc["default"] = df["default"]; | |||||
frm.refresh_field("web_form_fields"); | |||||
} | |||||
}); | }); |
@@ -9,11 +9,13 @@ | |||||
"docstatus": 0, | "docstatus": 0, | ||||
"doctype": "DocType", | "doctype": "DocType", | ||||
"document_type": "Document", | "document_type": "Document", | ||||
"editable_grid": 0, | |||||
"fields": [ | "fields": [ | ||||
{ | { | ||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "title", | "fieldname": "title", | ||||
"fieldtype": "Data", | "fieldtype": "Data", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -38,6 +40,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "route", | "fieldname": "route", | ||||
"fieldtype": "Data", | "fieldtype": "Data", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -63,6 +66,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "doc_type", | "fieldname": "doc_type", | ||||
"fieldtype": "Link", | "fieldtype": "Link", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -88,6 +92,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "module", | "fieldname": "module", | ||||
"fieldtype": "Link", | "fieldtype": "Link", | ||||
"hidden": 1, | "hidden": 1, | ||||
@@ -114,6 +119,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "column_break_4", | "fieldname": "column_break_4", | ||||
"fieldtype": "Column Break", | "fieldtype": "Column Break", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -137,6 +143,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "is_standard", | "fieldname": "is_standard", | ||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -162,6 +169,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "published", | "fieldname": "published", | ||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -186,6 +194,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "login_required", | "fieldname": "login_required", | ||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -210,6 +219,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"depends_on": "login_required", | "depends_on": "login_required", | ||||
"fieldname": "allow_edit", | "fieldname": "allow_edit", | ||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
@@ -235,6 +245,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"depends_on": "login_required", | "depends_on": "login_required", | ||||
"fieldname": "allow_multiple", | "fieldname": "allow_multiple", | ||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
@@ -260,6 +271,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"depends_on": "allow_multiple", | "depends_on": "allow_multiple", | ||||
"fieldname": "allow_delete", | "fieldname": "allow_delete", | ||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
@@ -286,6 +298,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"depends_on": "login_required", | "depends_on": "login_required", | ||||
"fieldname": "allow_comments", | "fieldname": "allow_comments", | ||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
@@ -311,6 +324,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "fields", | "fieldname": "fields", | ||||
"fieldtype": "Section Break", | "fieldtype": "Section Break", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -335,6 +349,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "introduction_text", | "fieldname": "introduction_text", | ||||
"fieldtype": "Text", | "fieldtype": "Text", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -359,6 +374,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "web_form_fields", | "fieldname": "web_form_fields", | ||||
"fieldtype": "Table", | "fieldtype": "Table", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -384,6 +400,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "actions", | "fieldname": "actions", | ||||
"fieldtype": "Section Break", | "fieldtype": "Section Break", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -408,6 +425,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"description": "Message to be displayed on successful completion", | "description": "Message to be displayed on successful completion", | ||||
"fieldname": "success_message", | "fieldname": "success_message", | ||||
"fieldtype": "Text", | "fieldtype": "Text", | ||||
@@ -433,6 +451,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"description": "Go to this url after completing the form.", | "description": "Go to this url after completing the form.", | ||||
"fieldname": "success_url", | "fieldname": "success_url", | ||||
"fieldtype": "Data", | "fieldtype": "Data", | ||||
@@ -454,10 +473,64 @@ | |||||
"set_only_once": 0, | "set_only_once": 0, | ||||
"unique": 0 | "unique": 0 | ||||
}, | }, | ||||
{ | |||||
"allow_on_submit": 0, | |||||
"bold": 0, | |||||
"collapsible": 1, | |||||
"columns": 0, | |||||
"fieldname": "sidebar_settings", | |||||
"fieldtype": "Section Break", | |||||
"hidden": 0, | |||||
"ignore_user_permissions": 0, | |||||
"ignore_xss_filter": 0, | |||||
"in_filter": 0, | |||||
"in_list_view": 0, | |||||
"label": "Sidebar Settings", | |||||
"length": 0, | |||||
"no_copy": 0, | |||||
"permlevel": 0, | |||||
"precision": "", | |||||
"print_hide": 0, | |||||
"print_hide_if_no_value": 0, | |||||
"read_only": 0, | |||||
"report_hide": 0, | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
"set_only_once": 0, | |||||
"unique": 0 | |||||
}, | |||||
{ | |||||
"allow_on_submit": 0, | |||||
"bold": 0, | |||||
"collapsible": 0, | |||||
"columns": 0, | |||||
"fieldname": "sidebar_items", | |||||
"fieldtype": "Table", | |||||
"hidden": 0, | |||||
"ignore_user_permissions": 0, | |||||
"ignore_xss_filter": 0, | |||||
"in_filter": 0, | |||||
"in_list_view": 0, | |||||
"label": "Sidebar Items", | |||||
"length": 0, | |||||
"no_copy": 0, | |||||
"options": "Portal Menu Item", | |||||
"permlevel": 0, | |||||
"precision": "", | |||||
"print_hide": 0, | |||||
"print_hide_if_no_value": 0, | |||||
"read_only": 0, | |||||
"report_hide": 0, | |||||
"reqd": 0, | |||||
"search_index": 0, | |||||
"set_only_once": 0, | |||||
"unique": 0 | |||||
}, | |||||
{ | { | ||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "advanced", | "fieldname": "advanced", | ||||
"fieldtype": "Section Break", | "fieldtype": "Section Break", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -483,6 +556,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"description": "Text to be displayed for Link to Web Page if this form has a web page. Link route will be automatically generated based on `page_name` and `parent_website_route`", | "description": "Text to be displayed for Link to Web Page if this form has a web page. Link route will be automatically generated based on `page_name` and `parent_website_route`", | ||||
"fieldname": "web_page_link_text", | "fieldname": "web_page_link_text", | ||||
"fieldtype": "Data", | "fieldtype": "Data", | ||||
@@ -509,6 +583,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"description": "In JSON as [{\"title\":\"Jobs\", \"name\":\"jobs\"}]", | "description": "In JSON as [{\"title\":\"Jobs\", \"name\":\"jobs\"}]", | ||||
"fieldname": "breadcrumbs", | "fieldname": "breadcrumbs", | ||||
"fieldtype": "Code", | "fieldtype": "Code", | ||||
@@ -543,7 +618,7 @@ | |||||
"issingle": 0, | "issingle": 0, | ||||
"istable": 0, | "istable": 0, | ||||
"max_attachments": 0, | "max_attachments": 0, | ||||
"modified": "2016-06-24 15:37:23.369646", | |||||
"modified": "2016-09-13 13:08:13.720070", | |||||
"modified_by": "Administrator", | "modified_by": "Administrator", | ||||
"module": "Website", | "module": "Website", | ||||
"name": "Web Form", | "name": "Web Form", | ||||
@@ -19,6 +19,7 @@ class WebForm(WebsiteGenerator): | |||||
) | ) | ||||
def onload(self): | def onload(self): | ||||
super(WebForm, self).onload() | |||||
if self.is_standard and not frappe.conf.developer_mode: | if self.is_standard and not frappe.conf.developer_mode: | ||||
self.use_meta_fields() | self.use_meta_fields() | ||||
@@ -31,9 +32,10 @@ class WebForm(WebsiteGenerator): | |||||
and self.is_standard and not frappe.conf.developer_mode): | and self.is_standard and not frappe.conf.developer_mode): | ||||
frappe.throw(_("You need to be in developer mode to edit a Standard Web Form")) | frappe.throw(_("You need to be in developer mode to edit a Standard Web Form")) | ||||
def convert_links_to_selects(self): | |||||
def reset_field_parent_and_convert_links_to_selects(self): | |||||
'''Convert link fields to select with names as options''' | '''Convert link fields to select with names as options''' | ||||
for df in self.web_form_fields: | for df in self.web_form_fields: | ||||
df.parent = self.doc_type | |||||
if df.fieldtype == "Link": | if df.fieldtype == "Link": | ||||
options = [d.name for d in frappe.get_all(df.options)] | options = [d.name for d in frappe.get_all(df.options)] | ||||
df.fieldtype = "Select" | df.fieldtype = "Select" | ||||
@@ -45,7 +47,7 @@ class WebForm(WebsiteGenerator): | |||||
else: | else: | ||||
df.options = "\n".join([""] + options) | df.options = "\n".join([""] + options) | ||||
def use_meta_fields(self): | def use_meta_fields(self): | ||||
'''Override default properties for standard web forms''' | '''Override default properties for standard web forms''' | ||||
meta = frappe.get_meta(self.doc_type) | meta = frappe.get_meta(self.doc_type) | ||||
@@ -107,8 +109,8 @@ def get_context(context): | |||||
frappe.form_dict.is_web_form = 1 | frappe.form_dict.is_web_form = 1 | ||||
logged_in = frappe.session.user != "Guest" | logged_in = frappe.session.user != "Guest" | ||||
args, delimeter = make_route_string(frappe.form_dict) | |||||
context.args = args | |||||
doc, delimeter = make_route_string(frappe.form_dict) | |||||
context.doc = doc | |||||
context.delimeter = delimeter | context.delimeter = delimeter | ||||
# check permissions | # check permissions | ||||
@@ -118,7 +120,7 @@ def get_context(context): | |||||
if frappe.form_dict.name and not has_web_form_permission(self.doc_type, frappe.form_dict.name): | if frappe.form_dict.name and not has_web_form_permission(self.doc_type, frappe.form_dict.name): | ||||
frappe.throw(_("You don't have the permissions to access this document"), frappe.PermissionError) | frappe.throw(_("You don't have the permissions to access this document"), frappe.PermissionError) | ||||
self.convert_links_to_selects() | |||||
self.reset_field_parent_and_convert_links_to_selects() | |||||
if self.is_standard: | if self.is_standard: | ||||
self.use_meta_fields() | self.use_meta_fields() | ||||
@@ -160,7 +162,6 @@ def get_context(context): | |||||
context.parents = self.get_parents(context) | context.parents = self.get_parents(context) | ||||
context.types = [f.fieldtype for f in self.web_form_fields] | |||||
if context.success_message: | if context.success_message: | ||||
context.success_message = context.success_message.replace("\n", | context.success_message = context.success_message.replace("\n", | ||||
"<br>").replace("'", "\'") | "<br>").replace("'", "\'") | ||||
@@ -193,14 +194,20 @@ def get_context(context): | |||||
def get_layout(self): | def get_layout(self): | ||||
layout = [] | layout = [] | ||||
for df in self.web_form_fields: | for df in self.web_form_fields: | ||||
if df.fieldtype=="Section Break" or not layout: | |||||
layout.append([]) | |||||
if not layout: | |||||
layout.append({'columns': []}) | |||||
if df.fieldtype=="Section Break": | |||||
layout.append({'label': df.label, 'columns': [] }) | |||||
if df.fieldtype=="Column Break" or not layout[-1]: | |||||
layout[-1].append([]) | |||||
if not layout[-1]['columns']: | |||||
layout[-1]['columns'].append([]) | |||||
if df.fieldtype=="Column Break" or not layout[-1]['columns']: | |||||
layout[-1]['columns'].append([]) | |||||
if df.fieldtype not in ("Section Break", "Column Break"): | if df.fieldtype not in ("Section Break", "Column Break"): | ||||
layout[-1][-1].append(df) | |||||
layout[-1]['columns'][-1].append(df) | |||||
return layout | return layout | ||||
@@ -215,40 +222,38 @@ def get_context(context): | |||||
return parents | return parents | ||||
@frappe.whitelist(allow_guest=True) | @frappe.whitelist(allow_guest=True) | ||||
def accept(): | |||||
args = frappe.form_dict | |||||
def accept(web_form, data): | |||||
data = frappe._dict(json.loads(data)) | |||||
files = [] | files = [] | ||||
web_form = frappe.get_doc("Web Form", args.web_form) | |||||
if args.doctype != web_form.doc_type: | |||||
web_form = frappe.get_doc("Web Form", web_form) | |||||
if data.doctype != web_form.doc_type: | |||||
frappe.throw(_("Invalid Request")) | frappe.throw(_("Invalid Request")) | ||||
elif args.name and not web_form.allow_edit: | |||||
elif data.name and not web_form.allow_edit: | |||||
frappe.throw(_("You are not allowed to update this Web Form Document")) | frappe.throw(_("You are not allowed to update this Web Form Document")) | ||||
if args.name: | |||||
if data.name: | |||||
# update | # update | ||||
doc = frappe.get_doc(args.doctype, args.name) | |||||
doc = frappe.get_doc(data.doctype, data.name) | |||||
else: | else: | ||||
# insert | # insert | ||||
doc = frappe.new_doc(args.doctype) | |||||
doc = frappe.new_doc(data.doctype) | |||||
# set values | # set values | ||||
for fieldname, value in args.iteritems(): | |||||
if fieldname not in ("web_form", "cmd", "owner"): | |||||
if value and value.startswith("{"): | |||||
try: | |||||
filedata = json.loads(value) | |||||
if "__file_attachment" in filedata: | |||||
files.append((fieldname, filedata)) | |||||
continue | |||||
for fieldname, value in data.iteritems(): | |||||
if value and isinstance(value, dict): | |||||
try: | |||||
if "__file_attachment" in value: | |||||
files.append((fieldname, value)) | |||||
continue | |||||
except ValueError: | |||||
pass | |||||
except ValueError: | |||||
pass | |||||
doc.set(fieldname, value) | |||||
doc.set(fieldname, value) | |||||
if args.name: | |||||
if doc.name: | |||||
if has_web_form_permission(doc.doctype, doc.name, "write"): | if has_web_form_permission(doc.doctype, doc.name, "write"): | ||||
doc.save(ignore_permissions=True) | doc.save(ignore_permissions=True) | ||||
else: | else: | ||||
@@ -14,16 +14,18 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"fieldname": "fieldname", | |||||
"columns": 0, | |||||
"fieldname": "fieldtype", | |||||
"fieldtype": "Select", | "fieldtype": "Select", | ||||
"hidden": 0, | "hidden": 0, | ||||
"ignore_user_permissions": 0, | "ignore_user_permissions": 0, | ||||
"ignore_xss_filter": 0, | "ignore_xss_filter": 0, | ||||
"in_filter": 0, | "in_filter": 0, | ||||
"in_list_view": 1, | "in_list_view": 1, | ||||
"label": "Fieldname", | |||||
"label": "Fieldtype", | |||||
"length": 0, | "length": 0, | ||||
"no_copy": 0, | "no_copy": 0, | ||||
"options": "Attach\nCheck\nData\nDate\nDatetime\nHTML\nLink\nSelect\nText\nTable\nSection Break\nColumn Break", | |||||
"permlevel": 0, | "permlevel": 0, | ||||
"print_hide": 0, | "print_hide": 0, | ||||
"print_hide_if_no_value": 0, | "print_hide_if_no_value": 0, | ||||
@@ -38,17 +40,17 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"fieldname": "fieldtype", | |||||
"columns": 0, | |||||
"fieldname": "fieldname", | |||||
"fieldtype": "Select", | "fieldtype": "Select", | ||||
"hidden": 0, | "hidden": 0, | ||||
"ignore_user_permissions": 0, | "ignore_user_permissions": 0, | ||||
"ignore_xss_filter": 0, | "ignore_xss_filter": 0, | ||||
"in_filter": 0, | "in_filter": 0, | ||||
"in_list_view": 1, | "in_list_view": 1, | ||||
"label": "Fieldtype", | |||||
"label": "Fieldname", | |||||
"length": 0, | "length": 0, | ||||
"no_copy": 0, | "no_copy": 0, | ||||
"options": "Attach\nCheck\nData\nDate\nDatetime\nHTML\nLink\nSelect\nText\nSection Break\nColumn Break", | |||||
"permlevel": 0, | "permlevel": 0, | ||||
"print_hide": 0, | "print_hide": 0, | ||||
"print_hide_if_no_value": 0, | "print_hide_if_no_value": 0, | ||||
@@ -63,6 +65,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "label", | "fieldname": "label", | ||||
"fieldtype": "Data", | "fieldtype": "Data", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -87,6 +90,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "reqd", | "fieldname": "reqd", | ||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -111,6 +115,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "read_only", | "fieldname": "read_only", | ||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -135,6 +140,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "hidden", | "fieldname": "hidden", | ||||
"fieldtype": "Check", | "fieldtype": "Check", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -159,6 +165,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "column_break_4", | "fieldname": "column_break_4", | ||||
"fieldtype": "Column Break", | "fieldtype": "Column Break", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -182,6 +189,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "options", | "fieldname": "options", | ||||
"fieldtype": "Text", | "fieldtype": "Text", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -206,6 +214,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "section_break_6", | "fieldname": "section_break_6", | ||||
"fieldtype": "Section Break", | "fieldtype": "Section Break", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -229,6 +238,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "description", | "fieldname": "description", | ||||
"fieldtype": "Text", | "fieldtype": "Text", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -253,6 +263,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "column_break_8", | "fieldname": "column_break_8", | ||||
"fieldtype": "Column Break", | "fieldtype": "Column Break", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -276,6 +287,7 @@ | |||||
"allow_on_submit": 0, | "allow_on_submit": 0, | ||||
"bold": 0, | "bold": 0, | ||||
"collapsible": 0, | "collapsible": 0, | ||||
"columns": 0, | |||||
"fieldname": "default", | "fieldname": "default", | ||||
"fieldtype": "Data", | "fieldtype": "Data", | ||||
"hidden": 0, | "hidden": 0, | ||||
@@ -307,7 +319,7 @@ | |||||
"issingle": 0, | "issingle": 0, | ||||
"istable": 1, | "istable": 1, | ||||
"max_attachments": 0, | "max_attachments": 0, | ||||
"modified": "2016-07-11 03:28:09.794347", | |||||
"modified": "2016-09-13 12:39:31.889290", | |||||
"modified_by": "Administrator", | "modified_by": "Administrator", | ||||
"module": "Website", | "module": "Website", | ||||
"name": "Web Form Field", | "name": "Web Form Field", | ||||