PHP Generator Feature Demo
  • Themes
    • Default
    • Default compact
    • Cerulean
    • Cerulean compact
    • Cosmo
    • Cyborg
    • Darkly
    • Darkly compact
    • Facebook
    • Flatly
    • Journal
    • Lumen
    • Paper
    • Readable
    • Sandstone
    • Simplex
    • Slate
    • Slate compact
    • Spacelab
    • Superhero
    • Superhero compact
    • United
    • United compact
    • Yeti
    • Yeti compact
  • English
    • German
    • Brazilian
    • Czech
    • Danish
    • Spanish
    • French
    • Hungarian
    • Italian
    • Dutch
    • Polish
    • Russian
    • Swedish
    • Slovak
    • Slovenian
    • Serbian
    • Turkish
  • Learn more
    • PHP Generator Feature Demo
    • About this demo
    • Download project file for this demo
    • Check out other PHP Generator demos
    • NBA Database Demo
    • MySQL Schema Browser Demo
    • Learn more about our products
    • Try PHP Generator for free
    • SQL Maestro Group website
  • What's new
    • Home Page
    • Column Grouping
    • Record Comparison
    • Card Mode Details
    • Adding multiple records
    • Form Layouts
    • On-the-Fly Adding
    • Quick Edit
    • Geo Charts
    • Column Filter
    • Card View
    • Master/Detail Basics
    • Inline Editing
    • Dependent Lookups
    • Image Galleries
    • Filter Builder
  • Recently Added Pages
    • Preliminary Filter
    • Custom Filter
    • Custom Icons
    • Custom Theme
    • Custom Editor
    • Page Embedding
    • Many-to-Many: Example 1
    • Many-to-Many: Example 2
    • Text Editor
    • Text Area Editor
    • Spin & Range Editors
    • Combobox Editor
    • Radio Group Editor
    • Autocomplete Editor
    • Multiple Select Editor
    • Checkbox Group Editor
    • Upload To Folder Editors
    • Editor Common Properties
  • Data Grid
    • Table View
    • Card View
    • Autohiding Columns
    • Totals
    • Grid Header
    • Column Grouping
    • Record Comparison
    • Unicode Support
    • Custom Drawing
    • Custom Table Template
    • Custom Card Template
  • Grid Columns
    • Column Types
    • Text Truncating
    • Column Fixed Width
    • Formatting
    • Null Label
    • Hyperlinks
    • Image Galleries
    • Custom Rendering
  • Grid Options
    • Fixed Grid Width
    • Fixed Column Header
    • Bordered Table
    • Condensed Table
    • Line Numbers
    • Control Buttons Position
  • Master-Detail Views
    • Master/Detail Basics
    • Multiple Details
    • Nested Details
    • Card Mode Details
  • Data Input Forms
    • Separate Page
    • Modal Window
    • Inline Editing
    • Custom Separate Page
    • Custom Modal Dialog
    • Custom Inline Form
    • Adding multiple records
    • Form Layouts
    • Editors Overview
    • Validation
    • Client-side API
    • Dependent Lookups
    • On-the-Fly Adding
    • Quick Edit
  • Editors
    • Text
    • Text Area
    • Spin & Range
    • Combobox
    • Radio Group
    • Autocomplete
    • Multiple Select
    • Checkbox Group
    • Upload To Folder
    • Common Properties
  • Data Filtering
    • Quick Filter
    • Filter Builder
    • Column Filter
    • Preliminary Filter
    • Custom Filter
  • Sorting
    • Sort By Click
    • Sort By Dialog
    • Default Sort Order
  • Partitioning
    • Range
    • List
    • Custom
  • Exporting & Printing
    • Grid
    • Single Record
    • Export Options
    • Custom Templates
  • Charts
    • Pie Chart
    • Column Chart
    • Bar Chart
    • Line Chart
    • Area Chart
    • Geo Charts
    • Multiple Charts
    • Chart Placement
    • Customizing Charts
    • Dashboard
  • Many-to-Many Relations
    • Classic Junction Table
    • Handling Extra Columns
  • Fine-tuning & Tweaking
    • Custom Icons
    • Custom Theme
    • Custom Editor
    • Page Embedding
  • Custom Templates
    • Grid View
    • Card View
    • Separate Page Editing
    • Modal Dialog Editing
    • Inline Form Editing
    • Exporting & Printing
  1. Many-to-Many Relations
  2. Many-to-Many.Classic Junction Table
    • Handling Extra Columns

Many-to-Many.Classic Junction Table

Page settings

Appearance

Here you can select the number of cards to be placed in a row for each of supported screen resolutions. Your current resolution is highlighted in this way.

Page size

Total record count: 200.

page(s).
Cancel Save changes
×

This page provides an example of handling many-to-many relationship when the junction table (sometimes referred to as a "bridge table", "join table", "association table", or "cross-reference table") contains exactly two columnns that both are foreign keys for other tables. In this case you can define a simple custom template with a multi-selection control (Checkbox Group or Multiple Select) to create an intuitive and easy-to-use interface that allows users to add/remove records to/from the junction table transparently (they will not even suspect its existence).

Technical details are as follows (click a link below to see the appropriate code):

  • OnGetCustomTemplate event handler code
  • OnAfterInsertRecord event handler code
  • OnAfterUpdateRecord event handler code
  • Custom form template (based on forms/form.tpl).

Open Insert or Edit forms to see this solution in action.

Refresh
Export
  • Export to Excel
  • Export to Word
  • Export to Xml
  • Export to Csv
  • Export to Pdf
Print
  • Print current page
  • Print all pages

        protected function doGetCustomTemplate($type, $part, $mode, &$result, &$params)
        {
            if ($mode == PageMode::FormEdit || $mode == PageMode::FormInsert) {
                $result = 'many_to_many_junction_custom_form.tpl';
                        
                // Get genre list
                $params['Genres'] = $this->GetConnection()->fetchAll("SELECT * FROM genres");
                                
                // Extract edited movie ID from GET parameters  
                if (GetApplication()->IsGETValueSet('pk0')) {
                    $movieId = GetApplication()->GetGETValue('pk0');
                }
            
                $movieGenres = array();
                if (isset($movieId)) {
                    // Get movie genres from junction table
                    $sql = "SELECT genre_id FROM movie_genres WHERE movie_id = $movieId";
                    $queryResult = $this->GetConnection()->fetchAll($sql);
                    foreach ($queryResult as $item) {
                        $movieGenres[] = $item['genre_id'];
                    }
                }
                $params['MovieGenres'] = $movieGenres;
            }
        }
        protected function doAfterInsertRecord($page, $rowData, $tableName, &$success, &$message, &$messageDisplayTime)
        {
            if ($success && GetApplication()->IsPOSTValueSet('genres_edit')) {
                $genres = GetApplication()->GetPOSTValue('genres_edit');
                $lastInsertId = $this->GetConnection()->GetLastInsertId();
                foreach ($genres as $genre) {
                    $sql = sprintf('INSERT INTO movie_genres VALUES(%d, %d);', $lastInsertId, $genre);
                    $this->GetConnection()->ExecSQL($sql);
                }
            }
        }
        protected function doAfterUpdateRecord($page, $rowData, $tableName, &$success, &$message, &$messageDisplayTime)
        {
            if ($success && GetApplication()->IsPOSTValueSet('genres_edit')) {
                $sql = sprintf('DELETE FROM movie_genres WHERE movie_id = %d;', $rowData['id']);
                $this->GetConnection()->ExecSQL($sql);
                $genres = GetApplication()->GetPOSTValue('genres_edit');
                foreach ($genres as $genre) {
                    $sql = sprintf('INSERT INTO movie_genres VALUES(%d, %d);', $rowData['id'], $genre);
                    $this->GetConnection()->ExecSQL($sql);
                }
            }
        }
<form id="{$Grid.FormId}" class="form-horizontal" enctype="multipart/form-data" method="POST" action="{$Grid.FormAction}">

    {if not $isEditOperation and $Grid.AllowAddMultipleRecords}
        <div class="btn-group pull-right form-collection-actions">
            <button type="button" class="btn btn-default icon-copy js-form-copy" title="Copy"></button>
            <button type="button" class="btn btn-default icon-remove js-form-remove" style="display: none" title="Delete"></button>
        </div>
    {/if}
    <div class="clearfix"></div>

    {include file='common/messages.tpl' type='danger' dismissable=true messages=$Grid.ErrorMessages displayTime=$Grid.MessageDisplayTime}
    {include file='common/messages.tpl' type='success' dismissable=true messages=$Grid.Messages displayTime=$Grid.MessageDisplayTime}

    {* <Custom template> *}

    <div class="row">
        {foreach item=Column from=$Grid.FormLayout->getColumns()}
            {include file="custom_templates/custom_form_column.tpl" Col=$Column}
        {/foreach}

        <div class="form-group col-sm-12">
            <hr />
        </div>

        <div class="form-group form-group-label col-sm-4">
            <label class="control-label">
                Genres
            </label>
        </div>
        <div class="form-group col-sm-8">
            <div class="col-input" style="width:100%;max-width:100%" data-column="genres">
                <select class="form-control" name="genres_edit[]" multiple data-max-selection-size="0" data-editor="multivalue_select">
                    {foreach item=Genre from=$Genres}
                        <option value="{$Genre.id}" {if $Genre.id|in_array:$MovieGenres} selected{/if}>{$Genre.name}</option>
                    {/foreach}
                </select>
            </div>
        </div>

    </div>

    {foreach key=HiddenValueName item=HiddenValue from=$HiddenValues}
        <input type="hidden" name="{$HiddenValueName}" value="{$HiddenValue}" />
    {/foreach}

    {* </Custom template> *}

    {if $flashMessages}
        <input type="hidden" name="flash_messages" value="1" />
    {/if}

    <div class="row">
        <div class="col-md-12 form-error-container"></div>
    </div>

    {include file='forms/form_scripts.tpl'}

</form>

 
Actions Title Runtime Release Date Rating Original Language
Star Wars 121 1977-03-20 7.81 English
Finding Nemo 100 2003-11-29 7.34 English
American Beauty 122 1999-09-15 7.63 English
Pirates of the Caribbean: The Curse of the Black Pearl 143 2003-07-03 7.24 English
Kill Bill: Vol. 1 111 2003-10-10 7.47 English
The Lord of the Rings: The Fellowship of the Ring 178 2001-12-18 7.75 English
The Lord of the Rings: The Two Towers 179 2002-12-18 7.72 English
The Lord of the Rings: The Return of the King 201 2003-12-01 7.85 English
The Dark Knight 152 2008-07-16 8.02 English
The Godfather 175 1972-03-15 8.23 English
There are no records to display

Multiple Sort

Column Order

Filter builder

  • «
  • 1
  • 2
  • ...
  • 11
  • ...
  • 20
  • »

About this demo

This demo application contains 60+ pages and illustrates most of features provided by PHP Generator. Hope it will help you to create even more powerful websites for your users.

You can download the demo project from our website and run the demo on your webserver as described in readme.txt.

Download PHP Generator Free Trial

Legend
New Pages showing new features implemented in the latest version of PHP Generator (currently 16.9).
Upd Pages showing features significantly updated in the latest version of PHP Generator (currently 16.9).
New Pages recently added to this demo.

© 2002- SQL Maestro Group. Created with PHP Generator for MySQL.

Change your password

Change password for user ''

Passwords do not match. Please try again.

Close Change password