Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mass Actions #56

Closed
imonteiro opened this issue Jan 13, 2014 · 13 comments
Closed

Mass Actions #56

imonteiro opened this issue Jan 13, 2014 · 13 comments

Comments

@imonteiro
Copy link
Contributor

It's possible provide the possibility to perfom some action on multiple rows, by adding an extra column with a checkbox and passing the primary key throw POST.

Example:

$action1 = array('url' => '/action1', 'caption' => 'Some action');
$action2 = array('url' => '/action2', 'caption' => 'Another action');
$actions = array($action1, $action2);
$grid->setMassActions($actions )

//OR
$grid->addMassAction($action1);
$grid->addMassAction($action2);
@ThaDafinser
Copy link
Owner

Currently this is not supported from the grid itself.

But you can achieve it yourself.
Add https://github.com/ThaDafinser/ZfcDatagrid/blob/master/src/ZfcDatagrid/Column/Action/Checkbox.php

And then over javascript and toolbar buttons.....

Sometime i hopefully get this done....maybe you can take a look on it :-)

@imonteiro
Copy link
Contributor Author

Thanks.

I'm starting re-factor my application using ZF2 and your module to display my data on tables.

At the moment I'm trying understanding your module. I will try contribute as possible :-)

@imonteiro
Copy link
Contributor Author

@ThaDafinser I will try implement Mass Actions on ZfcDatagrid, but first I want discuss some ideas. about how to achieve this.

  • Create Mass/Action.php class where will be defined the massAction object (uniqueName, url, confirmation message, etc.)
  • On Datagrid.php class implement all main code (addMassAction, getMassActions, hasMassActions, etc.)
  • Auto add checkbox column
  • On each render (bootstrapTable and jqGrid) print the JS Code [which get the checked rows and POST to the action defined], if mass actions is enabled

The user just need set in toolbar or view the code to call (link/button, combobox, etc.) a generic JS function (which was printed by render). The action will be identified by the unique name of each action, which must be the same of html element name/id.

What do you think?

@ThaDafinser
Copy link
Owner

@imonteiro good to hear.

here some thoughts from my side:
Reuse Column\Action for this purpose. You can normally add Actions to the column like today, with the only difference that you tell Column\Action over a method, that it's a "mass" action.

So you can use e.g. a delete action for row and mass action!
The only difference is that for mass the checkbox is shown and the action at top or elsewhere.

Example:

use ZfcDatagrid\Column;

$delete= new Column\Action\Button();
$delete->setLabel('Delete');
//....and so on

//here is the checkbox action column
$col = new Column\Action();
$col->setLabel(' ');
$col->setUniqueId('actionMass');
$col->setIsMassAction(true); // <-- this is the only difference
$col->addAction($delete);
$grid->addColumn($col);

//...actual selected data columns

//the default row action (like today)
$col = new Column\Action();
$col->setLabel('Actions');
$col->addAction($delete);
$grid->addColumn($col);

At server side you can than check if one or more are submitted, over the same action?

For the rest i have to think again....but how does this example look for you? Good/bad?

@imonteiro
Copy link
Contributor Author

@ThaDafinser Looks good, with this approach the user can define all Column\Action properties.
Just FYI, I'm also using Column\Action to automate the checkbox creation if Mass Actions is enabled:

on public function prepareViewModel()

if($grid->hasMassActions()) {
   $action = new Column\Action\Checkbox();
   $action->setAttribute('onclick', 'massActionCheckBox(this)');

   $col = new Column\Action('checkboxes');
   $col->addAction($action);
   $grid->addColumn($col);
} 

Continuing...

But, in your example ZfcDatagrid must throw Exception if more than one Column\Action is setted as massAction? (possible issues with checked uncked propriety)

The second part... ZfcDatagrid, in this example I will consider bootstrapTable render, will print the JS code when mass action was enabled, to process the checked boxes and fill the hidden form element with postMassIds. For this, we need something like:

$massAction = new Mass\Action('uniqueName');
$massAction->setUrl('/action1');
$massAction->setConfirm('Proceed?');

$grid->addMassAction($massAction);

and this JS code (isn't tested):

function massAction($action)
{
    if (postMassIds_.length == 0 || postMassIds_[0] == '')
    {
        alert('<?php $this->translate('No rows selected!'); ?>');
        return false;
    }

// TODO: show message, if enabled


    document.getElementById('postMassIds').value = postMassIds_
            .join(',');

// TODO: POST to action1 url

}

function massActionCheckBox(box)
{
    if(box.checked == true)
    {
        if(postMassIds_[box.value] != 'undefined')
        {
            postMassIds_.push(box.value);
        }
        rowsSelected_++;
    }else{
        if(postMassIds_[box.value] != 'undefined')
        {
            for(var i=0; i< postMassIds_.length;i++ )
            {
               if( postMassIds_[i]==box.value)
                    postMassIds_.splice(i,1);
             }
            rowsSelected_--;
        }
    }
    // massActionUpdateSelected();
}

finally the user, can put whatever he wants something like:

<input type="submit" name="action1" id="action1" value="Action 1"  onClick="massAction($this)"/>

What do you think? Is a good way?

@ThaDafinser
Copy link
Owner

@imonteiro much input / things to think about. i'll try to give you some feedback tomorrow, so this feature can finally get in 😄

@ThaDafinser
Copy link
Owner

@imonteiro haven't forget u...sry for the delay. 🍦

Good things:

  • if at least one mass actions is available -> auto add checkbox on the left
    • instead of a label/title at the header a checkbox to select/deselect all

Unsure:

  • provide only "basic" implementation or make it like the row actions...
  • using the current row actions is not that easy, since they are coupled with row specific things
    • the html rendering with row data
    • refactor needed
  • create "advanced" mass actions like for row actions

"basic" implementation like you suggested:

  • url with parameter
  • title
  • ...maybe confirm and others

*** What basic means ***
Because the actions are not integrated in the grid itself (like the row actions or the mass action related checkboxes) the rendering happens in the toolbar on top or bottom.

So maye it's better to only provide the parameters (url/title/....) to the view and let the user decide on its own how to display the buttons? E.g. you posted the example with submit...maybe someone wants to it with an <a> link or normal button?

Other implementations:
https://github.com/Abhoryo/APYDataGridBundle/blob/master/Grid/Action/MassAction.php#L34
https://github.com/zfdatagrid/grid2/blob/master/src/BvbGrid/Grid/Mass/Actions.php#L144

@ThaDafinser
Copy link
Owner

@imonteiro have it ready in next commit...bootstrapTable + jqGrid support.

Only thing missing: confirm...pinging you again when in master

@imonteiro
Copy link
Contributor Author

@ThaDafinser Awesome 👍

I will wait your commit to test.

@ThaDafinser
Copy link
Owner

@imonteiro pls checkout latest master

@imonteiro
Copy link
Contributor Author

Hi @ThaDafinser, sorry for my late response.

I agree with you, the links/buttons should be the user to decide where and how they must appear/look. The buttons render (at footer.phtml) will stay there, or will be optional? (something like: $action->setRender(false))

Confirm message isn't implemented, correct?

Suggestion... When selecting the checkbox (at title), implement tri-state: none selected (checked=false), page selection (indeterminate), all selected (checked=true).
How don't have experience with this CSS trick:
https://developer.mozilla.org/en-US/docs/Web/CSS/:indeterminate
https://developer.mozilla.org/en-US/docs/Web/CSS/:indeterminate#Browser_compatibility

Regarding to post parameters, make sense to pass more than one param? Other than primary key?

Good work! 👍

@imonteiro
Copy link
Contributor Author

Hi @ThaDafinser

Regarding Mass Actions I have changed TableRow.php to use the Action\Checkbox class when is active:

public function __invoke($row, array $cols, AbstractAction $rowClickAction = null, array $rowStyles = array(), $hasMassActions = false)
    {
        $return = $this->getTr($row);

        if ($hasMassActions === true) {
            $checkbox = new Column\Action\Checkbox('massActionSelected[]');
            $return .= '<td>' . $checkbox->toHtml($row) . '</td>';
        }

        foreach ($cols as $col) {

This it make sense? If yes, how we can can set attributes to this column? (like classes, etc.)

Should be implemented something like you have suggested above?

//here is the checkbox action column
$col = new Column\Action();
$col->setLabel(' ');
$col->setUniqueId('actionMass');
$col->setIsMassAction(true); // <-- this is the only difference
$col->addAction($delete);

$col->addClass('i-checks');

$grid->addColumn($col);

Regards,
Ivo

@ThaDafinser
Copy link
Owner

This issue was moved to zfc-datagrid/zfc-datagrid#6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants