From b34afadd8de0ce3a4269c82a17bd003a291886c7 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 9 May 2014 12:31:13 +0530 Subject: [PATCH 1/2] Further improvements to autocomplete --- frappe/public/js/frappe/form/control.js | 12 +- .../bootstrap_theme/jquery-ui.selected.css | 294 +++++++++--------- frappe/widgets/search.py | 2 +- 3 files changed, 155 insertions(+), 153 deletions(-) diff --git a/frappe/public/js/frappe/form/control.js b/frappe/public/js/frappe/form/control.js index 578abddaa6..ae1cc4b37b 100644 --- a/frappe/public/js/frappe/form/control.js +++ b/frappe/public/js/frappe/form/control.js @@ -888,17 +888,13 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({ } } }).data('ui-autocomplete')._renderItem = function(ul, d) { - var html = ""; - if(keys(d).length > 1) { - d.info = $.map(d, function(val, key) { return ["value", "label"].indexOf(key)!==-1 ? null : val }).join(", ") || ""; - html = repl("%(value)s
%(info)s
", d); - } else { - html = "" + d.value + ""; + var html = "" + d.value + ""; + if(d.value!==d.description) { + html += '
' + d.description + ''; } - return $('
  • ') .data('item.autocomplete', d) - .append(html) + .html('

    ' + html + '

    ') .appendTo(ul); }; // remove accessibility span (for now) diff --git a/frappe/public/js/lib/jquery/bootstrap_theme/jquery-ui.selected.css b/frappe/public/js/lib/jquery/bootstrap_theme/jquery-ui.selected.css index 1c84dd3704..486f9891cc 100644 --- a/frappe/public/js/lib/jquery/bootstrap_theme/jquery-ui.selected.css +++ b/frappe/public/js/lib/jquery/bootstrap_theme/jquery-ui.selected.css @@ -12,56 +12,56 @@ /* Layout helpers ----------------------------------*/ .ui-helper-hidden { display: none; } -.ui-helper-hidden-accessible { +.ui-helper-hidden-accessible { border: 0; clip: rect(0 0 0 0); - height: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - position: absolute; - width: 1px; + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; } -.ui-helper-reset { - margin: 0; - padding: 0; - border: 0; - outline: 0; - line-height: 1.3; - text-decoration: none; - font-size: 100%; - list-style: none; +.ui-helper-reset { + margin: 0; + padding: 0; + border: 0; + outline: 0; + line-height: 1.3; + text-decoration: none; + font-size: 100%; + list-style: none; } .ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; } -.ui-helper-clearfix:after { - content: "."; - display: block; - height: 0; - clear: both; - visibility: hidden; +.ui-helper-clearfix:after { + content: "."; + display: block; + height: 0; + clear: both; + visibility: hidden; } -.ui-helper-clearfix { +.ui-helper-clearfix { /*display: inline-block; */ display:block; min-height: 0; /* support: IE7 */ } /* required comment for clearfix to work in Opera \*/ -* html .ui-helper-clearfix { - height:1%; +* html .ui-helper-clearfix { + height:1%; } /* end clearfix */ -.ui-helper-zfix { - width: 100%; - height: 100%; - top: 0; - left: 0; - position: absolute; - opacity: 0; - filter:Alpha(Opacity=0); +.ui-helper-zfix { + width: 100%; + height: 100%; + top: 0; + left: 0; + position: absolute; + opacity: 0; + filter:Alpha(Opacity=0); } .ui-front { z-index: 100; @@ -77,11 +77,11 @@ ----------------------------------*/ /* states and images */ -.ui-icon { - display: block; - text-indent: -99999px; - overflow: hidden; - background-repeat: no-repeat; +.ui-icon { + display: block; + text-indent: -99999px; + overflow: hidden; + background-repeat: no-repeat; } @@ -89,12 +89,12 @@ ----------------------------------*/ /* Overlays */ -.ui-widget-overlay { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; +.ui-widget-overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; } /* @@ -107,72 +107,72 @@ * http://api.jqueryui.com/resizable/ */ -.ui-resizable { +.ui-resizable { position: relative; } -.ui-resizable-handle { +.ui-resizable-handle { position: absolute; font-size: 0.1px; - z-index: 99999; - display: block; + z-index: 99999; + display: block; } -.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { - display: none; +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { + display: none; } -.ui-resizable-n { - cursor: n-resize; - height: 7px; - width: 100%; - top: -5px; - left: 0; +.ui-resizable-n { + cursor: n-resize; + height: 7px; + width: 100%; + top: -5px; + left: 0; } -.ui-resizable-s { - cursor: s-resize; - height: 7px; - width: 100%; - bottom: -5px; - left: 0; +.ui-resizable-s { + cursor: s-resize; + height: 7px; + width: 100%; + bottom: -5px; + left: 0; } -.ui-resizable-e { - cursor: e-resize; - width: 7px; - right: -5px; - top: 0; - height: 100%; +.ui-resizable-e { + cursor: e-resize; + width: 7px; + right: -5px; + top: 0; + height: 100%; } -.ui-resizable-w { - cursor: w-resize; - width: 7px; - left: -5px; - top: 0; - height: 100%; +.ui-resizable-w { + cursor: w-resize; + width: 7px; + left: -5px; + top: 0; + height: 100%; } -.ui-resizable-se { - cursor: se-resize; - width: 12px; - height: 12px; - right: 1px; - bottom: 1px; +.ui-resizable-se { + cursor: se-resize; + width: 12px; + height: 12px; + right: 1px; + bottom: 1px; } -.ui-resizable-sw { - cursor: sw-resize; - width: 9px; - height: 9px; - left: -5px; - bottom: -5px; +.ui-resizable-sw { + cursor: sw-resize; + width: 9px; + height: 9px; + left: -5px; + bottom: -5px; } -.ui-resizable-nw { - cursor: nw-resize; - width: 9px; - height: 9px; - left: -5px; - top: -5px; +.ui-resizable-nw { + cursor: nw-resize; + width: 9px; + height: 9px; + left: -5px; + top: -5px; } -.ui-resizable-ne { - cursor: ne-resize; - width: 9px; - height: 9px; - right: -5px; +.ui-resizable-ne { + cursor: ne-resize; + width: 9px; + height: 9px; + right: -5px; top: -5px; } @@ -185,10 +185,10 @@ * * http://jqueryui.com/selectable/ */ -.ui-selectable-helper { - position: absolute; - z-index: 100; - border:1px dotted black; +.ui-selectable-helper { + position: absolute; + z-index: 100; + border:1px dotted black; } /* @@ -198,17 +198,18 @@ * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * - * + * * * To view and modify this theme, visit http://jqueryui.com/themeroller/ */ /* Component containers ----------------------------------*/ -.ui-widget { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size:13px; } +/*.ui-widget { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size:13px; }*/ .ui-widget .ui-widget { font-size: 1em; } -.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 1em; } -.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(../frappe/js/lib/jquery/bootstrap_theme/images/ui-bg_glass_75_ffffff_1x400.png) 50% 50% repeat-x; color: #404040; } +/*.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 1em; }*/ +/*.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(../frappe/js/lib/jquery/bootstrap_theme/images/ui-bg_glass_75_ffffff_1x400.png) 50% 50% repeat-x; color: #404040; }*/ +.ui-widget-content { border: 1px solid #aaaaaa; background-color: #ffffff; color: #404040;} .ui-widget-content a { color: #404040; } .ui-widget-header { font-weight:bold; @@ -514,41 +515,41 @@ ----------------------------------*/ /* Corner radius */ -.ui-corner-all, -.ui-corner-top, -.ui-corner-left, -.ui-corner-tl { - -moz-border-radius-topleft: 4px; - -webkit-border-top-left-radius: 4px; - -khtml-border-top-left-radius: 4px; - border-top-left-radius: 4px; +.ui-corner-all, +.ui-corner-top, +.ui-corner-left, +.ui-corner-tl { + -moz-border-radius-topleft: 4px; + -webkit-border-top-left-radius: 4px; + -khtml-border-top-left-radius: 4px; + border-top-left-radius: 4px; } -.ui-corner-all, -.ui-corner-top, -.ui-corner-right, -.ui-corner-tr { - -moz-border-radius-topright: 4px; - -webkit-border-top-right-radius: 4px; - -khtml-border-top-right-radius: 4px; - border-top-right-radius: 4px; +.ui-corner-all, +.ui-corner-top, +.ui-corner-right, +.ui-corner-tr { + -moz-border-radius-topright: 4px; + -webkit-border-top-right-radius: 4px; + -khtml-border-top-right-radius: 4px; + border-top-right-radius: 4px; } -.ui-corner-all, -.ui-corner-bottom, -.ui-corner-left, -.ui-corner-bl { - -moz-border-radius-bottomleft: 4px; - -webkit-border-bottom-left-radius: 4px; - -khtml-border-bottom-left-radius: 4px; - border-bottom-left-radius: 4px; +.ui-corner-all, +.ui-corner-bottom, +.ui-corner-left, +.ui-corner-bl { + -moz-border-radius-bottomleft: 4px; + -webkit-border-bottom-left-radius: 4px; + -khtml-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; } -.ui-corner-all, -.ui-corner-bottom, -.ui-corner-right, -.ui-corner-br { - -moz-border-radius-bottomright: 4px; - -webkit-border-bottom-right-radius: 4px; - -khtml-border-bottom-right-radius: 4px; - border-bottom-right-radius: 4px; +.ui-corner-all, +.ui-corner-bottom, +.ui-corner-right, +.ui-corner-br { + -moz-border-radius-bottomright: 4px; + -webkit-border-bottom-right-radius: 4px; + -khtml-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; } @@ -562,11 +563,11 @@ * http://jqueryui.com/autocomplete/ */ -.ui-autocomplete { - position: absolute; +.ui-autocomplete { + position: absolute; top: 0; left: 0; - cursor: default; + cursor: default; } /* @@ -685,9 +686,9 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad .ui-menu .ui-menu-divider { margin: 5px -2px 5px -2px; height: 0; font-size: 0; line-height: 0; border-width: 1px 0 0 0; } .ui-menu .ui-menu-item a { text-decoration: none; display: block; padding: 2px .4em; line-height: 1.5; zoom: 1; font-weight: normal; } .ui-menu .ui-menu-item a.ui-state-focus, -.ui-menu .ui-menu-item a.ui-state-active { - font-weight: normal; - margin: 0; +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: 0; color: #ffffff; background: #0064cd; background-color: #0064cd; @@ -695,6 +696,11 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad border-color: #0064cd #0064cd #003f81; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); } +.ui-menu .ui-menu-item a p { margin: 3px 0px; } +.ui-menu .ui-menu-item a .small { color: #555555; } +.ui-menu .ui-menu-item a.ui-state-focus .small, +.ui-menu .ui-menu-item a.ui-state-active .small { color: #ffffff; } + /* Fix problem with border in ui-state-active */ .ui-menu .ui-menu-item a.ui-state-active { padding: 1px .4em; @@ -884,4 +890,4 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad -moz-border-radius: 4px; -khtml-border-radius: 4px; border-radius: 4px; -} \ No newline at end of file +} diff --git a/frappe/widgets/search.py b/frappe/widgets/search.py index 4e45eab0f8..91a89baade 100644 --- a/frappe/widgets/search.py +++ b/frappe/widgets/search.py @@ -88,7 +88,7 @@ def get_std_fields_list(meta, key): def build_for_autosuggest(res): results = [] for r in res: - out = {"value": r[0], "description": ", ".join([cstr(d) for d in r[1:]])} + out = {"value": r[0], "description": ", ".join(list(set(cstr(d) for d in r[1:])))} results.append(out) return results From 3c160b6554f3117516cfbfb16ef9f3741b82d802 Mon Sep 17 00:00:00 2001 From: Anand Doshi Date: Fri, 9 May 2014 13:35:09 +0530 Subject: [PATCH 2/2] Deprecate Select fields with options as link: --- .../core/doctype/custom_field/custom_field.js | 2 +- frappe/core/doctype/doctype/doctype.py | 7 ----- .../core/doctype/event_user/event_user.json | 13 +++++--- .../doctype/print_format/print_format.json | 20 +++++++----- frappe/core/page/data_import_tool/exporter.py | 2 -- frappe/model/base_document.py | 3 -- frappe/model/create_new.py | 3 +- frappe/model/meta.py | 6 +--- frappe/model/rename_doc.py | 31 ++++++------------- frappe/patches.txt | 1 + frappe/patches/4_0/deprecate_link_selects.py | 13 ++++++++ frappe/public/js/frappe/model/create_new.js | 2 +- frappe/test_runner.py | 2 -- frappe/translate.py | 1 - frappe/utils/datautils.py | 6 +--- frappe/widgets/form/meta.py | 8 ----- 16 files changed, 50 insertions(+), 70 deletions(-) create mode 100644 frappe/patches/4_0/deprecate_link_selects.py diff --git a/frappe/core/doctype/custom_field/custom_field.js b/frappe/core/doctype/custom_field/custom_field.js index e5fc47075d..90a290ad98 100644 --- a/frappe/core/doctype/custom_field/custom_field.js +++ b/frappe/core/doctype/custom_field/custom_field.js @@ -48,7 +48,7 @@ cur_frm.fields_dict['dt'].get_query = function(doc, dt, dn) { cur_frm.cscript.fieldtype = function(doc, dt, dn) { if(doc.fieldtype == 'Link') cur_frm.fields_dict['options_help'].disp_area.innerHTML = 'Please enter name of the document you want this field to be linked to in Options.
    Eg.: Customer'; - else if(doc.fieldtype == 'Select') cur_frm.fields_dict['options_help'].disp_area.innerHTML = 'Please enter values in Options separated by enter.
    Eg.: Field: Country
    Options:
    China
    India
    United States

    OR
    You can also link it to existing Documents.
    Eg.: link:Customer'; + else if(doc.fieldtype == 'Select') cur_frm.fields_dict['options_help'].disp_area.innerHTML = 'Please enter values in Options, with each option on a new line.
    Eg.: Field: Country
    Options:
    China
    India
    United States

    '; else cur_frm.fields_dict['options_help'].disp_area.innerHTML = ''; } diff --git a/frappe/core/doctype/doctype/doctype.py b/frappe/core/doctype/doctype/doctype.py index a2928c5571..69e66017f0 100644 --- a/frappe/core/doctype/doctype/doctype.py +++ b/frappe/core/doctype/doctype/doctype.py @@ -31,7 +31,6 @@ class DocType(Document): validate_permissions(self) self.make_amendable() - self.check_link_replacement_error() def change_modified_of_parent(self): if frappe.flags.in_import: @@ -94,12 +93,6 @@ class DocType(Document): module.on_doctype_update() frappe.clear_cache(doctype=self.name) - def check_link_replacement_error(self): - for d in self.get("fields", {"fieldtype":"Select"}): - if (frappe.db.get_value("DocField", d.name, "options") or "").startswith("link:") \ - and not d.options.startswith("link:"): - frappe.throw(_("'link:' type Select {0} getting replaced").format(d.label)) - def on_trash(self): frappe.db.sql("delete from `tabCustom Field` where dt = %s", self.name) frappe.db.sql("delete from `tabCustom Script` where dt = %s", self.name) diff --git a/frappe/core/doctype/event_user/event_user.json b/frappe/core/doctype/event_user/event_user.json index 8ed3cfe2e0..5886cd21ba 100644 --- a/frappe/core/doctype/event_user/event_user.json +++ b/frappe/core/doctype/event_user/event_user.json @@ -1,17 +1,17 @@ { "autoname": "EVP.#####", - "creation": "2013-02-22 01:27:33.000000", + "creation": "2013-02-22 01:27:33", "docstatus": 0, "doctype": "DocType", "fields": [ { "fieldname": "person", - "fieldtype": "Select", + "fieldtype": "Link", "in_list_view": 1, "label": "Person", "oldfieldname": "person", "oldfieldtype": "Select", - "options": "link:User", + "options": "User", "permlevel": 0, "print_width": "240px", "search_index": 1, @@ -20,9 +20,12 @@ ], "idx": 1, "istable": 1, - "modified": "2013-12-20 19:23:14.000000", + "modified": "2014-05-09 02:12:32.374008", "modified_by": "Administrator", "module": "Core", "name": "Event User", - "owner": "Administrator" + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC" } \ No newline at end of file diff --git a/frappe/core/doctype/print_format/print_format.json b/frappe/core/doctype/print_format/print_format.json index 987023bf04..a8bcffd22e 100644 --- a/frappe/core/doctype/print_format/print_format.json +++ b/frappe/core/doctype/print_format/print_format.json @@ -3,21 +3,22 @@ "allow_copy": 0, "allow_rename": 0, "autoname": "Prompt", - "creation": "2013-01-23 19:54:43.000000", + "creation": "2013-01-23 19:54:43", "docstatus": 0, "doctype": "DocType", "fields": [ { "allow_on_submit": 0, "fieldname": "module", - "fieldtype": "Select", + "fieldtype": "Link", "hidden": 0, "in_filter": 1, + "in_list_view": 1, "label": "Module", "no_copy": 0, "oldfieldname": "module", "oldfieldtype": "Select", - "options": "link:Module Def", + "options": "Module Def", "permlevel": 0, "print_hide": 0, "report_hide": 0, @@ -27,10 +28,11 @@ { "description": "Belongs to", "fieldname": "doc_type", - "fieldtype": "Select", + "fieldtype": "Link", "in_filter": 1, + "in_list_view": 1, "label": "DocType", - "options": "link:DocType", + "options": "DocType", "permlevel": 0, "reqd": 0, "search_index": 0 @@ -47,6 +49,7 @@ "fieldtype": "Select", "hidden": 0, "in_filter": 1, + "in_list_view": 1, "label": "Standard", "no_copy": 1, "oldfieldname": "standard", @@ -62,6 +65,7 @@ { "fieldname": "print_format_type", "fieldtype": "Select", + "in_list_view": 1, "label": "Print Format Type", "options": "Client\nServer", "permlevel": 0 @@ -99,7 +103,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2014-01-20 17:49:00.000000", + "modified": "2014-05-09 02:12:39.540952", "modified_by": "Administrator", "module": "Core", "name": "Print Format", @@ -158,5 +162,7 @@ } ], "read_only": 0, - "read_only_onload": 0 + "read_only_onload": 0, + "sort_field": "modified", + "sort_order": "DESC" } \ No newline at end of file diff --git a/frappe/core/page/data_import_tool/exporter.py b/frappe/core/page/data_import_tool/exporter.py index b64b95b841..ab711e171b 100644 --- a/frappe/core/page/data_import_tool/exporter.py +++ b/frappe/core/page/data_import_tool/exporter.py @@ -108,8 +108,6 @@ def get_template(doctype=None, parent_doctype=None, all_doctypes="No", with_data if docfield.fieldtype == 'Select': if not docfield.options: return '' - elif docfield.options.startswith('link:'): - return 'Valid %s' % docfield.options[5:] else: return 'One of: %s' % ', '.join(filter(None, docfield.options.split('\n'))) elif docfield.fieldtype == 'Link': diff --git a/frappe/model/base_document.py b/frappe/model/base_document.py index 4b5767d3c1..9b48f37228 100644 --- a/frappe/model/base_document.py +++ b/frappe/model/base_document.py @@ -259,9 +259,6 @@ class BaseDocument(object): if not doctype: frappe.throw(_("Options not set for link field {0}").format(df.fieldname)) - elif doctype.lower().startswith("link:"): - doctype = doctype[5:] - docname = self.get(df.fieldname) if docname and not frappe.db.get_value(doctype, docname): invalid_links.append((df.fieldname, docname, get_msg(df, docname))) diff --git a/frappe/model/create_new.py b/frappe/model/create_new.py index 79d9ad5d10..ae3d12dc82 100644 --- a/frappe/model/create_new.py +++ b/frappe/model/create_new.py @@ -63,8 +63,7 @@ def get_new_doc(doctype, parent_doc = None, parentfield = None): elif d.fieldtype == "Time": doc.set(d.fieldname, nowtime()) - elif (d.fieldtype == "Select" and d.options and not d.options.startswith("link:") - and d.options != "[Select]"): + elif (d.fieldtype == "Select" and d.options and d.options != "[Select]"): doc.set(d.fieldname, d.options.split("\n")[0]) return doc diff --git a/frappe/model/meta.py b/frappe/model/meta.py index b40097ea43..c0e1ac0bca 100644 --- a/frappe/model/meta.py +++ b/frappe/model/meta.py @@ -59,11 +59,7 @@ class Meta(Document): raise def get_link_fields(self): - tmp = self.get("fields", {"fieldtype":"Link", "options":["!=", "[Select]"]}) - for df in self.get("fields", {"fieldtype":"Select", "options": "^link:"}): - tmp.append(frappe._dict({"fieldname":df.fieldname, "label":df.label, - "fieldtype":"Link", "options": df.options[5:]})) - return tmp + return self.get("fields", {"fieldtype": "Link", "options":["!=", "[Select]"]}) def get_table_fields(self): if not hasattr(self, "_table_fields"): diff --git a/frappe/model/rename_doc.py b/frappe/model/rename_doc.py index 32d7072c30..9e3ea152ed 100644 --- a/frappe/model/rename_doc.py +++ b/frappe/model/rename_doc.py @@ -11,7 +11,7 @@ from frappe.model.naming import validate_name def rename_doc(doctype, old, new, force=False, merge=False, ignore_permissions=False): """ Renames a doc(dt, old) to doc(dt, new) and - updates all linked fields of type "Link" or "Select" with "link:" + updates all linked fields of type "Link" """ if not frappe.db.exists(doctype, old): return @@ -138,9 +138,7 @@ def get_link_fields(doctype): where dt.name = df.parent) as issingle from tabDocField df where - df.parent not like "old%%%%" and df.parent != '0' and - ((df.options=%s and df.fieldtype='Link') or - (df.options='link:%s' and df.fieldtype='Select'))""" \ + df.options=%s and df.fieldtype='Link'""" \ % ('%s', doctype), (doctype,), as_dict=1) # get link fields from tabCustom Field @@ -150,9 +148,7 @@ def get_link_fields(doctype): where dt.name = df.dt) as issingle from `tabCustom Field` df where - df.dt not like "old%%%%" and df.dt != '0' and - ((df.options=%s and df.fieldtype='Link') or - (df.options='link:%s' and df.fieldtype='Select'))""" \ + df.options=%s and df.fieldtype='Link'""" \ % ('%s', doctype), (doctype,), as_dict=1) # add custom link fields list to link fields list @@ -167,7 +163,7 @@ def get_link_fields(doctype): where ps.property_type='options' and ps.field_name is not null and - (ps.value=%s or ps.value='link:%s')""" \ + ps.value=%s""" \ % ('%s', doctype), (doctype,), as_dict=1) link_fields += property_setter_link_fields @@ -199,10 +195,8 @@ def get_select_fields(old, new): where dt.name = df.parent) as issingle from tabDocField df where - df.parent not like "old%%%%" and df.parent != '0' and df.parent != %s and df.fieldtype = 'Select' and - df.options not like "link:%%%%" and - (df.options like "%%%%%s%%%%")""" \ + df.options like "%%%%%s%%%%" """ \ % ('%s', old), (new,), as_dict=1) # get link fields from tabCustom Field @@ -212,10 +206,8 @@ def get_select_fields(old, new): where dt.name = df.dt) as issingle from `tabCustom Field` df where - df.dt not like "old%%%%" and df.dt != '0' and df.dt != %s and df.fieldtype = 'Select' and - df.options not like "link:%%%%" and - (df.options like "%%%%%s%%%%")""" \ + df.options like "%%%%%s%%%%" """ \ % ('%s', old), (new,), as_dict=1) # add custom link fields list to link fields list @@ -231,8 +223,7 @@ def get_select_fields(old, new): ps.doc_type != %s and ps.property_type='options' and ps.field_name is not null and - ps.value not like "link:%%%%" and - (ps.value like "%%%%%s%%%%")""" \ + ps.value like "%%%%%s%%%%" """ \ % ('%s', old), (new,), as_dict=1) select_fields += property_setter_select_fields @@ -243,16 +234,14 @@ def update_select_field_values(old, new): frappe.db.sql("""\ update `tabDocField` set options=replace(options, %s, %s) where - parent != %s and parent not like "old%%%%" and - fieldtype = 'Select' and options not like "link:%%%%" and + parent != %s and fieldtype = 'Select' and (options like "%%%%\\n%s%%%%" or options like "%%%%%s\\n%%%%")""" % \ ('%s', '%s', '%s', old, old), (old, new, new)) frappe.db.sql("""\ update `tabCustom Field` set options=replace(options, %s, %s) where - dt != %s and dt not like "old%%%%" and - fieldtype = 'Select' and options not like "link:%%%%" and + dt != %s and fieldtype = 'Select' and (options like "%%%%\\n%s%%%%" or options like "%%%%%s\\n%%%%")""" % \ ('%s', '%s', '%s', old, old), (old, new, new)) @@ -260,7 +249,7 @@ def update_select_field_values(old, new): update `tabProperty Setter` set value=replace(value, %s, %s) where doc_type != %s and field_name is not null and - property='options' and value not like "link%%%%" and + property='options' and (value like "%%%%\\n%s%%%%" or value like "%%%%%s\\n%%%%")""" % \ ('%s', '%s', '%s', old, old), (old, new, new)) diff --git a/frappe/patches.txt b/frappe/patches.txt index e424ab761a..dee08bb327 100644 --- a/frappe/patches.txt +++ b/frappe/patches.txt @@ -26,3 +26,4 @@ frappe.patches.4_0.update_datetime frappe.patches.4_0.deprecate_control_panel frappe.patches.4_0.file_manager_hooks execute:frappe.get_doc("User", "Guest").save() +frappe.patches.4_0.deprecate_link_selects diff --git a/frappe/patches/4_0/deprecate_link_selects.py b/frappe/patches/4_0/deprecate_link_selects.py new file mode 100644 index 0000000000..317333b019 --- /dev/null +++ b/frappe/patches/4_0/deprecate_link_selects.py @@ -0,0 +1,13 @@ +# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +# MIT License. See license.txt + +from __future__ import unicode_literals +import frappe + +def execute(): + for name in frappe.db.sql_list("""select name from `tabCustom Field` + where fieldtype="Select" and options like "link:%" """): + custom_field = frappe.get_doc("Custom Field", name) + custom_field.fieldtype = "Link" + custom_field.options = custom_field.options[5:] + custom_field.save() diff --git a/frappe/public/js/frappe/model/create_new.js b/frappe/public/js/frappe/model/create_new.js index b2f0afc2c0..2b56ffe896 100644 --- a/frappe/public/js/frappe/model/create_new.js +++ b/frappe/public/js/frappe/model/create_new.js @@ -66,7 +66,7 @@ $.extend(frappe.model, { doc[f.fieldname] = v; updated.push(f.fieldname); } else if(f.fieldtype == "Select" && f.options - && f.options.substr(0, 5)!="link:" && f.options!="[Select]") { + && f.options!="[Select]") { doc[f.fieldname] = f.options.split("\n")[0]; } } diff --git a/frappe/test_runner.py b/frappe/test_runner.py index 128961600a..1e66d851ec 100644 --- a/frappe/test_runner.py +++ b/frappe/test_runner.py @@ -114,8 +114,6 @@ def make_test_records(doctype, verbose=0): frappe.connect() for options in get_dependencies(doctype): - if options.startswith("link:"): - options = options[5:] if options == "[Select]": continue diff --git a/frappe/translate.py b/frappe/translate.py index 309f144a46..f4a84f091c 100644 --- a/frappe/translate.py +++ b/frappe/translate.py @@ -196,7 +196,6 @@ def get_messages_from_doctype(name): messages.extend([d.label, d.description]) if d.fieldtype=='Select' and d.options \ - and not d.options.startswith("link:") \ and not d.options.startswith("attach_files:"): options = d.options.split('\n') if not "icon" in options[0]: diff --git a/frappe/utils/datautils.py b/frappe/utils/datautils.py index 0604f021d0..dfc515dfd0 100644 --- a/frappe/utils/datautils.py +++ b/frappe/utils/datautils.py @@ -105,11 +105,7 @@ def check_record(d): frappe.msgprint(_("{0} is required").format(docfield.label), raise_exception=1) if docfield.fieldtype=='Select' and val and docfield.options: - if docfield.options.startswith('link:'): - link_doctype = docfield.options.split(':')[1] - if not frappe.db.exists(link_doctype, val): - frappe.throw(_("{0} {1} must be a valid {2}").format(_(docfield.lable), val, _(link_doctype))) - elif docfield.options == "attach_files:": + if docfield.options == "attach_files:": pass elif val not in docfield.options.split('\n'): diff --git a/frappe/widgets/form/meta.py b/frappe/widgets/form/meta.py index b231fa568f..7209738e0a 100644 --- a/frappe/widgets/form/meta.py +++ b/frappe/widgets/form/meta.py @@ -29,7 +29,6 @@ class FormMeta(Meta): self.load_assets() def load_assets(self): - self.expand_selects() self.add_search_fields() if not self.istable: @@ -88,13 +87,6 @@ class FormMeta(Meta): content = frappe.get_jenv().from_string(content).render() return content - def expand_selects(self): - for df in self.get("fields", {"fieldtype": "Select"}): - if df.options and df.options.startswith("link:"): - df.link_doctype = df.options.split("\n")[0][5:] - df.options = '\n'.join([''] + [o.name for o in frappe.db.sql("""select - name from `tab%s` where docstatus<2 order by name asc""" % df.link_doctype, as_dict=1)]) - def add_search_fields(self): """add search fields found in the doctypes indicated by link fields' options""" for df in self.get("fields", {"fieldtype": "Link", "options":["!=", "[Select]"]}):