Inline list editing

JackGoa

Member
Hi, I saw a thread where it was said the inline editing plugin is being deprecated. So inline editing of a list is then not possible?
 
I sure hope it doesn't get deprecated. That and csv import/export, both with some minor modifications, are the most needed features of my project.

If someone can tell me how to get my tweaked inlineedit javascript working again (since they changed the way minified javascript was working), I'll be happy to share my "new and improved" inlineedit javascript code with you - and hopefully you will agree it's a big improvement and then we can both lobby for the changes in the Fabrik core. I could really use someone on my team.;)

Just curious - would you use the inlineedit plugin mostly for simple cell editing (like an Excel spreadsheet) using 'field' elements - or do you need/expect it to work with more complicated elements too?
 
We simply don't have time to work on it. It turned out to be an absolutely gigantic time sink, soaking up hundreds and hundreds of hours.

I'm more than happy if other folk want to work on it, and submit PR's on the code. But internally, we just don't have the time to devote to it.

-- hugh
 
I submitted a pull request for this 16 days ago - along with a detailed list of the new/changed functions and how it works. Github link: Update inlineedit.js

Rob responded 2 days later with some questions and concerns - to which I responded and/or fixed. But I haven't heard a peep since.

It's just one file and so easy to test.

Today I fixed a small issue I found regarding a js error that would occur if you clicked outside the list while in edit mode. But we've been using this plugin at my site with these changes for months. So it's been pretty well tested - though not thoroughly tested for every possible element, I admit. If you want something that works and navigates more 'like a spreadsheet' especially for use with simple 'field' elements, then this script, and a few lines of css to style numeric columns correctly (and/or change the color of all 'editable' columns) , is a big improvement over the way it was.

I attached the file if anyone wants to test it and provide some feedback. To use, rename your current ./plugins/fabrik_list/inlineedit/inlineedit-min.js file to another filename (e.g. inlineedit-min.SAV) - then copy this attached 'txt' file there and rename it to inlineedit-min.js.

For the new features to work, you will need to set the configuration of the plugin to allow 'save on tab'.

These are the basic directions that could be included in the list intro...
Directions: Use the Tab or Arrow keys to navigate between editable cells. Press the Spacebar or Enter key to edit a cell that currently has focus. You may also selectively edit any cell by clicking on that cell. Any values changed in this form list are automatically saved when the cell being edited loses focus - either by pressing the tab, enter, up, down keys - or clicking inside another cell.
 

Attachments

  • inlineedit-min.txt
    21.1 KB · Views: 176
I submitted a pull request for this 16 days ago - along with a detailed list of the new/changed functions and how it works. Github link: Update inlineedit.js

Rob responded 2 days later with some questions and concerns - to which I responded and/or fixed. But I haven't heard a peep since.

That would have been as he was packing and getting ready for his trip to Vietnam. He's there for month, visiting with his in-laws and their family. It's his daughter Eleanor's first birthday, which is apparently a huge deal in Vietnamese culture.

So it'll have to wait till he gets back.

-- hugh
 
This looks promising. Will test it as soon as I get a moment. My main reason for wanting something like this that I do follow ups on leads that come in through a site, and then I have added admin fields that are only visible to me which would be great if they can be edited without having to go into each record.
 
Hugh - Well that explains that.:)
Jack - Sorry I forgot about the css. I'll update both the js and css in this thread as any issues come up. (So always use the file/jsCode in the first post in this thread rather than the code I included in our conversation.)

Duhh.:oops: I'm just realizing that I never mentioned this. This will also require custom css styling (else it looks basically like it always did).

Use this css code as an example for what needs to be added to the custom_css.php file for your list template. Replace the list and group id used in this example as appropriate (You don't really need most of this - I added comments explaining what each does.)
CSS:
/* this formats what was the popup modal to fit inside the list cell */
td.fabrik_list_260_group_509 div.modal {
    position: initial;
    top: initial;
    left: initial;
    z-index: initial;
    width: auto;
    margin-left: initial;
}

td.fabrik_list_260_group_509 div.modal div.modal-body div.control-group{
    margin-bottom:0px;
}

tr[id^=list_260] td.focusClass div.modal div.modal-body {
    padding:0!important;
}

td.fabrik_list_260_group_509 div.modal div.modal-body div.control-group div.fabrikElement{
    display:flex;
}

/* gradient red border for cell with focus */
tr[id^=list_260] td.focusClass {
    box-shadow: inset 0 0 8px rgba(255, 0, 0, 0.3);
    -moz-box-shadow: inset 0 0 8px rgba(255, 0, 0, 0.3);
    -webkit-box-shadow: inset 0 0 8px rgba(255, 0, 0, 0.3);
}

/*
    This hides the labels and action buttons that are in the edit modal
    It also hides the action buttons in the list itself - but you can remove the 1st 3 lines if you want to also show the list action buttons
*/
table[id^=list_260] thead tr th.fabrik_actions,
table.temptable thead tr th.fabrik_actions,
tr[id^=list_260] td.fabrik_actions,
td.fabrik_list_260_group_509 div div.modal-header,
td.fabrik_list_260_group_509 div div.modal-footer,
td.fabrik_list_260_group_509 div div.modal-body div label {
    display:none;
}

/*
  this hides the PK id column (that I needed to include for csv export/import)
  and another textarea column that I don't want to show in the list yet include in csv/export import
*/
table[id^=list_260] thead tr th.master_report___id,
table.temptable thead tr th.master_report___id,
tr[id^=list_260] td.master_report___id,
table[id^=list_260] thead tr th.fb_jobcodes___job_description,
table.temptable thead tr th.fb_jobcodes___job_description,
tr[id^=list_260] td.fb_jobcodes___job_description {
    display:none;
}

/* sets text input fields to the full width of the cell */
input#master_report___your_job_code,
input#master_report___your_title
{
    width:100%; 
}

/* sets numeric input fields to the full width of the cell and aligns  right */
input#master_report___your_job_code,
input#master_report___ftes,
input#master_report___min_rate,
input#master_report___max_rate,
input#master_report___avg_rate,
input#master_report___min_mng,
input#master_report___max_mng,
input#master_report___avg_mng,
input#master_report___last_cash,
input#master_report___last_deferred,
input#master_report___years_in_job,
input#master_report___evening,
input#master_report___night,
input#master_report___weekend,
input#master_report___avg_base_comp,
input#master_report___add_cash_comp,
input#master_report___add_def_comp,
input#master_report___add_med_ed,
input#master_report___add_on_call,
input#master_report___physicians_in_category,
input#master_report___years_in_practice,
input#master_report___board_certified
{
    width:100%;
    text-align:right;
}

/* this is the 1st (left) non-editable text column that I want to show as bold */
tr[id^=list_260] td.master_report___job_title {
    font-weight:bold;
}

/* these are the editable columns with text data that I want to color blue to better identify as editable */
tr[id^=list_260] td.master_report___your_job_code,
tr[id^=list_260] td.master_report___your_title {
    color:blue;
}

/*   these are the headings for columns with numeric data that I want to align-right
      (This list is being used in 7 different menu options, each with different prefilters -
       so no list  ever really shows this many columns! - But this css covers all 7 possibilities
*/
th.master_report___ftes,
th.master_report___min_rate,
th.master_report___max_rate,
th.master_report___avg_rate,
th.master_report___min_mng,
th.master_report___max_mng,
th.master_report___avg_mng,
th.master_report___last_cash,
th.master_report___last_deferred,
th.master_report___years_in_job,
th.master_report___evening,
th.master_report___night,
th.master_report___weekend,
th.master_report___avg_base_comp,
th.master_report___add_cash_comp,
th.master_report___add_def_comp,
th.master_report___add_med_ed,
th.master_report___add_on_call,
th.master_report___physicians_in_category,
th.master_report___years_in_practice,
th.master_report___board_certified
{
    text-align:right!important;
}

/* these are the editable columns with numeric data that I want to color blue to better identify as editable, and to align-right */
tr[id^=list_260] td.master_report___ftes,
tr[id^=list_260] td.master_report___min_rate,
tr[id^=list_260] td.master_report___max_rate,
tr[id^=list_260] td.master_report___avg_rate,
tr[id^=list_260] td.master_report___min_mng,
tr[id^=list_260] td.master_report___max_mng,
tr[id^=list_260] td.master_report___avg_mng,
tr[id^=list_260] td.master_report___last_cash,
tr[id^=list_260] td.master_report___last_deferred,
tr[id^=list_260] td.master_report___years_in_job,
tr[id^=list_260] td.master_report___evening,
tr[id^=list_260] td.master_report___night,
tr[id^=list_260] td.master_report___weekend,
tr[id^=list_260] td.master_report___avg_base_comp,
tr[id^=list_260] td.master_report___add_cash_comp,
tr[id^=list_260] td.master_report___add_def_comp,
tr[id^=list_260] td.master_report___add_med_ed,
tr[id^=list_260] td.master_report___add_on_call,
tr[id^=list_260] td.master_report___physicians_in_category,
tr[id^=list_260] td.master_report___years_in_practice,
tr[id^=list_260] td.master_report___board_certified
{
    color:blue;
    text-align:right;
}

It's a little work - but not too complicated.:)
 
Last edited:
Hi Bauer. I'm terribly sorry for only coming back to you now. I've stretched myself thin over too many projects and this was not on the priority list.

I installed it now, and it took me all of 3 minutes! I did not install the CSS part and it actually works just fine for me. I'm basically just using it to update a list, Excel style. I've set it to 'double click' mode. And it works perfectly. Thanks a million! You've saved me so much time by not having to go into individual records to make updates. It works great for admin purposes.
 
FYI, now that I've seen how easy it was to install and how well it works, I can kick myself for not installing it earlier.

Hugh, worth a look to incorporate!!
 
One small thing I have noticed so far. If I do updates, and I click on the export button, those updates don't reflect in the CSV. Only once I refresh the page, export to CSV, then the updates reflect.
 
Good to know it works for you. But I abandoned this idea over a month ago (when I gave up on trying to get anyone to incorporated it into the Fabrik code).

What I have done instead is create a custom list template (only one file had to be edited) that basically does the same thing (shows the individual cells as inputs). In that code I added 2 checkboxes to each row (that are hidden) which 1. track whether any row has been edited 2. check that values in that row are valid. (That's all done with a focusout trigger on any cell using javascript.) Then I included a submit button in the footer that uses the user_ajax feature to run some php code that only updates rows that have been changed and have no validation errors.

That is a lot faster than having to query the server and make database replacements after any cell is changed. I have already written about this in another thread - and mentioned that I got the (edited row flag) idea from an old cumbersome 'Tablegear' script (modified forJoomla) that I was using before all of this. So don't feel bad - this is my 3rd different 'engine' for that list, but I'm finally happy with it.
 
BTW, are you going to make that new one available?
It warms my heart to no end to know someone recognizes my many hours of work, thank you. But I've been overturning enough apple carts around here lately to even think about that just yet.

While there may have been only one changed php file (the list 'default_row.php' ) - there's a lot of other javascript involved. And right now at least, it's some pretty messy code - but at least it works. I had to include my own validations (in javascript) because there really is no validations for a list. And just today I added (Bootstrap) 'tooltips'. So if I do decide to post it on the Wiki, it will take some work for me to create something that could be used like a template for other users - rather than just my 'custom code'. It could never really be released as template - just as a guide for how to do something similar.

Just the fact that those template files use a mix of php and HTML will have most users going cross-eyed trying to figure it out. But here's the code if you want to take a crack at it. It required a series of if / elseif statements to get the correct input element (or none at all) depending on if it was something I wanted to be read-only - or if it was something other than a standard 'field' input element - and to set classes for various numeric input masks. I also include a span (hidden if editable) to hold the original value in each TD with input (so I know if an input was changed and the row needs to be update in the database) - another trick I 'borrowed' from Tablegear.

The 2nd TR is the 'job_description' - a read-only field from a linked table that gets the Job Description for each row's Job Position/Job Title. Some of them are over 100 words long. So I show it (like a tooltip) in it's own spanned row beneath each row from the master table - with visibility triggered by javascript.
PHP:
<?php
/**
* Bootstrap List Template - boostrap_inline - default_row
*
* @package        Joomla
* @subpackage  Fabrik
* @author          Phil Bauer
* @license         GNU/GPL http://www.gnu.org/copyleft/gpl.html
*/

// No direct access
defined('_JEXEC') or die('Restricted access');

$arowId = explode('_',$this->_row->id);
$nCount = count($arowId)-1;
$cspan = count($this->headings)-1;
$jobdesc = '';

$hidearray = array("master_report___id","master_report___job_code","master_report___job_title");
$intarray = array("master_report___min_mng","master_report___max_mng","master_report___avg_mng","master_report___last_cash","master_report___last_deferred","master_report___avg_base_comp","master_report___add_cash_comp","master_report___add_def_comp","master_report___add_med_ed","master_report___add_on_call","master_report___physicians_in_category","master_report___years_in_practice","master_report___board_certified,min_md");
?>
<tr id="<?php echo $this->_row->id;?>" class="<?php echo $this->_row->class;?>">
<?php foreach ($this->headings as $heading => $label) {
        $thisClass = '';
        $fullelname = isset($this->_row->data) ? $heading : '';
        $style = empty($this->cellClass[$heading]['style']) ? '' : 'style="'.$this->cellClass[$heading]['style'].'"';
        ?>
        <td class="<?php echo $this->cellClass[$heading]['class']?>" <?php echo $style?>>
<?php if(strpos($this->cellClass[$heading]['class'],'fabrik_select')>-1){ ?>
            <?php echo isset($this->_row->data) ? $this->_row->data->$heading : '';?>
<?php }elseif(strpos($this->cellClass[$heading]['class'],'fabrik_actions')>-1){ ?>
            <input type="checkbox" class="inlineflag" id="flag_<?php echo $this->_row->id;?>" value="1">
            <input type="checkbox" class="validflag" id="valid_<?php echo $this->_row->id;?>" value="1">
<?php }else{
        if(in_array($fullelname,$hidearray)){?>       
            <span class="<?php echo isset($this->_row->data) ? $heading : '';?>"><?php echo isset($this->_row->data) ? trim(strip_tags($this->_row->data->$heading)) : '';?></span>
            <input style="display:none;" id="<?php echo isset($this->_row->data) ? $heading : '';?>_<?php echo $arowId[$nCount];?>" value="<?php echo isset($this->_row->data) ? trim(strip_tags($this->_row->data->$heading)) : '';?>">
  <?php }elseif($fullelname=='fb_jobcodes___job_description'){
            $jobdesc = isset($this->_row->data) ? trim(strip_tags($this->_row->data->$heading)) : '';
        }elseif($fullelname=='master_report___your_title'){?>
            <span style="display:none;" class="<?php echo isset($this->_row->data) ? $heading : '';?>"><?php echo isset($this->_row->data) ? trim(strip_tags($this->_row->data->$heading)) : '';?></span>
            <textarea rel="tooltip" data-placement="top" data-original-title="" data-html="true" id="<?php echo isset($this->_row->data) ? $heading : '';?>_<?php echo $arowId[$nCount];?>" rows="1"><?php echo isset($this->_row->data) ? trim(strip_tags($this->_row->data->$heading)) : '';?></textarea>
  <?php }elseif($fullelname=='master_report___your_job_code'){?>
            <span style="display:none;" class="<?php echo isset($this->_row->data) ? $heading : '';?>"><?php echo isset($this->_row->data) && $this->_row->data->$heading<>'0.00' ? trim(strip_tags($this->_row->data->$heading)) : '';?></span>
            <input rel="tooltip" data-placement="top" data-original-title="" data-html="true" id="<?php echo isset($this->_row->data) ? $heading : '';?>_<?php echo $arowId[$nCount];?>" class="<?php echo $thisClass;?>" value="<?php echo isset($this->_row->data) ? trim(strip_tags($this->_row->data->$heading)) : '';?>">
  <?php }else{
            if(isset($this->_row->data) && strpos($heading,'_ftes')!==false){
                $thisClass = 'dec1';
            }elseif(in_array($fullelname,$intarray)){
                $thisClass = 'dec0';
            }else{
                $thisClass = 'dec2';
            }
            ?>
            <span style="display:none;" class="<?php echo isset($this->_row->data) ? $heading : '';?>"><?php echo isset($this->_row->data) && $this->_row->data->$heading<>'0.00' ? trim(strip_tags($this->_row->data->$heading)) : '';?></span>
            <input rel="tooltip" data-placement="top" data-original-title="" data-html="true" id="<?php echo isset($this->_row->data) ? $heading : '';?>_<?php echo $arowId[$nCount];?>" class="<?php echo $thisClass;?>"  value="<?php echo isset($this->_row->data) && $this->_row->data->$heading<>'0.00' ? trim(strip_tags($this->_row->data->$heading)) : '';?>">
<?php } } ?>       
        </td>
<?php } ?>   
</tr>
<tr id="jd_<?php echo $this->_row->id;?>" class="jobcode" style="display:none;">
    <td><span class="icon-forward-2" style="float:right;"></span></td><td colspan="<?php echo $cspan;?>"><?php echo $jobdesc;?></td>
</tr>
?>
 
Last edited:
Hi Bauer. Thanks for that. My PHP knowledge is a bit restricted to doing very simple ifelse statements, MySql updates and that sort of thing. This is a bit over my head!
 
We are in need of some funding.
More details.

Thank you.

Members online

No members online now.
Back
Top