[almost] AUTOMATIC TAB FORMS

Discussions related to customizing hooks. Hooks are documented at http://bigprof.com/appgini/help/advanced-topics/hooks/
Post Reply
grimblefritz
Veteran Member
Posts: 287
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
Veteran Member
Posts: 287
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
Veteran Member
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
Veteran Member
Posts: 287
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
Veteran Member
Posts: 287
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
Veteran Member
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
Veteran Member
Posts: 287
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
Veteran Member
Posts: 287
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
Veteran Member
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
Veteran Member
Posts: 287
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
Veteran Member
Posts: 287
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
Veteran Member
Posts: 287
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
Posts: 10
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

landinialejandro
Posts: 4
Joined: 2016-03-06 00:59

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!

Post Reply