Jump to content

Need guidance for UI modules, sortable data


Recommended Posts

Hi all,

I have a database table of about 150 items and growing.  For each item there are about 20 data points, so the table has 150 rows and 20 columns.  The data in the columns is just a digit from 0 to 9.  The "item" name column is just a text field, linked to a URL.

I need help with two different UI's:

On the visitor side, I need them to be able to select a few (say 4 or 5) data points (columns) that are most relevant to their search, so the the table will be re-ordered to display the items that have the highest total numerical value (selected data columns added up) at the top.

On the back end, I need a simple data-entry panel for adding new items.  One field for the name, 20 labeled fields for their respective data points.  Of course it should automatically populate the publicly-visible page.

So, can you recommend any particular modules or other products or approaches to these needs?

I already have PWire installed with no hassle, but I have not gotten much further than that yet.


Link to comment
Share on other sites

In PW the best way is to think of each repetition of data as an individual page. The best approach in your case would be to create a page "table" and have the rows as children pages of that one. those pages would have their own template "row" (names are just as example) wish would hold all the fields that correspond to your columns. Everytime you want a new row on the table you just have to create a new page as child of the "table" page.

To convert these pages to table rows in the frontend is as easy as this:

foreach($pages->get("/table/")->children as $row){
    echo "<tr><td>{$row->field1}</td><td>{$row->field2}</td><td>{$row->field3}</td><td>{$row->field4}</td></tr>";

This is only one part of the answer, but I have to go now... hope it gives you some light.

  • Like 1
Link to comment
Share on other sites

Greetings bongomania,

One of the things that makes ProcessWire so amazing is how easy it is to link data at all levels with your styling/output concepts.

As diogo shows, displaying your results in a table is easy.

And you can get really fancy without too much more effort.  I'm working on a project now where the client wants to be able to sort various fields of data, and I am using the JQuery DataTables plugin: http://www.datatables.net/index

With this plugin, you can "foreach" through your pages as table rows, and then loop through fields in each page as table data, and make them sortable and styled beautifully.

Starting from there, and the possibilities grow and grow...



  • Like 1
Link to comment
Share on other sites

You don't need to install jQuery in pw, you use it as any other script. Drop the file in the scripts folder and link to it from the html head. (The default install already comes with the file jquery-1.4.2.min.js, but you might want to download another version). Or simply link to a jQuey CDN on the web (http://code.jquery.com/ or https://developers.google.com/speed/libraries/devguide#jquery).

Anyway, by using Mathew's solution, you have to be aware that you will have to list all the rows from the table, and hide them with javascript to paginate (I see that it also does server side, but didn't went deep on investigating). This means that processwire will have to pull all the results, wish might be a waste of memory. Best solution would be to render the table with a limited amount of results depending on the user choice. For this you will need the pagination module http://processwire.com/api/modules/markup-pager-nav/

Link to comment
Share on other sites

Greetings Everyone,

I am building a site for a public television station using ProcessWire, and I am making use of JQuery datatables to allow admins to display and sort show listings.

NOTE: The site is in its very early stages at the moment, but I wanted to at least show how I'm using databales with ProcessWire.  It's pretty incredible how much you can do combining ProcessWire with DataTables!

To see a page in progress, with 533 listings, look here:



  • Like 1
Link to comment
Share on other sites

To see a page in progress, with 533 listings, look here:
Very nice! But it took a long time to load here. Not sure if that's because of the connection that IP is going through, or if it's the result of loading and rendering data for 533 pages (?) in one request. But if you are loading that many pages in one request, it's good to keep in mind that you can only scale so far using that method. Eventually, you'll fill up memory if that table keeps growing. If it's not going to keep growing, then you may want to at least cache it with MarkupCache. Usually if I'm rendering something that's reusable and has 50+ pages loading as a result, I use MarkupCache to cache the output. 
  • Like 1
Link to comment
Share on other sites


Thanks Ryan...

Yes, at the moment I am simply showing what's possible, so the table loads all 533 pages and all 58 fields at once! This is NOT the way it will work when the site launches. However, it's a good test in a way because it's loading all of that data -- and on a shared server. ProcessWire performs well!

For the real site, only maybe 10 fields will be included in the table, and I am planning to have the user choose pre-filters before the table renders.

I really like using DataTables with ProcessWire. In fact, the two are similar in their attention to detail and clean code. With a little creativity, DataTables can be part of a custom ProcessWire interface for clients. More on that later!



  • Like 1
Link to comment
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.
  • Similar Content

    • By jom
      Chäs & Co is a b2b cheese trader. They love good cheese and are proud of their excellent knowledge und connections to small cheese producers. They maintain a custom made database and used to copy/paste (!) the cheese infos to the former CMS (Contao). Since substituting the database with ProcessWire was no option, they export now the database to a csv file and import it to the new website (expanded version of module ImportPagesCSV).
      From there, the pw magic begins. The staff works with the admin interface: They search and find products in notime using the build-in search field (using cheese names or id. Using ids only possible by adding hook, see this forum thread). They generate price lists easily based on a template, providing checkboxes and option buttons for some restrictions, choose i.e. the cheese origin and price audience (all implemented as page selectors). By saving the page a PDF list gets generated (using mpdf, a php pdf library).
      The visitors can sort and filter the products using a form by shuffle.js. Product details are shown in a popup (fancybox). There's also the option for generating a nice pdf data sheet. No CSS framework being used.
      Other modules used: ProcessJumpLinks, ProcessProMailer, ProcessWireUpgrade.
      Visual design: Nicole Haller

    • By Juergen
      Hello @ all,
      I am creating a new inputfield/fieldtype to store opening hours, but I am struggeling to save values from multiple dynamic created inputfields in 1 column of the database.
      The user can enter one or more opening times per day in a UI.
      Monday open from 08:00 to 12:00 and from 14:00 to 17:00 Tuesday open from 08:00 to 12:00 and from 14:00 to 19:00 and so on
      Via a little JavaScript you can add as much opening times as you need per day - the additional inputfield will be created dynamically.
      After form submission all the values are in the POST array -> this works (see example below):
      ProcessWire\WireInputData Object ( [openinghours_mo-0-start] => 09:00 [openinghours_mo-0-finish] => 13:00 [openinghours_mo-1-start] => 14:00 [openinghours_mo-1-finish] => 18:00 [openinghours_mo-2-start] => 21:00 [openinghours_mo-2-finish] => 23:00 [openinghours_tu-0-start] => 09:00 [openinghours_tu-0-finish] => 13:00 [openinghours_tu-1-start] => 14:00 [openinghours_tu-1-finish] => 18:00 [openinghours_we-0-start] => 09:00 [openinghours_we-0-finish] => 13:00 [openinghours_we-1-start] => 14:00 [openinghours_we-1-finish] => 18:00 [openinghours_th-0-start] => 09:00 [openinghours_th-0-finish] => 13:00 [openinghours_th-1-start] => 14:00 [openinghours_th-1-finish] => 18:00 [openinghours_fr-0-start] => 09:00 [openinghours_fr-0-finish] => 13:00 [openinghours_fr-1-start] => 14:00 [openinghours_fr-1-finish] => 18:00 [openinghours_sa-0-start] => [openinghours_sa-0-finish] => [openinghours_so-0-start] => [openinghours_so-0-finish] => ) The property name is always the name attribute of the field 😉 . If the property is empty means closed on that day.
      Now I need to combine all those values into 1 array (or json array) and store it in the database in 1 column called 'hours' in my case (see screenshot below):

      In my ___processInput(WireInputData $input) method I have tried to make it work like this:
      public function ___processInput(WireInputData $input): self { $name = $this->attr('name'); $value = $this->attr('value'); //input object includes always every input on the page, so lets filter out only inputs from this field //we need to do this, because the number of values is variable - so extract only values that starts with $name.'_' $nameAttributes = []; foreach($input as $key=>$value){ if(substr($key, 0, strlen($name.'_')) === $name.'_'){ $nameAttributes[$key] = $value; } } // loop through all inputfields of this fieldtype $time_values = []; foreach($nameAttributes as $nameAttr => $value) { $time_values[$nameAttr] = $value; } } //save it in the database $input->set('hours', serialize($time_values)); return $this; } The only important part of this code is the last part with the serialize function.
      After saving it will create a record in the database, but the value is always NULL (default value) (see below).

      Checking $time_values returns all the values, but printing out "$this" shows me that the property "hours" inside the Openinghours object is empty (see below) - so the mistake must be there, but I dont know where?!?!?!?
      [title] => Home [openinghours] => ProcessWire\OpeningHours Object ( [data] => Array ( [hours] => ) ) If I check the sleepValue() method or the sanitizeValue() - they are also empty. So it seems that the values will not reach these methods. I havent found a clear documentation of whats going on behind the saving process of an inputfield.
      As far as I know the saving process starts with the form submission. The values are in the POST array and will be processed by the processInput() method. Before they will be saved in the database they will be sanitized by the sanitizeValue() mehtod and afterwards they will be prepared for storage in the sleepValue() method.  The last step is the storage itself.
      Has someone an idea what is missing by storing values from multiple fields into 1 database column or has someone a working example of such a scenario on github to help me out.
      A clear explanation of the storage process will be also helpful.
      Thanks and best regards
    • By Pip
      Hi Everyone 
      I've been working on Processwire for two months now. Structuring the website as needed. Unsure why but I'm getting this one now. Seems my fields has crashed. 
      I've tried googling some answers but can't seem to find a step by step guide on how to rectify this. Any advise? Practically new on this. 

    • By Rodd
      Hi everyone!
      I have a website in a production environment and I want to duplicate it in a local environment. I exported the content of the website (with the 'Site Profile Exporter' module) but I cannot use it actually. I've got an issue with the database. I imported this one in MAMP then.

      I also exported the pages (with the 'ProcessPagesExportImport' module), but I cannot import it to my local website because the fields don't exist. So I created this fields, but I have this error :
      How can I use the elements that already exist and are presents in my database? How can I duplicate correctly the templates, fields and pages?
      Thanks by advance
      PS: Sorry if my english is bad
    • By ngrmm
      I have a page with a table. Each table row has a page-reference field and a checkbox.
      The Page sends emails to all users (page-refrence->email-field) and change the value of the checkbox in a row to 1.
      It works with this:
      <?php // event ID fron url query $eventID = $input->get('eventID','int'); // get event-page $event = $pages->get($eventID); // config $fromEmail = $event->event_mail_from; $fromName = $event->event_mail_from_name; $emailSubject = $event->event_subject; // email html body ob_start(); include('./_inc/emailbody.inc'); $emailBody = ob_get_clean(); // make event-page editable $event->of(false); // loop through table and send out emails foreach($event->event_clients_list as $event_table_row) { // get client page $clientPage = $event_table_row->client_name; // get client email $clientEmail = $clientPage->email; // if client isn't invited yet (checkbox not checked) if($event_table_row->client_invited == '') { // send email $m = new WireMail(); $m->to($clientEmail); $m->from($fromEmail, $fromName); $m->subject($emailSubject); $m->bodyHTML($emailBody); $m->send(); // mark client as invited $event_table_row->client_invited = 1; $event->save('event_clients_list'); } } ?> But i have to use a variable in my emailbody.inc which i'm able to get in the table-loop.
      So i do the including of the body inside my loop. But this doesn't work anymore. Page sends out the emails but is unable to change the value of the checkbox.
      I get no errors!
      I'm using ProTable
      <?php // event ID fron url query $eventID = $input->get('eventID','int'); // get event-page $event = $pages->get($eventID); // config $fromEmail = $event->event_mail_from; $fromName = $event->event_mail_from_name; $emailSubject = $event->event_subject; // loop through table and send out emails foreach($event->event_clients_list as $event_table_row) { // get client page $clientPage = $event_table_row->client_name; // get client email $clientEmail = $clientPage->email; // email html body ob_start(); include('./_inc/emailbody.inc'); $emailBody = ob_get_clean(); // make event-page editable $event->of(false); // if client isn't invited yet (checkbox not checked) if($event_table_row->client_invited == '') { // send email $m = new WireMail(); $m->to($clientEmail); $m->from($fromEmail, $fromName); $m->subject($emailSubject); $m->bodyHTML($emailBody); $m->send(); // mark client as invited $event_table_row->client_invited = 1; $event->save('event_clients_list'); } } ?>  
  • Create New...