Has anyone created an Amazon-style wish list with Editor?

Has anyone created an Amazon-style wish list with Editor?

stevevancestevevance Posts: 58Questions: 6Answers: 1
edited July 2017 in Free community support

I want to create an Amazon-style wish list, where people can have multiple lists and add items to one or more lists.

My thought is to create a "lists" table where users can add and edit their wish lists. The wish list table would appear on every item page. One of the columns in the wish list table would be an "item status" column. This "item status" column would have a checkbox to indicate if the rows of wish lists contained the item.

If the row (wish list) didn't contain the item, the user could click the checkbox and the item would be added to that list. This is the part I don't know how to design yet. I could create a link table but I don't know how to create a new row in that table (a row would represent the link between the item and a particular wish list), or to delete the row in that table when a user unchecks the checkbox.

Got any ideas?

Answers

  • stevevancestevevance Posts: 58Questions: 6Answers: 1

    okay, I've got something working.

    Here are two screenshots of it:

  • stevevancestevevance Posts: 58Questions: 6Answers: 1
    edited July 2017

    This is the code I used.
    It requires jQuery and Defiant.js.

    PHP:

    // DataTables PHP library and database connection
    include( "lib/DataTables.php" );
    
    // Alias Editor classes so they are easy to use
    use
        DataTables\Editor,
        DataTables\Editor\Field,
        DataTables\Editor\Format,
        DataTables\Editor\Mjoin,
        DataTables\Editor\Upload,
        DataTables\Editor\Validate;
    
    // Build our Editor instance and process the data coming from _POST
    Editor::inst( $db, 'wishlists', 'id' )
        ->field(
            Field::inst( 'wishlists.name' ),
            Field::inst( 'wishlists.id' ),
            Field::inst( 'wishlists.private' ),
            
            Field::inst( 'wishlists.updated_at' )
                ->setValue( date("Y-m-d H:i:s") ),
            Field::inst( 'wishlists.created_at' )
                ->set( Field::SET_CREATE )
                ->setValue( date("Y-m-d H:i:s") ),
                
            Field::inst( 'wishlists.user_id' )
                ->setValue($_SESSION['id'])
        )
        ->join(
            Mjoin::inst( 'wishlists_items' )
                ->link( 'wishlists_items.wishlist_id', 'wishlists.id' )
                ->fields(
                    Field::inst( 'id' ),
                    Field::inst( 'object_type' ),
                    Field::inst( 'object_id' )
                )
        )
        ->where("wishlists.user_id", $_SESSION['id'])
        ->debug(true)
        ->process($_POST)
        ->json();
    

    JavaScript:

    function loadListsEditor() {
    
        editor = new $.fn.dataTable.Editor( {
            ajax: '/php/editor.lists.php',
            table: '#table_lists',
            fields: [
                {
                    label: "Name:",
                    name: "wishlists.name",
                },
                {
                    label: "Private?:",
                    name: "wishlists.private",
                    type: "radio",
                    options: [
                        {
                            label: "Keep it private",
                            value: 1
                        },
                        {
                            label: "Make it public",
                            value: 0
                        }
                    ]
                },
            ]
        } );
    
        var buttons = [
            {
                extend: 'create',
                editor: editor,
                className: "btn-sm"
            },
            {
                extend: 'edit',
                editor: editor,
                className: "btn-sm"
            },
            { 
                text: "Reload",
                className: "btn-sm",
                action: function ( e, dt, node, config ) {
                    table.ajax.reload();
                }
            }
        ];
    
        table = $('#table_lists').DataTable( {
            dom: 'Bf<"#tag_filter">rtp',
            serverSide: true,
            processing: true,
            ajax: {
                url: '/php/editor.lists.php',
                type: "POST"
            },
            select: {
                style: 'os'
            },
            stateSave: false,
            pageLength: 3,
            columns: [
                {
                    data: "wishlists.name",
                    title: "Name",
                },
                {
                    data: "wishlists.private",
                    title: "Private?",
                    render: function( data, type, row, meta) {
                        return data == 1 ? "Private" : "Public";
                    }
                },
                {
                    title: "On this list?",
                    defaultContent: "",
                    searchable: false,
                    orderable: false,
                    data: "wishlists_items[]", 
                    render: function( data, type, row, meta) {
                        var checkbox = "";
                        // See if this wishlist item matches both the object_id and the object_id
                        if(window['object_id']) {
                            var search = JSON.search(data, '//*[object_id="' + object_id + '"][object_type="' + object_type + '"]');
                            if(search.length > 0) {
                                checked = "checked='checked'";
                            } else {
                                checked = "";
                            }
                            
                            checkbox = "<input type='checkbox' id='status_" + row.wishlists.id + "' data-object-id='" + object_id + "' data-object-type='" + object_type + "' data-list-id='" + row.wishlists.id + "' " + checked + " />";
                            return checkbox;
                        }
                    },
                    visible: page == "account" ? false : true
                },
                {
                    title: "Contains these objects",
                    data: "wishlists_items", 
                    render: "[, ].object_id",
                    searchable: false,
                    visible: false
                },
                {
                    title: "Items count",
                    data: "wishlists_items", 
                    render: function( data, type, row, meta) {
                        return data.length;
                    },
                    searchable: false,
                    visible: page == "account" ? true : false
                },
            ],
            select: true,
            buttons: buttons,
            drawCallback: function( settings ) {
                var table = this.api();
                var draw = table.settings()[0].iDraw;
                
                // Register this event (for some reason this has to be registered after every time a checkbox is clicked)
                $("input[type=checkbox]").on("click", function() {
                    checkbox = $(this);
                    object_id = $(checkbox).data("objectId");
                    object_type = $(checkbox).data("objectType");
                    list_id = $(checkbox).data("listId");
                    action = $(checkbox).attr("checked") === "checked" ? "remove" : "add";
                    
                    changeItemStatus(action, list_id, object_id, object_type);
                });
            },
            initComplete: function(settings) {
            }
        } );
    }
    
    function changeItemStatus(action, list_id, object_id, object_type) {
        var url = "/php/api.lists.php";
        $.ajax({
            type: "POST",
            url: url,
            data: {
                method: "datatables",
                action: action,
                list_id: list_id,
                object_id: object_id,
                object_type: object_type
            },
            success: function(response) {
                console.log(response);
                $("#action_message").html(response.message);
                
                // Redraw the table to ensure it's always rendering the latest data
                table.ajax.reload();
            }
        });
    }
    

    The function changeItemStatus() is a custom function that goes to a custom API that I wrote that simply adds or deletes a row to the "wishlists_items" table, based on clicking the checkbox.

  • allanallan Posts: 63,471Questions: 1Answers: 10,467 Site admin

    That looks good to me. How are you finding the interaction?

    One possible enhancement, which is based on what you mentioned about Amazon, would be to have another column called "wish_list" (or whatever) which would allow the user to group their items into multiple lists via a where condition.

    Allan

  • stevevancestevevance Posts: 58Questions: 6Answers: 1

    You can see it in action!

    https://www.chicagocityscape.com/permits.php?pid=100717579 - look for "My Lists"

    You'll have to sign up for a free account to be able to use it.

  • allanallan Posts: 63,471Questions: 1Answers: 10,467 Site admin

    So just to confirm - at you happy with how it is working just now, or are there any outstanding issues?

    Allan

  • stevevancestevevance Posts: 58Questions: 6Answers: 1

    @allan I'm happy with the way it works now!

This discussion has been closed.