{"id":1652,"date":"2013-08-22T18:45:30","date_gmt":"2013-08-22T16:45:30","guid":{"rendered":"http:\/\/www.itidea.nl\/?p=1652"},"modified":"2013-08-22T18:49:35","modified_gmt":"2013-08-22T16:49:35","slug":"background-of-what-about-you-must-fill-out-all-required-properties-before-completing-this-action-when-publishing-a-page","status":"publish","type":"post","link":"https:\/\/www.itidea.nl\/index.php\/background-of-what-about-you-must-fill-out-all-required-properties-before-completing-this-action-when-publishing-a-page\/","title":{"rendered":"Background of &#8220;What about &#8216;You must fill out all required properties before completing this action&#8217; when Publishing a page&#8221;"},"content":{"rendered":"<p>In <a href=\"https:\/\/www.itidea.nl\/index.php\/what-about-you-must-fill-out-all-required-properties-before-completing-this-action-when-publishing-a-page\/\">one of my posts<\/a> I wrote a solution for the nasty popup error message:<\/p>\n<p><a href=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2013\/08\/MMDRequiredFieldErrorMessage.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1646\" title=\"MMDRequiredFieldErrorMessage\" src=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2013\/08\/MMDRequiredFieldErrorMessage.png\" alt=\"\" width=\"502\" height=\"125\" srcset=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2013\/08\/MMDRequiredFieldErrorMessage.png 502w, https:\/\/www.itidea.nl\/wp-content\/uploads\/2013\/08\/MMDRequiredFieldErrorMessage-300x74.png 300w\" sizes=\"auto, (max-width: 502px) 100vw, 502px\" \/><\/a><\/p>\n<p>This post provides some background information about this issue.<\/p>\n<p>The ootb ribbon with its functionality is built out of  the ribbon definition xml from the cmdui.xml file, script from the  SP.Ribbon.js file and server side code from different assemblies. In  this case we\u2019re interested in the assemblies Microsoft.SharePoint and  Microsoft.SharePoint.Publishing (in the above case publishing is  enabled).<br \/>\nSharePoint loads a webcontrol SPPageStateControl at every  wiki or publishing page. This control handles the ribbon buttons  controlling the state of these pages:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nthis.commandHandlers&#x5B;3] = new EditCommandHandler(this);\r\nthis.commandHandlers&#x5B;0] = new SaveCommandHandler(this);\r\nthis.commandHandlers&#x5B;1] = new SaveBeforeNavigateHandler(this);\r\nthis.commandHandlers&#x5B;4] = new DontSaveAndStopCommandHandler(this);\r\nthis.commandHandlers&#x5B;2] = new SaveAndStopEditCommandHandler(this);\r\nthis.commandHandlers&#x5B;5] = new CheckinCommandHandler(this);\r\nthis.commandHandlers&#x5B;6] = new CheckoutCommandHandler(this);\r\nthis.commandHandlers&#x5B;7] = new OverrideCheckoutCommandHandler(this);\r\nthis.commandHandlers&#x5B;8] = new DiscardCheckoutCommandHandler(this);\r\nthis.commandHandlers&#x5B;11] = new PublishCommandHandler(this);\r\nthis.commandHandlers&#x5B;12] = new UnpublishCommandHandler(this);\r\nthis.commandHandlers&#x5B;9] = new SubmitForApprovalCommandHandler(this);\r\nthis.commandHandlers&#x5B;10] = new CancelApprovalCommandHandler(this);\r\nthis.commandHandlers&#x5B;13] = new ApproveCommandHandler(this);\r\nthis.commandHandlers&#x5B;14] = new RejectCommandHandler(this);\r\nthis.commandHandlers&#x5B;15] = new DeleteCommandHandler(this);\r\nthis.commandHandlers&#x5B;0x10] = new UpdatePageStateCommandHandler(this);\r\n<\/pre>\n<p>The state of a page can be the page is<\/p>\n<ul>\n<li>in display or edit mode<\/li>\n<li>checked out to the current user, another user or to the system user<\/li>\n<li>checked in<\/li>\n<li>scheduled<\/li>\n<li>rejected<\/li>\n<li>pending approval<\/li>\n<li>published<\/li>\n<li>draft<\/li>\n<li>not valid<\/li>\n<li>and more<\/li>\n<\/ul>\n<p>Based on these states<br \/>\nstatus messages can be displayed (like \u2018Checked out and editable\u2019,  \u2018Checked in and viewable by authorized users\u2019 or a number of others).<br \/>\nerror messages can be displayed (like \u2018This page contains content or  formatting that is not valid. You can find more information in the  affected sections.\u2019)<br \/>\nribbon buttons can be trimmed<br \/>\ninitial tab can be set<\/p>\n<p>With  this little background information about the SPPageStateControl the  difference in validating required fields when saving or publishing a  page directly can be investigated.<\/p>\n<h3>Save &amp; Close<\/h3>\n<p>The  command which handles the Save &amp; Close button is the  SaveAndStopEditCommandHandler. When this handler fires the page is  validated by calling this.Page.Validate(). When one of the required  fields on the page is left empty the page isn\u2019t valid and an error  condition is set and a status message is added with a message from a  resource file.<br \/>\nThe OnPreRender method of the SPStateControl  populates the status messages based on the state of the page, in this  case \u2018Checked out and editable\u2019 and \u2018This page contains content or  formatting that is not valid. You can find more information in the  affected sections.\u2019. These status messages and the error message are  serialized and written to the page by script.<\/p>\n<p>A serialized status  message contains a StatusBody(text of the message),  StatusTitle(\u2018Error:\u2019 or \u2018Status:\u2019) and StatusPriority(\u2018yellow\u2019).<br \/>\nA serialized error message consists of a Message, Title, ButtonCount, for each button a ButtonText and a ButtonCommand.<\/p>\n<p>Client side the status and error messages are shown at initialization:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nif (SP.Ribbon.PageState.NativeErrorState.ButtonCount &gt; 0 || !SP.Ribbon.SU.$2(SP.Ribbon.PageState.NativeErrorState.ShowErrorDialogScript)) {\r\n            SP.Ribbon.PageState.PageStateHandler.showErrorDialog();\r\n        }\r\n        SP.Ribbon.PageState.PageStateHandler.showPageStatus();\r\n<\/pre>\n<p>The  error message, this is the popup!, will be shown when some of the  properties like the ButtonCount and ShowErrorDialogScript are filled.<br \/>\nThe Save &amp; Close button added an error message with the following statement:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nthis.SetErrorCondition(msg, 0, null, null);\r\n <\/pre>\n<p>The SetErrorCondition is implemented as:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic void SetErrorCondition(string ErrorMessage, uint RemedialActionCount, string&#x5B;] RemedialActionButtonText, string&#x5B;] RemedialActionCommand)\r\n{\r\nthis.errorTitle = SPResource.GetString(&quot;PageStateErrorTitle&quot;, new object&#x5B;0]);\r\nthis.errorMessage = ErrorMessage;\r\nthis.remedialActionCount = RemedialActionCount;\r\nthis.remedialActionButtonText = RemedialActionButtonText;\r\nthis.remedialActionCommand = RemedialActionCommand;\r\n}\r\n<\/pre>\n<p>This  means the error message was added with only an error message, while the  other properties were left empty. This is why the popup doesn\u2019t show  and only the status messages are.<\/p>\n<h3>Publish as first \u2018save\u2019action<\/h3>\n<p>The  command which handles the Publish button is the  PublishingPagePublishHandler. When this handler fires the separate  required fields on the listitem are checked if they all have values.  This differs from Save &amp; Close which validates the page immediately  by calling this.Page.Validate() without the explicit check for missing  required fields.<br \/>\nThe check for missing required fields loops through  the FieldLinks of the ContentType to see if anything required is  missing. If so, it builds up the edit properties url of the listitem to  set as ButtonCommand on the errormessage it will format.<br \/>\nThe call to SetErrorCondition differs from the call at Save &amp; Close, all properties are now filled:<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nSetErrorCondition(Resources.GetString(&quot;MissingRequiredFieldsErrorMessage&quot;), 2, new string&#x5B;] { SPResource.GetString(&quot;PageStateOkButton&quot;, new object&#x5B;0]), SPResource.GetString(&quot;ButtonTextCancel&quot;, new object&#x5B;0]) }, new string&#x5B;] { builder.ToString(), &quot;SP.Ribbon.PageState.PageStateHandler.dismissErrorDialog();&quot; });\r\n <\/pre>\n<p>The  error message consists of the Message from resource file, Title from  resource file, ButtonCount of 2 and for each button a ButtonText from  resource: \u2018OK\u2019 and \u2018Cancel\u2019 and the ButtonCommands: builder.ToString()  in this case  \u2018SP.Utilities.HttpUtility.navigateTo(&#8216;\/Pages\/Forms\/EditForm.aspx?ID=4&amp;Source=%2FPages%2Ftest01%2Easpx&#8217;);\u2019  for the \u2018OK\u2019 button and  \u2018SP.Ribbon.PageState.PageStateHandler.dismissErrorDialog();\u2019 for the  \u2018Cancel\u2019 button.<\/p>\n<p>The OnPreRender method of the SPStateControl  populates the serialized status and error messages based on the state of  the page and at the end of the method script is added to the page, the  same as at Save &amp; Close.<br \/>\nSerializedPageStatusMessages method  (serverside) populates  &#8216;SP.Ribbon.PageState.ImportedNativeData.StatusBody and StatusTitle used  in showPageStatus (client side)<br \/>\nSerializedErrorState (server side) populates PageErrorState (client side)<br \/>\nPageErrorState var (client side) is set to this.SerializedErrorState  which builds an object which client script can handle (Message, Title,  ButtonCount, ButtonText, ButtonCommand)<br \/>\nAnd SP.Ribbon.PageState.NativeErrorState is set to the PageErrorState.<\/p>\n<p>Client side the status and error messages are shown at initialization:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nif (SP.Ribbon.PageState.NativeErrorState.ButtonCount &amp;gt; 0 || !SP.Ribbon.SU.$2(SP.Ribbon.PageState.NativeErrorState.ShowErrorDialogScript)) {\r\n            SP.Ribbon.PageState.PageStateHandler.showErrorDialog();\r\n        }\r\n        SP.Ribbon.PageState.PageStateHandler.showPageStatus();\r\n<\/pre>\n<p>Where the ButtonCount is now 2<\/p>\n<p><a href=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2013\/08\/MMDRequiredFieldNativeErrorState.png\"><img loading=\"lazy\" decoding=\"async\" title=\"MMDRequiredFieldNativeErrorState\" src=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2013\/08\/MMDRequiredFieldNativeErrorState.png\" alt=\"\" width=\"922\" height=\"179\" \/><\/a><\/p>\n<p>and the error dialog will be shown as a modal dialog:<\/p>\n<p><a href=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2013\/08\/MMDRequiredFieldErrorMessage.png\"><img loading=\"lazy\" decoding=\"async\" title=\"MMDRequiredFieldErrorMessage\" src=\"https:\/\/www.itidea.nl\/wp-content\/uploads\/2013\/08\/MMDRequiredFieldErrorMessage.png\" alt=\"\" width=\"502\" height=\"125\" \/><\/a><\/p>\n<p>Once the page has been saved with the required managed metadata field filled<br \/>\nWhen the page is saved with the required managed metadata field filled,  set in edit mode again, empty the field and Publish the page, the  result is different from the above: no popup error message is shown, all  messages appear as status messages.<br \/>\nThe code passes successfully  the check for missing required field, because it still has the previous  filled in value(!), then falls back on validating the page as with Save  &amp; Close. This one fails and the error message is added as a status  message and the process continues as with Save &amp; Close.<\/p>\n<p>The popup error message is confusing for a lot of users, they don\u2019t understand why this sometimes happens.<br \/>\nThey read the message and press \u2018Ok\u2019 and they are navigated away from  the page to the edit properties and then what. The field was on the  page, why am I now on another page?<\/p>\n<p>The solution can be found <a href=\"https:\/\/www.itidea.nl\/index.php\/what-about-you-must-fill-out-all-required-properties-before-completing-this-action-when-publishing-a-page\/\">here<\/a>.<\/p>\n<h3>Summary<\/h3>\n<p>With a few lines of code the nasty popup error  message can be prevented to be displayed. The background story behind it  is quite large, but important to understand. Be careful to never  overwrite SharePoint message when publishing stuff, because it can lead  to inappropriate behavior.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In one of my posts I wrote a solution for the nasty popup error message: This post provides some background information about this issue. The ootb ribbon with its functionality is built out of the ribbon definition xml from the &#8230; <a class=\"more-link\" href=\"https:\/\/www.itidea.nl\/index.php\/background-of-what-about-you-must-fill-out-all-required-properties-before-completing-this-action-when-publishing-a-page\/\">Read More &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[20,42],"class_list":["post-1652","post","type-post","status-publish","format-standard","hentry","category-sharepoint-2010","tag-c","tag-sharepoint-2010"],"_links":{"self":[{"href":"https:\/\/www.itidea.nl\/index.php\/wp-json\/wp\/v2\/posts\/1652","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.itidea.nl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.itidea.nl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.itidea.nl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.itidea.nl\/index.php\/wp-json\/wp\/v2\/comments?post=1652"}],"version-history":[{"count":7,"href":"https:\/\/www.itidea.nl\/index.php\/wp-json\/wp\/v2\/posts\/1652\/revisions"}],"predecessor-version":[{"id":1664,"href":"https:\/\/www.itidea.nl\/index.php\/wp-json\/wp\/v2\/posts\/1652\/revisions\/1664"}],"wp:attachment":[{"href":"https:\/\/www.itidea.nl\/index.php\/wp-json\/wp\/v2\/media?parent=1652"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.itidea.nl\/index.php\/wp-json\/wp\/v2\/categories?post=1652"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.itidea.nl\/index.php\/wp-json\/wp\/v2\/tags?post=1652"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}