Browse Source

started standard lists and views [wip] for portal

version-14
Rushabh Mehta 11 years ago
parent
commit
8ab1345d9a
9 changed files with 239 additions and 6 deletions
  1. +13
    -1
      frappe/model/meta.py
  2. +84
    -0
      frappe/templates/pages/list.html
  3. +46
    -0
      frappe/templates/pages/list.py
  4. +1
    -1
      frappe/templates/pages/message.html
  5. +40
    -0
      frappe/templates/pages/view.html
  6. +14
    -0
      frappe/templates/pages/view.py
  7. +3
    -0
      frappe/website/js/website.js
  8. +37
    -3
      frappe/website/render.py
  9. +1
    -1
      frappe/widgets/search.py

+ 13
- 1
frappe/model/meta.py View File

@@ -99,6 +99,18 @@ class Meta(Document):
def get_options(self, fieldname): def get_options(self, fieldname):
return self.get_field(fieldname).options return self.get_field(fieldname).options


def get_search_fields(self):
search_fields = self.search_fields or "name"
search_fields = [d.strip() for d in search_fields.split(",")]
if "name" not in search_fields:
search_fields.append("name")

return search_fields

def get_list_fields(self):
return ["name"] + [d.fieldname \
for d in self.fields if (d.in_list_view and d.fieldtype in type_map)]

def process(self): def process(self):
# don't process for special doctypes # don't process for special doctypes
# prevent's circular dependency # prevent's circular dependency
@@ -203,7 +215,7 @@ doctype_table_fields = [
def is_single(doctype): def is_single(doctype):
try: try:
return frappe.db.get_value("DocType", doctype, "issingle") return frappe.db.get_value("DocType", doctype, "issingle")
except IndexError, e:
except IndexError:
raise Exception, 'Cannot determine whether %s is single' % doctype raise Exception, 'Cannot determine whether %s is single' % doctype


def get_parent_dt(dt): def get_parent_dt(dt):


+ 84
- 0
frappe/templates/pages/list.html View File

@@ -0,0 +1,84 @@
{% block title %}{{ type }} {{ _("List") }}{% endblock %}

{% block header %}
<h2>{{ type }} {{ _("List") }}</h2>
{% endblock %}

{% block content %}
<!-- no-sidebar -->
<div class="row">
<div class=" col-sm-offset-8 col-sm-4">
<form class="form-inline form-search" action="/list">
<div class="input-group">
<input class="form-control" type="text" name="txt"
placeholder="Search..." value="{{ txt or '' }}">
<input type="hidden" name="type" value="{{ type }}">
<span class="input-group-btn">
<button class="btn btn-default" type="submit">
<i class="icon-search"></i></button>
</span>
</div>
</form>
</div>
</div>
<br>
{% if txt %}
<div class="alert alert-warning">Results filtered by <b>{{ txt }}</b>. <a href="/list?type={{ type }}" class="close">&times;</a></div>
{% endif %}
<div class="list-group" data-type="{{ type }}" data-txt="{{ txt or '[notxt]' }}">
{% for item in items %}
<div class="list-group-item">
{{ item }}
</div>
{% endfor %}
</div>
<div class="more-block text-center hide">
<button class="btn btn-default btn-more">More</button>
</div>
{% endblock %}

{% block script %}
<script>
frappe.ready(function() {
// show more button if len is 20
$list_group = $(".list-group[data-type='{{ type }}'][data-txt='{{ txt or "[notxt]" }}']");

// more ajax
frappe.start = 20;
$(".btn-more").on("click", function() {
$.ajax({
url:"/api/method/frappe.templates.pages.list.get_items",
data: {
type: "{{ type }}",
txt: "{{ txt or '' }}",
limit_start: frappe.start
},
statusCode: {
200: function(data) {
frappe.start += 20;
$.each(data.message.items, function(i, d) {
$('<div class="list-group-item">')
.html(d)
.appendTo($list_group);
});
show_more();
}
}
})
})

var show_more = function() {
var $items = $list_group.find(".list-group-item")
if($items.length && ($items.length % 20 === 0)) {
if($(".more-block").hasClass("hide"))
$(".more-block").removeClass("hide");
} else {
if(!$(".more-block").hasClass("hide"))
$(".more-block").addClass("hide");
}
};

show_more();
})
</script>
{% endblock %}

+ 46
- 0
frappe/templates/pages/list.py View File

@@ -0,0 +1,46 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt

from __future__ import unicode_literals
import frappe, os
from frappe.modules import get_doc_path
from jinja2 import Environment, Template, FileSystemLoader

no_cache = 1
no_sitemap = 1

def get_context(context):
context.type = frappe.local.form_dict.type
context.txt = frappe.local.form_dict.txt
context.update(get_items(context.type, context.txt))
return context

@frappe.whitelist(allow_guest=True)
def get_items(type, txt, limit_start=0):
meta = frappe.get_meta(type)
filters, or_filters = [], []
out = frappe._dict()

if txt:
if meta.search_fields:
for f in meta.get_search_fields():
or_filters.append([type, f.strip(), "like", "%" + txt + "%"])
else:
filters.append([type, "name", "like", "%" + txt + "%"])


out.raw_items = frappe.get_list(type, fields = meta.get_list_fields(),
filters=filters, or_filters = or_filters, limit_start=limit_start,
limit_page_length = 20)
template_path = os.path.join(get_doc_path(meta.module, "DocType", meta.name), "list_item.html")

if os.path.exists(template_path):
env = Environment(loader = FileSystemLoader("."))
template = env.get_template(template_path)
else:
template = Template("""<div><a href="/{{ doctype }}/{{ item.name }}">
{{ item.name }}</a></div>""")

out.items = [template.render(item=i, doctype=type) for i in out.raw_items]

return out

+ 1
- 1
frappe/templates/pages/message.html View File

@@ -7,4 +7,4 @@
<div class="message-content"> <div class="message-content">
<p>{{ message }}</p> <p>{{ message }}</p>
</div> </div>
{% endblock %}
{% endblock %}

+ 40
- 0
frappe/templates/pages/view.html View File

@@ -0,0 +1,40 @@
{% block title %}{{ doc.doctype }} / {{ doc.name }}{% endblock %}

{% block header %}
<h2>{{ doc.name }}</h2>
<p>{{ doc.doctype }}
{% endblock %}

{% block content %}
{% if custom_view %}
{{ custom_view }}
{% else %}
{% for df in meta.fields %}
{% if not df.hidden and not df.permlevel and not df.print_hide %}
{% if df.fieldtype=="Section Break" %}
<h2>{{ df.label or "" }}</h2>
{% elif df.fieldtype=="Column Break" %}
{% elif df.fieldtype=="Table" %}

{% else %}
<div class="row">
<div class="col-sm-4 text-right">
{% if df.fieldtype not in ("Image",) %}
<label>{{ df.label }}</label>
{% endif %}
</div>
<div class="col-sm-8">
{% if df.fieldtype=="Check" %}
<i class="{{ 'icon-check' if doc[df.fieldname] else 'icon-check-empty' }}"></i>
{% elif df.fieldtype=="Image" %}
<img src="{{ doc[meta.get_field(df.fieldname).options] }}" class="img-responsive">
{% else %}
{{ doc[df.fieldname] }}
{% endif %}
</div>
</div>
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% endblock %}

+ 14
- 0
frappe/templates/pages/view.py View File

@@ -0,0 +1,14 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt

from __future__ import unicode_literals
import frappe

no_cache = 1
no_sitemap = 1

def get_context(context):
return {
"doc": frappe.get_doc(frappe.local.form_dict.doctype, frappe.local.form_dict.name),
"meta": frappe.get_meta(frappe.local.form_dict.doctype)
}

+ 3
- 0
frappe/website/js/website.js View File

@@ -221,6 +221,9 @@ $.extend(frappe, {
if ( event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey ) if ( event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey )
return; return;


if (link.getAttribute("target"))
return;

// Ignore cross origin links // Ignore cross origin links
if ( location.protocol !== link.protocol || location.hostname !== link.hostname ) if ( location.protocol !== link.protocol || location.hostname !== link.hostname )
return; return;


+ 37
- 3
frappe/website/render.py View File

@@ -8,7 +8,7 @@ from werkzeug.wrappers import Response


from frappe.website.context import get_context from frappe.website.context import get_context
from frappe.website.utils import scrub_relative_urls, get_home_page, can_cache from frappe.website.utils import scrub_relative_urls, get_home_page, can_cache
from frappe.website.permissions import get_access, clear_permissions
from frappe.website.permissions import clear_permissions


class PageNotFoundError(Exception): pass class PageNotFoundError(Exception): pass


@@ -18,9 +18,25 @@ def render(path, http_status_code=None):


try: try:
data = render_page(path) data = render_page(path)

except frappe.DoesNotExistError, e: except frappe.DoesNotExistError, e:
path = "404"
doctype, name = get_doctype_from_path(path)
if doctype and name:
path = "view"
frappe.local.form_dict.doctype = doctype
frappe.local.form_dict.name = name
elif doctype:
path = "list"
frappe.local.form_dict.type = doctype
else:
path = "404"
http_status_code = e.http_status_code

data = render_page(path)

except frappe.PermissionError, e:
path = "message"
frappe.local.message = "Did you log out?"
frappe.local.message_title = "Not Permitted"
data = render_page(path) data = render_page(path)
http_status_code = e.http_status_code http_status_code = e.http_status_code


@@ -31,6 +47,24 @@ def render(path, http_status_code=None):


return build_response(path, data, http_status_code or 200) return build_response(path, data, http_status_code or 200)


def get_doctype_from_path(path):
doctypes = [d[0] for d in frappe.get_list("DocType", as_list=True)]

parts = path.split("/")

doctype = parts[0]
name = parts[1] if len(parts) > 1 else None

if doctype in doctypes:
return doctype, name

# try scrubbed
doctype = doctype.replace("_", " ").title()
if doctype in doctypes:
return doctype, name

return None, None

def build_response(path, data, http_status_code): def build_response(path, data, http_status_code):
# build response # build response
response = Response() response = Response()


+ 1
- 1
frappe/widgets/search.py View File

@@ -61,7 +61,7 @@ def search_widget(doctype, txt, query=None, searchfield=None, start=0,
# build from doctype # build from doctype
if txt: if txt:
if meta.search_fields: if meta.search_fields:
for f in meta.search_fields.split(","):
for f in meta.get_search_fields():
or_filters.append([doctype, f.strip(), "like", "%" + txt + "%"]) or_filters.append([doctype, f.strip(), "like", "%" + txt + "%"])
else: else:
filters.append([doctype, searchfield or "name", "like", filters.append([doctype, searchfield or "name", "like",


Loading…
Cancel
Save