Need a working example of how to create an all-in-one parent/child editing view/form.

Need a working example of how to create an all-in-one parent/child editing view/form.

koniahinkoniahin Posts: 186Questions: 39Answers: 7

I have a number of forms that are inter-related in a parent/child method. As is I have them set up so that I visit the parent form, categories.php, for example then inline I add a render link in one of the columns that passes the id to the child and opens the child form (separate page).

It would be many times easier to visit the categories page, click/select a category row and load the child articles in a second table on the same page. Click to a different category and it loads its child articles. I found this post:

https://datatables.net/blog/2016-03-25

It meets the goal and I tried to create the forms using 2 tables articles and article_categories but found that the post is incomplete towards the ends and I could not glue it together.

The link to my demo: https://www.dottedi.xyz/bin/article-categories.php

In the post there is a reference to the following code but it does not say where it gets added:

table.row( { selected: true } ).data();

When I got to this next item and added this code in the child table that would break the page article categories page from loading data. It sticks at "loading" but never loads:

->join(
        Mjoin::inst( 'users' )
            ->link( 'sites.id', 'users.site' )
            ->fields(
                Field::inst( 'id' )
            )
    )

And yes, I updated the fields to the correct table names and field names. With that disabled I updated the server side php file adding the if/else code described here but replacing it with my table name/fields:

if ( ! isset($_POST['site']) || ! is_numeric($_POST['site']) ) {
    echo json_encode( [ "data" => [] ] );
}
else {
    Editor::inst( $db, 'users' )
        ->field(
            Field::inst( 'users.first_name' ),
            Field::inst( 'users.last_name' ),
            Field::inst( 'users.phone' ),
            Field::inst( 'users.site' )
                ->options( 'sites', 'id', 'name' )
                ->validator( 'Validate::dbValues' ),
            Field::inst( 'sites.name' )
        )
        ->leftJoin( 'sites', 'sites.id', '=', 'users.site' )
        ->where( 'site', $_POST['site'] )
        ->process($_POST)
        ->json();
}

That caused the page to break. I also don't see how/where you bring the child table onto the page. The general problem is that the solution is incomplete and doesn't provide adequate help regarding where some of the code parts belong.

I made .txt copies of my php files. To see them visit:

https://www.dottedi.xyz/bin/dt/article-categories.php.txt
https://www.dottedi.xyz/bin/dt/articles.php.txt

The php/controller files:

https://www.dottedi.xyz/bin/controllers/article-categories.php.txt
https://www.dottedi.xyz/bin/controllers/articles.php.txt

I could add the text directly into this post but it would get very long. If it helps say so.
Thank you

Answers

  • colincolin Posts: 15,112Questions: 1Answers: 2,583
    edited July 2021

    Our records appear out of date, we're not seeing a license for Editor under your account. Was Editor licensed to another user? If so, please could you PM me the details.

    Colin

  • allanallan Posts: 61,438Questions: 1Answers: 10,052 Site admin

    In the post there is a reference to the following code but it does not say where it gets added:

    That line is meant to be an example of how you can get information about the selected row. The actual use of the concept introduced there is in the block just below it (and the one after that):

    var usersEditor = new $.fn.dataTable.Editor( {
        ajax: {
            url: '../php/users.php',
            data: function ( d ) {
                var selected = siteTable.row( { selected: true } );
     
                if ( selected.any() ) {
                    d.site = selected.data().id;
                }
            }
        },
        table: '#users',
        fields: [ ... ]
    } );
    

    The idea there is that you get the id from the currently selected row and send that to the Editor / DataTable PHP scripts for the child table so they know what group they should be working on.

    Allan

  • allanallan Posts: 61,438Questions: 1Answers: 10,052 Site admin

    This is that example in full and no explanation text, which might also be useful for you to refer to.

    Allan

  • rmeetinrmeetin Posts: 97Questions: 23Answers: 1
    edited August 2021

    I saw that earlier but thought it was incomplete, so kept looking. Anyway I copies the article-categories.php page to multi-level.php (just a name to differentiate) and then copied in and modified the code from the new example. The code for the new multi-level.php file:

    <?php
    // to populate category dropdown selection
    $categories = "{ label: '--Select--',  value: '' },";
    $query = "select * from article_categories";
    $result = $mysqli->query ($query);
    $number_results = mysqli_num_rows ($result);
    for ($n=0; $n < $number_results ; $n++ ) {
      $row = mysqli_fetch_array($result);
      $id = ($row['id']);
      $name = ($row['name']);
      $categories .= "{ label: '$name',  value: '$id' },";
    }
    ?>
    
    <script src='dt/lib/ck-toolbar.js'></script>
    
    <script type="text/javascript" language="javascript" class="init">
        $(document).ready(function() {
            var categoryEditor = new $.fn.dataTable.Editor( {
                ajax: 'controllers/multi-level.php',
                table: '#categories',
                fields: [ 
                    {
                        label: 'Order:',
                        name: 'article_categories.rowOrder',
                        default: 1,
                        type: 'hidden',
                    }, 
                    {
                        label: 'FAQ Category Name:',
                        name: 'article_categories.name'
                    }
                ]
            } );
    
            window.editor = categoryEditor;
            var table = $('#categories').DataTable( {
    
                dom: 'Bfrtip',
                ajax: 'controllers/multi-level.php',
                select: {
                    style: 'single'
                },
    
                rowReorder: { dataSrc: 'article_categories.rowOrder', editor: categoryEditor },
                order: [[ 0, "asc" ]],
                info: true,
    
                buttons: [
                    { extend: 'create', editor: categoryEditor },
                    { extend: 'edit', editor: categoryEditor },
                    { extend: 'remove', editor: categoryEditor }
                ],
    
                columns: [
                    { data: 'article_categories.rowOrder', className: 'reorder' },
                    { data: 'article_categories.id' },
                    { data: 'article_categories.name' },
                ],
    
            } );
    
            editor
                .on( 'postCreate postRemove', function () { table.ajax.reload( null, false ); } )
                .on( 'initCreate', function () { editor.field( 'article_categories.rowOrder' ).enable(); } )
                .on( 'initEdit', function () { editor.field( 'article_categories.rowOrder' ).disable(); } );
            } );
    
            var articleEditor = new $.fn.dataTable.Editor( {
                ajax: { 
                    url: 'controllers/articles.php',
                    data: function ( d ) {
                        var selected = categoryTable.row( { selected: true }
                        if ( selected.any() ) {
                            d.category = selected.data().id;
                        }
                    }
                },
                table: '#articles',
                fields: [
                    {
                        label: 'Order:',
                        name: 'articles.rowOrder',
                        type: 'hidden',
                        default: 1,
                    },
                    {
                        label: 'Short Title',
                        name:   'articles.title',
                    },
                    {
                        label: 'Text',
                        name:   'articles.fulltext',
                        default: '',
                        type: 'textarea',
                    },
                    {
                        label: 'Page type',
                        name:   'articles.page_type',
                        default: 'demonstration',
                        type: 'hidden',
                    },
                    {
                        label: 'Category',
                        name:   'articles.catid',
                        type:   'select',
                        options: [
                            <?php echo $categories; ?>
                        ]
                    }
                ]
            } );
    
            var articlesTable = $('#articles').DataTable( {
                dom: 'Bfrtip',
                ajax: {
                    url: 'controllers/articles.php',
                    type: 'post',
                    data: function ( d ) {
                        var selected = categoryTable.row( { selected: true } );
                        if ( selected.any() ) {
                            d.category = selected.data().id;
                        }
                    }
                },
                columns: [
                    { data: 'articles.title' },
                    { data: 'articles.page_type' },
                    { data: 'articles.catid' },
                    { data: 'article_categories.name' }
                ],
                select: true,
                buttons: [
                    { extend: 'create', editor: articleEditor, enabled: false, init: function(dt) {
                        var that = this;
                        siteTable.on('select deselect', function() {
                            that.enable(categoryTable.rows({selected: true}).any())
                        })
                    }},
                    { extend: 'edit',    editor: articleEditor },
                    { extend: 'remove', editor: articleEditor }
                ]
            } );
    
            categoryTable.on( 'select', function (e) {
                articleTable.ajax.reload();
    
                articleEditor
                    .field( 'artcles.catid' )
                    .def( categoryTable.row( { selected: true } ).data().id );
            } );
    
            categoryTable.on( 'deselect', function () {
                articleTable.ajax.reload();
            } );
    
            articleEditor.on( 'submitSuccess', function () {
                categoryTable.ajax.reload();
            } );
    
            categoryEditor.on( 'submitSuccess', function () {
                articleTable.ajax.reload();
            } );
        } );
    
    </script>
    
    <table id="categories" class="display">
        <thead>
            <tr>
                <th>Order</th>
                <th>ID</th>
                <th>Name</th>
            </tr>
        </thead>
    </table>
    <table id="articles" class="display">
        <thead>
            <tr>
                <th>Title</th>
                <th>Page type</th>
                <th>Category ID</th>
                <th>Category name</th>
            </tr>
        </thead>
    </table>
    

    You can see the result at:

    https://www.dottedi.xyz/bin/multi-level.php

    Not there yet. My 2 tables are article_categories and articles. I substituted in the name changes where I understood.

    You can view the php files at:

    https://www.dottedi.xyz/bin/controllers/articles.php.txt
    https://www.dottedi.xyz/bin/controllers/multi-level.php.txt

  • allanallan Posts: 61,438Questions: 1Answers: 10,052 Site admin

    Hi,

    Thanks for the link. I'm getting a Javascript syntax error in bin/multi-level.php line 101 (when rendered):

    var selected = categoryTable.row( { selected: true }
    

    Should be:

    var selected = categoryTable.row( { selected: true } );
    

    Allan

  • rmeetinrmeetin Posts: 97Questions: 23Answers: 1

    I found and updated that on line 72 yet the page is still not rendering.

  • kthorngrenkthorngren Posts: 20,141Questions: 26Answers: 4,735

    Please make sure to fix all your errors. You are now getting this error:

    Uncaught SyntaxError: Unexpected token '}' multi-level.php line: 191

    Kevin

Sign In or Register to comment.