[TikiWiki-commits] [Git][tikiwiki/tiki][29.x] [BP][FIX] Articles: Prevent silent save failure for missing image alt text when the image is used

"Baraka Kinywa \(@bkinywa24\) via TikiWiki-cvs" <[email protected]>
Newsgroups gmane.comp.cms.tiki.cvs
Message-ID <694e4db6e9200_2a17fd40308c6@gitlab-sidekiq-low-urgency-cpu-bound-v2-587dc6b794-jws7f.mail>

Baraka Kinywa pushed to branch 29.x at Tiki Wiki CMS Groupware / Tiki


Commits:
8986b372 by Alain Cisirika at 2025-12-26T10:48:28+02:00
[BP][FIX] Articles: Prevent silent save failure for missing image alt text when the image is used
---
* [FIX] Articles: Prevent silent save failure for missing image alt text when the image is used
---
* [FIX] Articles: Prevent silent save failure for missing image alt text when the image is used

See merge request tikiwiki/tiki!8786

See merge request tikiwiki/tiki!9271

- - - - -


6 changed files:

- path_js_importmap_generator.php
- + src/js/jquery-tiki/validate-alt-image.js
- templates/tiki-edit_article.tpl
- templates/tiki-edit_submission.tpl
- tiki-edit_article.php
- tiki-edit_submission.php


Changes:

=====================================
path_js_importmap_generator.php
=====================================
@@ -73,6 +73,9 @@ function generateJsImportmapScripts(bool $useBaseUrl = false)
                 "@jquery-tiki/tiki-password" => $tikiUrl . JS_ASSETS_PATH . "/jquery-tiki/tiki-password.js",
                 "@jquery-tiki/timeago" => $tikiUrl . JS_ASSETS_PATH . "/jquery-tiki/timeago.js",
                 "@jquery-tiki/tracker-fields/emailFolder" => $tikiUrl . JS_ASSETS_PATH . "/jquery-tiki/tracker-fields/emailFolder.js",
+                "@jquery-tiki/tracker-fields/files" => $tikiUrl . JS_ASSETS_PATH . "/jquery-tiki/tracker-fields/files.js",
+                "@jquery-tiki/tracker-fields/dirtyCheck" => $tikiUrl . JS_ASSETS_PATH . "/jquery-tiki/tracker-fields/all.dirtyCheck.js",
+                "@jquery-tiki/validate-alt-image" => $tikiUrl . JS_ASSETS_PATH . "/jquery-tiki/validate-alt-image.js",
                 "@tiki-modules/sentryBrowser" => $tikiUrl . JS_ASSETS_PATH . "/tiki-sentry-browser.js",
                 "@mermaidPack" => $tikiUrl . JS_ASSETS_PATH . "/tiki-mermaid.js",
                 "@tiki-glightbox" => $tikiUrl . JS_ASSETS_PATH . "/tiki-glightbox.js",


=====================================
src/js/jquery-tiki/validate-alt-image.js
=====================================
@@ -0,0 +1,33 @@
+// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
+//
+// All Rights Reserved. See copyright.txt for details and a complete list of authors.
+// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
+//
+// This JavaScript file is used in tiki-edit_article.php and tiki-edit_submission.php.
+// It provides client-side validation to ensure that when "Use Own Image" is enabled,
+// an Alt Text value is required before allowing the form to be submitted.
+
+(function ($) {
+    var form = document.getElementById("editpageform");
+    var $altInput = $("#image_alt");
+    var $useImageCheckbox = $("#useImage");
+
+    $(form).on("submit", function (event) {
+        var action = $(document.activeElement).attr("name");
+
+        if (action === "save" || action === "submitarticle" || action === "preview") {
+            // Explicit Logic: If "Use Own Image" is Checked AND "Alt Text" is empty
+            if ($useImageCheckbox.is(":checked") && $altInput.val().trim() === "") {
+                event.preventDefault();
+                event.stopPropagation();
+
+                $altInput.attr("required", "required");
+                form.classList.add("was-validated");
+
+                $altInput.focus();
+
+                return false;
+            }
+        }
+    });
+})(jQuery);


=====================================
templates/tiki-edit_article.tpl
=====================================
@@ -15,7 +15,7 @@
     <h2>{tr}Preview{/tr}</h2>
     {include file='article.tpl'}
 {/if}
-<form enctype="multipart/form-data" method="post" action="tiki-edit_article.php" id='editpageform'>
+<form enctype="multipart/form-data" method="post" action="tiki-edit_article.php" id='editpageform' novalidate>
     {ticket}
     <input type="hidden" name="articleId" value="{$articleId|escape}">
     <input type="hidden" name="previewId" value="{$previewId|escape}">
@@ -184,7 +184,7 @@
                 <input type="hidden" name="MAX_FILE_SIZE" value="{$prefs.article_image_file_size_max}">
                 <label for="userfile1" class="col-form-label col-md-4">{tr}Own Image{/tr}</label>
                 <div class="col-md-8">
-                    <input class="form-control" name="userfile1" id="userfile1" type="file" onchange="document.getElementById('useImage').checked = true; document.getElementById('image_alt').setAttribute('required', 'required');">
+                    <input class="form-control" name="userfile1" id="userfile1" type="file" onchange="document.getElementById('useImage').checked = true;">
                     <span class="form-text">{tr}If not the topic image{/tr} - {tr}Max file size : {$prefs.article_image_file_size_max/1000} KB{/tr}</span>
                 </div>
             </div>
@@ -204,6 +204,9 @@
                 <label class="col-md-4 col-form-label" for="image_alt">{tr}Image alternative text{/tr}</label>
                 <div class="col-md-8">
                     <input type="text" class="form-control" name="image_alt" id="image_alt" value="{$image_alt|escape}" {if $hasImage eq 'y'} required{/if}>
+                    <div class="invalid-feedback">
+                        {tr}Please enter an alternative text when using your own image.{/tr}
+                    </div>
                 </div>
             </div>
             <div class="mb-3 {if $types.$type.show_image_caption neq 'y'}hidden{/if}">
@@ -382,21 +385,21 @@
     </div>
     {if $smarty.session.wysiwyg neq 'y'}
         {jq}
-$("#editpageform").on("submit", function(evt) {
-    var isHtml = false;
-    if (this.saving && !$("input[name=allowhtml]:checked").length) {
-        $("textarea", this).each(function(){
-            if ($(this).val().match(/<([A-Z][A-Z0-9]*)\b[^>]*>(.*?)<\/\1>/i)) {
-                isHtml = true;
-            }
-        });
-        if (isHtml) {
-            this.saving = false;
-            return confirm(tr('You appear to be using HTML in your article but have not selected "Allow full HTML".\nThis will result in HTML tags being removed.\nDo you want to save your edits anyway?'));
-        }
-    }
-    return true;
-}).attr('saving', false);
+            $("#editpageform").on("submit", function(evt) {
+                var isHtml = false;
+                if (this.saving && !$("input[name=allowhtml]:checked").length) {
+                    $("textarea", this).each(function(){
+                        if ($(this).val().match(/<([A-Z][A-Z0-9]*)\b[^>]*>(.*?)<\/\1>/i)) {
+                            isHtml = true;
+                        }
+                    });
+                    if (isHtml) {
+                        this.saving = false;
+                        return confirm(tr('You appear to be using HTML in your article but have not selected "Allow full HTML".\nThis will result in HTML tags being removed.\nDo you want to save your edits anyway?'));
+                    }
+                }
+                return true;
+            }).attr('saving', false);
         {/jq}
     {/if}
 </form>


=====================================
templates/tiki-edit_submission.tpl
=====================================
@@ -21,7 +21,7 @@
     {tr}Use {$wikiPageSeparator} to separate pages in a multi-page post{/tr}
 {/remarksbox}
 
-<form enctype="multipart/form-data" method="post" action=" " id="editpageform">
+<form enctype="multipart/form-data" method="post" action=" " id="editpageform" novalidate>
     {ticket}
     <input type="hidden" name="subId" value="{$subId|escape}">
     <input type="hidden" name="previewId" value="{$previewId|escape}">
@@ -124,13 +124,16 @@
         <label class="col-sm-3 col-form-label">{tr}Own Image{/tr}</label>
         <div class="col-sm-7">
             <input type="hidden" name="MAX_FILE_SIZE" value="1000000">
-            <input name="userfile1" type="file" onchange="document.getElementById('useImage').checked = true; document.getElementById('image_alt').setAttribute('required', 'required');">
+            <input class="form-control" name="userfile1" id="userfile1" type="file" onchange="document.getElementById('useImage').checked = true;">
         </div>
     </div>
-    <div class="mb-3 row">
-        <label class="col-sm-3 col-form-label" for="image_alt">{tr}Image alternative text{/tr}</label>
-        <div class="col-sm-7">
+    <div class="mb-3">
+        <label class="col-md-4 col-form-label" for="image_alt">{tr}Image alternative text{/tr}</label>
+        <div class="col-md-8">
             <input type="text" class="form-control" name="image_alt" id="image_alt" value="{$image_alt|escape}" {if $hasImage eq 'y'} required{/if}>
+            <div class="invalid-feedback">
+                {tr}Please enter an alternative text when using your own image.{/tr}
+            </div>
         </div>
     </div>
     {if $hasImage eq 'y'}
@@ -289,25 +292,24 @@
             <input type="submit" class="wikiaction btn btn-primary" name="save" value="{tr}Auto-Approve Article{/tr}" onclick="needToConfirm=false;">
         {/if}
     </div>
-{if $smarty.session.wysiwyg neq 'y'}
-    {jq}
-$("#editpageform").on("submit", function(evt) {
-    var isHtml = false;
-    if (this.saving && !$("input[name=allowhtml]:checked").length) {
-        $("textarea", this).each(function(){
-            if ($(this).val().match(/<([A-Z][A-Z0-9]*)\b[^>]*>(.*?)<\/\1>/i)) {
-                isHtml = true;
-            }
-        });
-        if (isHtml) {
-            this.saving = false;
-            return confirm(tr('You appear to be using HTML in your article but have not selected "Allow full HTML".\nThis will result in HTML tags being removed.\nDo you want to save your edits anyway?'));
-        }
-    }
-    return true;
-}).attr('saving', false);
-    {/jq}
-{/if}
+    {if $smarty.session.wysiwyg neq 'y'}
+        {jq}
+            $("#editpageform").on("submit", function(evt) {
+                var isHtml = false;
+                if (this.saving && !$("input[name=allowhtml]:checked").length) {
+                    $("textarea", this).each(function(){
+                        if ($(this).val().match(/<([A-Z][A-Z0-9]*)\b[^>]*>(.*?)<\/\1>/i)) {
+                            isHtml = true;
+                        }
+                    });
+                    if (isHtml) {
+                        this.saving = false;
+                        return confirm(tr('You appear to be using HTML in your article but have not selected "Allow full HTML".\nThis will result in HTML tags being removed.\nDo you want to save your edits anyway?'));
+                    }
+                }
+                return true;
+            }).attr('saving', false);
+        {/jq}
+    {/if}
 </form>
-
 <br>


=====================================
tiki-edit_article.php
=====================================
@@ -813,6 +813,9 @@ $smarty->assign('metatag_robots', 'NOINDEX, NOFOLLOW');
 
 $smarty->assign('displayTimezone', TikiLib::lib('tiki')->get_display_timezone());
 
+// Enforce alt-text requirement when “Use Own Image” is enabled
+$headerlib->add_js_module('import "@jquery-tiki/validate-alt-image";');
+
 // Display the Index Template
 $smarty->assign('mid', 'tiki-edit_article.tpl');
 $smarty->display('tiki.tpl');


=====================================
tiki-edit_submission.php
=====================================
@@ -659,6 +659,9 @@ include_once('tiki-section_options.php');
 // disallow robots to index page:
 $smarty->assign('metatag_robots', 'NOINDEX, NOFOLLOW');
 
+// Enforce alt-text requirement when “Use Own Image” is enabled
+$headerlib->add_js_module('import "@jquery-tiki/validate-alt-image";');
+
 // Display the Index Template
 $smarty->assign('mid', 'tiki-edit_submission.tpl');
 $smarty->display('tiki.tpl');



View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/8986b372cfcacc91becef0f4c448397cd15df6fe

-- 
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/8986b372cfcacc91becef0f4c448397cd15df6fe
You're receiving this email because of your account on gitlab.com.

_______________________________________________
TikiWiki-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tikiwiki-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.