attr-column-mapping-setting-old.html 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Column Mapping</title>
  7. <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"/>
  8. <script src="https://unpkg.com/xlsx/dist/xlsx.full.min.js"></script>
  9. <style>
  10. .mapping-container {
  11. max-width: 1000px;
  12. margin: 30px auto;
  13. background: #fff;
  14. padding: 20px;
  15. border-radius: 8px;
  16. box-shadow: 0 4px 10px rgba(0,0,0,0.1);
  17. }
  18. .drag-item {
  19. padding: 10px;
  20. margin: 5px 0;
  21. background: #f1f1f1;
  22. border-radius: 4px;
  23. cursor: grab;
  24. }
  25. .drop-zone {
  26. min-height: 50px;
  27. padding: 10px;
  28. border: 2px dashed #ccc;
  29. border-radius: 4px;
  30. margin-bottom: 10px;
  31. background: #fafafa;
  32. }
  33. .drop-zone.hover {
  34. border-color: #007bff;
  35. background: #e9f5ff;
  36. }
  37. .preview-table {
  38. margin-top: 20px;
  39. }
  40. </style>
  41. </head>
  42. <body>
  43. <div class="mapping-container">
  44. <h3 class="text-center mb-4">Attribute Extraction File Upload Setting</h3>
  45. <!-- File Upload -->
  46. <div class="mb-3">
  47. <label for="fileUpload" class="form-label">Upload CSV File</label>
  48. <input type="file" class="form-control" id="fileUpload" accept="*">
  49. </div>
  50. <div class="row">
  51. <!-- Uploaded Columns -->
  52. <div class="col-md-5">
  53. <h5>Uploaded Columns</h5>
  54. <div id="uploaded-columns">
  55. <!-- Draggable items -->
  56. </div>
  57. </div>
  58. <!-- System Columns -->
  59. <div class="col-md-7">
  60. <h5>System Columns</h5>
  61. <div id="system-columns">
  62. <!-- Drop zones -->
  63. </div>
  64. </div>
  65. </div>
  66. <!-- Preview Section -->
  67. <!-- <div class="preview-table">
  68. <h5>Preview Data</h5>
  69. <table class="table table-bordered">
  70. <thead>
  71. <tr id="preview-header"></tr>
  72. </thead>
  73. <tbody id="preview-body"></tbody>
  74. </table>
  75. </div> -->
  76. <div class="text-end mt-3">
  77. <button class="btn btn-secondary" id="resetBtn">Reset</button>
  78. <button class="btn btn-primary" id="saveBtn">Save Mapping</button>
  79. </div>
  80. </div>
  81. <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  82. <script>
  83. const uploadedColumns = [];
  84. const systemColumns = ["PRODUCT NAME", "ITEM ID", "PRODUCT TYPE", "Product Short Description", "Product Long Description", "image_path"];
  85. const previewData = [
  86. // {Name: "John", Email: "john@example.com", Phone: "1234567890", Address: "NY"},
  87. // {Name: "Alice", Email: "alice@example.com", Phone: "9876543210", Address: "LA"}
  88. ];
  89. $(document).ready(function() {
  90. // Populate draggable uploaded columns
  91. uploadedColumns.forEach(col => {
  92. $("#uploaded-columns").append(`<div class="drag-item" draggable="true" data-col="${col}">${col}</div>`);
  93. });
  94. // Populate drop zones for system columns
  95. systemColumns.forEach(col => {
  96. $("#system-columns").append(`<div class="drop-zone" data-system="${col}">${col}</div>`);
  97. });
  98. // Handle file upload
  99. // $("#fileUpload").on("change", function(e) {
  100. // const file = e.target.files[0];
  101. // if (!file) return;
  102. // const reader = new FileReader();
  103. // reader.onload = function(event) {
  104. // const text = event.target.result;
  105. // const rows = text.split("\n").map(r => r.split(","));
  106. // const headers = rows[0];
  107. // const sampleRows = rows.slice(1, 6); // first 5 rows for preview
  108. // // Populate uploaded columns
  109. // $("#uploaded-columns").empty();
  110. // headers.forEach(col => {
  111. // $("#uploaded-columns").append(`<div class="drag-item" draggable="true" data-col="${col}">${col}</div>`);
  112. // });
  113. // // Populate preview table
  114. // $("#preview-header").html(headers.map(h => `<th>${h}</th>`).join(''));
  115. // $("#preview-body").empty();
  116. // sampleRows.forEach(row => {
  117. // let tr = "<tr>";
  118. // headers.forEach((h, i) => tr += `<td>${row[i] || ""}</td>`);
  119. // tr += "</tr>";
  120. // $("#preview-body").append(tr);
  121. // });
  122. // // Enable drag-and-drop
  123. // $(".drag-item").on("dragstart", function(e) {
  124. // e.originalEvent.dataTransfer.setData("text", $(this).data("col"));
  125. // });
  126. // };
  127. // reader.readAsText(file);
  128. // });
  129. // Handle Excel file upload
  130. $("#fileUpload").on("change", function(e) {
  131. const file = e.target.files[0];
  132. if (!file) return;
  133. const reader = new FileReader();
  134. reader.onload = function(event) {
  135. const data = new Uint8Array(event.target.result);
  136. const workbook = XLSX.read(data, { type: "array" });
  137. const sheetName = workbook.SheetNames[0];
  138. const sheet = workbook.Sheets[sheetName];
  139. const jsonData = XLSX.utils.sheet_to_json(sheet, { header: 1 });
  140. const headers = jsonData[0];
  141. const sampleRows = jsonData.slice(1, 6); // first 5 rows for preview
  142. // Populate uploaded columns
  143. $("#uploaded-columns").empty();
  144. headers.forEach(col => {
  145. $("#uploaded-columns").append(`<div class="drag-item" draggable="true" data-col="${col}">${col}</div>`);
  146. });
  147. // Populate preview table
  148. $("#preview-header").html(headers.map(h => `<th>${h}</th>`).join(''));
  149. $("#preview-body").empty();
  150. sampleRows.forEach(row => {
  151. let tr = "<tr>";
  152. headers.forEach((h, i) => tr += `<td>${row[i] || ""}</td>`);
  153. tr += "</tr>";
  154. $("#preview-body").append(tr);
  155. });
  156. // Enable drag-and-drop
  157. $(".drag-item").on("dragstart", function(e) {
  158. e.originalEvent.dataTransfer.setData("text", $(this).data("col"));
  159. });
  160. };
  161. reader.readAsArrayBuffer(file);
  162. });
  163. // Preview table
  164. $("#preview-header").html(uploadedColumns.map(c => `<th>${c}</th>`).join(''));
  165. previewData.forEach(row => {
  166. let tr = "<tr>";
  167. uploadedColumns.forEach(c => tr += `<td>${row[c]}</td>`);
  168. tr += "</tr>";
  169. $("#preview-body").append(tr);
  170. });
  171. // Drag and Drop Logic
  172. $(".drag-item").on("dragstart", function(e) {
  173. e.originalEvent.dataTransfer.setData("text", $(this).data("col"));
  174. });
  175. $(".drop-zone").on("dragover", function(e) {
  176. e.preventDefault();
  177. $(this).addClass("hover");
  178. }).on("dragleave", function() {
  179. $(this).removeClass("hover");
  180. }).on("drop", function(e) {
  181. e.preventDefault();
  182. $(this).removeClass("hover");
  183. const col = e.originalEvent.dataTransfer.getData("text");
  184. $(this).html(`${$(this).data("system")} → <strong>${col}</strong>`);
  185. $(this).data("mapped", col);
  186. });
  187. // $("#saveBtn").click(function() {
  188. // let mapping = {};
  189. // $(".drop-zone").each(function() {
  190. // mapping[$(this).data("system")] = $(this).data("mapped") || null;
  191. // });
  192. // console.log("Mapping:", mapping);
  193. // alert("Mapping saved successfully!");
  194. // });
  195. $("#saveBtn").click(function() {
  196. let mapping = {};
  197. let allMapped = true;
  198. $(".drop-zone").each(function() {
  199. const systemCol = $(this).data("system");
  200. const mappedCol = $(this).data("mapped");
  201. mapping[systemCol] = mappedCol || null;
  202. if (!mappedCol) {
  203. allMapped = false;
  204. }
  205. });
  206. if (!allMapped) {
  207. alert("Please map all system columns before saving.");
  208. return;
  209. }
  210. console.log("Mapping:", mapping);
  211. alert("Mapping saved successfully!");
  212. });
  213. $("#resetBtn").click(function() {
  214. $(".drop-zone").each(function() {
  215. $(this).html($(this).data("system"));
  216. $(this).removeData("mapped");
  217. });
  218. });
  219. });
  220. </script>
  221. </body>
  222. </html>
  223. <!-- <script>
  224. const uploadedColumns = [];
  225. const systemColumns = ["PRODUCT NAME", "ITEM ID", "PRODUCT TYPE", "Product Short Description", "Product Long Description", "image_path"];
  226. let globalHeaders = []; // To store headers for preview
  227. $(document).ready(function() {
  228. // --- Initial Drop Zone Setup ---
  229. systemColumns.forEach(col => {
  230. $("#system-columns").append(`
  231. <div class="drop-zone" data-system="${col}">
  232. <span class="system-label">${col}</span>
  233. <span class="mapped-content">
  234. <span class="text-muted">No column mapped</span>
  235. </span>
  236. </div>
  237. `);
  238. });
  239. // --- File Upload Handler (Supports CSV/Excel) ---
  240. $("#fileUpload").on("change", function(e) {
  241. const file = e.target.files[0];
  242. if (!file) return;
  243. const reader = new FileReader();
  244. reader.onload = function(event) {
  245. let jsonData;
  246. try {
  247. const data = new Uint8Array(event.target.result);
  248. const workbook = XLSX.read(data, { type: "array" });
  249. const sheetName = workbook.SheetNames[0];
  250. const sheet = workbook.Sheets[sheetName];
  251. // Use { header: 1 } to get an array of arrays, preserving the first row as headers
  252. jsonData = XLSX.utils.sheet_to_json(sheet, { header: 1 });
  253. } catch (err) {
  254. alert("Error reading file. Ensure it is a valid CSV or Excel file.");
  255. console.error(err);
  256. return;
  257. }
  258. const headers = jsonData[0];
  259. const sampleRows = jsonData.slice(1, 6);
  260. globalHeaders = headers; // Store headers globally
  261. // Populate uploaded columns
  262. $("#uploaded-columns").empty();
  263. headers.forEach(col => {
  264. // Check if the column name is not empty or null
  265. if (col && String(col).trim() !== "") {
  266. $("#uploaded-columns").append(`<div class="drag-item" draggable="true" data-col="${col}">${col}</div>`);
  267. }
  268. });
  269. // Remove placeholder text
  270. $("#upload-placeholder").hide();
  271. // Populate preview table
  272. $("#preview-header").html(headers.map(h => `<th scope="col">${h}</th>`).join(''));
  273. $("#preview-body").empty();
  274. if (sampleRows.length > 0) {
  275. sampleRows.forEach(row => {
  276. let tr = "<tr>";
  277. headers.forEach((h, i) => tr += `<td>${row[i] || "-"}</td>`);
  278. tr += "</tr>";
  279. $("#preview-body").append(tr);
  280. });
  281. } else {
  282. $("#preview-body").html('<tr><td colspan="100%" class="text-center text-warning">File uploaded, but no data rows found.</td></tr>');
  283. }
  284. // Re-enable drag-and-drop for new items
  285. enableDragDrop();
  286. };
  287. reader.readAsArrayBuffer(file);
  288. });
  289. // --- Drag and Drop Logic ---
  290. function enableDragDrop() {
  291. // Drag Start
  292. $(".drag-item").off("dragstart").on("dragstart", function(e) {
  293. e.originalEvent.dataTransfer.setData("text/plain", $(this).data("col"));
  294. // Add a class to the item being dragged
  295. $(this).addClass("dragging-active");
  296. });
  297. // Drag End (optional, for cleanup)
  298. $(".drag-item").off("dragend").on("dragend", function() {
  299. $(this).removeClass("dragging-active");
  300. });
  301. // Drop Zone Events
  302. $(".drop-zone").off("dragover").on("dragover", function(e) {
  303. e.preventDefault();
  304. $(this).addClass("hover");
  305. e.originalEvent.dataTransfer.dropEffect = "move";
  306. }).off("dragleave").on("dragleave", function() {
  307. $(this).removeClass("hover");
  308. }).off("drop").on("drop", function(e) {
  309. e.preventDefault();
  310. $(this).removeClass("hover");
  311. const col = e.originalEvent.dataTransfer.getData("text/plain");
  312. const systemCol = $(this).data("system");
  313. // Update the drop zone content
  314. $(this).find('.mapped-content').html(`
  315. <strong>${col}</strong>
  316. <span class="reset-map" title="Unmap Column" data-system="${systemCol}">✖️</span>
  317. `);
  318. $(this).data("mapped", col);
  319. $(this).removeClass("border-danger").addClass("border-success");
  320. // Visually "move" the item from the uploaded list (optional, for a cleaner look)
  321. // $(`.drag-item[data-col="${col}"]`).hide();
  322. });
  323. }
  324. // --- Reset Single Mapping ---
  325. $(document).on("click", ".reset-map", function() {
  326. const dropZone = $(this).closest(".drop-zone");
  327. const systemCol = dropZone.data("system");
  328. const mappedCol = dropZone.data("mapped");
  329. // Reset drop zone appearance and data
  330. dropZone.find('.mapped-content').html(`<span class="text-muted">No column mapped</span>`);
  331. dropZone.removeData("mapped");
  332. dropZone.removeClass("border-success").addClass("border-danger");
  333. // Show the uploaded column item again
  334. if (mappedCol) {
  335. $(`.drag-item[data-col="${mappedCol}"]`).show();
  336. }
  337. });
  338. // --- Reset All Button ---
  339. $("#resetBtn").click(function() {
  340. $(".drop-zone").each(function() {
  341. $(this).find('.mapped-content').html(`<span class="text-muted">No column mapped</span>`);
  342. $(this).removeData("mapped");
  343. $(this).removeClass("border-success border-danger");
  344. });
  345. // Show all uploaded columns again
  346. $(".drag-item").show();
  347. });
  348. // --- Save Button with Validation ---
  349. $("#saveBtn").click(function() {
  350. let mapping = {};
  351. let missingMaps = [];
  352. let allMapped = true;
  353. $(".drop-zone").each(function() {
  354. const systemCol = $(this).data("system");
  355. const mappedCol = $(this).data("mapped");
  356. mapping[systemCol] = mappedCol || null;
  357. if (!mappedCol) {
  358. allMapped = false;
  359. missingMaps.push(systemCol);
  360. $(this).addClass("border-danger"); // Highlight missing map
  361. } else {
  362. $(this).removeClass("border-danger");
  363. }
  364. });
  365. if (!allMapped) {
  366. alert(`Please map all system columns before saving. Missing: ${missingMaps.join(', ')}`);
  367. return;
  368. }
  369. console.log("Final Mapping:", mapping);
  370. alert(`Mapping saved successfully! System Columns Mapped: ${Object.keys(mapping).length}`);
  371. });
  372. // Initial call to enable drag/drop for any pre-populated items (though none are currently)
  373. enableDragDrop();
  374. });
  375. </script> -->