1jQuery(function() { 2 var $board = jQuery('.kanban-board'); 3 var $mycard = jQuery('.kanban-card'); 4 if (!$board.length) return; 5 var boardName = $board.data('board'); 6 7 // Helper to send data to PHP 8 function saveCardData($card) { 9 jQuery.post(DOKU_BASE + 'lib/exe/ajax.php', { 10 call: 'kanban_save', // Match this with your action.php check 11 board: boardName, 12 card_id: $card.data('id'), 13 column: $card.closest('.kanban-col').data('id'), 14 name: $card.find('.card-title').text(), 15 importance: $card.attr('class').split(' ').filter(c => ['high','medium','low'].includes(c))[0] || 'medium', 16 desc: $card.find('.card-desc').text(), 17 note: $card.find('.card-note').text(), 18 checked: $card.find('.checkbox-inline').prop('checked') 19 }).done(function(res){ console.log("Saved:", res); }); 20 } 21 22 // Prevent movement of the card column placeholder 23 /* 24 jQuery(function() { 25 jQuery(".cards-container").sortable({ 26 // Only allow children WITHOUT the 'fixed-top-item' class to be moved 27 items: "> div:not(.fixed-top)", 28 29 // Listen for when an item is being moved to a new position 30 update: function(event, ui) { 31 // ui.item.index() returns the current position in the DOM 32 if (ui.item.index() === 0) { 33 // Find the fixed element 34 var $fixed = jQuery(this).find(".fixed-top"); 35 // Immediately force the dropped item to go AFTER the fixed div 36 ui.item.insertAfter($fixed); 37 } 38 } 39 }); 40 }); 41 */ 42 43 // Initialize Drag and Drop ONCE 44 45 jQuery(".cards-container").sortable({ 46 connectWith: ".cards-container", 47 placeholder: "ui-sortable-placeholder", 48 tolerance: "pointer", 49 50 51 start: function(e, ui) { 52 //start-added 53 const card = document.querySelector('.kanban-card'); 54 55 distance: 15, // Dragging won't trigger until moved 15px 56 // Add and start the draggable class only AFTER the 15px threshold is met 57 ui.item.addClass("is-dragging"); 58 //distance: -15, // Dragging won't trigger until moved -15px 59 // Add and start the draggable class only AFTER the -15px threshold is met 60 //ui.item.addClass("is-left-dragging"); 61 //end-added 62 ui.placeholder.height(ui.item.outerHeight()); 63 }, 64 stop: function(event, ui) { 65 //Remove the draggable class when you are done 66 ui.item.removeClass("is-dragging"); 67 //ui.item.removeClass("is-left-dragging"); 68 //Fires once when dropped 69 //alert(ui.item.text()); //debugging function works 70 //alert(ui.item.data('id')); //debugging function 71 //saveCardData(ui.item); 72 //Modified to capture the text value in JQuery format 73 //saveCardData(ui.item); 74 saveCardData(ui.item); //replaced to bring about real name for saving 75 //const divId = ui.item.closest('.kanban-col').data('id'); 76 //ui.item.closest('.kanban-col').preventDefault(); // This is required to allow a drop 77 //console.log("Dropped on ID:", divId); 78 } 79 }).disableSelection(); 80 81 // Fix: Event Delegation for "Add Card" 82 $board.on('click', '.add-card-btn', function() { 83 var name = prompt("Job Name:"); 84 if (!name) return; 85 var imp = (prompt("Importance (high, medium, low):", "medium") || "medium").toLowerCase(); 86 var cardId = "c" + Date.now(); 87 var note = "There are no notes on this card yet."; 88 89 var $newCard = jQuery(` 90 <div class="kanban-card ${imp}" data-id="${cardId}"> 91 <input type="checkbox"> 92 <strong class="card-title">${name}</strong> 93 <div class="card-desc">Click to add description...</div> 94 <div style="color:black;">Refresh for Notes</div> 95 <div class="card-note"></div> 96 </div> 97 `); 98 99 jQuery(this).closest('.kanban-col').find('.cards-container').append($newCard); 100 saveCardData($newCard); 101 }); 102 103 //make the kanban cards add note button clickable 104 $mycard.on('click', '.btn-notes', function() { 105 //var $note = jQuery(this); 106 //var currentNote = $note.text(); 107 //alert('this is my click'); 108 var mynote = prompt("Add Note:",""); 109 //Get the current username 110 //var userlogin = JSINFO['user']; // Login username 111 // Standard DokuWiki configuration object 112 //attempt to query the user from the interface first 113 var userlogin = jQuery('meta[name="plugin_do_user"]').attr('content'); 114 //console.log(JSINFO); //debugging line 115 if (!userlogin && typeof JSINFO !== 'undefined') { 116 //pull the user from php if the interface query fails 117 userlogin = JSINFO['plugin_do_user']; 118 } 119 //return currentNote + " | " + note; 120 if(mynote !== null){ 121 //Sanitize the input 122 function sanitizeInlineCommands(inputText) { 123 // Regex to match "javascript:" and other common inline command patterns 124 const commandPattern = /javascript:|on\w+=|style="[^"]*expression[^"]*"|\+/gi; 125 126 // Replace found commands with an empty string 127 return inputText.replace(commandPattern, ''); 128 } 129 130 // Example usage 131 //const userInput = 'Hello <a href="javascript:alert(1)">Click</a>! <img src=x onerror=alert(1)>'; 132 const cleanedNote = sanitizeInlineCommands(mynote); 133 //end sanitize 134 //Get the current date string 135 const date = new Date().toLocaleDateString('en-US'); 136 //Get the current time string 137 const mytime = new Date().toLocaleTimeString(); 138 //Get the closest kanban-card to the object clicked 139 var $note = jQuery(this).closest('.kanban-card'); 140 // filter() checks if $note IS the class; find() checks if it's INSIDE $note 141 var $target = $note.filter('.card-note').add($note.find('.card-note')); 142 // 2. Attach new data to the inner div with <br> delimiter 143 $target.append("<br>+ " + userlogin + " - " + date + ":" + mytime + " - " + cleanedNote); 144 145 saveCardData($note.closest('.kanban-card')); 146 } 147 }); 148 149 // Fix: Event Delegation for Clickable Description 150 $board.on('click', '.card-desc', function() { 151 var $desc = jQuery(this); 152 var currentText = $desc.text() === "Click to add description..." ? "" : $desc.text(); 153 var newDesc = prompt("Enter Description:", currentText); 154 if (newDesc !== null) { 155 $desc.text(newDesc || "Click to add description..."); 156 saveCardData($desc.closest('.kanban-card')); 157 } 158 }); 159 // Fix: Event Delegation for Clickable Checkbox 160 $board.on('click', '.checkbox-inline', function() { 161 var $checkit = jQuery(this); 162 var currentVal = $checkit.prop('checked'); 163 if ($checkit){ 164 saveCardData($checkit.closest('.kanban-card')); 165 } 166 }); 167 168 169}); 170