diff --git a/include/ajax.tickets.php b/include/ajax.tickets.php index a0017b5cf6f32bf44e9ffce29546789dcc8a436f..38c1490967ccb8ae1b2ef31be678981bab239a2f 100644 --- a/include/ajax.tickets.php +++ b/include/ajax.tickets.php @@ -24,30 +24,35 @@ class TicketsAjaxAPI extends AjaxController { $limit = isset($_REQUEST['limit']) ? (int) $_REQUEST['limit']:25; $items=array(); - $ticketid=false; - if(is_numeric($_REQUEST['q'])) { - $WHERE=' WHERE ticketID LIKE \''.db_input($_REQUEST['q'], false).'%\''; - $ticketid=true; - } elseif(isset($_REQUEST['q'])) { - $WHERE=' WHERE email LIKE \'%'.db_input(strtolower($_REQUEST['q']), false).'%\''; - } else { - Http::response(400, 'Query argument is required'); + + $sql='SELECT DISTINCT ticketID, email' + .' FROM '.TICKET_TABLE; + + $emailSearch=false; + if(is_numeric($_REQUEST['q'])) + $sql.=' WHERE ticketID LIKE \''.db_input($_REQUEST['q'], false).'%\''; + else { + $emailSearch=true; + $sql.=' WHERE email LIKE \'%'.db_input(strtolower($_REQUEST['q']), false).'%\' '; } - $sql='SELECT DISTINCT ticketID, email, name ' - .' FROM '.TICKET_TABLE.' '.$WHERE - .' ORDER BY created ' - .' LIMIT '.$limit; - if(($res=db_query($sql)) && db_num_rows($res)){ + $sql.=' ORDER BY created LIMIT '.$limit; + + if(($res=db_query($sql)) && db_num_rows($res)) { while(list($id,$email,$name)=db_fetch_row($res)) { - $info=($ticketid)?$email:$id; - $id=($ticketid)?$id:$email; - $items[] = array('id'=>$id, 'value'=>$id, 'info'=>$info, - 'name'=>$name); + if($emailSearch) { + $info = "$email - $id"; + $value = $email; + } else { + $info = "$id -$email"; + $value = $id; + } + + $items[] = array('id'=>$id, 'email'=>$email, 'value'=>$value, 'info'=>$info); } } - return $this->encode($items); + return $this->json_encode($items); } function acquireLock($tid) { diff --git a/include/ajax.users.php b/include/ajax.users.php new file mode 100644 index 0000000000000000000000000000000000000000..01a0cdbf4ba9807f44368e8c834bd17656cd24f1 --- /dev/null +++ b/include/ajax.users.php @@ -0,0 +1,50 @@ +<?php +/********************************************************************* + ajax.users.php + + AJAX interface for users (based on submitted tickets) + XXX: osTicket doesn't support user accounts at the moment. + + Peter Rotich <peter@osticket.com> + Copyright (c) 2006-2012 osTicket + http://www.osticket.com + + Released under the GNU General Public License WITHOUT ANY WARRANTY. + See LICENSE.TXT for details. + + vim: expandtab sw=4 ts=4 sts=4: +**********************************************************************/ + +if(!defined('INCLUDE_DIR')) die('403'); + +include_once(INCLUDE_DIR.'class.ticket.php'); + +class UsersAjaxAPI extends AjaxController { + + /* Assumes search by emal for now */ + function search() { + + if(!isset($_REQUEST['q'])) { + Http::response(400, 'Query argument is required'); + } + + $limit = isset($_REQUEST['limit']) ? (int) $_REQUEST['limit']:25; + $users=array(); + + $sql='SELECT DISTINCT email, name ' + .' FROM '.TICKET_TABLE + .' WHERE email LIKE \'%'.db_input(strtolower($_REQUEST['q']), false).'%\' ' + .' ORDER BY created ' + .' LIMIT '.$limit; + + if(($res=db_query($sql)) && db_num_rows($res)){ + while(list($email,$name)=db_fetch_row($res)) { + $users[] = array('email'=>$email, 'name'=>$name, 'info'=>"$email - $name"); + } + } + + return $this->json_encode($users); + + } +} +?> diff --git a/include/staff/ticket-open.inc.php b/include/staff/ticket-open.inc.php index a858c5708089f877bdb11d1ce9d58b49375e0046..d15eb6170a9a6b02cabcdf9e4cdba0093639b534 100644 --- a/include/staff/ticket-open.inc.php +++ b/include/staff/ticket-open.inc.php @@ -22,7 +22,8 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); Email Address: </td> <td> - <input type="text" size="30" name="email" value="<?php echo $info['email']; ?>"> + <input type="text" size="30" name="email" id="email" class="typeahead" value="<?php echo $info['email']; ?>" + autocomplete="off" autocorrect="off" autocapitalize="off"> <span class="error">* <?php echo $errors['email']; ?></span> <?php if($cfg->notifyONNewStaffTicket()) { ?> @@ -37,7 +38,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); Full Name: </td> <td> - <input type="text" size="30" name="name" value="<?php echo $info['name']; ?>"> + <input type="text" size="30" name="name" id="name" value="<?php echo $info['name']; ?>"> <span class="error">* <?php echo $errors['name']; ?></span> </td> </tr> @@ -46,9 +47,9 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); Phone Number: </td> <td> - <input type="text" size="18" name="phone" value="<?php echo $info['phone']; ?>"> + <input type="text" size="18" name="phone" id="phone" value="<?php echo $info['phone']; ?>"> <span class="error"> <?php echo $errors['phone']; ?></span> - Ext <input type="text" size="5" name="phone_ext" value="<?php echo $info['phone_ext']; ?>"> + Ext <input type="text" size="5" name="phone_ext" id="phone_ext" value="<?php echo $info['phone_ext']; ?>"> <span class="error"> <?php echo $errors['phone_ext']; ?></span> </td> </tr> diff --git a/include/staff/tickets.inc.php b/include/staff/tickets.inc.php index 14d0514ecb43f7b42eed6b5740c2ce51d423b2fa..ef3d3a312c350e552ec02f4f6c79476570705703 100644 --- a/include/staff/tickets.inc.php +++ b/include/staff/tickets.inc.php @@ -256,99 +256,13 @@ $basic_display=!isset($_REQUEST['advance_search'])?true:false; <input type="hidden" name="a" value="search"> <table> <tr> - <td><input type="text" id="ticket-search" name="query" size=30 value="<?php echo Format::htmlchars($_REQUEST['query']); ?>"></td> + <td><input type="text" id="basic-ticket-search" name="query" size=30 value="<?php echo Format::htmlchars($_REQUEST['query']); ?>" + autocomplete="off" autocorrect="off" autocapitalize="off"></td> <td><input type="submit" name="basic_search" class="button" value="Search"></td> </tr> </table> </form> </div> -<div id='advance' style="display:<?php echo $basic_display?'none':'block'; ?>"> - <form action="tickets.php" method="get"> - <input type="hidden" name="a" value="search"> - <table> - <tr> - <td>Query: </td><td><input type="text" id="query" name="query" value="<?php echo Format::htmlchars($_REQUEST['query']); ?>"></td> - <td>Dept:</td> - <td><select name="dept"><option value=0>All Departments</option> - <?php - //Showing only departments the user has access to... - $sql='SELECT dept_id,dept_name FROM '.DEPT_TABLE; - if(!$thisstaff->isadmin()) - $sql.=' WHERE dept_id IN ('.implode(',',$thisstaff->getDepts()).')'; - - $depts= db_query($sql); - while (list($deptId,$deptName) = db_fetch_row($depts)){ - $selected = ($_GET['dept']==$deptId)?'selected':''; ?> - <option value="<?php echo $deptId; ?>"<?php echo $selected; ?>><?php echo $deptName; ?></option> - <?php - } ?> - </select> - </td> - <td>Status is:</td><td> - - <select name="status"> - <option value='any' selected >Any status</option> - <option value="open" <?php echo !strcasecmp($_REQUEST['status'],'Open')?'selected':''; ?>>Open</option> - <option value="overdue" <?php echo !strcasecmp($_REQUEST['status'],'overdue')?'selected':''; ?>>Overdue</option> - <option value="closed" <?php echo !strcasecmp($_REQUEST['status'],'Closed')?'selected':''; ?>>Closed</option> - </select> - </td> - </tr> - </table> - <div> - Date Span: - From <input id="sd" name="startDate" value="<?php echo Format::htmlchars($_REQUEST['startDate']); ?>" - onclick="event.cancelBubble=true;calendar(this);" autocomplete=OFF> - <a href="#" onclick="event.cancelBubble=true;calendar(getObj('sd')); return false;"><img src='images/cal.png'border=0 alt=""></a> - to - <input id="ed" name="endDate" value="<?php echo Format::htmlchars($_REQUEST['endDate']); ?>" - onclick="event.cancelBubble=true;calendar(this);" autocomplete=OFF > - <a href="#" onclick="event.cancelBubble=true;calendar(getObj('ed')); return false;"><img src='images/cal.png'border=0 alt=""></a> - - </div> - <table> - <tr> - <td>Type:</td> - <td> - <select name="stype"> - <option value="LIKE" <?php echo (!$_REQUEST['stype'] || $_REQUEST['stype'] == 'LIKE') ?'selected':''; ?>>Scan (%)</option> - <option value="FT"<?php echo $_REQUEST['stype'] == 'FT'?'selected':''; ?>>Fulltext</option> - </select> - - - </td> - <td>Sort by:</td><td> - <?php - $sort=$_GET['sort']?$_GET['sort']:'date'; - ?> - <select name="sort"> - <option value="ID" <?php echo $sort== 'ID' ?'selected':''; ?>>Ticket #</option> - <option value="pri" <?php echo $sort == 'pri' ?'selected':''; ?>>Priority</option> - <option value="date" <?php echo $sort == 'date' ?'selected':''; ?>>Date</option> - <option value="dept" <?php echo $sort == 'dept' ?'selected':''; ?>>Dept.</option> - </select> - <select name="order"> - <option value="DESC"<?php echo $_REQUEST['order'] == 'DESC' ?'selected':''; ?>>Descending</option> - <option value="ASC"<?php echo $_REQUEST['order'] == 'ASC'?'selected':''; ?>>Ascending</option> - </select> - </td> - <td>Results Per Page:</td><td> - <select name="limit"> - <?php - $sel=$_REQUEST['limit']?$_REQUEST['limit']:15; - for ($x = 5; $x <= 25; $x += 5) { ?> - <option value="<?php echo $x; ?>" <?php echo ($sel==$x )?'selected':''; ?>><?php echo $x; ?></option> - <?php } ?> - </select> - </td> - <td> - <input type="submit" name="advance_search" class="button" value="Search"> - [ <a href="#" onClick="showHide('advance','basic'); return false;" >Basic</a> ] - </td> - </tr> - </table> - </form> -</div> <!-- SEARCH FORM END --> <div class="clear"></div> <div style="margin-bottom:20px"> diff --git a/scp/ajax.php b/scp/ajax.php index 7c66da27ca0b1853953bdec0c624560db3176215..471e9c710d577d662abae098ef2053dbfd702694 100644 --- a/scp/ajax.php +++ b/scp/ajax.php @@ -30,27 +30,28 @@ ini_set('display_startup_errors','0'); //TODO: disable direct access via the browser? i,e All request must have REFER? if(!defined('INCLUDE_DIR')) Http::response(500,'config error'); -require_once INCLUDE_DIR."/class.dispatcher.php"; -require_once INCLUDE_DIR."/class.ajax.php"; -$dispatcher = patterns("", - url("^/kb/", patterns("ajax.kbase.php:KbaseAjaxAPI", +require_once INCLUDE_DIR.'/class.dispatcher.php'; +require_once INCLUDE_DIR.'/class.ajax.php'; +$dispatcher = patterns('', + url('^/kb/', patterns('ajax.kbase.php:KbaseAjaxAPI', # Send ticket-id as a query arg => canned-response/33?ticket=83 - url_get("^canned-response/(?P<id>\d+).(?P<format>json|txt)", "cannedResp"), - url_get("^faq/(?P<id>\d+)","faq") + url_get('^canned-response/(?P<id>\d+).(?P<format>json|txt)', 'cannedResp'), + url_get('^faq/(?P<id>\d+)', 'faq') )), - url("^/content/", patterns("ajax.content.php:ContentAjaxAPI", - url_get("^log/(?P<id>\d+)", 'log'), - url_get("^ticket_variables",'ticket_variables') + url('^/content/', patterns('ajax.content.php:ContentAjaxAPI', + url_get('^log/(?P<id>\d+)', 'log'), + url_get('^ticket_variables', 'ticket_variables') )), - url("^/config/", patterns("ajax.config.php:ConfigAjaxAPI", - url_get("^ui",'ui') + url('^/config/', patterns('ajax.config.php:ConfigAjaxAPI', + url_get('^ui', 'ui') )), - url_get("^/tickets$", array("ajax.tickets.php:TicketsAjaxAPI", "search")), - url("^/ticket/", patterns("ajax.tickets.php:TicketsAjaxAPI", - url_get("^(?P<tid>\d+)/preview", "previewTicket"), - url_get("^(?P<tid>\d+)/lock", "acquireLock"), - url_post("^(?P<tid>\d+)/lock/(?P<id>\d+)/renew", "renewLock"), - url_post("^(?P<tid>\d+)/lock/(?P<id>\d+)/release", "releaseLock") + url_get('^/users$', array('ajax.users.php:UsersAjaxAPI', 'search')), + url_get('^/tickets$', array('ajax.tickets.php:TicketsAjaxAPI', 'search')), + url('^/ticket/', patterns('ajax.tickets.php:TicketsAjaxAPI', + url_get('^(?P<tid>\d+)/preview', 'previewTicket'), + url_get('^(?P<tid>\d+)/lock', 'acquireLock'), + url_post('^(?P<tid>\d+)/lock/(?P<id>\d+)/renew', 'renewLock'), + url_post('^(?P<tid>\d+)/lock/(?P<id>\d+)/release', 'releaseLock') )) ); diff --git a/scp/js/bootstrap-typeahead.js b/scp/js/bootstrap-typeahead.js index dd3ca6dd8c8f26c29c0758202e6fdefb8f66ebb3..1e039f02ade3395bac99ae5ef35ae113ce837879 100644 --- a/scp/js/bootstrap-typeahead.js +++ b/scp/js/bootstrap-typeahead.js @@ -82,7 +82,6 @@ , value this.query = this.$element.val(); - /*Check if we have a match on the current source?? */ if (typeof this.source == "function") { value = this.source(this, this.query) @@ -157,8 +156,12 @@ items = $(items).map(function (i, item) { i = $(that.options.item).attr('data-value', JSON.stringify(item)) - if (!that.strings) - item = item[that.options.property] + if (!that.strings) { + if(item[that.options.render]) + item = item[that.options.render]; + else + item = item[that.options.property]; + } i.find('a').html(that.highlighter(item)) return i[0] }) @@ -294,6 +297,7 @@ , item: '<li><a href="#"></a></li>' , onselect: null , property: 'value' + , render: 'info' } $.fn.typeahead.Constructor = Typeahead diff --git a/scp/js/scp.js b/scp/js/scp.js index f993a5a468ea7e6d96eb3ec903b89dc4d99f2ade..08da6525eef13c66bfbfd9136a9961fdfebadcda 100644 --- a/scp/js/scp.js +++ b/scp/js/scp.js @@ -199,7 +199,7 @@ $(document).ready(function(){ } /* Typeahead init */ - $('#ticket-search').typeahead({ + $('#basic-ticket-search').typeahead({ source: function (typeahead, query) { $.ajax({ url: "ajax.php/tickets?q="+query, @@ -210,9 +210,31 @@ $(document).ready(function(){ }); }, onselect: function (obj) { - $('#ticket-search').closest('form').submit(); + $('#basic-ticket-search').val(obj.id); /*overwriting email*/ + $('#basic-ticket-search').closest('form').submit(); }, property: "value" }); + $('#email.typeahead').typeahead({ + source: function (typeahead, query) { + if(query.length > 2) { + $.ajax({ + url: "ajax.php/users?q="+query, + dataType: 'json', + success: function (data) { + typeahead.process(data); + } + }); + } + }, + onselect: function (obj) { + var fObj=$('#email.typeahead').closest('form'); + if(obj.name) + $('#name', fObj).val(obj.name); + }, + property: "email" + }); + + });