Jump to content

Module: Matrix Fieldtype & Inputfield


kongondo

Recommended Posts

Some more thoughts on this - I wonder if maybe it's just best to turn on output formatting - that should handle getting the language for the current user.

On an unrelated note, I noticed that each entry in the matrix is a full PageArray - is this necessary? I haven't looked into/thought through this, but it seems like a lot of info to have in memory when all we need is a single value with its relevant row and column page ids. Maybe the full PageArray is needed, or maybe it doesn't matter - just thought I'd ask :)

Link to comment
Share on other sites

Hi Adrian. Glad you found a solution.

10 hours ago, adrian said:

Not sure if you want to implement just like this, or whether you think it's worth adding a more complete ML solution.

I haven't looked at this module in a while. I will have a think.

10 hours ago, adrian said:

PS - what about changing "Row Label" to the title of the parent page of the first column. In my case I have a page branch of Years to control this column. It would be much nicer if this read "Years" or "Year". Would that work, or are there more things to consider?

Ditto :).

Link to comment
Share on other sites

7 hours ago, adrian said:

On an unrelated note, I noticed that each entry in the matrix is a full PageArray - is this necessary?

That's strange. Where did you see that? The module does not return Page or PageArrays anywhere . A single entry is a Matrix object (a WireData) and groups of entries are MatrixArray objects (WireArray). Maybe I haven't looked at this in a while but I am pretty sure about this :).

Link to comment
Share on other sites

Hey @kongondo - note the Page within each Matrix item. Each one of these contains a full reference to the current page. This comes from dumping $page->matrix_field

58de67f336206_ScreenShot2017-03-31at7_29_43AM.png.3bebfb53ba4d61ab004d09a691779876.png

 

Here is the dump of $rows and $columns from the export function. You can see that each row is a full PW page object.

58de6dbbe8f1d_ScreenShot2017-03-31at7_53_28AM.png.463af2d8871a92b23da4f19b82c30be3.png

Is this expected?

Link to comment
Share on other sites

@adrian,

Aah, my bad. The culprit is where I grab the respective row and column pages in order to get the friendly rowLabel and columnLabel respectively. Would uncacheAll do the trick (to clear memory)? If not I could get titles using raw SQL...

Thanks for catching this.

Link to comment
Share on other sites

  • 2 weeks later...

Hey @kongondo - me again :)

I have another issue for you - I recently deleted a page that was driving the matrix rows (ie in the "data" field in the DB), but it didn't remove that row from the matrix table. Maybe this in intentional to prevent potential data loss, but it seems like there is no way of removing these without a manual SQL query to delete the appropriate entries from the DB. I am away from my computer the next couple of days and don't have time to test further right now, but please let me know if you have any trouble reproducing and I'll run some more tests.

Link to comment
Share on other sites

  • 1 month later...

I'm trying to keep 'scores' for users on certain pages.  So far Matrix seems to do the job, as I can type a score for every user and for different assignments. 

What I'm trying to do now is to enter scores using the API, so *not* using the admin pages. 

If I understand things right, Matrix is simular to (or an instance of?) WireArray, so I should use $matrix->add(sth)?  I just can't find my way through. 

Does anyone have an example code snippet for entering values to a Matrix using the API?  It would help me a lot. 

 

edit: Of course I can always enter the data directly into the database, but I'd rather use the power of PW if possible. 

Link to comment
Share on other sites

  • 3 weeks later...
On 2017-4-9 at 10:41 PM, adrian said:

I have another issue for you - I recently deleted a page that was driving the matrix rows (ie in the "data" field in the DB), but it didn't remove that row from the matrix table.

Thanks Adrian, I'll have a look.

On 2017-5-16 at 9:35 AM, longtom said:

Does anyone have an example code snippet for entering values to a Matrix using the API? 

Sorry for the late reply Longtom.  Here's a code snippet:

 

Link to comment
Share on other sites

  • 5 months later...
  • 1 month later...

Hello @Kongodo and thanks for this module,

I am always in a hurry, and probably that is the reason why I still can't find right solution how to use this field.
Please can somebody write short instruction how to get this on attached image using this field?

Thanks.

 

opening-time.png

Link to comment
Share on other sites

12 hours ago, OLSA said:

Please can somebody write short instruction how to get this on attached image using this field?

The very, admittedly limited, docs are here.

Your days of the week are Matrix Rows. Your Open and Close are Matrix Columns. I suggest you create a parent page for both. So A Days of the Week page whose children are the Days themselves and something similar for Open and Close. Then use method 1 or 2 as described in the docs to populate your rows and columns. Alternatively, see method 3 which allows you to use multi pagefields.

  • Like 1
Link to comment
Share on other sites

  • 1 month later...
2 hours ago, Juergen said:

Hello @kongondo

only a question: is it possible to use a special field of a page for the field of the matrix (fe a date field, an integer field,..)?

For storage, no, for reference, yes. Matrix stores a page ID for Row, a page ID for Column and a varchar for the value of the matrix (i.e. row-column = value). Using the page IDs of Row and Column, you can use PW API to get the page and hence, any field on that page.

Maybe not what you are after but thought to clarify anyway.

  • Thanks 1
Link to comment
Share on other sites

Hello @kongondo,

I have discovered a strange behavior:

I use a pagetable field inside a parent page. If click on the link inside the pagetable to open a child page inside a modal, I will be logged out from the system if the child page has a matrix field inside.

I have traced down the problem and it has to do with a hook that I run on the pagetable field of the parent page (inside my ready.php):

$wire->addHookBefore('InputfieldPageTable::render', function($event) {
   if($this->process != 'ProcessPageEdit') return;
   $table = $event->object;
   $page = $this->process->getPage();
   // event table   
   if(in_array($table->name, ['datespagetable', 'specialbusinesshourstable', 'eventspagetable', 'businessvacationpagetable'])) {
       if(count($page->children) == 0){          
           $table->notes = "";
            $this->buttonHook = $this->addHookAfter("InputfieldButton::render", null, function(HookEvent $event){
                $event->return = __("Here all dates will be shown afterwards if some were created.");
            });
      } 
      //this part of the button hook is responsible for loggin me out if I click on the link to the page inside the pagetable 
      else {
      $this->addHookBefore("InputfieldButton::render", null, function(HookEvent $event){      
         $button = $event->object;
         if($button->name == 'button'){
          $button->attr('value', __('Add event'));
         }
      });
} 
}
}); 

Inside this hook there is another hook for rendering the "Add new" button. So this "InputfieldButton::render" hook is responsible for loggin me out (if I remove this part everthing is fine).

So its not a big problem for me (I have comment it out), but maybe you have an idea, why these lines of code could lead to this behavior in combination with the matrix field.

Best regards

 

Link to comment
Share on other sites

19 hours ago, Juergen said:

but maybe you have an idea, why these lines of code could lead to this behavior in combination with the matrix field.

I'm totally clueless about this :lol:. I'll have to investigate, but it might not be soon, I'm afraid. I need to finish  work on some other module first, before I can turn my attention to Matrix.

Thanks for reporting.

Link to comment
Share on other sites

  • 11 months later...

@kongondo Thank you very much for this module. Very useful in a simple shop scenario that I'm building with PW 3.0.125 on PHP 7.2.

When I try to dump a Matrix field on a page with bd($p->variationmatrix) I get an error:
Exception: Class 'MatrixArray' doesn't yet implement method 'makeBlankItem()' and it needs to. on line: 190 in /var/www/hugoerke.local/wire/core/WireArray.php

Just looping over $p->variationmatrix does not throw the exception.

As a quick fix, I added the amended original method from WireArray to the MatrixArray Class like this
 

	public function makeBlankItem() {
		$class = wireClassName($this, false); 
		if($class != 'MatrixArray' && $class != 'PaginatedArray') {
			throw new WireException("Class '$class' doesn't yet implement method 'makeBlankItem()' and it needs to.");
		}
		return null;
	}

No more exception now. But still wondering why this happened, maybe something in the core changed that requires every WireArray derived class to redefine this method?

Link to comment
Share on other sites

On 2/14/2019 at 10:13 AM, gebeer said:

Thank you very much for this module

@gebeer, glad it's been of help :-).

On 2/14/2019 at 10:13 AM, gebeer said:

But still wondering why this happened, maybe something in the core changed that requires every WireArray derived class to redefine this method?

I can't remember when this was introduced, but yeah, it's now a requirement. I'll add the method though. Thanks!

On 2/14/2019 at 10:13 AM, gebeer said:

As a quick fix, I added the amended original method from WireArray to the MatrixArray Class like this

Use this instead:

/**
 * Per the WireArray interface, return a blank Matrix
 *
 * @return WireData $matrix A blank Matrix.
 *
 */
public function makeBlankItem() {
    $matrix = new Matrix();
    return $matrix;
}

 

  • Like 1
Link to comment
Share on other sites

  • 3 months later...

Thanks again for this great module. I enjoy working with it.

Found a small bug, though.

The MatrixArray->getValue() method retrieves the value from a matrix field on wire('page').

So it tries to get the matrix field of the page the code is executed on. This isn't always the page we want to process and where the matrix field actually lives on.

I changed MatrixArray.php, line 157 to

$value = $this->page->$n->get("$rowSel, $colSel");
// instaed of $value = wire('page')->$n->get("$rowSel, $colSel");

Now it is working fine.

  • Like 1
Link to comment
Share on other sites

  • 8 months later...

Hi there.

I'm trying to work out if this module will suit a site I am working on, but I'm not sure how to add items via API. I saw your code snippet, but is there a way to modify individual elements rather than adding to them? What I mean is something like

$row = 1024;
$column = 2048;

$value = "hello, matrix!";

$matrix = $page->matrix_field;
$matrix->set($row, $column, $value);

or similar?

The dynamic nature of the row/column generation is perfect for my use case, but I will be needing to modify "cells" from the front end and not sure if this is how this module is designed to work or if I am just missing something obvious.

Thanks!

Link to comment
Share on other sites

Hi again.

Further to my last question, how do I use the class in the front end? I tried to copy the snippet with $matrix = new Matrix(); but it couldn't find the class. I tried to add the Matrix.php as a require_once line but now I get an error stating WireData cannot be found, so I assumed I need to instantiate the module some other way. I then tried to use the $modules->get method to load the module and changed new Matrix() to new \Matrix(). This seemed to load the Matrix class now, but it now complains with the following error:

Class 'MatrixArray' doesn't yet implement method 'makeBlankItem()' and it needs to.

I don't get this error when using the module in the back-end so I assume there is something else obvious I am missing.

Link to comment
Share on other sites

  • 2 months later...
  • 6 months later...
On 11/21/2020 at 9:56 PM, Aleksey Popov said:

But I need to sort it like in the admin tree or by titles, for example. Is it possible?

Sorry for the late reply @Aleksey Popov,

If you mean sort the displayed table on the fly, then that's not possible currently. If you mean one off sort for the field in respect to how it retrieves pages for building the rows of the matrix, then you do this in the field's settings. See the details tab when editing the field. For instance, if using a selector, you would do it as shown below:

matrix_field_sort.thumb.png.6b2f5c25338f3b6d8cb790cdb3280298.png

I hope this answers your question. If not, please let me know.

Link to comment
Share on other sites

2 hours ago, kongondo said:

Sorry for the late reply @Aleksey Popov,

If you mean sort the displayed table on the fly, then that's not possible currently. If you mean one off sort for the field in respect to how it retrieves pages for building the rows of the matrix, then you do this in the field's settings. See the details tab when editing the field. For instance, if using a selector, you would do it as shown below:

I hope this answers your question. If not, please let me know.

Thanks a lot! I tried to do this, but using the table, as in the instructions, it did not work, I will experiment a little later. But for myself, I made a solution (simplified here) like this that works:
 

<? php
$output .= "";
$items = priceTable(pages()->find("template=page-lang, sort=sort")
foreach ($items as $item) {
  $matrixRow = $matrix->find("row={$item->id}");
  $output .="<div class='row py-1 border-bottom font-xs-sm'>";
  $output .= "
    <div class='col-4 language'>
      <a class='link text-danger' href='{$item->url}'>{$item->title}</a>
    </div>";
  foreach ($matrix->find("row=$item") as $value) {
    $output .= "<div class='col price text-right'><strong>$value->value</strong><small class='d-none d-md-inline'></small></div>";
  }
  $output .= "</div>";
}
return $output;

image.png.a6b7740c9ba05f98f1991bb40e7644e3.png

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
×
×
  • Create New...