[almost] AUTOMATIC TAB FORMS

Discussions related to customizing hooks. Hooks are documented at http://bigprof.com/appgini/help/advanced-topics/hooks/
Post Reply
grimblefritz
AppGini Super Hero
AppGini Super Hero
Posts: 336
Joined: 2015-12-23 16:52

[almost] AUTOMATIC TAB FORMS

Post by grimblefritz » 2016-06-28 15:26

I have coded a module that will, with two lines added to the tablename.php hook file, create tabbed forms.

There are some caveats, of course.

FIRST:
The fields in AppGini must be prefixed with the tab id. For example, lets say you have an address book and want to always show the name, and have address and phone in separate tabs.

Table: contacts

Fields:
id
name
addr_street
addr_unit
addr_city
addr_st
addr_zip
phone_home
phone_cell
phone_work
phone_fax
phone_other_name
phone_other

It is necessary for all fields in a tab to be grouped together as shown. In the example, the tab IDs are 'addr' and 'phone'.

Because the 'name' field has no prefix, it has no tab. However, it will end up in a tab called 'name', which is not what is desired. There's a way to handle this, of course, which leads to the second caveat.

SECOND:
Any fields named 'id' or '?????_id' (ending with _id) will be excluded from any tab. This is so they will display at the top of the form, above the tabs. You can, of course, exclude any fields you wish.

THIRD:
Sometimes the best tab ID isn't the best tab NAME. In the example, the 'addr' and 'phone' tab IDs become tab names 'Addr' and 'Phone'. While 'Phone' is probably okay, 'Addr' isn't the best choice.

There is a method provided for dealing with this. So, in AppGini, you can use short and simple abbreviations, but in the form you can have meaningful names.

HOW-TO:
Copy the code block at the bottom of this post into your hooks folder as 'hooks/_mktabbed.php'.

In the hooks/contacts.php file, insert the following into the contacts_dv function:

Code: Select all

        function contacts_dv($selectedID, $memberInfo, &$html, &$args){

                require('hooks/_mktabbed.php');

                $html .= mktabbed('contacts', 'addr=Address info', 'id,name');
        }
This pulls the code into the detail view function and then invokes it passing:

-- the table/form name
-- a string to remap the addr tab name to "Address info"
-- instructions to exclude the 'id' and 'name' fields from tabs

Note that if a field (such as id) is hidden from the detail view in AppGini, then it is not strictly necessary to exclude it from mktabbed(). On the other hand, it hurts nothing.

RESULTS:
Here is the resulting detail view.
Image



SOURCE CODE for hooks/_mktabbed.php

Code: Select all

<?php
function mktabbed($table, $names="", $omit="id,.*_id") {

        // no tabs in print preview
        if(isset($_REQUEST['dvprint_x'])) return;

        // clean up return from get_sql_fields() to create
        // a list of field names as 'f1'f2'f3...'

        $search  = array ( "/,.*? as /"  ,  "/''/" );

        $replace = array ( ""            ,  "'"    );

        $fieldnames = preg_replace($search, $replace, ",".get_sql_fields($table));

        // drop any omitted fields (ie, omitted from tabs)
        //
        // by default, the primary key (id) and foreign keys
        // (tablename_id) are omitted so they're not tabbed,
        // but the $omit parameter can be used to change this
        // (ie, drop other fields, or set to "" to drop none)

        foreach (explode(",", $omit) as $field) {
                $fieldnames = preg_replace("/'$field'/U", "'", $fieldnames);
        }

        // delete leading and trailing ' and explode into array

        $fieldnames = preg_replace("/^'|'$/", "", $fieldnames);

        $fields = explode("'", $fieldnames);

        // build an associative array that separates fields by
        // group, sets the tab name, and fields in the tab

        $tabs=array();
        $current="";

        foreach ($fields as $field) {
                // tab id is the chars up to the first _
                $tab = preg_replace("/_.*/", "", $field);
                if ($tab != $current) {
                        // replace the tab name if found in $names
                        $name = preg_replace("/.*,$tab=(.*?),.*/", "$1", ",$names,");
                        // if name still has a , in it, use the tab id
                        if (strpos($name, ",") !== false) $name=ucfirst($tab);
                        $tabs[$tab]['name'] = $name;
                        $tabs[$tab]['id'] = "{$tab}-info";
                }
                // append the field name to the fields array for the tab id
                $tabs[$tab]['fields'][] = $field;
        }


        // what follows is basically what Ahmad provided in
        // the Udemy course, but restructured a bit to allow
        // it to be scripted a bit more cleanly

        ob_start(); ?>

        <div id="form-tabs">

                <ul class="nav nav-tabs">
                        <?php
                        // we only want the first tab to be active
                        $first=true;
                        foreach ($tabs as $tab => $tabinfo) {
                                echo '<li '.(($first)?' class="active"':'')."><a href='#{$tabinfo[id]}' data-toggle='tab'>{$tabinfo[name]}</a></li>\n";
                                $first=false;
                        }
                        ?>
                </ul>

                <ul class="tab-content">

                        <?php
                        // again, only the first panel is active
                        $first=true;
                        foreach ($tabs as $tab => $tabinfo) {
                                echo '<div class="tab-pane form-horizontal '.(($first)?' active':'').'" id="'.$tabinfo['id'].'"></div>'."\n";
                                $first=false;
                        }
                        ?>
                </ul>

        </div>

        <style>
                #form-tabs .nav-tabs a{ display: block !important; }
        </style>

        <script>
                $j(function(){
                        <?php
                        // here is where we move fields into tabs
                        echo "\$j('#form-tabs').appendTo('#{$table}_dv_form');\n";
                        foreach ($tabs as $tab => $tabinfo) {
                          foreach ($tabinfo['fields'] as $tabfield) {
                            echo "\$j('#{$tabfield}').parents('.form-group').appendTo('#{$tabinfo[id]}');\n";
                          }
                        }
                        ?>
                })
        </script>

        <?php

        $html = ob_get_contents();
        ob_end_clean();

        return $html;
}

grimblefritz
AppGini Super Hero
AppGini Super Hero
Posts: 336
Joined: 2015-12-23 16:52

Re: [almost] AUTOMATIC TAB FORMS

Post by grimblefritz » 2016-06-28 15:29

Almost forgot. There's a live preview here:

http://grimblefritz.com/mktabbed

DevGiu
AppGini Super Hero
AppGini Super Hero
Posts: 151
Joined: 2016-05-27 09:08

Re: [almost] AUTOMATIC TAB FORMS

Post by DevGiu » 2016-06-29 19:12

I have to try this. Thanks for share.
/Giuseppe
Professional Outsourcing Services

grimblefritz
AppGini Super Hero
AppGini Super Hero
Posts: 336
Joined: 2015-12-23 16:52

Re: [almost] AUTOMATIC TAB FORMS

Post by grimblefritz » 2016-06-30 00:28

Do let me know. I've used it on four sites now and it seems to behave perfectly. For me. Naturally, I've not encountered every possible scenario, so it may stumble - I don't know.

Also, regarding the remapping of tab names. In my example I showed:

Code: Select all

mktabbed('contacts', 'addr=Address info', 'id,name')
The changes the addr field prefix to display as 'Address info'.

You can change more than one tab name:

Code: Select all

mktabbed('contacts', 'addr=Address info,phone=Phone numbers', 'id,name')
It a comma-delimited list of prefix=tabname pairs. The order is not important. (That's true of the third parameter to exclude fields from being tabbed - the order doesn't matter.)

Case matters, for the table name, field prefixes and excluded fields.

grimblefritz
AppGini Super Hero
AppGini Super Hero
Posts: 336
Joined: 2015-12-23 16:52

Re: [almost] AUTOMATIC TAB FORMS

Post by grimblefritz » 2016-07-07 21:10

Has anyone tried this?

Also, I'm working on an update that will provide control over tab+field(s) assignments, without having to rely on field name prefixes. More complicated to setup in tablename_dv.php, but easier for existing projects in that it doesn't require fields to be renamed.

DevGiu
AppGini Super Hero
AppGini Super Hero
Posts: 151
Joined: 2016-05-27 09:08

Re: [almost] AUTOMATIC TAB FORMS

Post by DevGiu » 2016-07-07 21:17

I didnt had time. Im bery busy witj non appgini projects, but my idea is to use something similar to this, but as you say, not based on table prefixes
/Giuseppe
Professional Outsourcing Services

grimblefritz
AppGini Super Hero
AppGini Super Hero
Posts: 336
Joined: 2015-12-23 16:52

Re: [almost] AUTOMATIC TAB FORMS

Post by grimblefritz » 2016-07-07 21:21

I will post my updated script when I have it debugged. I will work with any existing project.

grimblefritz
AppGini Super Hero
AppGini Super Hero
Posts: 336
Joined: 2015-12-23 16:52

Re: [almost] AUTOMATIC TAB FORMS

Post by grimblefritz » 2016-07-09 20:45

I have split the original function into two.

mktabbed() uses field names to generate the tabs array, and then calls mktabbed_html().

mktabbed_html() accepts a tabs array, and then generates the needed html/css/jquery code for tabbed froms.

So, if you're starting from scratch, you can used the field naming convention "tabid_fieldname" and simply called mktabbed().

Or, if you don't like that naming convention, or have an existing project, then in tablename_dv() build up the tabs array and then call mktabbed_html().

Visit http://grimblefritz.com/mktabbed/ to see the demo app.

There is an option there to view the latest source.

DevGiu
AppGini Super Hero
AppGini Super Hero
Posts: 151
Joined: 2016-05-27 09:08

Re: [almost] AUTOMATIC TAB FORMS

Post by DevGiu » 2016-07-09 21:49

I will take a look. Do you provide some sample of how to use? For example.
Customer table.
Id
Name
Surname
Country
State
Address
Sales pricing

Where name and surname goes on personal data tab, country,address and state on address tab and sales pricing on Sales tab?
/Giuseppe
Professional Outsourcing Services

grimblefritz
AppGini Super Hero
AppGini Super Hero
Posts: 336
Joined: 2015-12-23 16:52

Re: [almost] AUTOMATIC TAB FORMS

Post by grimblefritz » 2016-07-10 13:42

I realized I could drop an element from the tabs array, so I've updated the demo site with the new code.

The comments in the source now include an example based on your suggestion. I've copied that here:

Code: Select all

  /*
  TABLE     TAB            FIELDS
  customer  <no tab>       ID, FullName
            Personal Info  FirstName, LastName, Birthdate, Age
            Contact Info   Address, City, State, Zip, HomePhone, CellPhone
            Sales Info     ContractID, DiscountRate, FirstSale, LastSale

  In the customer.php file, customer_dv() function, add this code:
  */

  require('hooks/_mktabbed.php');

  $tabs['pi']['name']   = 'Personal Info';
  $tabs['pi']['fields'] = explode(',' 'FirstName,LastName,Birthdate,Age');

  $tabs['ci']['name']   = 'Contact Info';
  $tabs['ci']['fields'] = explode(',' 'Address,City,State,Zip,HomePhone,CellPhone');

  $tabs['si']['name']   = 'Sales Info';
  $tabs['si']['fields'] = explode(',' 'ContractID,DiscountRate,FirstSale,LastSale');

  $html .= mktabbed_html('Customer', $tabs)


grimblefritz
AppGini Super Hero
AppGini Super Hero
Posts: 336
Joined: 2015-12-23 16:52

Re: [almost] AUTOMATIC TAB FORMS

Post by grimblefritz » 2016-07-16 02:18

Oops!

I neglected to exclude mktabbed_html() from firing in print preview mode.

It's a quick one-liner update. The full source is available at the demo site.

grimblefritz
AppGini Super Hero
AppGini Super Hero
Posts: 336
Joined: 2015-12-23 16:52

Re: [almost] AUTOMATIC TAB FORMS

Post by grimblefritz » 2016-07-26 16:29

HOW-TO: HIDE/SHOW TABS

I have an app where I want to hide tabs, based on the condition of another input.

Turns out, it's really easy!

In tablename-dv.js use (inside your main $j block:

Code: Select all

if($j('#field_to_check').val()=='some_key_value'){
    $j('a[href="#tabname-info"]').parents('li').show();
}else{
    $j('a[href="#tabname-info"]').parents('li').hide();
}
Note that this only hides the tab index, not the tab panel. Turns out that's okay, however, since hiding the index effectively prevents the tab panel from ever being shown.

Caveat: Make sure you don't have the affected panel active at the time it is hidden. That is, if the value of FieldX is to be used to show/hide PanelB, then FieldX should not reside on PanelB.

FTH Abrar
Posts: 4
Joined: 2017-01-11 05:28

TAB FORMS

Post by FTH Abrar » 2017-03-27 08:09

How could we do the same on multiple tables, given example :
TableA --> TA_IDNumber, MyTagID, Name, TelephoneNumber
TableB--> TB_IDNumber, MyTagID, Address Road 1,City, Town

What I would like to display is :

Under 1 single Appgini Form, there is a form entry of MyTagID while 2 Tab , 1st Tab is 'PersonalData' with 2 fields (Name & TelephoneNumber) while the second Tab 'AddressData' with the 3 fields of Address Road 1,City and Town.

In short having multiple tabs but each tabs representing it own forms (entry) of Appgini

xbox2007
Veteran Member
Posts: 129
Joined: 2016-12-16 16:49

Re: [almost] AUTOMATIC TAB FORMS

Post by xbox2007 » 2017-04-10 14:38

grimblefritz very nice Project ,, Thanks a lot

User avatar
landinialejandro
AppGini Super Hero
AppGini Super Hero
Posts: 126
Joined: 2016-03-06 00:59
Location: Argentina
Contact:

Re: [almost] AUTOMATIC TAB FORMS

Post by landinialejandro » 2017-04-24 23:00

Very good contribution, I tried the tabs and works perfectly.
Thank you!
Alejandro.
AppGini 5.98 - Linux OpenSuse Tumblewweed.

Some of my posts that may interest you:
:arrow: Landini Admin Template: Template for Appgini like AdminLTE
:arrow: Profile image plugin: add and changue image user profile
:arrow: Field editor in table view: Configurable fast edit fields in TV
:idea: my personal page

User avatar
Bachtiar
Posts: 5
Joined: 2017-08-26 15:28

Re: [almost] AUTOMATIC TAB FORMS

Post by Bachtiar » 2017-10-24 03:48

grimblefritz wrote:
2016-07-10 13:42
I realized I could drop an element from the tabs array, so I've updated the demo site with the new code.

The comments in the source now include an example based on your suggestion. I've copied that here:

Code: Select all

  /*
  TABLE     TAB            FIELDS
  customer  <no tab>       ID, FullName
            Personal Info  FirstName, LastName, Birthdate, Age
            Contact Info   Address, City, State, Zip, HomePhone, CellPhone
            Sales Info     ContractID, DiscountRate, FirstSale, LastSale

  In the customer.php file, customer_dv() function, add this code:
  */

  require('hooks/_mktabbed.php');

  $tabs['pi']['name']   = 'Personal Info';
  $tabs['pi']['fields'] = explode(',' 'FirstName,LastName,Birthdate,Age');

  $tabs['ci']['name']   = 'Contact Info';
  $tabs['ci']['fields'] = explode(',' 'Address,City,State,Zip,HomePhone,CellPhone');

  $tabs['si']['name']   = 'Sales Info';
  $tabs['si']['fields'] = explode(',' 'ContractID,DiscountRate,FirstSale,LastSale');

  $html .= mktabbed_html('Customer', $tabs)

where I put this code, do I create a separate file?

User avatar
Bachtiar
Posts: 5
Joined: 2017-08-26 15:28

Re: [almost] AUTOMATIC TAB FORMS

Post by Bachtiar » 2017-10-24 04:13

ups sorry.. I got it..Oke Succes for Grimblefritz

D Campbell
Posts: 20
Joined: 2017-03-12 09:32

Re: [almost] AUTOMATIC TAB FORMS

Post by D Campbell » 2017-10-26 19:09

Umm Where can I find this tablename-dv.js?
grimblefritz wrote:
2016-07-26 16:29
HOW-TO: HIDE/SHOW TABS

I have an app where I want to hide tabs, based on the condition of another input.

Turns out, it's really easy!

In tablename-dv.js use (inside your main $j block:

Code: Select all

if($j('#field_to_check').val()=='some_key_value'){
    $j('a[href="#tabname-info"]').parents('li').show();
}else{
    $j('a[href="#tabname-info"]').parents('li').hide();
}
Note that this only hides the tab index, not the tab panel. Turns out that's okay, however, since hiding the index effectively prevents the tab panel from ever being shown.

Caveat: Make sure you don't have the affected panel active at the time it is hidden. That is, if the value of FieldX is to be used to show/hide PanelB, then FieldX should not reside on PanelB.

peebee
AppGini Super Hero
AppGini Super Hero
Posts: 352
Joined: 2013-03-21 04:37

Re: [almost] AUTOMATIC TAB FORMS

Post by peebee » 2017-10-26 22:17


ErikC
Posts: 2
Joined: 2017-03-12 08:17

Re: [almost] AUTOMATIC TAB FORMS

Post by ErikC » 2017-11-30 11:20

Hi Grimblefritz,

I tried using your implementation and the mktabbed() option works great but as you mentioned it makes for a lot of work as I have to change all other applications which obtain data from the table.

I tried to implement the mktabbed.html() option, but all I get is a blank page. Based on your markup on the sample table above, I removed all the rows and provisioned only for one row/Tab. I also changed the "customer" name to my table name. This had no effect. I confirmed the syntax used was correct and as per your sample I could only find one difference which was the "customer" table name and the "Customer" (Capital C) in your table reference. I would really like to implement the html() option as the original option does not allow me to make changes to the hierarchy of the table fields as it is loaded.

Your assistance will be appreciated.

Erik

jimstoffel
Posts: 22
Joined: 2017-01-13 02:43

Re: [almost] AUTOMATIC TAB FORMS

Post by jimstoffel » 2018-07-24 19:50

Hi Grimblefritz,

Is there a way to create additional tabs from another table within the page view of say the "main table view?"

Appreciate the work you've done to create and post for others.

Jim.

Post Reply