Jump to content
benbyf

Grid layout input using pages

Recommended Posts

Is there any way to create an input grid within a edit page which allows the user to select a cell and assign a page to it, e.g. from a list of pages of template "x" select one and assing it so that in the templates the table can be created and cells refer to the page itself or its id?

I'm working on a site where the clients wishes to have a grid layout that they can adhocly put different page images into that link to the pages about that project. However they want each cell to be assignable or not and be able to span 1 or more cells... making an expressive layout.

Any thoughts would be appreciated

Share this post


Link to post
Share on other sites

Hi @benbyf

20 hours ago, benbyf said:

Any thoughts would be appreciated

Just ideas, I hope this helps:

As far as I know, the closest module which at least partially could be used for such grid building is @Macrura's Inputfield Selectize: https://processwire.com/talk/topic/13549-selectizejs-modules-family/ 

Another idea – which also needs additional coding – but could be a working solution is to use @gebeer's new module FieldtypeImage Picker which is currently being polished: https://processwire.com/talk/topic/22665-module-fieldtypeimagepicker-pick-images-from-a-folder/

And for the grid part you could implement a grid builder with something like this: https://gridstackjs.com/

FieldtypeImage Picker could be used for setting the image, and the event of that selection could notify gridstack.js which could then set the content of corresponding the grid cell accordingly. As for uploading images on the fly, I have no idea about the possibilities, but if you can use ajax request in the correct order, then it might be possible to wire it all up.

If a PW image inputfield is set to replace images with an already uploaded image having the same file name, then PW uploads and assigns the image to that page without the need to click the Save button, therefore images uploaded to the very same page could be made available right after being uploaded, provided FieldtypeImage Picker "be refreshed". You could consult Gebeer for such a possibility...

Again, I am just brainstorming here.

 

 

Edited by szabesz
typo
  • Like 4

Share this post


Link to post
Share on other sites
On 12/8/2019 at 12:18 PM, szabesz said:

Hi @benbyf

Just ideas, I hope this helps:

As far as I know, the closest module which at least partially could be used for such grid building is @Macrura's Inputfield Selectize: https://processwire.com/talk/topic/13549-selectizejs-modules-family/ 

Another idea – which also needs additional coding – but could be a working solution is to use @gebeer's new module FieldtypeImage Picker which is currently being polished: https://processwire.com/talk/topic/22665-module-fieldtypeimagepicker-pick-images-from-a-folder/

And for the grid part you could implement a grid builder with something like this: https://gridstackjs.com/

FieldtypeImage Picker could be used for setting the image, and the event of that selection could notify gridstack.js which could then set the content of corresponding the grid cell accordingly. As for uploading images on the fly, I have no idea about the possibilities, but if you can use ajax request in the correct order, then it might be possible to wire it all up.

If a PW image inputfield is set to replace images with an already uploaded image having the same file name, then PW uploads and assigns the image to that page without the need to click the Save button, therefore images uploaded to the very same page could be made available right after being uploaded, provided FieldtypeImage Picker "be refreshed". You could consult Gebeer for such a possibility...

Again, I am just brainstorming here.

 

 

Thanks! Hugely usefull! Think my main issue is the grid editing element so I might implement most of the site and leave the editable image/link section till last and maybe look at building something. I would like it to mirror the frontend as much as possible, so i could just use css grid and do some limited js stuff pushing the page id's, item number and span columns and rows into the database..... mmmmmmmmmmmmm

  • Like 1

Share this post


Link to post
Share on other sites

Tried to create a module for this and got into a hole of SQL schema and module doc spagetti so gave up.

Instead I bought Pro fields: Tables as it looked like it was almost there and hacked some javascript and css ontop to get this. I'm going to use the row and column data in the frontend to assign my grid so they should be the same.

  • Like 2

Share this post


Link to post
Share on other sites

Also as an aside... does anyone esle think the functionality in Pro fields: Table should be in core?? Seems too useful or basic requirement.

Share this post


Link to post
Share on other sites
44 minutes ago, benbyf said:

does anyone esle think the functionality in Pro fields: Table should be in core?? Seems too useful or basic requirement.

It's hard to tell. PageTable is in the core and does not get any attention so it's been in its initial state ever since its introduction. Table received some extra features during the years and Ryan has plans to improve it.

Share this post


Link to post
Share on other sites
40 minutes ago, benbyf said:

does anyone esle think the functionality in Pro fields: Table should be in core?? Seems too useful or basic requirement.

I am totally fine with paying money for that extra functionality. PW has so many great features already in the core. And I am happy to support Ryan with a ProFields subscription. Looking at how many great tools you get in that bundle, the price is more than fair.

  • Like 1

Share this post


Link to post
Share on other sites
50 minutes ago, benbyf said:

and hacked some javascript and css ontop to get this

This looks really useful. Might still be a bit cumbersome for editors with all those start end rows columns. But nice how you made changes reflect instantly in the preview. Mind to share the code? 🙂

What do you need the row settings for, Couldn't you act on drag&drop of the rows themselves inside the table field?

  • Like 1

Share this post


Link to post
Share on other sites
22 hours ago, gebeer said:

This looks really useful. Might still be a bit cumbersome for editors with all those start end rows columns. But nice how you made changes reflect instantly in the preview. Mind to share the code? 🙂

What do you need the row settings for, Couldn't you act on drag&drop of the rows themselves inside the table field?

Want to save the col and row info in the db so i can use it for css grid in the frontend. This will allow the client to add content that spans the first row, has two on the send that goes across half the grid, has 4 on the third row and has 2 with a gap in the middle on the fourth.... basically given them power to making interesting layout with whitespace.

Ideally your right I would have the grid power the input of the PW fields and hide the col and row inputs but this is what i have so far.

 

admin.php

$config->scripts->add($config->urls->templates . "admin.js");
$config->styles->add($config->urls->templates . "admin.css");

admin.cs

.table-grid{
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
}
.grid-item{
    /* border: 1px solid £; */
    padding: 0.5em;
}
.activeGridName{
    background: rgb(197, 219, 226) !important;
}

admin.js

$(function(){
    
    // custom grid script for pages with applicable table
    // name of input field
    var inputFieldName = "#wrap_Inputfield_featured_grid";

    if($(inputFieldName)){ // table found
        
        var table = "<br><div class='table-grid-container'><label class='uk-form-label'>Frontend representation</label><div class='table-grid Inputfield'>";

        // setup table
        var rows = $(inputFieldName+" .InputfieldContent table tbody tr"); // UI has 1 hidden row
        for (var i = 1; i < rows.length; i++) {
            
            var director = $(rows).eq(i).find(".InputfieldPageAutocomplete input.ui-autocomplete-input");
            var tds = $(rows).eq(i).find("td");
            var colStart = $(tds).eq(2).find('input');
            var colStartValue = $(colStart).attr("value");
            var rowStart = $(tds).eq(3).find('input');
            var rowStartValue = $(rowStart).attr("value");
            var colEnd = $(tds).eq(4).find('input');
            var colEndValue = $(colEnd).attr("value");
            var rowEnd = $(tds).eq(5).find('input');
            var rowEndValue = $(rowEnd).attr("value");

            var name = $(director).attr("value");

            $(colStart).addClass('table-value-input')
                        .attr('data-table-type','colStart')
                        .attr('data-name-data',name);
            $(rowStart).addClass('table-value-input')
                        .attr('data-table-type','rowStart')
                        .attr('data-name-data',name);
            $(colEnd).addClass('table-value-input')
                        .attr('data-table-type','colEnd')
                        .attr('data-name-data',name)
            $(rowEnd).addClass('table-value-input')
                        .attr('data-table-type','rowEnd')
                        .attr('data-name-data',name)

            $(rows).eq(i).attr("data-name",name);
            // console.log(colStart + " - " + rowStart + " - " + colEnd + " - " + rowEnd);
            
            var styles = "grid-row-start: "+rowStartValue+"; grid-column-start: "+colStartValue+"; grid-row-end: "+rowEndValue+"; grid-column-end: "+colEndValue+";";
            table += "<div class='grid-item Inputfield' style='"+styles+"' data-name='"+name+"'>"+name+"</div>";
        }

        table += "</div></div>";
        
        // add table to UI
        $(inputFieldName+" .InputfieldContent").append(table)


        // value changes and event listening
        $(document).on("change", "input.table-value-input", function(){
            var name = $(this).attr("data-name-data");
            var data = $(this).attr("value");
            var type = $(this).attr('data-table-type');
            console.log(data);
            console.log(type);
            console.log(name);
            
            switch (type) {
                case "colStart":
                    $(".grid-item[data-name='"+name+"']").css("grid-column-start", data);
                    break;
                case "rowStart":
                    $(".grid-item[data-name='"+name+"']").css("grid-row-start", data);
                    break;
                case "colEnd":
                    $(".grid-item[data-name='"+name+"']").css("grid-column-end", data);
                    break;
                case "rowEnd":
                    $(".grid-item[data-name='"+name+"']").css("grid-row-end", data);
                    break;
                default:
                    break;
            }
        });
        $(document).on("mouseover", "[data-name]", function(){
            var data = $(this).attr("data-name");
            $("[data-name='"+data+"']").addClass("activeGridName");
        });
        $(document).on("mouseout", "[data-name]", function(){
            var data = $(this).attr("data-name");
            $("[data-name='"+data+"']").removeClass("activeGridName");
        });
    }

});

Main problem at the moment is it isn't very portable–you have to know the field name for it to work.

  • Like 2

Share this post


Link to post
Share on other sites

@benbyf Thanks a lot for sharing!

6 minutes ago, benbyf said:

This will allow the client to add content that spans the first row, has two on the send that goes across half the grid

That makes sense.

8 minutes ago, benbyf said:

Ideally your right I would have the grid power the input of the PW fields and hide the col and row inputs

This should be possible with gridstack.js, as suggested by @szabesz

8 minutes ago, benbyf said:

Main problem at the moment is it isn't very portable–you have to know the field name for it to work

If someone wanted to wrap this into a portable inputfield module, they could create an module which extend InputfieldTable class and add the logic there. 🙂

 

  • Like 1

Share this post


Link to post
Share on other sites
1 minute ago, gebeer said:

If someone wanted to wrap this into a portable inputfield module, they could create an module which extend InputfieldTable class and add the logic there. 🙂

this would be ace. if I had more time I would look into it, but sort of scares me. 😕

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...