Add options from Pop-Up to Table

I’m in the process of creating a timetable. If I click on a
Tables, a pop-up window will open in which the individual subjects are included. If I select an option from there, the pop-up window should close and the selected option should be entered in the table.

HTML

<div class="popup-table">
        <div class="popup-window">
            <div class="close-popup" onclick="closingPopUp()">
                <h4>X</h4>
            </div>
            <p class="options">Deu</p>
            <p class="options">Eng</p>
            <p class="options">Mat</p>
            <p class="options">Erd</p>
            <p class="options">Ges</p>
            <p class="options">Mus</p>
            <p class="options">Kun</p>
            <p class="options">Spo</p>
            <p class="options">Che</p>
            <p class="options">Phy</p>
            <p class="options">Bio</p>
            <p class="options">Fra</p>
            <p class="options">Spa</p>
            <p class="options">Pol</p>
        </div>
    </div>
    
    <div class="table">
        <div class="row headline">
            <p>Std</p>
            <p>Mo</p>
            <p>Di</p>
            <p>Mi</p>
            <p>Do</p>
            <p>Fr</p>
        </div>
        <div class="row extra">
            <p>1</p>
            <p id="selectText" onclick="openPopUp()"></p>
            <p onclick="openPopUp()"></p>
            <p onclick="openPopUp()"></p>
            <p onclick="openPopUp()"></p>
            <p onclick="openPopUp()"></p>
        </div>
        <div class="row">
            <p>2</p>
            <p onclick="openPopUp()"></p>
            <p onclick="openPopUp()"></p>
            <p onclick="openPopUp()"></p>
            <p onclick="openPopUp()"></p>
            <p onclick="openPopUp()"></p>
        </div>

JavaScript

let row = document.querySelectorAll(".row");
let popUp = document.querySelector(".popup-table");
let closePopUp = document.querySelector(".close-popup");
let options = document.getElementsByClassName("options");
let selectText = document.getElementById("selectText");

function openPopUp() {
    popUp.classList.add("show")
}

function closingPopUp() {
    popUp.classList.remove("show")
}

for(option of options){
    option.onclick = function(){
        selectText.innerHTML = this.textContent;
        closingPopUp();
    }
}

The whole thing only works if I assign an Id and not on a Class. But I can only change this one table field.

Maybe someone can help me make this work and I can make a selection individually in each table field.

Astro project on Vercel deployment

Title:
Error when deploying Astro project on Vercel: “500: INTERNAL_SERVER_ERROR – Code: FUNCTION_INVOCATION_FAILED”

Issue Description:
When attempting to deploy my Astro project on Vercel, the deployment process completes successfully, but I encounter the following error:

500: INTERNAL_SERVER_ERROR
Code: FUNCTION_INVOCATION_FAILED
This issue is accompanied by the following log information:

Time: October 06 12:22:41.74 GMT+02:00
Request Path: /
Status Code: 500
Host: 7sb8p-1696587762095-ea66c95e5111
Request User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
Level: Error
Environment: preview
Branch: v04
Cache: MISS
Type: Serverless Function
Function: /render
Runtime: Node.js 18.x
Execution Duration / Limit: 241ms / 10s
Memory Used / Limit: 19 MB / 1024 MB
In addition, the following module not found error is reported in the logs:

plaintext
Copy code
Error [ERR_MODULE_NOT_FOUND]: Cannot find module ‘/var/task/dist/entry.mjs’ imported from /var/task/___vc/__launcher/__launcher.js
at new NodeError (node:internal/errors:405:5)
at finalizeResolution (node:internal/modules/esm/resolve:329:11)
at moduleResolve (node:internal/modules/esm/resolve:992:10)

I have also tried creating a new project with the same src folder, but the issue persists during deployment on Vercel. Previous versions of the project worked without any problems.

Can someone please help me identify and resolve the “FUNCTION_INVOCATION_FAILED” error and the module not found issue during the deployment of my Astro project on Vercel?

How to add to array by id in react

I’m trying to update an existing array in react using useState, a react hook. What I’m doing in the function below is trying to update the array by id. I want to update the inner ‘inspections’ array and add a new inspection. But whats happening instead is that it’s adding to the end of the ‘data’ array and not to the end of ‘inspections’ array.

Here is my array:

export const data = [
  {
    id: Math.floor(Math.random() * 999999),
    description: "",
    type: "car",
    inspections: [
      {
        id: Math.floor(Math.random() * 999999),
        name: `Inspection${Math.floor(Math.random() * 999999)}`,
        type: "any",
      },
    ],
  },
];

Here is my update function:

 const [dataArray, setDataArray] = useState(data);
 const [inspection, setInspection] = useState("");

 function handleInspection(id) {
    setDataArray((prevState) => [
      ...prevState,
      {
        id: id,
        description: "",
        type: "",
        inspections: [
          {
            id: Math.floor(Math.random() * 999999),
            name: `Inspection${Math.floor(Math.random() * 999999)}`,
            type: inspection,
          },
        ],
      },
    ]);
  }

Here is the data mapped and radio buttons, I’m using radio buttons to select what kind of inspection you can choose: any, car, lorry, van. Once you select an Inspection you should be able to click the button and ‘add a new inspection’ to an existing array of inspections.

  {dataArray.map((vehicles) => {
          return (
            <div>
              <div key={vehicles.id}>vehicle type:{vehicles.type}</div>
              <ul>
                {vehicles.inspections.map((inspection) => {
                  return <li>type: {inspection.type}</li>;
                })}
                lorry
                <input
                  name="option"
                  type="radio"
                  className="form-control"
                  autoFocus={true}
                  onChange={() => setInspection("Lorry")}
                  aria-label="Enter the title of your todo"
                  placeholder="Enter a new todo"
                  value={inspection}
                />
                van
                <input
                  name="option"
                  type="radio"
                  className="form-control"
                  onChange={() => setInspection("Van")}
                  autoFocus={true}
                  aria-label="Enter the title of your todo"
                  placeholder="Enter a new todo"
                  value={inspection}
                />
                car
                <input
                  name="option"
                  type="radio"
                  className="form-control"
                  onChange={() => setInspection("Car")}
                  autoFocus={true}
                  aria-label="Enter the title of your todo"
                  placeholder="Enter a new todo"
                  value={inspection}
                />
                any
                <input
                  name="option"
                  type="radio"
                  className="form-control"
                  onChange={() => setInspection("Any")}
                  autoFocus={true}
                  aria-label="Enter the title of your todo"
                  placeholder="Enter a new todo"
                  value={inspection}
                />
              </ul>
              <button
                className="addButton"
                onClick={() => handleInspection(vehicles.id)}
              >
                Add Inspection
              </button>
            </div>
          );
        })}

Issue with controlled Input in react

Using controlled input to set the value of my input area, but it occurs that when i use backspace on the input field it doesn’t delete the last character in the object where i am saving the input values.

I have don’t know what to try because i’m entirely new to react.

Creating a Dynamic Roulette Wheel in Vue.js with Custom Design

I’m looking to implement a dynamic roulette wheel in a Vue.js application. The wheel needs to adapt its segment sizes, text size, and line breaks automatically based on the number of segments and their content. Additionally, I want to set custom probabilities for each segment. Here’s the design I have in mind: enter image description here

Can anyone guide me on how to create a highly customizable and sharp-looking roulette wheel that meets my design requirements? Any help or pointers to the right libraries or approaches would be greatly appreciated.

I’ve explored several libraries like winwheel.js and wheelnav.js, but I haven’t been able to achieve the desired design and quality. I’m using Vue.js in a Node.js environment and have tried various approaches.

Specifically, with winwheel.js, I faced difficulties in rendering text exactly as per my Figma design, and the output didn’t appear as sharp as desired. enter image description here

How to fill textbox with values dynamically in data table

I am getting data back from the API which I was previously displaying in a table cell. I have now added an input box to the cell and I would like my values to now display in the text box.

My code below fills the values with a hard coded string “Time Remaining”

    columns: [
                    { 'data': 'Studentid' },
                    { 'Testid': 'Testid' },
                    { 'data': 'Name' },
                    { 'data': 'Surname' },
                    { 'data': 'ExamNo' },
                    { 'Studentid': 'Studentid' },
                    { 'data': 'TestName' },
                    { 'data': 'StartDate'},
                    { 'data': 'EndDate' },
                    { 'data': 'Description' },
                    {
                        'data': 'TimeRemaining',
                        render: function (data, type, row) {
                            return '<input class="form-control" id="Markup" name="Markup" type="text"  value = ' +'TimeRemaining'+ '  >'
                        }
                    },
                    {
                        'data': null,
                        "defaultContent": '<button id="btnUpdateTime" type="button" class="btn btn-block btn-primary glow" style="width:100px">Update Time</button>'
                    },
                    {
                        'data': null,
                        "defaultContent": '<button id="btnReset" type="button" class="btn btn-block btn-primary mb-2" style="width:100px">Reset</button>'
                    }
    
                ]

Data is not showing on double button click in reactjs

I am working on reactjs web app where i have a search bar in my home page where user can search within the website and then i am getting that search input and finding data from the firestore and i am going to the new page with the data i got from firestore and then showing the data everytning is working fine but as soon as i clikced again on the search button the data becomes null why ??

my code is

const searchFirestore = async () => {
    try {
      let query = dataref.collectionGroup("room_details");
  
      if (lastVisible) {
        query = query.startAfter(lastVisible);
      }
  
      // Add a filter based on the search input
      if (searchInput.trim() !== "") {
        query = query.where("address", "array-contains", searchInput.trim());
        const snapshot = await query.limit(5).get();
        const newData = snapshot.docs.map((doc) => doc.data());      
        navigation(`/rooms_in` , {state : {newData : newData}})
  
        setFirebaseData(newData); // Update the state with search results
          
    
        if (snapshot.docs.length > 0) {
          setLastVisible(snapshot.docs[snapshot.docs.length - 1]);
        } else {
          setLastVisible(null);
        }
      
    }else{

        toast.success("search field empty!!")
      }
  
     
    } catch (error) {
      console.error("Error searching Firestore:", error);
    }
  };

I have called the search firestore method on the button Search.

the code where i am coming with the data


    const [firebaseData, setFirebaseData] = useState([])


 useEffect(() => {


          setFirebaseData(location.state.newData);
               

    }, [location])

and then i am setting the data in the component but when i clicked the button search again it does not shows the data. Why this is happening???

How to stop a section reloading after Greensock animation is complete

I’ve got a website sectio pinned while image scroll up as the user scrolls. After the animaiton is complete the section seems to reload in to position. Can someone point to me what my mistake is. – here’s a link to the dev site http://ant.mhwddev.co.uk/

Here’s the HTML

<section id="landing-hero" class="full-height">
            <div class="container">
                <h1>A<span class="text-behind">n</span>t<br />S<span class="text-behind">t</span>e<span class="text-behind">e</span>l</h1>
                <img id="landing-hero-image-one" src="<?php echo esc_url( $image_1['url'] ); ?>" alt="<?php echo esc_attr( $image_1['alt'] ); ?>" />
                <img id="landing-hero-image-two" src="<?php echo esc_url( $image_2['url'] ); ?>" alt="<?php echo esc_attr( $image_2['alt'] ); ?>" />
                 <img id="landing-hero-image-three" src="<?php echo esc_url( $image_3['url'] ); ?>" alt="<?php echo esc_attr( $image_3['alt'] ); ?>" />
 
            </div>
        </section>

Here’s the GSAP

gsap.registerPlugin(ScrollTrigger);

const tl = gsap.timeline({
  scrollTrigger: {
    trigger: '#landing-hero',
    start: 'top top',
    end: '+=500', // Adjust this value as needed to ensure images move up before scrolling down
    scrub: 0.1, // Smaller scrub value for smoother animation
  },
});

// Set initial positions of the images off-screen
gsap.set(['#landing-hero-image-one', '#landing-hero-image-two', '#landing-hero-image-three'], { y: '200%' });

// Animate all images simultaneously with smaller increments
tl.to(['#landing-hero-image-one', '#landing-hero-image-two', '#landing-hero-image-three'], {
  duration: 150, // Increase duration for slower animation
  y: '-90%', // Smaller increment for smoother animation
});

// Pin the #landing-hero section and set endTrigger to #landing-hero-image-three
ScrollTrigger.create({
  trigger: '#landing-hero',
  start: 'top top',
  pin: true,
  endTrigger: '#landing-hero-image-three',
  end: 'top+=90', // Adjust this value as needed to match the height of the images
  scrub: 0.1, // Smaller scrub value for smoother pinning
});

// Scroll down the page after the images have reached the top
ScrollTrigger.create({
  trigger: '#landing-hero-image-three',
  start: 'top top',
  end: 'top+=90', // Adjust this value as needed to match the offset of your content
  scrub: 0.1, // Smaller scrub value for smoother scrolling
  onEnter: () => {
    window.scrollTo(0, window.scrollY + 1);
  },
});

I’m expecing the page to scroll as normal once the animations are over, Instead the section seems to reload.

Issue with Google Chrome chrome.sidePanel API

I am developing a simple extension that will allow users to select a text from a web page and then right click on it, choose an item from the contextual menu and see a definition for that word. When doing this I want to open the Chrome side panel only for that specific tab.

I wrote the following in the service-worker.js

function setupContextMenu() {
  chrome.contextMenus.create({
    id: 'define-word',
    title: 'Define',
    contexts: ['selection']
  });
}

chrome.runtime.onInstalled.addListener(() => {
  setupContextMenu();
});

chrome.contextMenus.onClicked.addListener((data) => {

  chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
          if (tabs.length > 0) {
            const tabId = tabs[0].id;
            chrome.sidePanel.open({ tabId });
          }
        });

        chrome.runtime.sendMessage({
                name: 'define-word',
                data: { value: data.selectionText }
              })


});

The problem is that the side panel is opened but the definition is not displayed so, once opened I have to select again the term to see the definition displayed. I think it’s a problem of timing, probably the selected text is sent before the side panel is opened so I don’t see it… do you have an idea on how I could fix it and make so that the side panel is opened and then the definition is displayed? Thanks for helping!

Giaco

Set heightbase on inside height

I am doing a base method to create a button CreateButtonBase(BtnOptions); on C#.

Here is the structure of a button:

<div onClick="someOnclickFunc">
    <image src="/someimage.png" height="someHeight">
    <span>SomeText</span>
</div>

BtnOptions include height that needs to be set for the button. And I have some problems there.

I can set attribute height for an , but it will not have any effect on the height of whole . The height of a div depends on the font-size. If i just change height using a css height with inline-style (which is incorrect) the button will be cut and not shown properly.

Has anyone encountered such a problem?

How to generate pdf or words file that using data input by the user at the webpage

I cant figure out how to make the pdf file get the data input by the user from the website Icreated. The data is successfully retrieve by the database and now I dont know how to make the data from the database to be placed into the pdf file or words.

This is the coding I tried.

HTML:

<input type="button" value="Generate CV" onclick="generatePDF()">
</center>

<script src="https://unpkg.com/[email protected]/dist/index.js"></script>
<script src="lectureredit.js"></script>

and this is the Javascript code:

function generatePDF(){
    var Lecturername = document.getElementById('nameField').value;
    
    props.business.name = Lecturername;  
    var pdfObject = jsPDFInvoiceTemplate.default(props);
    console.log("CV generated : ",pdfObject);
}
        
var props = {
    outputType: jsPDFInvoiceTemplate.OutputType.Save,
    returnJsPDFDocObject: true,
    fileName:"2021",
    orientationLandscape: false,
    compress: true,
    logo: {
        src: "img/logonew.png",
        type: 'PNG', //optional, when src= data:uri (nodejs case)
        width: 53.33, //aspect ratio = width/height
        height: 26.66,
        margin: {
            top: 0, //negative or positive num, from the current position
            left: 0 //negative or positive num, from the current position
        }
    },
    stamp: {
        inAllPages: true, //by default = false, just in the last page
        src: "https://raw.githubusercontent.com/edisonneza/jspdf-invoice-template/demo/images/qr_code.jpg",
        type: 'JPG', //optional, when src= data:uri (nodejs case)
        width: 20, //aspect ratio = width/height
        height: 20,
        margin: {
            top: 0, //negative or positive num, from the current position
            left: 0 //negative or positive num, from the current position
        }
    },
    business: {
        name: "Harry",
        address: "Albania, Tirane ish-Dogana, Durres 2001",
        phone: "(+355) 069 11 11 111",
        email: "[email protected]",
        email_1: "[email protected]",
        website: "www.example.al",
    },
    contact: {
        label: "Invoice issued for:",
        name: "Client Name",
        address: "Albania, Tirane, Astir",
        phone: "(+355) 069 22 22 222",
        email: "[email protected]",
        otherInfo: "www.website.al",
    },
    invoice: {
        label: "Invoice #: ",
        num: 19,
        invDate: "Payment Date: 01/01/2021 18:12",
        invGenDate: "Invoice Date: 02/02/2021 10:17",
        headerBorder: false,
        tableBodyBorder: false,
        header: [
          {
            title: "#", 
            style: { 
              width: 10 
            } 
          }, 
          { 
            title: "Title",
            style: {
              width: 30
            } 
          }, 
          { 
            title: "Description",
            style: {
              width: 80
            } 
          }, 
          { title: "Price"},
          { title: "Quantity"},
          { title: "Unit"},
          { title: "Total"}
        ],
        table: Array.from(Array(10), (item, index)=>([
            index + 1,
            "There are many variations ",
            "Lorem Ipsum is simply dummy text dummy text ",
            200.5,
            4.5,
            "m2",
            400.5
        ])),
        additionalRows: [{
            col1: 'Total:',
            col2: '145,250.50',
            col3: 'ALL',
            style: {
                fontSize: 14 //optional, default 12
            }
        },
        {
            col1: 'VAT:',
            col2: '20',
            col3: '%',
            style: {
                fontSize: 10 //optional, default 12
            }
        },
        {
            col1: 'SubTotal:',
            col2: '116,199.90',
            col3: 'ALL',
            style: {
                fontSize: 10 //optional, default 12
            }
        }],
        invDescLabel: "Invoice Note",
        invDesc: "There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don't look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn't anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary.",
    },
    footer: {
        text: "The invoice is created on a computer and is valid without the signature and stamp.",
    },
    pageEnable: true,
    pageLabel: "Page ",
};

I want to create a dynamic form, but when I enter the jobRespons and projectAccomplishm data it doesn’t match the work experience num, here is my code

Form

Result input

HTML:

<div class="bg-primary flex p-3">
                <h3 class="font-medium text-white">WORK EXPERIENCE</h3>
            </div>
            <div class="bg-white shadow-2xl p-5 flex flex-wrap mb-10">
                <a id="btnExperience" class="cursor-pointer flex ml-auto bg-primary p-2 text-white rounded-md hover:bg-gray-600">Add Work Experience
                    <svg width="22" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="#000000">
                        <g id="SVGRepo_bgCarrier" stroke-width="0"></g>
                        <g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>
                        <g id="SVGRepo_iconCarrier">
                            <title></title>
                            <g id="Complete">
                                <g data-name="add" id="add-2">
                                    <g>
                                        <line fill="none" stroke="#fcfcfc" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" x1="12" x2="12" y1="19" y2="5"></line>
                                        <line fill="none" stroke="#fcfcfc" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" x1="5" x2="19" y1="12" y2="12"></line>
                                    </g>
                                </g>
                            </g>
                        </g>
                    </svg>
                </a>
                <div id="experience" class="w-screen mt-4">
                    <div class="mb-4 flex flex-col gap-2">
                        <div class="tracking-wide font-semibold bg-green-500 px-2 py-1 text-white w-fit rounded-md">
                            Work Experience 1
                        </div>
                        <div class="lg:flex md:flex gap-5 mb-6">
                            <div class="w-full">
                                <label class="tracking-wide text-primary font-semibold mb-2" for="position[]">
                                    Position
                                </label>
                                <input type="text" id="position[]" name="position[]" class="rounded-[20px] appearance-none block w-full bg-gray-50 shadow-[0px_4px_15px_4px_rgba(0,0,0,0.25)] text-gray-700 border border-primary py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-gray-50 focus:border-black">
                            </div>
                            <div class="w-full">
                                <label class="tracking-wide text-primary font-semibold mb-2" for="date_start[]">
                                    Start date
                                </label>
                                <input type="date" id="date_start[]" name="date_start[]" class="rounded-[20px] appearance-none block w-full bg-gray-50 shadow-[0px_4px_15px_4px_rgba(0,0,0,0.25)] text-gray-700 border border-primary py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-gray-50 focus:border-black">
                            </div>
                            <div class="w-full">
                                <label class="tracking-wide text-primary font-semibold  mb-2" for="date_end[]">
                                    End date
                                </label>
                                <input type="date" id="date_end[]" name="date_end[]" class="rounded-[20px] appearance-none block w-full bg-gray-50 shadow-[0px_4px_15px_4px_rgba(0,0,0,0.25)] text-gray-700 border border-primary py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-gray-50 focus:border-black">
                            </div>
                        </div>
                        <div class="lg:flex md:flex gap-5 lg:mb-0">
                            <div data-job="1" id="jobResponsibiities" class="jobResponsibiities  w-full flex flex-col">
                                <a id="btnJob" data-job-experience="1" class="btnJob cursor-pointer bg-primary px-2 py-1 text-white rounded-md hover:bg-gray-600 w-fit mb-4 text-sm">Add Job Responsibilities</a>
                                <div class=" w-full">
                                    <label class="tracking-wide text-primary font-semibold" for="job_responsibilities[]">
                                        Job Responsibilities 1.1
                                    </label>
                                    <input type="text" id="job_responsibilities[]" name="job_responsibilities[]" class=" rounded-[20px] appearance-none block w-full bg-gray-50 shadow-[0px_4px_15px_4px_rgba(0,0,0,0.25)] text-gray-700 border border-primary py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-gray-50 focus:border-black">
                                </div>
                            </div>
                            <div data-project="1" id="projectAccomplishment" class="projectAccomplishment  w-full flex flex-col">
                                <a id="btnProject" data-project-experience="1" class="btnProject cursor-pointer bg-primary px-2 py-1 text-sm text-white rounded-md hover:bg-gray-600 w-fit mb-4">Add Project Accomplishment</a>
                                <div class=" w-full">
                                    <label class="tracking-wide text-primary font-semibold" for="project_accomplishment[]">
                                        Project Accomplishment 1.1
                                    </label>
                                    <input type="text" id="project_accomplishment[]" name="project_accomplishment[]" class=" rounded-[20px] appearance-none block w-full bg-gray-50 shadow-[0px_4px_15px_4px_rgba(0,0,0,0.25)] text-gray-700 border border-primary py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-gray-50 focus:border-black">
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

Javascript(Using JQuery):

<script>
    $(document).ready(function() {
        let number = 2

        $("#btnExperience").click(function() {
            const jobNumber = 1
            const projectNumber = 1

            const experienceHtml = `
            <div class="mb-4 flex flex-col gap-2">
                <div class="tracking-wide font-semibold bg-green-500 px-2 py-1 text-white w-fit rounded-md">
                    Work Experience ${number}
                </div>
                <div class="lg:flex md:flex gap-5 mb-6">
                    <div class="w-full">
                        <label class="tracking-wide text-primary font-semibold mb-2" for="position[]">Position</label>
                        <input type="text" id="position[]" name="position[]" class="rounded-[20px] appearance-none block w-full bg-gray-50 shadow-[0px_4px_15px_4px_rgba(0,0,0,0.25)] text-gray-700 border border-primary py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-gray-50 focus:border-black">
                    </div>
                    <div class="w-full">
                        <label class="tracking-wide text-primary font-semibold mb-2" for="date_start[]">Start date</label>
                        <input type="date" id="date_start[]" name="date_start[]" class="rounded-[20px] appearance-none block w-full bg-gray-50 shadow-[0px_4px_15px_4px_rgba(0,0,0,0.25)] text-gray-700 border border-primary py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-gray-50 focus:border-black">
                    </div>
                    <div class="w-full">
                        <label class="tracking-wide text-primary font-semibold mb-2" for="date_end[]">End date</label>
                        <input type="date" id="date_end[]" name="date_end[]" class="rounded-[20px] appearance-none block w-full bg-gray-50 shadow-[0px_4px_15px_4px_rgba(0,0,0,0.25)] text-gray-700 border border-primary py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-gray-50 focus:border-black">
                    </div>
                </div>
                <div class="lg:flex md:flex gap-5 lg:mb-0">
                    <div data-job="${number}" id="jobResponsibiities" class="jobResponsibiities w-full flex flex-col">
                        <a id="btnJob" data-job-experience="${number}" class="btnJob cursor-pointer bg-primary px-2 py-1 text-white rounded-md hover:bg-gray-600 w-fit mb-4 text-sm">Add Job Responsibilities</a>
                        <div class="w-full">
                            <label class="tracking-wide text-primary font-semibold" for="job_responsibilities[]">Job Responsibilities ${number}.${jobNumber}</label>
                            <input type="text" id="job_responsibilities[]" name="job_responsibilities[]" class="rounded-[20px] appearance-none block w-full bg-gray-50 shadow-[0px_4px_15px_4px_rgba(0,0,0,0.25)] text-gray-700 border border-primary py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-gray-50 focus:border-black">
                        </div>
                    </div>
                    <div data-project="${number}" id="projectAccomplishment" class="projectAccomplishment w-full flex flex-col">
                        <a id="btnProject" data-project-experience="${number}" class="btnProject cursor-pointer bg-primary px-2 py-1 text-sm text-white rounded-md hover:bg-gray-600 w-fit mb-4">Add Project Accomplishment</a>
                        <div class="w-full">
                            <label class="tracking-wide text-primary font-semibold" for="project_accomplishment[]">Project Accomplishment ${number}.${projectNumber}</label>
                            <input type="text" id="project_accomplishment[]" name="project_accomplishment[]" class="rounded-[20px] appearance-none block w-full bg-gray-50 shadow-[0px_4px_15px_4px_rgba(0,0,0,0.25)] text-gray-700 border border-primary py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-gray-50 focus:border-black">
                        </div>
                    </div>
                </div>
                <hr class="mt-2">
            </div>
        `;
            $("#experience").append(experienceHtml);
            number++
        })

        $("#experience").on("click", ".btnJob", function() {
            const experienceJob = $(this).data("job-experience")
            const job = $(this).closest("#jobResponsibiities").data("job")
            console.log(job)

            $jobResponsibilities = $(`[data-job="${job}"]`)

            let jobNumber = 2
            $jobResponsibilities.find(".job-item label").each(function() {
                const labelText = $(this).text()
                const parts = labelText.split(".")
                const currentJobNumber = parseInt(parts[1])

                if (!isNaN(currentJobNumber) && currentJobNumber >= jobNumber) {
                    jobNumber = currentJobNumber + 1
                }
            })

            let jobHtml = `
            <div class="job-item w-full mb-3">
                <label class="tracking-wide text-primary font-semibold" for="job_responsibilities[]">
                    Job Responsibilities ${experienceJob}.${jobNumber}
                </label>
                <div class="flex items-center gap-2">
                    <input
                        type="text"
                        id="job_responsibilities[]"
                        name="job_responsibilities[]"
                        class="rounded-[20px] appearance-none block w-full bg-gray-50 shadow-[0px_4px_15px_4px_rgba(0,0,0,0.25)] text-gray-700 border border-primary py-3 px-4 leading-tight focus:outline-none focus:bg-gray-50 focus:border-black"
                    >
                    <span
                        id="deleteJob"
                        class="bg-white fill-red-500 flex h-fit rounded-full hover:bg-gray-100 hover:fill-red-600 cursor-pointer"
                    >
                        <svg class="w-8" viewBox="0 -0.5 21 21" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
                            <g id="SVGRepo_bgCarrier" stroke-width="0"></g>
                            <g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>
                            <g id="SVGRepo_iconCarrier">
                                <title>minus_circle [#1426]</title>
                                <desc>Created with Sketch.</desc>
                                <defs> </defs>
                                <g id="Page-1" stroke="none" stroke-width="1" fill-rule="evenodd">
                                    <g id="Dribbble-Light-Preview" transform="translate(-219.000000, -600.000000)">
                                        <g id="icons" transform="translate(56.000000, 160.000000)">
                                            <path
                                                d="M177.7,450 C177.7,450.552 177.2296,451 176.65,451 L170.35,451 C169.7704,451 169.3,450.552 169.3,450 C169.3,449.448 169.7704,449 170.35,449 L176.65,449 C177.2296,449 177.7,449.448 177.7,450 M173.5,458 C168.86845,458 165.1,454.411 165.1,450 C165.1,445.589 168.86845,442 173.5,442 C178.13155,442 181.9,445.589 181.9,450 C181.9,454.411 178.13155,458 173.5,458 M173.5,440 C167.70085,440 163,444.477 163,450 C163,455.523 167.70085,460 173.5,460 C179.29915,460 184,455.523 184,450 C184,444.477 179.29915,440 173.5,440"
                                                id="minus_circle-[#1426]"
                                            >
                                            </path>
                                        </g>
                                    </g>
                                </g>
                            </g>
                        </svg>
                    </span>
                </div>
            </div>
            `;
            $jobResponsibilities.append(jobHtml)
        })

        $("#experience").on("click", ".btnProject", function() {
            const experienceProject = $(this).data("project-experience")
            const project = $(this).closest("#projectAccomplishment").data("project")
            console.log(project)

            $projectAccomplishment = $(`[data-project="${project}"]`)

            let projectNumber = 2
            $projectAccomplishment.find(".project-item label").each(function() {
                const labelText = $(this).text()
                const parts = labelText.split(".")
                const currentprojectNumber = parseInt(parts[1])

                if (!isNaN(currentprojectNumber) && currentprojectNumber >= projectNumber) {
                    projectNumber = currentprojectNumber + 1
                }
            })

            let projectHtml = `
            <div class="project-item w-full mb-3">
                <label class="tracking-wide text-primary font-semibold" for="project_accomplishment[]">
                    Project Accomplishment ${experienceProject}.${projectNumber}
                </label>
                <div class="flex items-center gap-2">
                    <input
                        type="text"
                        id="project_accomplishment[]"
                        name="project_accomplishment[]"
                        class="rounded-[20px] appearance-none block w-full bg-gray-50 shadow-[0px_4px_15px_4px_rgba(0,0,0,0.25)] text-gray-700 border border-primary py-3 px-4 leading-tight focus:outline-none focus:bg-gray-50 focus:border-black"
                    >
                    <span
                        id="deleteProject"
                        class="bg-white fill-red-500 flex h-fit rounded-full hover:bg-gray-100 hover:fill-red-600 cursor-pointer"
                    >
                        <svg class="w-8" viewBox="0 -0.5 21 21" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
                            <g id="SVGRepo_bgCarrier" stroke-width="0"></g>
                            <g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>
                            <g id="SVGRepo_iconCarrier">
                                <title>minus_circle [#1426]</title>
                                <desc>Created with Sketch.</desc>
                                <defs> </defs>
                                <g id="Page-1" stroke="none" stroke-width="1" fill-rule="evenodd">
                                    <g id="Dribbble-Light-Preview" transform="translate(-219.000000, -600.000000)">
                                        <g id="icons" transform="translate(56.000000, 160.000000)">
                                            <path
                                                d="M177.7,450 C177.7,450.552 177.2296,451 176.65,451 L170.35,451 C169.7704,451 169.3,450.552 169.3,450 C169.3,449.448 169.7704,449 170.35,449 L176.65,449 C177.2296,449 177.7,449.448 177.7,450 M173.5,458 C168.86845,458 165.1,454.411 165.1,450 C165.1,445.589 168.86845,442 173.5,442 C178.13155,442 181.9,445.589 181.9,450 C181.9,454.411 178.13155,458 173.5,458 M173.5,440 C167.70085,440 163,444.477 163,450 C163,455.523 167.70085,460 173.5,460 C179.29915,460 184,455.523 184,450 C184,444.477 179.29915,440 173.5,440"
                                                id="minus_circle-[#1426]"
                                            >
                                            </path>
                                        </g>
                                    </g>
                                </g>
                            </g>
                        </svg>
                    </span>
                </div>
            </div>
            `;
            $projectAccomplishment.append(projectHtml)
        })

        $("#experience").on("click", "#deleteJob", function() {
            $(this).closest(".job-item").remove()
        })

        $("#experience").on("click", "#deleteProject", function() {
            $(this).closest(".project-item").remove()
        })
    })
</script>

Controller(Using CI 3):

$noExperiences = count($this->input->post('position'));
            for ($noExperience = 0; $noExperience < $noExperiences; $noExperience++) {
                $dataExperience[] = [
                    'cv_id' => $cvId,
                    'experience_number' => $noExperience + 1,
                    'position' => $this->input->post('position')[$noExperience],
                    'date_start' => $this->input->post('date_start')[$noExperience],
                    'date_end' => $this->input->post('date_end')[$noExperience],
                ];

                // Insert the data work experience into the database
                if (!empty($dataExperience)) {
                    $this->db->insert_batch('cv_work_experience', $dataExperience);
                }

                $work_experience_id = $this->db->insert_id();

                for ($noJob = 0; $noJob < count($this->input->post('job_responsibilities')); $noJob++) {
                    $dataJob[] = [
                        'cv_id' => $cvId,
                        'work_experience_id' => $work_experience_id,
                        'experience_number' => $noExperience + 1,
                        'job_responsibilities_number' => $noJob + 1,
                        'job_responsibilities' => $this->input->post('position')[$noExperience] . $this->input->post('job_responsibilities')[$noJob],
                    ];
                }

                for ($noProject = 0; $noProject < count($this->input->post('project_accomplishment')); $noProject++) {
                    $dataProject[] = [
                        'cv_id' => $cvId,
                        'work_experience_id' => $work_experience_id,
                        'experience_number' => $noExperience + 1,
                        'project_accomplishment_number' => $noProject + 1,
                        'project_accomplishment' => $this->input->post('position')[$noExperience] . $this->input->post('project_accomplishment')[$noProject],
                    ];
                }
            }

            echo "<pre>";
            print_r($dataJob);
            echo "</pre>";
            die;

I want to create a dynamic form, but when I enter the jobResponsibilities and projectAccomplishment data it doesn’t match the work experience number, here is my code.

I expect the jobResponbilities and projectAccomplishment data to match the work experience number.

asp.net and jquery ui sortable, mantain order of elements after button click

in the header I have this javascript code:

<script>
    $(function () {
        $("#sortable").sortable();
        $("#sortable").disableSelection();
    });
 function checkOrd() {
     var items = $('#sortable li').map(function () {
         return $.trim($(this).attr('id'));
     }).get();
     
     document.getElementById("rightOrder").value = items;
}
</script>

and this markup:

<form id="form1" runat="server">
    <div>
        <div class="mt-5">
            <div id="d" runat="server"></div>
        </div>
        <asp:HiddenField runat="server" ID="rightOrder" />
        <button onclick="sortItems();">Sort lists</button>
        <button onclick="checkOrd();" runat="server" id="btnCheckOrder" onserverclick="btnCheckOrder_ServerClick">Check order</button>

    </div>
</form>

This is the markup I add by code behind:

<ul id="sortable" class="sortable-list">
 <li id="3" class="item" draggable="true">
  <div class="details">
   <img src="images/img-1.jpg" />
   <span>Bello</span>
  </div>
  <i class="uil uil-draggabledots"></i>
 </li>
 ...
</ul>

And this is my button click:

protected void btnCheckOrder_ServerClick(object sender, EventArgs e) /*versione iniziale*/
 {
     string[] order = rightOrder.Value.Split(',');
     Int16 i = 0;
     foreach (string ordinalID in order)
     {
         ++i;

         HtmlGenericControl ul = (HtmlGenericControl)d.FindControl("sortable");
         HtmlGenericControl listItem = (HtmlGenericControl)ul.FindControl(ordinalID);
         listItem.Attributes.Remove("dragging");
         if (ordinalID != i.ToString()){listItem.Attributes.Add("class", "item bg-danger");}
         else{listItem.Attributes.Add("class", "item bg-success");}
         
     }

The result:

enter image description here

When I change the order of the elements (for example switching the first two) I can get the right order in code behind and change the background color of elements in the correct position to green, but right after that the list order is restored as it was initially (I assume there is a postBack or page refresh). How could I avoid this? After the button is clicked I want to check the correct position of elements and mantain their order. Thanks!

initialize select2 more than twice, but first select2 element got reset

i try to use select2 to make my select input easier to find data, here’s my js and html

<table class="mt-2.5">
<thead>
    <tr>
        <th>Item Name</th>
        <th>Item Qty</th>
        <th>Item Price</th>
        <th>Item Total</th>
        <th>Action</th>
    </tr>
</thead>
<tbody id="items">
    <tr id="items_sample">
        <td>
            <select name="items[]['inventory_id']" id="items[]['inventory_id']"
                class="item_box w-full rounded border-[1.5px] border-stroke bg-transparent py-3 px-5 font-medium outline-none transition focus:border-primary active:border-primary dark:border-form-strokedark dark:bg-form-input dark:focus:border-primary">
                <option value="" disabled selected>Select Item</option>
                @foreach($inventories as $inventory)
                <option value="{{ $inventory->id }}">{{ $inventory->name }}
                </option>
                @endforeach
            </select>
        </td>
        <td>
            <input type="number" name="items[]['qty']" id="items[]['qty']"
                class="w-full rounded border-[1.5px] border-stroke bg-transparent py-3 px-5 font-medium outline-none transition focus:border-primary active:border-primary dark:border-form-strokedark dark:bg-form-input dark:focus:border-primary">
        </td>
        <td>
            <input type="number" name="items[]['price']" id="items[]['price']"
                readonly
                class="w-full rounded border-[1.5px] border-stroke bg-transparent py-3 px-5 font-medium outline-none transition focus:border-primary active:border-primary dark:border-form-strokedark dark:bg-form-input dark:focus:border-primary">
        </td>
        <td>
            <input type="number" name="items[]['total']" id="items[]['total']"
                readonly
                class="w-full rounded border-[1.5px] border-stroke bg-transparent py-3 px-5 font-medium outline-none transition focus:border-primary active:border-primary dark:border-form-strokedark dark:bg-form-input dark:focus:border-primary">
        </td>
        <td>
            <center><a href="javascript:void(0)" onClick="removeItem(this)"
                    class="hover:text-primary" title="Remove Item"><i
                        class="fi fi-rr-trash"></i></a></center>
        </td>
    </tr>
</tbody>
<tfoot>
    <tr>
        <td colspan="3"><b>Total</b></td>
        <td colspan="2"><b id="total">Rp 0,00</b></td>
    </tr>
</tfoot>
</table>

let’s focus on <select.... only with class item_box, and here’s my javascript with first select2 init

var items_sample = null; //variable to save html that i want to clone

$(document).ready(function () {
    items_sample = $("#items_sample").html();
    $('.item_box').select2(); //first select2 when dom is loaded
});

$("#addnewitem").click(function() {
    $("#items").append("<tr>" + items_sample + "</tr>"); //append the cloned html
    var current_item = $("#items").children().last(); //get latest html dom
    current_item.find(".item_box").attr("class", "item_box_" + $("#items").children().length + " w-full rounded border-[1.5px] border-stroke bg-transparent py-3 px-5 font-medium outline-none transition focus:border-primary active:border-primary dark:border-form-strokedark dark:bg-form-input dark:focus:border-primary"); //rename the class to add _index, example item_box_2, item_box_3, item_box_n
    $(".item_box_" + $("#items").children().length).select2(); //select2 ini for the cloned html
});

when the page is loaded, the first select2 .item_box is a success, but when I try (let’s say click button #addnewitem to append cloned html to #items) to click button #addnewitem. the first select2 .item_box is reset/becomes a normal select form and the select2 change to a new select form .item_box_2.

how to fix it?