protected function getFormActions() { $actions = parent::getFormActions(); // Check if record is versionable /** @var Versioned|DataObject $record */ $record = $this->getRecord(); if (!$record || !$record->has_extension('SilverStripe\\ORM\\Versioning\\Versioned')) { return $actions; } // Save & Publish action if ($record->canPublish()) { // "publish", as with "save", it supports an alternate state to show when action is needed. $publish = FormAction::create('doPublish', _t('VersionedGridFieldItemRequest.BUTTONPUBLISH', 'Publish'))->setUseButtonTag(true)->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'accept'); // Insert after save if ($actions->fieldByName('action_doSave')) { $actions->insertAfter('action_doSave', $publish); } else { $actions->push($publish); } } // Unpublish action $isPublished = $record->isPublished(); if ($isPublished && $record->canUnpublish()) { $actions->push(FormAction::create('doUnpublish', _t('VersionedGridFieldItemRequest.BUTTONUNPUBLISH', 'Unpublish'))->setUseButtonTag(true)->setDescription(_t('VersionedGridFieldItemRequest.BUTTONUNPUBLISHDESC', 'Remove this record from the published site'))->addExtraClass('ss-ui-action-destructive')); } // Archive action if ($record->canArchive()) { // Replace "delete" action $actions->removeByName('action_doDelete'); // "archive" $actions->push(FormAction::create('doArchive', _t('VersionedGridFieldItemRequest.ARCHIVE', 'Archive'))->setDescription(_t('VersionedGridFieldItemRequest.BUTTONARCHIVEDESC', 'Unpublish and send to archive'))->addExtraClass('delete ss-ui-action-destructive')); } return $actions; }
/** * Test that schema is merged correctly */ public function testMergeSchema() { $publishAction = FormAction::create('publish', 'Publish'); $publishAction->setIcon('save'); $publishAction->setSchemaData(['data' => ['buttonStyle' => 'primary']]); $schema = $publishAction->getSchemaData(); $this->assertEquals(['icon' => 'save', 'buttonStyle' => 'primary'], $schema['data']); }
public function __construct(Controller $controller, $name) { // Set default fields $fields = new FieldList(HiddenField::create("AuthenticationMethod", null, $this->authenticator_class, $this), HiddenField::create('tempid', null, $controller->getRequest()->requestVar('tempid')), PasswordField::create("Password", _t('Member.PASSWORD', 'Password')), LiteralField::create('forgotPassword', sprintf('<p id="ForgotPassword"><a href="%s" target="_top">%s</a></p>', $this->getExternalLink('lostpassword'), _t('CMSMemberLoginForm.BUTTONFORGOTPASSWORD', "Forgot password?")))); if (Security::config()->autologin_enabled) { $fields->push(CheckboxField::create("Remember", _t('Member.REMEMBERME', "Remember me next time?"))); } // Determine returnurl to redirect to parent page $logoutLink = $this->getExternalLink('logout'); if ($returnURL = $controller->getRequest()->requestVar('BackURL')) { $logoutLink = Controller::join_links($logoutLink, '?BackURL=' . urlencode($returnURL)); } // Make actions $actions = new FieldList(FormAction::create('dologin', _t('CMSMemberLoginForm.BUTTONLOGIN', "Log back in")), LiteralField::create('doLogout', sprintf('<p id="doLogout"><a href="%s" target="_top">%s</a></p>', $logoutLink, _t('CMSMemberLoginForm.BUTTONLOGOUT', "Log out")))); parent::__construct($controller, $name, $fields, $actions); }
public function getEditForm($id = null, $fields = null) { $this->setCurrentPageID(Member::currentUserID()); $form = parent::getEditForm($id, $fields); if ($form instanceof HTTPResponse) { return $form; } $form->Fields()->removeByName('LastVisited'); $form->Fields()->push(new HiddenField('ID', null, Member::currentUserID())); $form->Actions()->push(FormAction::create('save', _t('CMSMain.SAVE', 'Save'))->addExtraClass('ss-ui-button ss-ui-action-constructive')->setAttribute('data-icon', 'accept')->setUseButtonTag(true)); $form->Actions()->removeByName('action_delete'); if ($member = Member::currentUser()) { $form->setValidator($member->getValidator()); } else { $form->setValidator(Member::singleton()->getValidator()); } if ($form->Fields()->hasTabSet()) { $form->Fields()->findOrMakeTab('Root')->setTemplate('SilverStripe\\Forms\\CMSTabSet'); } $form->addExtraClass('member-profile-form root-form cms-edit-form center fill-height'); return $form; }
/** * @param File $record * @return FormAction */ protected function getInsertAction($record) { if ($record && $record->isInDB() && $record->canEdit()) { return FormAction::create('insert', _t('CMSMain.INSERT', 'Insert file'))->setSchemaData(['data' => ['buttonStyle' => 'primary']]); } return null; }
/** * Calls {@link SiteTree->getCMSFields()} * * @param Int $id * @param FieldList $fields * @return Form */ public function getEditForm($id = null, $fields = null) { if (!$id) { $id = $this->currentPageID(); } if (is_object($id)) { $record = $id; } else { $record = $this->getRecord($id); if ($record && !$record->canView()) { return Security::permissionFailure($this); } } if ($record) { $fields = $fields ? $fields : $record->getCMSFields(); if ($fields == null) { user_error("getCMSFields() returned null - it should return a FieldList object.\n\t\t\t\t\tPerhaps you forgot to put a return statement at the end of your method?", E_USER_ERROR); } // Add hidden fields which are required for saving the record // and loading the UI state if (!$fields->dataFieldByName('ClassName')) { $fields->push(new HiddenField('ClassName')); } $tree_class = $this->stat('tree_class'); if ($tree_class::has_extension(Hierarchy::class) && !$fields->dataFieldByName('ParentID')) { $fields->push(new HiddenField('ParentID')); } // Added in-line to the form, but plucked into different view by frontend scripts. if ($record instanceof CMSPreviewable) { /** @skipUpgrade */ $navField = new LiteralField('SilverStripeNavigator', $this->getSilverStripeNavigator()); $navField->setAllowHTML(true); $fields->push($navField); } if ($record->hasMethod('getAllCMSActions')) { $actions = $record->getAllCMSActions(); } else { $actions = $record->getCMSActions(); // add default actions if none are defined if (!$actions || !$actions->count()) { if ($record->hasMethod('canEdit') && $record->canEdit()) { $actions->push(FormAction::create('save', _t('CMSMain.SAVE', 'Save'))->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'accept')); } if ($record->hasMethod('canDelete') && $record->canDelete()) { $actions->push(FormAction::create('delete', _t('ModelAdmin.DELETE', 'Delete'))->addExtraClass('ss-ui-action-destructive')); } } } // Use <button> to allow full jQuery UI styling $actionsFlattened = $actions->dataFields(); if ($actionsFlattened) { /** @var FormAction $action */ foreach ($actionsFlattened as $action) { $action->setUseButtonTag(true); } } $negotiator = $this->getResponseNegotiator(); $form = Form::create($this, "EditForm", $fields, $actions)->setHTMLID('Form_EditForm'); $form->addExtraClass('cms-edit-form'); $form->loadDataFrom($record); $form->setTemplate($this->getTemplatesWithSuffix('_EditForm')); $form->setAttribute('data-pjax-fragment', 'CurrentForm'); $form->setValidationResponseCallback(function () use($negotiator, $form) { $request = $this->getRequest(); if ($request->isAjax() && $negotiator) { $form->setupFormErrors(); $result = $form->forTemplate(); return $negotiator->respond($request, array('CurrentForm' => function () use($result) { return $result; })); } }); // Announce the capability so the frontend can decide whether to allow preview or not. if ($record instanceof CMSPreviewable) { $form->addExtraClass('cms-previewable'); } $form->addExtraClass('fill-height'); // Set this if you want to split up tabs into a separate header row // if($form->Fields()->hasTabset()) { // $form->Fields()->findOrMakeTab('Root')->setTemplate('SilverStripe\\Forms\\CMSTabSet'); // } // Add a default or custom validator. // @todo Currently the default Validator.js implementation // adds javascript to the document body, meaning it won't // be included properly if the associated fields are loaded // through ajax. This means only serverside validation // will kick in for pages+validation loaded through ajax. // This will be solved by using less obtrusive javascript validation // in the future, see http://open.silverstripe.com/ticket/2915 and // http://open.silverstripe.com/ticket/3386 if ($record->hasMethod('getCMSValidator')) { $validator = $record->getCMSValidator(); // The clientside (mainly LeftAndMain*.js) rely on ajax responses // which can be evaluated as javascript, hence we need // to override any global changes to the validation handler. if ($validator != NULL) { $form->setValidator($validator); } } else { $form->unsetValidator(); } if ($record->hasMethod('canEdit') && !$record->canEdit()) { $readonlyFields = $form->Fields()->makeReadonly(); $form->setFields($readonlyFields); } } else { $form = $this->EmptyForm(); } return $form; }
/** * @return Form */ public function SearchForm() { $context = $this->getSearchContext(); /** @skipUpgrade */ $form = new Form($this, "SearchForm", $context->getSearchFields(), new FieldList(FormAction::create('search', _t('MemberTableField.APPLY_FILTER', 'Apply Filter'))->setUseButtonTag(true)->addExtraClass('ss-ui-action-constructive'), ResetFormAction::create('clearsearch', _t('ModelAdmin.RESET', 'Reset'))->setUseButtonTag(true)), new RequiredFields()); $form->setFormMethod('get'); $form->setFormAction($this->Link($this->sanitiseClassName($this->modelClass))); $form->addExtraClass('cms-search-form'); $form->disableSecurityToken(); $form->loadDataFrom($this->getRequest()->getVars()); $this->extend('updateSearchForm', $form); return $form; }
/** * Get delete action, if this record is deletable * * @param File $record * @return FormAction */ protected function getDeleteAction($record) { // Delete action if ($record && $record->isInDB() && $record->canDelete()) { $deleteText = _t('SilverStripe\\AssetAdmin\\Controller\\AssetAdmin.DELETE_BUTTON', 'Delete'); return FormAction::create('delete', $deleteText)->setIcon('trash-bin'); } return null; }
/** * @todo Use GridFieldDetailForm once it can handle structured data and form schemas * * @param int $id * @return Form */ public function getDetailEditForm($id) { // Get record-specific fields $record = null; if ($id) { $record = ChangeSet::get()->byID($id); if (!$record || !$record->canView()) { return null; } } if (!$record) { $record = ChangeSet::singleton(); } $fields = $record->getCMSFields(); // Add standard fields $fields->push(HiddenField::create('ID')); $form = Form::create($this, 'DetailEditForm', $fields, FieldList::create(FormAction::create('save', _t('CMSMain.SAVE', 'Save'))->setIcon('save'), FormAction::create('cancel', _t('LeftAndMain.CANCEL', 'Cancel'))->setUseButtonTag(true))); // Load into form if ($id && $record) { $form->loadDataFrom($record); } $form->getValidator()->addRequiredField('Name'); // Configure form to respond to validation errors with form schema // if requested via react. $form->setValidationResponseCallback(function () use($form, $record) { $schemaId = Controller::join_links($this->Link('schema/DetailEditForm'), $record->exists() ? $record->ID : ''); return $this->getSchemaResponse($form, $schemaId); }); return $form; }
public function Form() { $form = new Form($this, 'Form', new FieldList(new EmailField('Email'), new TextField('SomeRequiredField'), new CheckboxSetField('Boxes', null, array('1' => 'one', '2' => 'two')), new NumericField('Number')), new FieldList(FormAction::create('doSubmit'), FormAction::create('doSubmitValidationExempt'), FormAction::create('doSubmitActionExempt')->setValidationExempt(true)), new RequiredFields('Email', 'SomeRequiredField')); $form->setValidationExemptActions(array('doSubmitValidationExempt')); $form->disableSecurityToken(); // Disable CSRF protection for easier form submission handling return $form; }
/** * Build the set of form field actions for this DataObject * * @return FieldList */ protected function getFormActions() { $canEdit = $this->record->canEdit(); $canDelete = $this->record->canDelete(); $actions = new FieldList(); if ($this->record->ID !== 0) { if ($canEdit) { $actions->push(FormAction::create('doSave', _t('GridFieldDetailForm.Save', 'Save'))->setUseButtonTag(true)->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'accept')); } if ($canDelete) { $actions->push(FormAction::create('doDelete', _t('GridFieldDetailForm.Delete', 'Delete'))->setUseButtonTag(true)->addExtraClass('ss-ui-action-destructive action-delete')); } } else { // adding new record //Change the Save label to 'Create' $actions->push(FormAction::create('doSave', _t('GridFieldDetailForm.Create', 'Create'))->setUseButtonTag(true)->addExtraClass('ss-ui-action-constructive')->setAttribute('data-icon', 'add')); // Add a Cancel link which is a button-like link and link back to one level up. $crumbs = $this->Breadcrumbs(); if ($crumbs && $crumbs->count() >= 2) { $oneLevelUp = $crumbs->offsetGet($crumbs->count() - 2); $text = sprintf("<a class=\"%s\" href=\"%s\">%s</a>", "crumb ss-ui-button ss-ui-action-destructive cms-panel-link ui-corner-all", $oneLevelUp->Link, _t('GridFieldDetailForm.CancelBtn', 'Cancel')); $actions->push(new LiteralField('cancelbutton', $text)); } } $this->extend('updateFormActions', $actions); return $actions; }
/** * Constructor * * @skipUpgrade * @param Controller $controller The parent controller, necessary to * create the appropriate form action tag. * @param string $name The method on the controller that will return this * form object. * @param FieldList $fields All of the fields in the form - a * {@link FieldList} of {@link FormField} * objects. * @param FieldList|FormAction $actions All of the action buttons in the * form - a {@link FieldList} of * {@link FormAction} objects * @param bool $checkCurrentUser If set to TRUE, it will be checked if a * the user is currently logged in, and if * so, only a logout button will be rendered */ public function __construct($controller, $name, $fields = null, $actions = null, $checkCurrentUser = true) { // This is now set on the class directly to make it easier to create subclasses // $this->authenticator_class = $authenticatorClassName; $customCSS = project() . '/css/member_login.css'; if (Director::fileExists($customCSS)) { Requirements::css($customCSS); } if (isset($_REQUEST['BackURL'])) { $backURL = $_REQUEST['BackURL']; } else { $backURL = Session::get('BackURL'); } if ($checkCurrentUser && Member::currentUser() && Member::logged_in_session_exists()) { $fields = FieldList::create(HiddenField::create("AuthenticationMethod", null, $this->authenticator_class, $this)); $actions = FieldList::create(FormAction::create("logout", _t('Member.BUTTONLOGINOTHER', "Log in as someone else"))); } else { if (!$fields) { $label = Member::singleton()->fieldLabel(Member::config()->unique_identifier_field); $fields = FieldList::create(HiddenField::create("AuthenticationMethod", null, $this->authenticator_class, $this), $emailField = TextField::create("Email", $label, null, null, $this), PasswordField::create("Password", _t('Member.PASSWORD', 'Password'))); if (Security::config()->remember_username) { $emailField->setValue(Session::get('SessionForms.MemberLoginForm.Email')); } else { // Some browsers won't respect this attribute unless it's added to the form $this->setAttribute('autocomplete', 'off'); $emailField->setAttribute('autocomplete', 'off'); } if (Security::config()->autologin_enabled) { $fields->push(CheckboxField::create("Remember", _t('Member.KEEPMESIGNEDIN', "Keep me signed in"))->setAttribute('title', sprintf(_t('Member.REMEMBERME', "Remember me next time? (for %d days on this device)"), RememberLoginHash::config()->get('token_expiry_days')))); } } if (!$actions) { $actions = FieldList::create(FormAction::create('dologin', _t('Member.BUTTONLOGIN', "Log in")), LiteralField::create('forgotPassword', '<p id="ForgotPassword"><a href="' . Security::lost_password_url() . '">' . _t('Member.BUTTONLOSTPASSWORD', "I've lost my password") . '</a></p>')); } } if (isset($backURL)) { $fields->push(HiddenField::create('BackURL', 'BackURL', $backURL)); } // Reduce attack surface by enforcing POST requests $this->setFormMethod('POST', true); parent::__construct($controller, $name, $fields, $actions); $this->setValidator(RequiredFields::create('Email', 'Password')); // Focus on the email input when the page is loaded $js = <<<JS \t\t\t(function() { \t\t\t\tvar el = document.getElementById("MemberLoginForm_LoginForm_Email"); \t\t\t\tif(el && el.focus && (typeof jQuery == 'undefined' || jQuery(el).is(':visible'))) el.focus(); \t\t\t})(); JS; Requirements::customScript($js, 'MemberLoginFormFieldFocus'); }