Answers.Body: <p>According to <a href="https://craftcms.stackexchange.com/a/25443">this answer</a> from Robin, you can use <code>Craft::$app-&gt;session-&gt;setError($message);</code> to show that flash error message you're looking for...</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-06-07T04:02:01.327Z
Answers.Text: The issue with "Craft::$app->session->setError($message)" is it only will show one error message in the end. For example, if you used beforeSaveElement event and setError message to something there. The message will likely get overwrite by any other Craft::$app->session->setError($message) called after you. And its often craft's default error message wins. And Ryan is trying to set error message at asynchronous JS interface, "Craft::$app->session->setError($message)" will not work here.
Answers.UserDisplayName: Parry Huang
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-06-07T17:25:24.327Z
Answers.Text: @jalen, I set the error flash message but you don't see it until you refresh or change the page.
Answers.UserDisplayName: Ryan
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-06-06T13:19:05.887Z
Answers.LastActivityDate: 2020-06-06T13:19:05.887Z
Answers.UserDisplayName: Jalen Davenport
Answers.Body: <p>I haven't tried this yet, but I think you can try to use "Server Side Event" with "Control Panel JS plugin for Craft CMS": <a href="https://github.com/doublesecretagency/craft-cpjs/blob/v2/README.md" rel="nofollow noreferrer">https://github.com/doublesecretagency/craft-cpjs/blob/v2/README.md</a></p>
  
  <p>Listen to server and append a custom alert when some event triggered at server side.</p>
  
  <p>Here is some information about SSE.</p>
  
  <p>W3S:
  <a href="https://www.w3schools.com/html/html5_serversentevents.asp" rel="nofollow noreferrer">https://www.w3schools.com/html/html5_serversentevents.asp</a></p>
  
  <p>SSE Browser Support:
  <a href="https://caniuse.com/#search=Server%20Side%20Event" rel="nofollow noreferrer">https://caniuse.com/#search=Server%20Side%20Event</a></p>
  
  <p>SSE Polyfill to Support Mobile Android and IE8+
  <a href="https://github.com/Yaffle/EventSource" rel="nofollow noreferrer">https://github.com/Yaffle/EventSource</a></p>
  
  <p>Yii2 SSE Server Side Example:
  <a href="https://www.yiiframework.com/wiki/329/real-time-display-of-server-push-data-using-server-sent-events-sse" rel="nofollow noreferrer">https://www.yiiframework.com/wiki/329/real-time-display-of-server-push-data-using-server-sent-events-sse</a></p>
  
  <p>Yii2 SSE component:
  <a href="https://github.com/odannyc/yii2-sse" rel="nofollow noreferrer">https://github.com/odannyc/yii2-sse</a></p>
  
  <p>Hope this helps.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-06-06T02:57:11.313Z
Answers.LastActivityDate: 2020-06-06T02:57:11.313Z
Answers.UserDisplayName: Parry Huang
Body: <p>If I change an order's status to "Cancelled" (my custom order status I created), I want to ensure that the CP editors provide a "Cancellation Reason" from a dropdown field in the order.  I've set up a custom validator to do this but it doesn't get recognized in Commerce's flash message.</p>
  
  <p>In my plugin, I'm adding a custom rule to <code>Order</code> elements like:</p>
  
  <pre><code>use my\plugin\validators\CancellationReasonValidator;
  use craft\events\DefineRulesEvent;
  use craft\commerce\elements\Order;
  use yii\base\Event;
  
  Event::on(
      Order::class,
      Order::EVENT_DEFINE_RULES,
      static function(DefineRulesEvent $event) {
          /* @var Order $order */
          $event-&gt;rules[] = [['cancellationReason'], CancellationReasonValidator::class];
      });
  </code></pre>
  
  <p>My validator looks like:</p>
  
  <pre><code>use Craft;
  use craft\commerce\elements\Order;
  use yii\validators\Validator;
  
  class CancellationReasonValidator extends Validator
  {
      public function validateAttribute($model, $attribute)
      {
          $cancellationReasonField = $model-&gt;$attribute;
  
          /* @var Order $model */
          if (   $model-&gt;isCompleted
              &amp;&amp; $model-&gt;getOrderStatus()-&gt;handle === 'cancelled'
              &amp;&amp; ! $cancellationReasonField-&gt;value) {
  
              $this-&gt;addError($model, $attribute, Craft::t(
                  'site',
                  'A cancellation reason is required for {orderNumber}',
                  ['orderNumber' =&gt; $model-&gt;shortNumber]
              ));
  
          }
      }
  }
  </code></pre>
  
  <p>If I edit an order, change the status to "Cancelled", and click the red update button, the validation works:
  <a href="https://i.sstatic.net/hXjad.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/hXjad.png" alt="Cancellation Reason dropdown field is invalid"></a></p>
  
  <p>However, if I do this from the orders listing view, where I try to update an order's status like in the screenshot below, there is no flash message displayed to the user that the order couldn't save.</p>
  
  <p><a href="https://i.sstatic.net/9H4G5.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/9H4G5.png" alt="No error message displays after updating order with cancelled status message"></a></p>
  
  <p>I understand there's a lot of asynchronous JS happening here, but how do I tap into showing some sort of message to my CP editors, preferably one that mentions the order's <code>shortNumber</code>?</p>
  
  <p><a href="https://i.sstatic.net/ECpkl.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/ECpkl.png" alt="Add error flash message at top of page"></a></p>
  
Tags: <plugin-development><plugin-craftcommerce><validation>
Title: How to show flash message for Commerce order when changing status on listing page?
ThreadText: # How to show flash message for Commerce order when changing status on listing page?
  
  (Asked by: username_0 on 2020-06-05)
  
  If I change an order's status to "Cancelled" (my custom order status I created), I want to ensure that the CP editors provide a "Cancellation Reason" from a dropdown field in the order. I've set up a custom validator to do this but it doesn't get recognized in Commerce's flash message.
  
  In my plugin, I'm adding a custom rule to `Order` elements like:
  
  ```
  use my\plugin\validators\CancellationReasonValidator;
  use craft\events\DefineRulesEvent;
  use craft\commerce\elements\Order;
  use yii\base\Event;
  
  Event::on(
      Order::class,
      Order::EVENT_DEFINE_RULES,
      static function(DefineRulesEvent $event) {
          /* @var Order $order */
          $event->rules[] = [['cancellationReason'], CancellationReasonValidator::class];
      });
  
  ```
  
  My validator looks like:
  
  ```
  use Craft;
  use craft\commerce\elements\Order;
  use yii\validators\Validator;
  
  class CancellationReasonValidator extends Validator
  {
      public function validateAttribute($model, $attribute)
      {
          $cancellationReasonField = $model->$attribute;
  
          /* @var Order $model */
          if (   $model->isCompleted
              && $model->getOrderStatus()->handle === 'cancelled'
              && ! $cancellationReasonField->value) {
  
              $this->addError($model, $attribute, Craft::t(
                  'site',
                  'A cancellation reason is required for {orderNumber}',
                  ['orderNumber' => $model->shortNumber]
              ));
  
          }
      }
  }
  
  ```
  
  If I edit an order, change the status to "Cancelled", and click the red update button, the validation works:
  [![Cancellation Reason dropdown field is invalid](https://i.sstatic.net/hXjad.png)](https://i.sstatic.net/hXjad.png)
  
  However, if I do this from the orders listing view, where I try to update an order's status like in the screenshot below, there is no flash message displayed to the user that the order couldn't save.
  
  [![No error message displays after updating order with cancelled status message](https://i.sstatic.net/9H4G5.png)](https://i.sstatic.net/9H4G5.png)
  
  I understand there's a lot of asynchronous JS happening here, but how do I tap into showing some sort of message to my CP editors, preferably one that mentions the order's `shortNumber`?
  
  [![Add error flash message at top of page](https://i.sstatic.net/ECpkl.png)](https://i.sstatic.net/ECpkl.png)
  
  **Tags:** plugin-development, plugin-craftcommerce, validation
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_1 on 2020-06-06. Score: 1
  
  According to [this answer](https://craftcms.stackexchange.com/a/25443) from Robin, you can use `Craft::$app->session->setError($message);` to show that flash error message you're looking for...
  
  > **Comments:**
  > **username_2**: The issue with "Craft::$app->session->setError($message)" is it only will show one error message in the end. For example, if you used beforeSaveElement event and setError message to something there. The message will likely get overwrite by any other Craft::$app->session->setError($message) called after you. And its often craft's default error message wins. And username_0 is trying to set error message at asynchronous JS interface, "Craft::$app->session->setError($message)" will not work here.  
  > **username_0**: @username_1, I set the error flash message but you don't see it until you refresh or change the page.  
  
  ---
  
  ### Answer by username_2 on 2020-06-06. Score: 1
  
  I haven't tried this yet, but I think you can try to use "Server Side Event" with "Control Panel JS plugin for Craft CMS": <https://github.com/doublesecretagency/craft-cpjs/blob/v2/README.md>
  
  Listen to server and append a custom alert when some event triggered at server side.
  
  Here is some information about SSE.
  
  W3S:
  <https://www.w3schools.com/html/html5_serversentevents.asp>
  
  SSE Browser Support:
  <https://caniuse.com/#search=Server%20Side%20Event>
  
  SSE Polyfill to Support Mobile Android and IE8+
  <https://github.com/Yaffle/EventSource>
  
  Yii2 SSE Server Side Example:
  <https://www.yiiframework.com/wiki/329/real-time-display-of-server-push-data-using-server-sent-events-sse>
  
  Yii2 SSE component:
  <https://github.com/odannyc/yii2-sse>
  
  Hope this helps.
  
  
  ---
  
  