I'm currently running version 1.14.x as I have made a number of changes to the core files to allow me and my teams to more easily filter the visible tickets. Before I start working on the same changes for 1.16 I wanted to ask if these sorts of changes could be achieved using a plugin so that I don't have to edit the core files every time I upgrade (minor versions)

I remove the pagination built into the ticket lists pages and replace it with a .js plugin called tablefilter that allows me to filter on each column, either based on a picklist or free text search etc. This allows me to batch process tickets much more effectively (eg where a lot of tickets need reassigning or status changing or closing).

The tablefilter js adds a filter bar with filter boxes above each column, a pagination bar that also includes help, filter removal button and page length chooser and additionally I've added script that allow me to bulk check the a tick box for each ticket, handy when 200 vulnerability tickets are created that don't apply to any systems I use that all need closing.
I've not seen a plugin that allows changing of these views so I was wondering:
1) do plugins allow alteration of the ticket list pages?
2) is there documentation on how to write a plugin?
Thanks

    cjohnsonuk

    1.) No, plugins can only connect to what we call Signals, they cannot inject HTML/content into pages.
    2.) Not at the moment. This is something we hope to create for v2.0 once we have the plugin architecture more easily extendable.

    Cheers.

    OK, thanks for the feedback. Do you think HTML/js modification/injection into pages will be possible in v2.x??

    @cjohnsonuk

    I'm not sure if injection will be a thing but it will definitely have a ton more possibilities. We haven't gotten to the Plugin stage of the v2.0 project yet so we'll see what we decide when we get there.

    Cheers.

    3 months later

    Hi guys,
    Actually this can be done with Motherload if you want.
    Check out this 1 min video to verify this is what you expected.

    You can inject JS in any page (you can restrict this to the ticket pages for example).
    You can execute code directly as a script and you can also import js files directly into the page.

    All you need is motherload and a short script I just came up with to get you started.

    Edited by admin.

    @cartmega

    Again, please stop posting on other threads with advertisement. You create one main thread and link everyone to that.

    Cheers.

    Honestly I thought that this is what I did. I wanted to let this person know that there is a solution to his problem and gave a link to the page where he can read more about it. The page does not mention anything about injecting JS, so I thought it prudent to let the guy know this. I am aware of what you are saying and it is not my intention.

    BTW the video I did it specifically for @cjohnsonuk just now to show that it is actually possible. I do not think anybody else would find that vid useful as it is specific to this thread only. I wouldn't call it an advertisement.

    6 months later

    I added my edits into my 1.17 install to insert tablefilter into the pages with long lists of tickets and did a few more tweaks to how it presents. All up and running as before. Now to learn all the other new options in 1.17... :-)

      5 months later

      cjohnsonuk I am planning to add a tablefilter too for our agents. Are you interested to open source your changes or give me a hint on where to start?

      I have also made some modifications to the core code and I need a mechanism of sharing and deploying them. I was thinking of making a Plugin but they are mostly javascript changes like the jstree implementation of Help Topics in the following screenshot:

      Uploading a git repo with my custom osticket code to be used for new installations or to update a running installation is not safe if not impossible.

      Having the Plugin architecture support HTML/JS injections into pages, it would make development/deployment manageable by having a separate codebase for the modifications instead of messing with the upstream code.

      4 months later

      Just updated to 1.18.0

      these are the git diffs for the files I've edited.

      diff --git a/home/cjohnson/downloads/osTicket/osTicket_orig/upload/assets/default/css/theme.css b/home/cjohnson/downloads/osTicket/osTicket_mod/upload/assets/default/css/theme.css
      index e8435a4..2456877 100644
      --- a/home/cjohnson/downloads/osTicket/osTicket_orig/upload/assets/default/css/theme.css
      +++ b/home/cjohnson/downloads/osTicket/osTicket_mod/upload/assets/default/css/theme.css
      @@ -291,7 +291,9 @@ body {
       }
       #container {
         background: #fff;
      +/*
         width: 840px;
      +*/
         margin: 0 auto;
         box-shadow: 0 0 6px rgba(0, 0, 0, 0.5);
         -moz-box-shadow: 0 0 6px rgba(0, 0, 0, 0.5);
      @@ -417,7 +419,10 @@ body {
       .front-page-button {
       }
       .main-content {
      +/*
      +Code changed by CJ 2022-11-15 22:12:06 : removed width limit
         width: 565px;
      +*/
       }
       #landing_page #new_ticket {
         margin-top: 40px;
      @@ -630,7 +635,7 @@ label.required, span.required {
           table-layout: fixed;
       }
       #ticketForm > table td {
      -    width: 160px;
      +    width: 100%;
       }
       #ticketForm > table td + td {
           width: auto;
      diff --git a/home/cjohnson/downloads/osTicket/osTicket_orig/upload/include/client/tickets.inc.php b/home/cjohnson/downloads/osTicket/osTicket_mod/upload/include/client/tickets.inc.php
      index c320966..cd903f5 100644
      --- a/home/cjohnson/downloads/osTicket/osTicket_orig/upload/include/client/tickets.inc.php
      +++ b/home/cjohnson/downloads/osTicket/osTicket_mod/upload/include/client/tickets.inc.php
      @@ -130,10 +130,11 @@ if($search)
       $negorder=$order=='-'?'ASC':'DESC'; //Negate the sorting
       
       $tickets->order_by($order.$order_by);
      +// Code changed by CJ 2023-08-30 10:34:34 : 
       $tickets->values(
      -    'ticket_id', 'number', 'created', 'isanswered', 'source', 'status_id',
      +    'ticket_id', 'user_id', 'number', 'created', 'lastupdate', 'isanswered', 'source', 'status_id',
           'status__state', 'status__name', 'cdata__subject', 'dept_id',
      -    'dept__name', 'dept__ispublic', 'user__default_email__address', 'user_id'
      +    'dept__name', 'dept__ispublic', 'user__default_email__address', 'user__name'
       );
       
       ?>
      @@ -171,7 +172,13 @@ foreach (Topic::getHelpTopics(true) as $id=>$name) {
       
       
       <h1 style="margin:10px 0">
      -    <a href="<?php echo Http::refresh_url(); ?>"
      +
      +    <a href="<?php 
      +//echo Html::refresh_url(); 
      +// Code changed by CJ 2022-11-10 21:17:25 : line above threw an error
      +
      + Format::htmlchars($_SERVER['REQUEST_URI']);
      +?>"
               ><i class="refresh icon-refresh"></i>
           <?php echo __('Tickets'); ?>
           </a>
      @@ -200,24 +207,33 @@ if ($closedTickets) {?>
           </small>
       </div>
       </h1>
      -<table id="ticketTable" width="800" border="0" cellspacing="0" cellpadding="0">
      +<?php // Code changed by CJ 2022-11-10 19:46:36 : removed table width, added table filter 
      +?>
      +<script src="/thirdparty/tablefilter/tablefilter.js" ></script>
      +<table id="ticketTable"  border="0" cellspacing="0" cellpadding="0">
           <caption><?php echo $showing; ?></caption>
           <thead>
               <tr>
                   <th nowrap>
      -                <a href="tickets.php?sort=ID&order=<?php echo $negorder; ?><?php echo $qstr; ?>" title="<?php echo sprintf('%s %s', __('Sort By'), __('Ticket ID')); ?>"><?php echo __('Ticket #');?>&nbsp;<i class="icon-sort"></i></a>
      +                <?php echo __('Ticket #');?>
      +            </th>
      +            <th width="120">
      +                <?php echo __('Create Date');?>
      +            </th>
      +            <th width="120">
      +                <?php echo __('Last Updated');?>
                   </th>
                   <th width="120">
      -                <a href="tickets.php?sort=date&order=<?php echo $negorder; ?><?php echo $qstr; ?>" title="<?php echo sprintf('%s %s', __('Sort By'), __('Date')); ?>"><?php echo __('Create Date');?>&nbsp;<i class="icon-sort"></i></a>
      +                <?php echo __('Created By');?>
                   </th>
                   <th width="100">
      -                <a href="tickets.php?sort=status&order=<?php echo $negorder; ?><?php echo $qstr; ?>" title="<?php echo sprintf('%s %s', __('Sort By'), __('Status')); ?>"><?php echo __('Status');?>&nbsp;<i class="icon-sort"></i></a>
      +                <?php echo __('Status');?>
                   </th>
                   <th width="320">
      -                <a href="tickets.php?sort=subject&order=<?php echo $negorder; ?><?php echo $qstr; ?>" title="<?php echo sprintf('%s %s', __('Sort By'), __('Subject')); ?>"><?php echo __('Subject');?>&nbsp;<i class="icon-sort"></i></a>
      +                <?php echo __('Subject');?>
                   </th>
                   <th width="120">
      -                <a href="tickets.php?sort=dept&order=<?php echo $negorder; ?><?php echo $qstr; ?>" title="<?php echo sprintf('%s %s', __('Sort By'), __('Department')); ?>"><?php echo __('Department');?>&nbsp;<i class="icon-sort"></i></a>
      +                <?php echo __('Department');?>
                   </th>
               </tr>
           </thead>
      @@ -249,13 +265,23 @@ if ($closedTickets) {?>
                       <a class="Icon <?php echo strtolower($T['source']); ?>Ticket" title="<?php echo $T['user__default_email__address']; ?>"
                           href="tickets.php?id=<?php echo $T['ticket_id']; ?>"><?php echo $ticketNumber; ?></a>
                       </td>
      -                <td><?php echo Format::date($T['created']); ?></td>
      +                <td><?php echo Format::datetime($T['created']); ?></td>
      +                <td><?php echo Format::datetime($T['lastupdate']); ?></td>
      +
      +		<td nowrap><div><?php
      +		// Code changed by CJ 2022-11-10 19:56:36 : added username column 
      +			$un = new UsersName($T['user__name']);
      +			echo Format::htmlchars($un);
      +			?>
      +		</div></td>
                       <td><?php echo $status; ?></td>
                       <td>
      -                  <?php if ($isCollab) {?>
      -                    <div style="max-height: 1.2em; max-width: 320px;" class="link truncate" href="tickets.php?id=<?php echo $T['ticket_id']; ?>"><i class="icon-group"></i> <?php echo $subject; ?></div>
      +                  <?php if ($isCollab) {
      +// Code changed by CJ 2022-11-10 19:58:10 : removed max-width
      +?>
      +                    <div style="max-height: 1.2em;" class="link truncate" href="tickets.php?id=<?php echo $T['ticket_id']; ?>"><i class="icon-group"></i> <?php echo $subject; ?></div>
                         <?php } else {?>
      -                    <div style="max-height: 1.2em; max-width: 320px;" class="link truncate" href="tickets.php?id=<?php echo $T['ticket_id']; ?>"><?php echo $subject; ?></div>
      +                    <div style="max-height: 1.2em;" class="link truncate" href="tickets.php?id=<?php echo $T['ticket_id']; ?>"><?php echo $subject; ?></div>
                           <?php } ?>
                       </td>
                       <td><span class="truncate"><?php echo $dept; ?></span></td>
      @@ -270,7 +296,74 @@ if ($closedTickets) {?>
           </tbody>
       </table>
       <?php
      +// Code changed by CJ 2022-11-10 20:00:14 : added table filter code
      +?>
      +
      +<script type="text/javascript">
      +	var tf = new TableFilter('ticketTable',{
      +        base_path: '/thirdparty/tablefilter/', 
      +        col_widths: ['130px', '140px','140px','120px', '160px','320px', '250px'],
      +        btn_reset: 'true',
      +        enable_default_theme: 'true',
      +        loader: 'true',
      +        loader_text: 'Filtering table...',
      +        grid_layout: {width:'100%',height:'auto'},
      +        status_bar: 'true',
      +        enable_empty_option: 'true',
      +        enable_non_empty_option: 'true',
      +	rows_counter: 'true',
      +        auto_filter: 'true',
      +        alternate_rows: 'true',
      +        col_types: ['String', 'date','date','String','String','String','String'],
      +            extensions: [
      +                { name: 'colsVisibility',
      +                text: 'Columns to hide: ',
      +                enable_tick_all: true
      +                  },
      +                { name: 'sort',
      +                        sort_col_at_start:[1,true]
      +            }
      +                        ],
      +            col_3: 'multiple',
      +            col_4: 'multiple',
      +            col_6: 'multiple',
      +            paging: {
      +          results_per_page: ['Records: ', [10, 25, 50, 100, 500]]
      +        },
      +            state: {
      +                types: ['local_storage'],
      +                filters: true,
      +                page_number: true,
      +                page_length: true,
      +                sort: true,
      +                columns_visibility: true
      +                }
      + });
      +tf.init();
      +  //tf.attr('style', 'width:100% !important;');
      +  //  console.log(tf.id);
      +	var dom = tf.gridLayout ? tf.feature("gridLayout").headTbl : tf.dom();
      +                        if(tf.gridLayout){
      +                        // table header
      +                           $(dom).css("width","calc(100% - 0px)");
      +						   $("#" + tf.id).css("width", "100%");
      +                        // table body
      +			//				console.log(dom);
      +                        }
      +						else{
      +			//				console.log("false");
      +						}
      +//$.toggleOverlay(false); 
      +</script> 
      +
      +
      +
      +
      +<?php
      +
      +// Code changed by CJ 2022-11-10 20:03:29 : removed page count from bottom of screen
       if ($total) {
           echo '<div>&nbsp;'.__('Page').':'.$pageNav->getPageLinks().'&nbsp;</div>';
       }
      + Format::htmlchars($_SERVER['REQUEST_URI']);
       ?>
      diff --git a/home/cjohnson/downloads/osTicket/osTicket_orig/upload/include/staff/filters.inc.php b/home/cjohnson/downloads/osTicket/osTicket_mod/upload/include/staff/filters.inc.php
      index cc1b890..cc31006 100644
      --- a/home/cjohnson/downloads/osTicket/osTicket_orig/upload/include/staff/filters.inc.php
      +++ b/home/cjohnson/downloads/osTicket/osTicket_mod/upload/include/staff/filters.inc.php
      @@ -12,7 +12,8 @@ $sql='SELECT filter.*,count(rule.id) as rules, topic.configuration AS topic, dep
       $sortOptions=array('name'=>'filter.name','status'=>'filter.isactive','order'=>'filter.execorder','rules'=>'rules',
                          'target'=>'filter.target', 'created'=>'filter.created','updated'=>'filter.updated');
       $orderWays=array('DESC'=>'DESC','ASC'=>'ASC');
      -$sort=($_REQUEST['sort'] && $sortOptions[strtolower($_REQUEST['sort'])])?strtolower($_REQUEST['sort']):'name';
      +// Code changed by CJ 2022-11-11 10:33:47 : changed detault sort order to order from name
      +$sort=($_REQUEST['sort'] && $sortOptions[strtolower($_REQUEST['sort'])])?strtolower($_REQUEST['sort']):'order';
       //Sorting options...
       if($sort && $sortOptions[$sort]) {
           $order_column =$sortOptions[$sort];
      @@ -87,7 +88,7 @@ else
        <?php csrf_token(); ?>
        <input type="hidden" name="do" value="mass_process" >
       <input type="hidden" id="action" name="a" value="" >
      - <table class="list" border="0" cellspacing="1" cellpadding="0" width="940">
      + <table class="list" border="0" cellspacing="1" cellpadding="0" >
           <thead>
               <tr>
                   <th width="4%">&nbsp;</th>
      diff --git a/home/cjohnson/downloads/osTicket/osTicket_orig/upload/include/staff/profile.inc.php b/home/cjohnson/downloads/osTicket/osTicket_mod/upload/include/staff/profile.inc.php
      index 00cd7e0..d9fe607 100644
      --- a/home/cjohnson/downloads/osTicket/osTicket_orig/upload/include/staff/profile.inc.php
      +++ b/home/cjohnson/downloads/osTicket/osTicket_mod/upload/include/staff/profile.inc.php
      @@ -14,7 +14,7 @@ if(!defined('OSTSTAFFINC') || !$staff || !$thisstaff) die('Access Denied');
         </ul>
       
         <div class="tab_content" id="account">
      -    <table class="table two-column" width="940" border="0" cellspacing="0" cellpadding="2">
      +    <table class="table two-column"  border="0" cellspacing="0" cellpadding="2">
             <tbody>
               <tr><td colspan="2"><div>
               <div class="avatar pull-left" style="margin: 10px 15px; width: 100px; height: 100px;">
      @@ -206,8 +206,9 @@ if (($bks=Staff2FABackend::allRegistered())) {
                       <select name="max_page_size">
                           <option value="0">&mdash; <?php echo __('System Default');?> &mdash;</option>
                           <?php
      +// Code changed by CJ 2022-11-10 20:35:03 : change page size options for staff profile
                           $pagelimit = $staff->max_page_size ?: $cfg->getPageSize();
      -                    for ($i = 5; $i <= 50; $i += 5) {
      +                    for ($i = 50; $i <= 750; $i += 50) {
                               $sel=($pagelimit==$i)?'selected="selected"':'';
                                echo sprintf('<option value="%d" %s>'.__('show %s records').'</option>',$i,$sel,$i);
                           } ?>
      diff --git a/home/cjohnson/downloads/osTicket/osTicket_orig/upload/include/staff/settings-system.inc.php b/home/cjohnson/downloads/osTicket/osTicket_mod/upload/include/staff/settings-system.inc.php
      index d5de6ed..511d96f 100644
      --- a/home/cjohnson/downloads/osTicket/osTicket_orig/upload/include/staff/settings-system.inc.php
      +++ b/home/cjohnson/downloads/osTicket/osTicket_mod/upload/include/staff/settings-system.inc.php
      @@ -7,7 +7,7 @@ $gmtime = Misc::gmtime();
       <form action="settings.php?t=system" method="post" class="save">
       <?php csrf_token(); ?>
       <input type="hidden" name="t" value="system" >
      -<table class="form_table settings_table" width="940" border="0" cellspacing="0" cellpadding="2">
      +<table class="form_table settings_table"  border="0" cellspacing="0" cellpadding="2">
           <thead>
               <tr>
                   <th colspan="2">
      @@ -84,7 +84,8 @@ $gmtime = Misc::gmtime();
                       <select name="max_page_size">
                           <?php
                            $pagelimit=$config['max_page_size'];
      -                    for ($i = 5; $i <= 50; $i += 5) {
      +// Code changed by CJ 2022-11-10 20:36:18 : changed page size options
      +                    for ($i = 50; $i <= 750; $i += 50) {
                               ?>
                               <option <?php echo $config['max_page_size']==$i?'selected="selected"':''; ?> value="<?php echo $i; ?>"><?php echo $i; ?></option>
                               <?php
      diff --git a/home/cjohnson/downloads/osTicket/osTicket_orig/upload/include/staff/templates/queue-tickets.tmpl.php b/home/cjohnson/downloads/osTicket/osTicket_mod/upload/include/staff/templates/queue-tickets.tmpl.php
      index 1f88fa5..0e06c9d 100644
      --- a/home/cjohnson/downloads/osTicket/osTicket_orig/upload/include/staff/templates/queue-tickets.tmpl.php
      +++ b/home/cjohnson/downloads/osTicket/osTicket_mod/upload/include/staff/templates/queue-tickets.tmpl.php
      @@ -226,8 +226,11 @@ if ($queue->id > 0 && $queue->isOwner($thisstaff)) { ?>
       <?php csrf_token(); ?>
        <input type="hidden" name="a" value="mass_process" >
        <input type="hidden" name="do" id="action" value="" >
      -
      -<table class="list queue tickets" border="0" cellspacing="1" cellpadding="2" width="940">
      +<?php 
      +// Code changed by CJ 2022-11-10 20:12:56 : added tablefilter and table ID
      +?>
      +<script src="/thirdparty/tablefilter/tablefilter.js" ></script>
      +<table class="list queue tickets" border="0" cellspacing="1" cellpadding="2" id="tickettable" >
         <thead>
           <tr>
       <?php
      @@ -275,6 +278,9 @@ foreach ($tickets as $T) {
       }
       ?>
         </tbody>
      +<?php
      +/*
      +// Code changed by CJ 2022-11-10 20:14:59 :  removed table footer
         <tfoot>
           <tr>
             <td colspan="<?php echo count($columns)+1; ?>">
      @@ -291,7 +297,196 @@ foreach ($tickets as $T) {
             </td>
           </tr>
         </tfoot>
      +*/
      +?>
       </table>
      +<?php
      +// Code changed by CJ 2022-11-10 20:16:15 : added table filter
      +?>
      +<script type="text/javascript">
      +	$(document).ready(function(){
      +	$(document).on('click', '#selectVisible',function(e){
      +		console.log('clicked visible');
      +		let tr = $('#tickettable tr');
      +		$.each( tr, function() {
      +			let none= $(this).css("display");
      +			if(none=="none"){
      +				// Row is invisible
      +			} else{
      +				// Row is visible
      +			let checkbox = $(this).find('td:first').find('input').prop('checked',true);
      +			}
      +	});
      +	});
      +	$(document).on('click','#toggleVisible',function(e){
      +		console.log('clicked Toggle visible');
      +		let tr = $('#tickettable tr');
      +		$.each( tr, function() {
      +			let none= $(this).css("display");
      +			if(none=="none"){
      +				// Row is invisible
      +			} else{
      +				// Row is visible
      +			let checkbox  = $(this).find('td:first').find('input');
      +			if(checkbox.is(':checked')){
      +				checkbox.prop('checked',false);
      +			}else{
      +				checkbox.prop('checked',true);
      +			}
      +			}
      +		});
      +	});
      +	$(document).on('click','#mySelectNone', function(e){
      +		console.log('clicked none');
      +		let tr = $('#tickettable tr');
      +		console.log(e);
      +		$.each( tr, function() {
      +			let checkbox = $(this).find('td:first').find('input').prop('checked',false);
      +		});
      +	});
      +	});
      +
      +        var tf;
      +        function tablefilter_init() {
      +        // destroy tf if it exists
      +
      +	if(typeof tf != "undefined"){console.log("tf exists"); }
      +	// if(typeof tf != "undefined"){console.log("tf exists, destroying"); tf.destroy();}
      +        //create new Tabefilter object
      +
      +	tf = new TableFilter(
      +		"tickettable",{
      +                base_path: '/thirdparty/tablefilter/',
      +                btn_reset: 'true',
      +                themes: [{ name: 'default' }],
      +                grid_layout:{width:'100%',height:'auto'},
      +                loader: 'true',
      +                loader_text: 'Filtering table...',
      +                enable_empty_option: 'true',
      +                enable_non_empty_option: 'true',
      +                status_bar: 'true',
      +                rows_counter: 'true',
      +                auto_filter: 'true',
      +                alternate_rows: 'true',
      +		col_0: 'none',
      +		col_1: 'input',
      +		col_2: 'input',
      +		col_3: 'input',
      +		col_4: 'input',
      +		col_5: 'multiple',
      +		col_6: 'multiple',
      +		col_7: 'multiple',
      +		col_8: 'multiple',
      +		col_9: 'multiple',
      +		col_10: 'multiple',
      +		state: {
      +                    types: ['local_storage'],
      +                    filters: true,
      +                    page_number: true,
      +                    page_length: true,
      +                    sort: true,
      +                    columns_visibility: true
      +                },
      +		extensions: [
      +                    { name: 'colsVisibility',
      +                        text: 'Columns to hide: ',
      +                        enable_tick_all: true
      +                    },
      +                    {name: 'sort'} ],
      +                paging: {
      +                    results_per_page: ['Records: ', [10, 25, 50, 100,500,1000,5000]]
      +                }
      +            }
      +        );
      +
      +        // get headers from table id tickettable
      +        var myHeader= Array();
      +        $("table#tickettable thead tr th").each(function(i,v) {
      +                myHeader[i] = $(this).text();
      +            }
      +        ) ;
      +        // not used : set default column width (25 pixels for the tick box column, 30 for the margins
      +        myColWidth = Math.floor((window.innerWidth - 25 - 50 ) / (myHeader.length-1)) + "px";
      +
      +        // add tf  column types
      +        myHeader.forEach(function(i,v){
      +                if( v == 0) {
      +                    tf.colTypes.push('none');
      +                }
      +                else if (myHeader[v].search(/[dD]ate/)!== -1) {
      +                    tf.colTypes.push('date');
      +                }
      +                else {
      +                    tf.colTypes.push('string');
      +                }
      +            }
      +        );
      +        // set filter types for each column
      +        myHeader.forEach(function(i,v){
      +            switch ( myHeader[v]) {
      +                case "" :
      +                    tf[`col_${v}`]='none';
      +                    tf.colWidths.push('25px');
      +                    break;
      +                case "Ticket" :
      +                    tf[`col_${v}`]='input';
      +                    tf.colWidths.push('160px');
      +                    break;
      +                case "Date Created" :
      +                    tf[`col_${v}`]='input';
      +                    tf.colWidths.push('140px');
      +                    break;
      +                case "Last Update" :
      +                    tf[`col_${v}`]='input';
      +                    tf.colWidths.push('140px');
      +                    break;
      +                case "Last Updated" :
      +                    tf[`col_${v}`]='input';
      +                    tf.colWidths.push('140px');
      +                    break;
      +                case "Subject" :
      +                    tf[`col_${v}`]='input';
      +                    tf.colWidths.push('425px');
      +                    break;
      +                case "From" :
      +                    tf[`col_${v}`]='multiple';
      +                    tf.colWidths.push('140px');
      +                    break;
      +                case "Status" :
      +                    tf[`col_${v}`]='multiple';
      +                    tf.colWidths.push('260px');
      +                    break;
      +                case "Priority" :
      +                    tf[`col_${v}`]='multiple';
      +                    tf.colWidths.push('95px');
      +                    break;
      +                case "Assignee" :
      +                    tf[`col_${v}`]='multiple';
      +                    tf.colWidths.push('125px');
      +                    break;
      +                case "Assigned To" :
      +                    tf[`col_${v}`]='multiple';
      +                    tf.colWidths.push('125px');
      +                    break;
      +                case "Department" :
      +                    tf[`col_${v}`]='multiple';
      +                    tf.colWidths.push('210px');
      +                    break;
      +                case "Team" :
      +                    tf[`col_${v}`]='multiple';
      +                    tf.colWidths.push('175px');
      +                    break;
      +                default :
      +                    tf[`col_${v}`]='input';
      +                    tf.colWidths.push('125px');
      +            }
      +        });
      +
      +        tf.init();
      +}
      +tablefilter_init();
      +</script>
      +
       
       <?php
           if ($count > 0 || $skipCount) { //if we actually had any tickets returned.
      @@ -304,7 +499,28 @@ foreach ($tickets as $T) {
               id="queue-export" class="no-pjax export"
                   ><?php echo __('Export'); ?></a>
               <i class="help-tip icon-question-sign" href="#export"></i>
      +<?php // Code changed by CJ 2022-11-02 16:44:46 Added toggles for selecting tickets ?>
      +        <span>Select:&nbsp;[
      +        <a id="selectVisible" href="#ckb">Visible</a>&nbsp;|&nbsp;
      +        <a id="mySelectNone" href="#ckb">None</a>&nbsp;|&nbsp;
      +        <a id="toggleVisible" href="#ckb">Toggle Visible</a>&nbsp;]
      +	</span>
      +
           </div>
       <?php
           } ?>
       </form>
      +<?php // Code changed by CJ 2022-11-02 17:05:49 action for clicking the export link ?>
      +<script type="text/javascript">
      +$(function() {
      +    $(document).on('click', 'a#queue-export', function(e) {
      +        e.preventDefault();
      +        var url = 'ajax.php/'+$(this).attr('href').substr(1)
      +        $.dialog(url, 201, function (xhr) {
      +            window.location.href = '?a=export&queue=<?php echo $queue->getId(); ?>';
      +            return false;
      +         });
      +        return false;
      +    });
      +});
      +</script>
      diff --git a/home/cjohnson/downloads/osTicket/osTicket_orig/upload/include/staff/users.inc.php b/home/cjohnson/downloads/osTicket/osTicket_mod/upload/include/staff/users.inc.php
      index 5480706..fb6337d 100644
      --- a/home/cjohnson/downloads/osTicket/osTicket_orig/upload/include/staff/users.inc.php
      +++ b/home/cjohnson/downloads/osTicket/osTicket_mod/upload/include/staff/users.inc.php
      @@ -151,18 +151,16 @@ else
        <input type="hidden" id="action" name="a" value="" >
        <input type="hidden" id="selected-count" name="count" value="" >
        <input type="hidden" id="org_id" name="org_id" value="" >
      - <table class="list" border="0" cellspacing="1" cellpadding="0" width="940">
      +<?php // Code changed by CJ 2022-11-10 23:36:10 :added table filter ?>
      +<script src="/thirdparty/tablefilter/tablefilter.js" ></script>
      + <table id="ticketTable" class="list" border="0" cellspacing="1" cellpadding="0" >
           <thead>
               <tr>
                   <th nowrap width="4%">&nbsp;</th>
      -            <th><a <?php echo $name_sort; ?> href="users.php?<?php
      -                echo $qstr; ?>&sort=name"><?php echo __('Name'); ?></a></th>
      -            <th width="22%"><a  <?php echo $status_sort; ?> href="users.php?<?php
      -                echo $qstr; ?>&sort=status"><?php echo __('Status'); ?></a></th>
      -            <th width="20%"><a <?php echo $create_sort; ?> href="users.php?<?php
      -                echo $qstr; ?>&sort=create"><?php echo __('Created'); ?></a></th>
      -            <th width="20%"><a <?php echo $update_sort; ?> href="users.php?<?php
      -                echo $qstr; ?>&sort=update"><?php echo __('Updated'); ?></a></th>
      +            <th> <?php echo __('Name'); ?></th>
      +            <th width="22%"><?php echo __('Status'); ?></th>
      +            <th width="20%"><?php echo __('Created'); ?></th>
      +            <th width="20%"><?php echo __('Updated'); ?></th>
               </tr>
           </thead>
           <tbody>
      @@ -224,6 +222,49 @@ else
            </tr>
           </tfoot>
       </table>
      +<script type="text/javascript">
      +	var tf = new TableFilter('ticketTable',{
      +        base_path: '/thirdparty/tablefilter/', 
      +//        col_widths: ['50px','350px', '200px','150px', '150px'],
      +        col_0: 'none',
      +//	col_1: 'String',
      +        col_2: 'multiple',
      +//	col_3: 'date',
      +//	col_4: 'date',
      +	btn_reset: 'true',
      +        enable_default_theme: 'true',
      +        loader: 'true',
      +        loader_text: 'Filtering table...',
      +        status_bar: 'true',
      +	rows_counter: 'true',
      +        auto_filter: 'true',
      +        alternate_rows: 'true',
      +        col_types: ['none', 'string','string','date','date'],
      +        extensions: [
      +            { name: 'sort',
      +//              sort_col_at_start: [1, true]
      +              }
      +            ],
      +        paging: {
      +            length: '50', 
      +            results_per_page: ['Results per page', [25, 50, 75, 100,200,400,800]]
      +        },
      +	state: {
      +                types: ['local_storage'],
      +                filters: true,
      +                page_number: true,
      +                page_length: true,
      +                sort: true,
      +                columns_visibility: true
      +                }
      +
      + });
      +tf.init();
      +
      +</script> 
      +
      +
      +
       <?php
       if ($total) {
           echo '<div>';
      diff --git a/home/cjohnson/downloads/osTicket/osTicket_orig/upload/scp/css/scp.css b/home/cjohnson/downloads/osTicket/osTicket_mod/upload/scp/css/scp.css
      index b99e0c9..6ace5ee 100644
      --- a/home/cjohnson/downloads/osTicket/osTicket_orig/upload/scp/css/scp.css
      +++ b/home/cjohnson/downloads/osTicket/osTicket_mod/upload/scp/css/scp.css
      @@ -126,7 +126,10 @@ a time {
       
       
       #container {
      +/* 
      +Code changed by CJ 2022-11-15 20:52:43 : removed width
           width:960px;
      +*/
           margin:0 auto 20px auto;
       }
       
      @@ -725,7 +728,10 @@ a time {
       .jb-overflowmenu {
           position: relative;
           height:35px;
      +/*
      +Code changed by CJ 2022-11-15 20:53:19 : removed width
           width: 960px;
      +*/
       }
       
       
      @@ -1119,7 +1125,10 @@ table.dashboard-stats tbody:nth-child(2) tr:hover th {
           color:#000;
       }
       
      -table { vertical-align:top; }
      +table { 
      +    vertical-align:top;
      +    width:100%;
      + }
       
       table.list {
           clear:both;
      Write a Reply...