@@ -12,10 +12,10 @@ cur_frm.cscript.onload = function(doc) { | |||||
}; | }; | ||||
cur_frm.fields_dict.customer.get_query = function(doc,cdt,cdn) { | cur_frm.fields_dict.customer.get_query = function(doc,cdt,cdn) { | ||||
return{ query:"controllers.queries.customer_query" } } | |||||
return { query:"controllers.queries.customer_query" } } | |||||
cur_frm.fields_dict.supplier.get_query = function(doc,cdt,cdn) { | cur_frm.fields_dict.supplier.get_query = function(doc,cdt,cdn) { | ||||
return{ query:"controllers.queries.supplier_query" } } | |||||
return { query:"controllers.queries.supplier_query" } } | |||||
if(doc.content) | if(doc.content) | ||||
doc.content = wn.utils.remove_script_and_style(doc.content); | doc.content = wn.utils.remove_script_and_style(doc.content); | ||||
@@ -31,6 +31,7 @@ | |||||
"lib/public/css/common.css", | "lib/public/css/common.css", | ||||
"lib/public/css/tree_grid.css", | "lib/public/css/tree_grid.css", | ||||
"lib/public/css/nprogress.css", | "lib/public/css/nprogress.css", | ||||
"lib/public/css/typeahead.css", | |||||
] | ] | ||||
}, | }, | ||||
@@ -41,6 +42,7 @@ | |||||
"lib/public/js/lib/jquery/jquery.hotkeys.js", | "lib/public/js/lib/jquery/jquery.hotkeys.js", | ||||
"lib/public/js/lib/center_image.js", | "lib/public/js/lib/center_image.js", | ||||
"lib/public/js/lib/bootstrap.min.js", | "lib/public/js/lib/bootstrap.min.js", | ||||
"lib/public/js/lib/typeahead.js", | |||||
"lib/public/js/lib/nprogress.js", | "lib/public/js/lib/nprogress.js", | ||||
"lib/public/js/wn/provide.js", | "lib/public/js/wn/provide.js", | ||||
@@ -1,40 +1,16 @@ | |||||
.typeahead, | .typeahead, | ||||
.tt-query, | .tt-query, | ||||
.tt-hint { | .tt-hint { | ||||
width: 100%; | |||||
height: 46px; | |||||
padding: 8px 12px; | |||||
font-size: 24px; | |||||
line-height: 30px; | |||||
border: 2px solid #ccc; | |||||
-webkit-border-radius: 8px; | |||||
-moz-border-radius: 8px; | |||||
border-radius: 8px; | |||||
outline: none; | |||||
} | |||||
.typeahead { | |||||
background-color: #fff; | |||||
} | |||||
.typeahead:focus { | |||||
border: 2px solid #0097cf; | |||||
} | |||||
.tt-query { | |||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); | |||||
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); | |||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); | |||||
} | } | ||||
.tt-hint { | .tt-hint { | ||||
color: #999 | |||||
color: #999; | |||||
} | } | ||||
.tt-dropdown-menu { | .tt-dropdown-menu { | ||||
width: 422px; | |||||
margin-top: 12px; | |||||
padding: 8px 0; | |||||
width: 100%; | |||||
margin-top: 3px; | |||||
padding: 3px 0; | |||||
background-color: #fff; | background-color: #fff; | ||||
border: 1px solid #ccc; | border: 1px solid #ccc; | ||||
border: 1px solid rgba(0, 0, 0, 0.2); | border: 1px solid rgba(0, 0, 0, 0.2); | ||||
@@ -48,14 +24,20 @@ | |||||
.tt-suggestion { | .tt-suggestion { | ||||
padding: 3px 20px; | padding: 3px 20px; | ||||
font-size: 18px; | |||||
line-height: 24px; | |||||
} | } | ||||
.tt-suggestion.tt-is-under-cursor { | .tt-suggestion.tt-is-under-cursor { | ||||
color: #fff; | color: #fff; | ||||
background-color: #0097cf; | background-color: #0097cf; | ||||
} | |||||
.tt-suggestion.tt-is-under-cursor .text-muted { | |||||
color: #ddd; | |||||
} | |||||
.input-group input.tt-query { | |||||
border-top-left-radius: 4px !important; | |||||
border-bottom-left-radius: 4px !important; | |||||
} | } | ||||
.tt-suggestion p { | .tt-suggestion p { | ||||
@@ -19,7 +19,7 @@ wn.Application = Class.extend({ | |||||
init: function() { | init: function() { | ||||
this.load_startup(); | this.load_startup(); | ||||
}, | }, | ||||
load_startup: function() { | load_startup: function() { | ||||
var me = this; | var me = this; | ||||
if(window.app) { | if(window.app) { | ||||
@@ -28,9 +28,21 @@ wn.assets = { | |||||
// if version is different then clear localstorage | // if version is different then clear localstorage | ||||
if(window._version_number != localStorage.getItem("_version_number")) { | if(window._version_number != localStorage.getItem("_version_number")) { | ||||
localStorage.clear(); | localStorage.clear(); | ||||
localStorage.setItem("_version_number", window._version_number); | |||||
console.log("Cleared App Cache."); | console.log("Cleared App Cache."); | ||||
} | } | ||||
if(localStorage._last_load) { | |||||
var not_updated_since = new Date() - new Date(localStorage._last_load); | |||||
if(not_updated_since < 10000 || not_updated_since > 86400000) { | |||||
localStorage.clear(); | |||||
console.log("Cleared localstorage"); | |||||
} | |||||
} else { | |||||
localStorage.clear(); | |||||
console.log("Cleared localstorage"); | |||||
} | |||||
localStorage._last_load = new Date(); | |||||
localStorage._version_number = window._version_number; | |||||
}, | }, | ||||
// check if the asset exists in | // check if the asset exists in | ||||
@@ -608,19 +608,9 @@ wn.ui.form.ControlLink = wn.ui.form.ControlData.extend({ | |||||
this.has_input = true; | this.has_input = true; | ||||
//this.bind_change_event(); | //this.bind_change_event(); | ||||
var me = this; | var me = this; | ||||
this.$input.on("blur", function() { | |||||
if(me.selected) { | |||||
me.selected = false; | |||||
return; | |||||
} | |||||
if(me.doctype && me.docname) { | |||||
var value = me.get_value(); | |||||
if(value!==me.last_value) { | |||||
me.parse_validate_and_set_in_model(value); | |||||
} | |||||
}}); | |||||
this.setup_buttons(); | this.setup_buttons(); | ||||
this.setup_autocomplete(); | |||||
this.setup_typeahead(); | |||||
//this.setup_autocomplete(); | |||||
}, | }, | ||||
setup_buttons: function() { | setup_buttons: function() { | ||||
var me = this; | var me = this; | ||||
@@ -630,7 +620,7 @@ wn.ui.form.ControlLink = wn.ui.form.ControlData.extend({ | |||||
new wn.ui.form.LinkSelector({ | new wn.ui.form.LinkSelector({ | ||||
doctype: me.df.options, | doctype: me.df.options, | ||||
target: me, | target: me, | ||||
txt: me.$input.val() | |||||
txt: me.get_value() | |||||
}); | }); | ||||
}); | }); | ||||
@@ -653,17 +643,102 @@ wn.ui.form.ControlLink = wn.ui.form.ControlData.extend({ | |||||
this.$input_area.find(".btn-new").remove(); | this.$input_area.find(".btn-new").remove(); | ||||
} | } | ||||
}, | }, | ||||
setup_autocomplete: function() { | |||||
setup_typeahead: function() { | |||||
var me = this; | var me = this; | ||||
var method = "webnotes.widgets.search.search_link"; | |||||
var args = {}; | |||||
this.set_custom_query(args); | |||||
// custom query | |||||
if(args.query) { | |||||
method = args.query | |||||
} | |||||
var _change = function() { | |||||
var val = me.get_value(); | |||||
if(me.frm && me.frm.doc) { | |||||
me.selected = true; | |||||
me.parse_validate_and_set_in_model(val); | |||||
} else { | |||||
me.$input.trigger("change"); | |||||
} | |||||
} | |||||
// filter based on arguments | |||||
var filter_fn = function(r) { | |||||
if(r.exc) console.log(r.exc); | |||||
var filter_args = {}; | |||||
me.set_custom_query(filter_args) | |||||
if(filter_args.filters) { | |||||
return wn.utils.filter_dict(r.results, filter_args.filters); | |||||
} else { | |||||
return r.results; | |||||
} | |||||
} | |||||
// default query args | |||||
var query_args = { | |||||
cmd: method, | |||||
txt: "%", | |||||
page_len: "9999", | |||||
doctype: me.df.options, | |||||
} | |||||
// append filter keys (needed for client-side filtering) | |||||
if(args.filters) { | |||||
query_args.search_fields = ["name"].concat(keys(args.filters)); | |||||
} | |||||
this.$input.typeahead("destroy").typeahead({ | |||||
name: me.df.parent + ":" + me.df.fieldname, | |||||
prefetch: { | |||||
url: "server.py?" + wn.utils.get_url_from_dict(query_args), | |||||
filter: filter_fn, | |||||
}, | |||||
remote: { | |||||
url: "server.py?" + wn.utils.get_url_from_dict($.extend(query_args, {"txt": null})) + "&txt=%QUERY", | |||||
filter: filter_fn, | |||||
}, | |||||
template: function(d) { | |||||
if(keys(d).length > 1) { | |||||
d.info = $.map(d, function(val, key) { return key==="name" ? null : val }).join(", "); | |||||
return repl("<p>%(value)s<br><span class='text-muted'>%(info)s</span></p>", d); | |||||
} else { | |||||
return d.value; | |||||
} | |||||
} | |||||
}).on("typeahead:selected", function(d) { | |||||
_change(); | |||||
}).on("typeahead:autocompleted", function(d) { | |||||
_change(); | |||||
}); | |||||
this.set_input = function(val) { | |||||
me.$input.typeahead("setQuery", val || ""); | |||||
} | |||||
}, | |||||
setup_autocomplete: function() { | |||||
this.$input.on("blur", function() { | |||||
if(me.selected) { | |||||
me.selected = false; | |||||
return; | |||||
} | |||||
if(me.doctype && me.docname) { | |||||
var value = me.get_value(); | |||||
if(value!==me.last_value) { | |||||
me.parse_validate_and_set_in_model(value); | |||||
} | |||||
}}); | |||||
this.$input.autocomplete({ | this.$input.autocomplete({ | ||||
source: function(request, response) { | source: function(request, response) { | ||||
var args = { | var args = { | ||||
'txt': request.term, | 'txt': request.term, | ||||
'doctype': me.df.options, | 'doctype': me.df.options, | ||||
}; | }; | ||||
me.set_custom_query(args); | me.set_custom_query(args); | ||||
return wn.call({ | return wn.call({ | ||||
type: "GET", | type: "GET", | ||||
method:'webnotes.widgets.search.search_link', | method:'webnotes.widgets.search.search_link', | ||||
@@ -690,6 +765,7 @@ wn.ui.form.ControlLink = wn.ui.form.ControlData.extend({ | |||||
} | } | ||||
} | } | ||||
}).data('uiAutocomplete')._renderItem = function(ul, item) { | }).data('uiAutocomplete')._renderItem = function(ul, item) { | ||||
if(!item.label) item.label = item.value; | |||||
return $('<li></li>') | return $('<li></li>') | ||||
.data('item.autocomplete', item) | .data('item.autocomplete', item) | ||||
.append(repl('<a><span style="font-weight: bold;">%(label)s</span><br>\ | .append(repl('<a><span style="font-weight: bold;">%(label)s</span><br>\ | ||||
@@ -22,7 +22,7 @@ wn.ui.form.LinkSelector = Class.extend({ | |||||
"fields": [ | "fields": [ | ||||
{ | { | ||||
fieldtype: "Data", fieldname: "txt", label: "Beginning with", | fieldtype: "Data", fieldname: "txt", label: "Beginning with", | ||||
description: "You can use wildcard %" | |||||
description: "You can use wildcard %", | |||||
}, | }, | ||||
{ | { | ||||
fieldtype: "Select", fieldname: "search_field", label: "Search With" | fieldtype: "Select", fieldname: "search_field", label: "Search With" | ||||
@@ -55,6 +55,8 @@ wn.ui.form.LinkSelector = Class.extend({ | |||||
} else { | } else { | ||||
this.dialog.fields_dict.search_field.$wrapper.toggle(false); | this.dialog.fields_dict.search_field.$wrapper.toggle(false); | ||||
} | } | ||||
if(this.txt) | |||||
this.dialog.fields_dict.txt.set_input(this.txt); | |||||
this.dialog.fields_dict.search.$input.on("click", function() { | this.dialog.fields_dict.search.$input.on("click", function() { | ||||
me.search(this); | me.search(this); | ||||
}); | }); | ||||
@@ -63,6 +63,7 @@ wn.ui.form.ScriptManager = Class.extend({ | |||||
'options': df.options, | 'options': df.options, | ||||
'fetch': fetch | 'fetch': fetch | ||||
}, | }, | ||||
no_spinner: true, | |||||
callback: function(r) { | callback: function(r) { | ||||
if(r.message=='Ok') { | if(r.message=='Ok') { | ||||
if(r.fetch_values) | if(r.fetch_values) | ||||
@@ -42,6 +42,14 @@ wn.utils = { | |||||
} else if(filters[key][0]=="not in") { | } else if(filters[key][0]=="not in") { | ||||
if(filters[key][1].indexOf(d[key])!=-1) | if(filters[key][1].indexOf(d[key])!=-1) | ||||
return; | return; | ||||
} else if(filters[key][0]=="<") { | |||||
if (!(d[key] < filters[key])) return; | |||||
} else if(filters[key][0]=="<=") { | |||||
if (!(d[key] <= filters[key])) return; | |||||
} else if(filters[key][0]==">") { | |||||
if (!(d[key] > filters[key])) return; | |||||
} else if(filters[key][0]==">=") { | |||||
if (!(d[key] >= filters[key])) return; | |||||
} | } | ||||
} else { | } else { | ||||
if(d[key]!=filters[key]) return; | if(d[key]!=filters[key]) return; | ||||
@@ -105,7 +113,12 @@ wn.utils = { | |||||
return args; | return args; | ||||
}, | }, | ||||
get_url_from_dict: function(args) { | get_url_from_dict: function(args) { | ||||
return encodeURIComponent($.map(args, function(val, key) { return key+"="+val; }).join("&") || ""); | |||||
return $.map(args, function(val, key) { | |||||
if(val!==null) | |||||
return encodeURIComponent(key)+"="+encodeURIComponent(val); | |||||
else | |||||
return null; | |||||
}).join("&") || ""; | |||||
}, | }, | ||||
disable_export_btn: function(btn) { | disable_export_btn: function(btn) { | ||||
if(!wn.user.is_report_manager()) { | if(!wn.user.is_report_manager()) { | ||||
@@ -18,11 +18,6 @@ import webnotes.webutils | |||||
local_manager = LocalManager([webnotes.local]) | local_manager = LocalManager([webnotes.local]) | ||||
class MyResponse(Response): | |||||
def set_cookie(self, *args, **kwargs): | |||||
print args, kwargs | |||||
super(Response, self).set_cookie(*args, **kwargs) | |||||
@Request.application | @Request.application | ||||
def application(request): | def application(request): | ||||
webnotes.local.request = request | webnotes.local.request = request | ||||
@@ -32,7 +27,7 @@ def application(request): | |||||
webnotes.local.form_dict = webnotes._dict({ k:v[0] if isinstance(v, (list, tuple)) else v \ | webnotes.local.form_dict = webnotes._dict({ k:v[0] if isinstance(v, (list, tuple)) else v \ | ||||
for k, v in (request.form or request.args).iteritems() }) | for k, v in (request.form or request.args).iteritems() }) | ||||
webnotes.local._response = MyResponse() | |||||
webnotes.local._response = Response() | |||||
try: | try: | ||||
webnotes.http_request = webnotes.auth.HTTPRequest() | webnotes.http_request = webnotes.auth.HTTPRequest() | ||||
@@ -57,7 +57,7 @@ class HTTPRequest: | |||||
import translate | import translate | ||||
lang_list = translate.get_lang_dict() | lang_list = translate.get_lang_dict() | ||||
lang_list = lang_list and lang_list.values() or [] | lang_list = lang_list and lang_list.values() or [] | ||||
if not lang: | if not lang: | ||||
return | return | ||||
if ";" in lang: # not considering weightage | if ";" in lang: # not considering weightage | ||||
@@ -16,9 +16,10 @@ except ImportError: | |||||
# this is called by the Link Field | # this is called by the Link Field | ||||
@webnotes.whitelist() | @webnotes.whitelist() | ||||
def search_link(doctype, txt, query=None, filters=None): | |||||
search_widget(doctype, txt, query, page_len=20, filters=filters) | |||||
webnotes.response['results'] = build_for_autosuggest(webnotes.response["values"]) | |||||
def search_link(doctype, txt, query=None, filters=None, page_len=20, searchfield="name"): | |||||
search_widget(doctype, txt, query, searchfield=searchfield, page_len=page_len, filters=filters) | |||||
webnotes.response['results'] = build_for_autosuggest(webnotes.response["values"], searchfield) | |||||
del webnotes.response["values"] | |||||
# this is called by the search box | # this is called by the search box | ||||
@webnotes.whitelist() | @webnotes.whitelist() | ||||
@@ -77,16 +78,15 @@ def get_std_fields_list(meta, key): | |||||
return ['`tab%s`.`%s`' % (meta[0].name, f.strip()) for f in sflist] | return ['`tab%s`.`%s`' % (meta[0].name, f.strip()) for f in sflist] | ||||
def build_for_autosuggest(res): | |||||
def build_for_autosuggest(res, searchfield): | |||||
searchfield = [s.strip() for s in searchfield.split(",")] | |||||
results = [] | results = [] | ||||
for r in res: | for r in res: | ||||
info = '' | |||||
if len(r) > 1: | |||||
info = ', '.join([cstr(t) for t in r[1:]]) | |||||
if len(info) > 50: | |||||
info = "<span title=\"%s\">%s...</span>" % (info, info[:50]) | |||||
results.append({'label':r[0], 'value':r[0], 'info':info}) | |||||
out = {} | |||||
for i, s in enumerate(searchfield): | |||||
if s=="name": s="value" | |||||
out[s] = r[i] | |||||
results.append(out) | |||||
return results | return results | ||||
def scrub_custom_query(query, key, txt): | def scrub_custom_query(query, key, txt): | ||||
@@ -123,7 +123,7 @@ login.show_forgot_password = function() { | |||||
} | } | ||||
login.set_message = function(message, color) { | login.set_message = function(message, color) { | ||||
wn.msgprint(html); | |||||
wn.msgprint(message); | |||||
return; | return; | ||||
$('#login_message').html(message).toggle(true); | $('#login_message').html(message).toggle(true); | ||||
} | } |