Yii2如何实现单按钮兼具保存与预览双重功能
Got it, let's figure out how to merge your separate Save and View buttons into one that does both actions seamlessly! Here are two reliable approaches you can use:
方法1:后端处理(提交后跳转预览)
This approach keeps everything server-side, which is great for users who have JavaScript disabled and keeps your logic consolidated in the controller.
First, replace your two buttons with a single submit button that sends a specific flag to your backend:
echo Html::submitInput('Save & View', ['name' => 'saveAndView','value' => '1', 'class' => 'btn btn-primary']);
Then, in your controller's action method (where you handle the form submission), add logic to redirect to the preview page after saving:
// Your existing save logic here (validate and save the model) if ($model->load(Yii::$app->request->post()) && $model->save()) { // Check if we need to redirect to preview after save if (Yii::$app->request->post('saveAndView') == 1) { // Redirect directly to the preview URL using the saved model's ID return $this->redirect("https://url.xxxx/something/show/{$model->id}"); } else { // Your original post-save redirect (e.g., back to the list) return $this->redirect(['index']); } }
Note: If this is for a new record (not updating an existing one), using $model->id here works perfectly because Yii populates the model's primary key right after saving.
方法2:前端JavaScript(异步保存 + 打开预览)
If you want a smoother, no-refresh experience, use JavaScript to first submit the form via AJAX, then open the preview window once saving is successful.
First, replace your buttons with a regular button and add some JS to handle the click:
// Add a single button with an ID for JS targeting echo Html::button('Save & View', ['class' => 'btn btn-primary', 'id' => 'saveAndViewBtn']); // Register the JavaScript to handle the action $this->registerJs(" $('#saveAndViewBtn').on('click', function() { const form = $('form'); // Submit the form via AJAX to save the data $.ajax({ url: form.attr('action'), type: 'POST', data: form.serialize() + '&saveOnly=1', // Reuse your original save flag success: function() { // On success, open the preview in a new tab window.open('https://url.xxxx/something/show/" . $model->id . "', '_blank'); }, error: function() { // Show an error message if saving fails alert('Oops, save failed! Please try again.'); } }); }); ");
Heads up: If you're creating a new record, you'll need to return the new ID from your backend AJAX response and use that in the preview URL instead of the initial $model->id (since it won't exist yet). For example, modify your controller to echo the new ID on success:
// In your controller's action after saving a new record echo json_encode(['id' => $model->id]); exit;
Then update the JS success callback:
success: function(response) { const newId = JSON.parse(response).id; window.open(`https://url.xxxx/something/show/${newId}`, '_blank'); }
内容的提问来源于stack exchange,提问作者Mattpl12

