Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

All other Modules /

Discuss all other Modules here.

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Adding custom forms to gridfield bulk editing tools


Go to End


2 Posts   1543 Views

Avatar
Mo

Community Member, 541 Posts

3 February 2015 at 11:05am

Hi All,

I have a model admin interface that manages "Contacts" and "Lists" and a "List" can contain multiple contacts. I have added a bulk action to the "Contacts" gridfield that adds an "Assign to list" option to the gridfield, that generates a form containing a dropdown of lists.

When I use the dropdown and then assign the list, I would like to click and "Add" button and the records I am editing get assigned.

I have previously got this working with the old version of bulk editing tools, but cannot get it to work with the lates version (2.1.1). For some reason, the form will not post to the correct method (instead it seems to post to index).

Below is my bulk action handler:

<?php
/**
 * Bulk action handler that adds selected records to a mailing list
 * 
 * @author colymba
 * @package GridFieldBulkEditingTools
 * @subpackage BulkManager
 */
class BulkActionAssignToList extends GridFieldBulkActionHandler
{	
	/**
	 * RequestHandler allowed actions
	 * @var array
	 */
	private static $allowed_actions = array(
        'index',
        'listForm',
        'doAddToList'
    );


	/**
	 * RequestHandler url => action map
	 * @var array
	 */
	private static $url_handlers = array(
		'assign/listForm' => 'listForm',
		'assign' => 'index'
	);
    
    
    
    /**
     * Return URL to this RequestHandler
     * @param string $action Action to append to URL
     * @return string URL
     */
    public function Link($action = null) {
        return Controller::join_links(
            parent::Link(),
            'assign',
            $action
        );
    }
    
    
    /**
	 * Creates and return the editing interface
	 * 
	 * @return string Form's HTML
	 */
	public function index() {
        
		$form = $this->listForm();
		$form->setTemplate('LeftAndMain_EditForm');
		$form->addExtraClass('center cms-content');
		$form->setAttribute('data-pjax-fragment', 'CurrentForm Content');
        
        if($this->request->isAjax()) {
            $response = new SS_HTTPResponse(
                Convert::raw2json(array( 'Content' => $form->forAjaxTemplate()->getValue() ))
            );
            
            $response->addHeader('X-Pjax', 'Content');
            $response->addHeader('Content-Type', 'text/json');
            $response->addHeader('X-Title', 'SilverStripe - Bulk '.$this->gridField->list->dataClass.' Editing');
            
            return $response;
        } else {
            $controller = $this->getToplevelController();
            return $controller->customise(array( 'Content' => $form ));
        }
	}


	/**
	 * Return a form with a dropdown to select the list you want to use
	 * 
	 * @return Form Selected DataObjects editable fields
	 */
	public function listForm() {
		$crumbs = $this->Breadcrumbs();
        
		if($crumbs && $crumbs->count()>=2) {
			$one_level_up = $crumbs->offsetGet($crumbs->count()-2);
		}
        
        $fields = new FieldList();
        
        $record_ids = "";
        $query_string = "";
        
        foreach ($this->getRecordIDList() as $id) {
            $record_ids .= $id . ',';
            $query_string .= "records[]={$id}&";
        }
        
        // Cut off the last 2 parts of the string
        $record_ids = substr($record_ids, 0, -1);
        $query_string = substr($query_string, 0, -1);
        
        $fields->push(HiddenField::create(
            "RecordIDs",
            "",
            $record_ids
        ));
        
        $fields->push(
            (new DropdownField(
                "MailingListID",
                "Choose a mailing list",
                MailingList::get()->map()
            ))->setEmptyString("Select a List")
        );
        
        $actions = new FieldList(
			FormAction::create('doAddToList', 'Add')
				->setAttribute('id', 'bulkEditingAddToListBtn')
				->addExtraClass('ss-ui-action-constructive cms-panel-link')
				->setAttribute('data-icon', 'accept')
				->setUseButtonTag(true),
                
			FormAction::create('Cancel', _t('GRIDFIELD_BULKMANAGER_EDIT_HANDLER.CANCEL_BTN_LABEL', 'Cancel'))
				->setAttribute('id', 'bulkEditingUpdateCancelBtn')
				->addExtraClass('ss-ui-action-destructive cms-panel-link')
				->setAttribute('data-icon', 'decline')
				->setAttribute('href', $one_level_up->Link)
				->setUseButtonTag(true)
		);
        
		$form = new Form(
			$this,
			'listForm',
			$fields,
			$actions
		);
		
		if($crumbs && $crumbs->count() >= 2){
			$form->Backlink = $one_level_up->Link;
		}
        
        // override form action URL back to bulkEditForm
		// and add record ids GET var		
		$form->setAttribute(
			'action',
			$this->Link('listForm?' . $query_string)
		);

		return $form;
	}

	
	/**
	 * Saves the changes made in the bulk edit into the dataObject
	 * 
	 * @return Redirect 
	 */
	public function doAddToList($data, $form) {
        $className  = $this->gridField->list->dataClass;
		$singleton  = singleton($className);
        
		$return = array();

        if ( isset($data['RecordIDs']) )
            $ids = explode(",", $data['RecordIDs']);
        else
            $ids = array();

        $list_id = (isset($data['MailingListID'])) ? $data['MailingListID'] : 0;
        $list = MailingList::get()->byID($list_id);
        
        try {
			foreach ($ids as $record_id) {
                if($list_id) {
                    $record = DataObject::get_by_id($className, $record_id);
                    
                    if($record->hasMethod("MailingLists")) {
                        $list->Recipients()->add($record);
                        $list->write();
                    }
                    
                    $return[] = $record->ID;
                }
            }
		} catch(Exception $e) {
            $controller = $this->controller;
            
			$form->sessionMessage(
                $e->getResult()->message(),
                'bad',
                false
            );
                
			$responseNegotiator = new PjaxResponseNegotiator(array(
				'CurrentForm' => function() use(&$form) {
					return $form->forTemplate();
				},
				'default' => function() use(&$controller) {
					return $controller->redirectBack();
				}
			));
            
			if($controller->getRequest()->isAjax()){
				$controller->getRequest()->addHeader('X-Pjax', 'CurrentForm');
			}
            
			return $responseNegotiator->respond($controller->getRequest());
		}
        
        
        $controller = $this->getToplevelController();
        $form = $controller->EditForm();
        
        $message = "Added " . count($return) . " contacts to mailing list '{$list->Title}'";
		$form->sessionMessage($message, 'good', false);
        
        // Changes to the record properties might've excluded the record from
        // a filtered list, so return back to the main view if it can't be found
        $link = $controller->Link();
        $controller->getRequest()->addHeader('X-Pjax', 'Content');
        return $controller->redirect($link);
	}
}

Any help would be greatly appreciated, I am really scratching my head over what is going wrong :-(.

Many thanks,

Mo

Avatar
Mo

Community Member, 541 Posts

5 February 2015 at 4:30am

Ok, I have managed to disable the ajax submission, though it would be nicer if I could keep the Ajax and get it to perform a background post to the forms action URL (at the moment it is performing a GET request back to the current URL).

I had to remove the "cms-panel-link" class from the Add button. Doing that disabled the Ajax call.