diff --git a/public/build.json b/public/build.json
index af15a55f51..668619f335 100644
--- a/public/build.json
+++ b/public/build.json
@@ -143,6 +143,7 @@
"lib/public/js/legacy/wn/widgets/form/comments.js",
"lib/public/js/legacy/wn/widgets/form/attachments.js",
"lib/public/js/legacy/wn/widgets/form/assign_to.js",
+ "lib/public/js/wn/form/linked_with.js",
'lib/public/js/lib/jquery/jquery.ui.interactions.min.js',
diff --git a/public/js/legacy/widgets/form/fields.js b/public/js/legacy/widgets/form/fields.js
index fecf18fc48..89d134ac80 100644
--- a/public/js/legacy/widgets/form/fields.js
+++ b/public/js/legacy/widgets/form/fields.js
@@ -998,14 +998,17 @@ SelectField.prototype.make_input = function() {
if(this.file_attach)
this.set_attach_options();
- me.options_list = me.df.options?me.df.options.split('\n'):[''];
+ if(typeof me.df.options=="object")
+ me.options_list = me.df.options
+ else
+ me.options_list = me.df.options?me.df.options.split('\n'):[''];
// add options
- empty_select(this.input);
if(me.in_filter && me.options_list[0]!='') {
- me.options_list = add_lists([''], me.options_list);
+ me.options_list = add_lists([''], me.options_list);
}
- add_sel_options(this.input, me.options_list);
+
+ $(this.input).empty().add_options(me.options_list);
}
// refresh options
@@ -1197,7 +1200,7 @@ function makeinput_popup(me, iconsrc, iconsrc1, iconsrc2) {
}
if(iconsrc2) {
- var c3 = tab.rows[0].insertCell(3);
+ var c3 = tab.rows[0].insertCell(tab.rows[0].cells.length);
$y(c3,{width: '20px'});
me.btn2 = $a(c3, 'i', iconsrc2, icon_style)
me.btn2.setAttribute('title','Create New');
diff --git a/public/js/legacy/wn/widgets/form/sidebar.js b/public/js/legacy/wn/widgets/form/sidebar.js
index 25d60552c2..7fae9ef56c 100644
--- a/public/js/legacy/wn/widgets/form/sidebar.js
+++ b/public/js/legacy/wn/widgets/form/sidebar.js
@@ -37,24 +37,7 @@ wn.widgets.form.sidebar = { Sidebar: function(form) {
},
onclick: function() { new_doc(me.form.doctype) }
},
-
- {
- type: 'link',
- label: 'List',
- icon: 'icon-list',
- display: function() {
- return !me.form.meta.issingle && !me.form.meta.read_only;
- },
- onclick: function() { window.location.href="#!List/" + me.form.doctype }
- },
- {
- type: 'link',
- label: 'Refresh',
- icon: 'icon-refresh',
- onclick: function() { me.form.reload_doc() }
- },
-
{
type: 'link',
label: 'Print',
@@ -104,6 +87,23 @@ wn.widgets.form.sidebar = { Sidebar: function(form) {
},
icon: 'icon-retweet',
onclick: function() { me.form.rename_doc() }
+ },
+
+ {
+ type: 'link',
+ label: 'Linked With',
+ display: function() {
+ return !me.form.doc.__islocal;
+ },
+ icon: 'icon-random',
+ onclick: function() {
+ if(!me.form.linked_with) {
+ me.form.linked_with = new wn.ui.form.LinkedWith({
+ frm: me.form
+ });
+ }
+ me.form.linked_with.show();
+ }
}
],
diff --git a/public/js/wn/form/formatters.js b/public/js/wn/form/formatters.js
index 4113e8fcd3..be41e94d45 100644
--- a/public/js/wn/form/formatters.js
+++ b/public/js/wn/form/formatters.js
@@ -1,24 +1,4 @@
-// Copyright (c) 2012 Web Notes Technologies Pvt Ltd (http://erpnext.com)
-//
-// MIT License (MIT)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
-// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
-// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
+// for license information please see license.txt
wn.provide("wn.form.formatters")
wn.form.formatters = {
diff --git a/public/js/wn/form/linked_with.js b/public/js/wn/form/linked_with.js
new file mode 100644
index 0000000000..67f677ce5d
--- /dev/null
+++ b/public/js/wn/form/linked_with.js
@@ -0,0 +1,106 @@
+// for license information please see license.txt
+
+wn.provide("wn.ui.form")
+
+wn.ui.form.LinkedWith = Class.extend({
+ init: function(opts) {
+ var me = this;
+ $.extend(this, opts);
+ },
+ show: function() {
+ if(!this.dialog)
+ this.make_dialog();
+
+ this.dialog.show();
+ this.dialog.get_input("list_by").change();
+ },
+ make_dialog: function() {
+ var me = this;
+ this.linked_with = this.frm.meta.__linked_with;
+ var links = $.map(keys(this.linked_with), function(v) {
+ return in_list(wn.boot.profile.can_get_report, v) ? {value:v, label:wn._(v)} : null
+ }).sort(function(a, b) { return a.label > b.label ? 1 : -1 });
+
+ this.dialog = new wn.ui.Dialog({
+ width: 640,
+ title: wn._("Linked With"),
+ fields: [
+ { fieldtype: "HTML", label: "help",
+ options:"
" + wn._("List of records in which this document is linked")
+ +"
" },
+ { fieldtype: "Select", options: links,
+ label: wn._("Type"), fieldname: "list_by" },
+ { fieldtype: "HTML", label: "hr", options:"
" },
+ { fieldtype: "HTML", label: "list" }
+ ]
+ });
+
+ this.dialog.get_input("list_by").val(links[0].value);
+
+ if(!links) {
+ this.dialog.fields_dict.list.$wrapper.html(""
+ + this.frm.doctype + ": "
+ + (this.linked_with ? wn._("Not Linked to any record.") : wn._("Not enough permission to see links."))
+ + "
")
+ this.dialog.fields_dict.list_by.$wrapper.toggle(false);
+ this.dialog.fields_dict.help.$wrapper.toggle(false);
+ return;
+ }
+
+ this.dialog.get_input("list_by").change(function() {
+ me.doctype = me.dialog.get_input("list_by").val();
+ me.is_table = (!in_list(wn.boot.profile.can_read, me.doctype) &&
+ in_list(wn.boot.profile.can_get_report, me.doctype))
+
+ wn.model.with_doctype(me.doctype, function(r) {
+ me.make_listing();
+ me.lst.run();
+ })
+ })
+ },
+ make_listing: function() {
+ var me = this;
+ this.lst = new wn.ui.Listing({
+ hide_refresh: true,
+ no_loading: true,
+ no_toolbar: true,
+ doctype: me.doctype,
+ show_filters: true,
+ parent: $(this.dialog.fields_dict.list.wrapper).empty().css("min-height", "300px")
+ .get(0),
+ method: 'webnotes.widgets.reportview.get',
+ get_args: function() {
+ return {
+ doctype: me.doctype,
+ fields: [ '`tab' + me.doctype + '`.name',
+ '`tab' + me.doctype + '`.modified',
+ '`tab' + me.doctype + '`.modified_by',
+ '`tab' + me.doctype + '`.docstatus'],
+ filters: me.lst.filter_list.get_filters(),
+ docstatus: ['0','1']
+ }
+ },
+ render_row: function(parent, data) {
+ $(parent).html(repl('%(avatar)s \
+ \
+ %(doctype)s: %(name)s\
+ Last Updated: %(modified)s', {
+ avatar: wn.avatar(data.modified_by, null,
+ "Last Modified By: " + wn.user_info(data.modified_by).fullname),
+ doctype: me.is_table ? data.parenttype : me.doctype,
+ modified: dateutil.comment_when(data.modified),
+ name: me.is_table ? data.parent : data.name
+ })).find('.avatar img').centerImage();
+ },
+ get_no_result_message: function() {
+ return repl("%(doctype)s: " + wn._("Not linked") + "
", {
+ name: me.frm.doc.name,
+ doctype: wn._(me.doctype)
+ })
+ }
+ });
+ me.lst.filter_list.show_filters(true);
+ me.lst.filter_list.clear_filters();
+ me.lst.set_filter(me.linked_with[me.doctype], me.frm.doc.name);
+ }
+});
\ No newline at end of file
diff --git a/public/js/wn/misc/user.js b/public/js/wn/misc/user.js
index cded9b8f88..952d4cd5e4 100644
--- a/public/js/wn/misc/user.js
+++ b/public/js/wn/misc/user.js
@@ -14,6 +14,20 @@ wn.user_info = function(uid) {
return wn.boot.user_info[uid];
}
+wn.avatar = function(user, large, title) {
+ var image = wn.user_info(user).image;
+ var to_size = large ? 72 : 30;
+ if(!title) title = wn.user_info(user).fullname;
+
+ return repl('\
+
', {
+ image: image,
+ len: to_size + "px",
+ title: title
+ });
+}
+
wn.provide('wn.user');
$.extend(wn.user, {
diff --git a/public/js/wn/ui/filters.js b/public/js/wn/ui/filters.js
index dd00fb069c..35b971d48a 100644
--- a/public/js/wn/ui/filters.js
+++ b/public/js/wn/ui/filters.js
@@ -45,6 +45,11 @@ wn.ui.FilterList = Class.extend({
if(!this.filters.length)
this.add_filter();
},
+
+ clear_filters: function() {
+ this.filters = [];
+ this.$w.find('.filter_area').empty();
+ },
add_filter: function(tablename, fieldname, condition, value) {
this.push_new_filter(tablename, fieldname, condition, value);
diff --git a/public/js/wn/ui/listing.js b/public/js/wn/ui/listing.js
index d691c02292..5e4071d068 100644
--- a/public/js/wn/ui/listing.js
+++ b/public/js/wn/ui/listing.js
@@ -279,7 +279,16 @@ wn.ui.Listing = Class.extend({
} else {
if(this.start==0) {
this.$w.find('.result').toggle(false);
- this.$w.find('.no-result').toggle(true);
+
+ var msg = this.get_no_result_message
+ ? this.get_no_result_message()
+ : (this.no_result_message
+ ? this.no_result_message
+ : wn._("Nothing to show"));
+
+ this.$w.find('.no-result')
+ .html(msg)
+ .toggle(true);
}
}
@@ -331,5 +340,35 @@ wn.ui.Listing = Class.extend({
add_limits: function(query) {
query += ' LIMIT ' + this.start + ',' + (this.page_length+1);
return query
- }
+ },
+ set_filter: function(fieldname, label) {
+ var filter = this.filter_list.get_filter(fieldname);
+ //this.filter_list.show_filters(true);
+ if(filter) {
+ var v = filter.field.get_value();
+ if(v.indexOf(label)!=-1) {
+ // already set
+ return false;
+ } else {
+ // second filter set for this field
+ if(fieldname=='_user_tags') {
+ // and for tags
+ this.filter_list.add_filter(this.doctype, fieldname,
+ 'like', '%' + label);
+ } else {
+ // or for rest using "in"
+ filter.set_values(this.doctype, fieldname, 'in', v + ', ' + label);
+ }
+ }
+ } else {
+ // no filter for this item,
+ // setup one
+ if(fieldname=='_user_tags') {
+ this.filter_list.add_filter(this.doctype, fieldname,
+ 'like', '%' + label);
+ } else {
+ this.filter_list.add_filter(this.doctype, fieldname, '=', label);
+ }
+ }
+ }
});
\ No newline at end of file
diff --git a/public/js/wn/ui/search.js b/public/js/wn/ui/search.js
index 40637a0548..338f85cdd6 100644
--- a/public/js/wn/ui/search.js
+++ b/public/js/wn/ui/search.js
@@ -37,7 +37,7 @@ wn.ui.Search = Class.extend({
fields: [ '`tab' + me.doctype + '`.name'],
filters: me.list.filter_list.get_filters(),
docstatus: ['0','1']
- }
+ }
}
},
render_row: function(parent, data) {
diff --git a/webnotes/model/doctype.py b/webnotes/model/doctype.py
index 10e0d5d0ef..f0fb8c64bd 100644
--- a/webnotes/model/doctype.py
+++ b/webnotes/model/doctype.py
@@ -65,7 +65,7 @@ def get(doctype, processed=False):
expand_selects(doclist)
add_print_formats(doclist)
add_search_fields(doclist)
- #add_linked_with(doclist)
+ add_linked_with(doclist)
#add_workflows(doclist)
#update_language(doclist)