From 08566970fe34c0eaf401fa945ae167cf4e2d349f Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 29 May 2014 18:10:46 +0530 Subject: [PATCH] added awesome bar version 0.1 fixes frappe/erpnext#1049 and ablity to create new from link option, fixes frappe/erpnext#1375 --- frappe/public/js/frappe/form/control.js | 18 +- frappe/public/js/frappe/router.js | 31 ++-- frappe/public/js/frappe/ui/filters.js | 3 +- frappe/public/js/frappe/ui/toolbar/search.js | 154 +++++++++++++++++- frappe/public/js/frappe/ui/toolbar/toolbar.js | 18 +- frappe/public/js/frappe/views/doclistview.js | 6 +- 6 files changed, 208 insertions(+), 22 deletions(-) diff --git a/frappe/public/js/frappe/form/control.js b/frappe/public/js/frappe/form/control.js index 3c8a0e580a..b21b729088 100644 --- a/frappe/public/js/frappe/form/control.js +++ b/frappe/public/js/frappe/form/control.js @@ -868,6 +868,12 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({ no_spinner: true, args: args, callback: function(r) { + if(frappe.model.can_read(me.df.options)) { + r.results.push({ + value: " " + __("Create a new {0}", [me.df.options]) + "", + make_new: true + }); + }; cache[request.term] = r.results; response(r.results); }, @@ -879,8 +885,18 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({ close: function(event, ui) { me.autocomplete_open = false; }, + focus: function( event, ui ) { + if(ui.item.make_new) { + return false; + } + }, select: function(event, ui) { me.autocomplete_open = false; + if(ui.item.make_new) { + me.frm.new_doc(me.df.options, me); + return false; + } + if(me.frm && me.frm.doc) { me.selected = true; me.parse_validate_and_set_in_model(ui.item.value); @@ -891,7 +907,7 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({ } }).data('ui-autocomplete')._renderItem = function(ul, d) { var html = "" + d.value + ""; - if(d.value!==d.description) { + if(d.description && d.value!==d.description) { html += '
' + d.description + ''; } return $('
  • ') diff --git a/frappe/public/js/frappe/router.js b/frappe/public/js/frappe/router.js index f857856f9a..544542e046 100644 --- a/frappe/public/js/frappe/router.js +++ b/frappe/public/js/frappe/router.js @@ -16,7 +16,7 @@ frappe.route = function() { // "New DocType 1" and the renamed "TestDocType", both exist in history // now if we try to go back, // it doesn't allow us to go back to the one prior to "New DocType 1" - // Hence if this check is true, instead of changing location hash, + // Hence if this check is true, instead of changing location hash, // we just do a back to go to the doc previous to the "New DocType 1" var re_route_val = frappe.get_route_str(frappe.re_route[window.location.hash]); var cur_route_val = frappe.get_route_str(frappe._cur_route); @@ -32,12 +32,12 @@ frappe.route = function() { route = frappe.get_route(); frappe.route_history.push(route); - + if(route[0] && frappe.views[route[0] + "Factory"]) { // has a view generator, generate! if(!frappe.view_factory[route[0]]) frappe.view_factory[route[0]] = new frappe.views[route[0] + "Factory"](); - + frappe.view_factory[route[0]].show(); } else { // show page @@ -49,7 +49,7 @@ frappe.route = function() { } } -frappe.get_route = function(route) { +frappe.get_route = function(route) { // for app return frappe.get_route_str(route).split('/') } @@ -60,25 +60,28 @@ frappe.get_route_str = function(route) { if(route.substr(0,1)=='#') route = route.substr(1); if(route.substr(0,1)=='!') route = route.substr(1); - - route = $.map(route.split('/'), + + route = $.map(route.split('/'), function(r) { return decodeURIComponent(r); }).join('/'); return route; } frappe.set_route = function() { - route = $.map(arguments, function(a) { + if(arguments.length===1 && $.isArray(arguments[0])) { + arguments = arguments[0]; + } + route = $.map(arguments, function(a) { if($.isPlainObject(a)) { frappe.route_options = a; return null; } else { - return a ? encodeURIComponent(a) : null; + return a ? encodeURIComponent(a) : null; } }).join('/'); - + window.location.hash = route; - + // Set favicon (app.js) frappe.app.set_favicon(); } @@ -98,10 +101,10 @@ $(window).on('hashchange', function() { if(window.location.hash==frappe._cur_route) return; - + // hide open dialog - if(cur_dialog && cur_dialog.hide_on_page_refresh) + if(cur_dialog && cur_dialog.hide_on_page_refresh) cur_dialog.hide(); - + frappe.route(); -}); \ No newline at end of file +}); diff --git a/frappe/public/js/frappe/ui/filters.js b/frappe/public/js/frappe/ui/filters.js index 2370e02f8e..1da081c540 100644 --- a/frappe/public/js/frappe/ui/filters.js +++ b/frappe/public/js/frappe/ui/filters.js @@ -163,12 +163,11 @@ frappe.ui.Filter = Class.extend({ // set the field if(me.fieldname) { - // presents given (could be via tags!) + // pre-sets given (could be via tags!) this.set_values(me.tablename, me.fieldname, me.condition, me.value); } else { me.set_field(me.doctype, 'name'); } - }, set_values: function(tablename, fieldname, condition, value) { diff --git a/frappe/public/js/frappe/ui/toolbar/search.js b/frappe/public/js/frappe/ui/toolbar/search.js index 6b8c3379d9..9d77d3d2b1 100644 --- a/frappe/public/js/frappe/ui/toolbar/search.js +++ b/frappe/public/js/frappe/ui/toolbar/search.js @@ -10,8 +10,160 @@ frappe.ui.toolbar.Search = frappe.ui.toolbar.SelectorDialog.extend({ }, help: __("Shortcut") + ": Ctrl+G" }); - + // get new types this.set_values(frappe.boot.user.can_search.join(',').split(',')); } }); + +frappe.search = { + setup: function() { + $("#navbar-search").autocomplete({ + minLength: 0, + source: function(request, response) { + var txt = strip(request.term); + if(!txt) return; + var lower = strip(txt.toLowerCase()); + frappe.search.options = []; + $.each(frappe.search.verbs, function(i, action) { + action(lower); + }); + + // sort options + frappe.search.options.sort(function(a, b) { + return a.match.length - b.match.length; }); + + frappe.search.options.push({ + value: __("Help on Search"), + onclick: function() { + var txt = '\ + \ + \ + \ + \ +
    '+__("Make a new record")+''+ + __("new type of document")+'
    '+__("List a document type")+''+ + __("document type..., e.g. customer")+'
    '+__("Search in a document type")+''+ + __("text in document type")+'
    '+__("Open a module or tool")+''+ + __("module name...")+'
    ' + msgprint(txt, "Search Help"); + } + }); + + response(frappe.search.options); + }, + select: function(event, ui) { + if(ui.item.route_options) { + frappe.route_options = ui.item.route_options; + } + + if(ui.item.onclick) { + ui.item.onclick(ui.item.match); + } else { + frappe.set_route(ui.item.route); + } + setTimeout(function() { $("#navbar-search").val(""); }, 100); + } + }).data('ui-autocomplete')._renderItem = function(ul, d) { + var html = "" + d.value + ""; + if(d.description && d.value!==d.description) { + html += '
    ' + d.description + ''; + } + return $('
  • ') + .data('item.autocomplete', d) + .html('

    ' + html + '

    ') + .appendTo(ul); + };; + }, + find: function(list, txt, process) { + var ret = null; + $.each(list, function(i, item) { + _item = __(item).toLowerCase().replace(/-/g, " "); + if(txt===_item || _item.indexOf(txt) !== -1) { + var option = process(item); + option.match = item; + frappe.search.options.push(option); + } + }); + return ret; + } +} + +frappe.search.verbs = [ + // search in list if current + function(txt) { + var route = frappe.get_route(); + if(route[0]==="List") { + frappe.search.options.push({ + value: __('Find "{0}" in {1}', [txt, route[1]]), + route_options: {"name": ["like", "%" + txt + "%"]}, + onclick: function() { + frappe.container.page.doclistview.set_route_options(); + }, + match: txt + }); + } + }, + + // new doc + function(txt) { + var ret = false; + if(txt.split(" ")[0]==="new") { + frappe.search.find(frappe.boot.user.can_create, txt.substr(4), function(match) { + return { + value:__("New {0}", [match]), + route:["Form", match, "New " + match] + } + }); + } + }, + + // doctype list + function(txt) { + frappe.search.find(frappe.boot.user.can_read, txt, function(match) { + return { + value: __("{0} List", [match]), + route:["List", match] + } + }); + }, + + // pages + function(txt) { + frappe.search.find(keys(frappe.boot.page_info), txt, function(match) { + return { + value: __("Open {0}", [match]), + route: [match] + } + }); + }, + + // modules + function(txt) { + frappe.search.find(keys(frappe.modules), txt, function(match) { + ret = { + value: __("Open {0}", [match]), + } + if(frappe.modules[match].link) { + ret.route = [frappe.modules[match].link]; + } else { + ret.route = ["Module", match]; + } + return ret; + }); + }, + + // in + function(txt) { + if(in_list(txt.split(" "), "in")) { + parts = txt.split(" in "); + frappe.search.find(frappe.boot.user.can_read, parts[1], function(match) { + return { + value: __('Find "{0}" in {1}', [parts[0], match]), + route_options: {"name": ["like", "%" + parts[0] + "%"]}, + route: ["List", match] + } + }); + } + }, +]; diff --git a/frappe/public/js/frappe/ui/toolbar/toolbar.js b/frappe/public/js/frappe/ui/toolbar/toolbar.js index 4a2f3197a9..5a56114879 100644 --- a/frappe/public/js/frappe/ui/toolbar/toolbar.js +++ b/frappe/public/js/frappe/ui/toolbar/toolbar.js @@ -20,7 +20,9 @@ frappe.ui.toolbar.Toolbar = Class.extend({ // clear all custom menus on page change $(document).on("page-change", function() { $("header .navbar .custom-menu").remove(); - }) + }); + + frappe.search.setup(); }, make: function() { $('header').append('