I need to figure out how to incorporate a specific feature into my personal list by leveraging Javascript

Looking at the list below, it's a simple one that allows users to add and remove items while also changing their order using buttons. However, I want to enhance this feature by removing the "up" button for the first item and the "down" button for the last item. Initially, everything might seem fine, but in reality, I only took 4 lines of code to make these changes which led to issues when users modified or added new items. I'm sure there are smarter ways to implement this, but I've personally tried an approach that I can't seem to get working after spending over 2 hours on it.

My idea:

FIRST PART: Creating functions to remove the "up" button from the second li and moving it to the first li. Also, removing the "down" button from the penultimate li and relocating it to the last li.

function upButtonFixer (li1,li2){

var up = document.createElement("BUTTON");
up.className = "up"
up.textContent="up"
li1.appendChild(up); 

var upper = li2.getElementsByClassName('up')[0];
li2.removeChild(upper);
}


 function downButtonFixer (li1,li2){

 var down = document.createElement("BUTTON");
 down.className = "down"
 down.textContent="down" 
 li2.appendChild(down);

 var downer = li1.getElementsByClassName('down')[0];
 li1.removeChild(downer);
 }

SECOND PART : Then I called both functions within an if statement as shown below:

ul.addEventListener('click',(event)=>{

if (event.target.tagName == "BUTTON"){
        if (event.target.className=="up"){

            **if (prevLi == ul.firstElementChild)
                  upAdderRemover(prevLi,li);**     
          }

        if (event.target.className=="down"){

               **if (li==ul.lastElementChild) 
                   downAdderRemover(li,nextLi);**


          } 
            }
... (The remaining HTML, CSS, and JavaScript code has been omitted for brevity) ...

Answer β„–1

After dedicating 4 hours to the problem, I finally found a solution using javascript, although it may not be the most efficient one. But nonetheless, I'm thrilled that it's now implemented and working! 😊

A big shoutout to those who provided their creative CSS solutions. Feel free to check it out.

Without further ado, here are the details:

const toggleList = document.getElementById('toggle');
const listDiv = document.querySelector("div");
const inputDescription = document.querySelector("input.description");
const pDescription = document.querySelector('p.description');
const buttonDescription = document.querySelector('button.description');
const addItemList = document.querySelector('button.adder');
const addInput = document.getElementsByClassName('addInput')[0];
const ul = document.querySelector('ul');
const removeButton = document.querySelector('button.remover');
const lis = ul.children;

// Function to add buttons
function addButtons (li){

    let up = document.createElement("BUTTON");
    up.className = "up"
    up.textContent="up"
    li.appendChild(up);
    
    let down = document.createElement("BUTTON");
    down.className = "down"
    down.textContent="down"
    li.appendChild(down);
    
    let remove = document.createElement("BUTTON");
    remove.className = "remove"
    remove.textContent="remove"
    li.appendChild(remove);
}

for (var i = 0 ; i<lis.length ;i++){
    
    addButtons(lis[i]);
}

// More functions and event listeners follow...

@import 'https://fonts.googleapis.com/css?family=Lato:400,700';

/* CSS styles go here */

<!DOCTYPE html>
<html>
    <head>
        <title>My First Website</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <h2>Im the H2!</h2>
        <p>Im the p!</p>
        <button id="toggle">Hide list!</button> 
        <div class="list">
            <p class="description">The title of the list</p>
            <input type="text" class="description">
            <button class="description">change the title!</button>
            <ul>
                <li>first </li>
                <li>second</li>
                <li>third</li>
                <li>forth</li>
                <li>fifth</li>
                <li>sixth</li>
                <li>seventh</li>
            </ul>
            <input type="text" class="addInput">
            <button class="adder">Add!</button>
            <button class="remover">Remove!</button>
        </div>
        <script src="app.js"></script>
    </body>  
</html>

Answer β„–2

To achieve this effect, you can utilize CSS. Upon implementation, I observed that the initial set of buttons has shifted to the left, but overall, it fulfills your requirements.

Feel free to experiment with the CSS to rectify any minor issues that may arise.

To suppress the JavaScript function responsible for removing the first up and last down button, I opted to conceal these buttons using CSS instead by including the following code snippet:

ul li:first-child .up{ 
    display:none;
}
ul li:last-child .down{ 
    display:none;
}

If you require further clarifications on the changes I've applied, please don’t hesitate to leave a comment below, and I'll address them promptly.

I trust this information proves beneficial. Happy coding!

Edit: Rectified button alignment issue

If you seek a quick resolution for the button positioning problem, consider replacing the CSS with the revised code snippet provided below:

ul li:first-child .up{ 
    visibility:hidden;
}

Answer β„–3

The solution provided here utilizes CSS to meet your requirement in the simplest way possible.

The usage of :last-child and :first-child selectors is employed to toggle the visibility of up and down buttons.

.list>ul>li:first-child>button.up{
  display:none;
}
.list>ul>li:first-child>button.down{
  margin-left: auto;
}
.list>ul>li:last-child>button.down{
  display:none;
}

const listDiv = document.querySelector("div");
const inputDescription = document.querySelector("input.description");
const pDescription = document.querySelector('p.description');
const buttonDescription = document.querySelector('button.description');
const addItemList = document.querySelector('button.adder');
const addInput = document.getElementsByClassName('addInput')[0];
const ul = document.querySelector('ul');
const removeButton = document.querySelector('button.remover');
const lis = ul.children;


function addButtons (li){

    let up = document.createElement("BUTTON");
    up.className = "up"
    up.textContent="up"
    li.appendChild(up);
    
    let down = document.createElement("BUTTON");
    down.className = "down"
    down.textContent="down"
    li.appendChild(down);
    
    let remove = document.createElement("BUTTON");
    remove.className = "remove"
    remove.textContent="remove"
    li.appendChild(remove);
}

for (var i = 0 ; i<lis.length ;i++){
    
    addButtons(lis[i]);
}

buttonDescription.addEventListener('click', ()=>{
   pDescription.textContent = inputDescription.value+':';
});  


addItemList.addEventListener('click',()=>{
    
    let newLI = document.createElement("li"); 
    newLI.textContent = addInput.value;
    addButtons(newLI)
    ul.appendChild(newLI);
    addInput.value = '';
});


removeButton.addEventListener('click', ()=>{
    
    const lastChild = document.querySelector('li:last-child');
    ul.removeChild(lastChild);
    
});



ul.addEventListener('click',(event)=>{
        
    if (event.target.tagName == "BUTTON"){
       if (event.target.className=="remove"){
       const par1 = event.target.parentNode;
       const par2 = par1.parentNode;
       par2.removeChild(par1);
   }
       if (event.target.className=="up"){
        
            const li = event.target.parentNode;
            const prevLi = li.previousElementSibling;
            if (prevLi)
                ul.insertBefore(li,prevLi);
       }
        
        else if (event.target.className=="down"){
           
            const li = event.target.parentNode;
            const nextLi = li.nextElementSibling;
            if (nextLi)
                ul.insertBefore(nextLi,li);                    

   }
   }
});
@import 'https://fonts.googleapis.com/css?family=Lato:400,700';

body {
  color: #484848;
  font-family: 'Lato', sans-serif;
  padding: .45em 2.65em 3em;
  line-height: 1.5;
}
h1 {
  margin-bottom: 0;
}
.list>ul>li:first-child>button.up{
  display:none;
}
.list>ul>li:first-child>button.down{
  margin-left: auto;
}
.list>ul>li:last-child>button.down{
  display:none;
}
h1 + p {
  font-size: 1.08em;
  color: #637a91;
  margin-top: .5em;
  margin-bottom: 2.65em;
  padding-bottom: 1.325em;
  border-bottom: 1px dotted;
}
ul {
  padding-left: 0;
  list-style: none;
}
li {
  padding: .45em .5em;
  margin-bottom: .35em;
  display: flex;
  align-items: center;
}
input,
button {
  font-size: .85em;
  padding: .65em 1em;
  border-radius: .3em;
  outline: 0;
}
input {
  border: 1px solid #dcdcdc;
  margin-right: 1em;
}
div {
  margin-top: 2.8em;
  padding: 1.5em 0 .5em;
  border-top: 1px dotted #637a91;
}
p.description,
p:nth-of-type(2) {
  font-weight: bold;
}
/* Buttons */
button {
  color: white;
  background: #508abc;
  border: solid 1px;
  border-color: rgba(0, 0, 0, .1);
  cursor: pointer;
}
button + button {
  margin-left: .5em;
}
p + button {
  background: #52bab3;
}
.list button + button {
  background: #768da3;
}
list li button + button {
  background: #508abc;
}
li button:first-child {
  margin-left: auto;
  background: #52bab3;
}
.list li button:last-child {
  background: #768da3;
}
li button {
  font-size: .75em;
  padding: .5em .65em;
}
<!DOCTYPE html>
<html>
    
    
    
    <head>
        
        <title>My First Website</title>
        <link rel="stylesheet" href="style.css">

    </head>
    
    
    <body>
    
        <h2>Im the H2!</h2>
        <p>Im the p!</p>        
        <div class="list">
            <p class="description">The title of the list</p>
            <input type="text" class="description">
            <button class="description">change the title!</button>
            <ul>
                <li>first </li>
                <li>second</li>
                <li>third</li>
                <li>forth</li>
                <li>fifth</li>
                <li>sixth</li>
                <li>seventh</li>
                
            </ul>
            <input type="text" class="addInput">
            <button class="adder">Add!</button>
            <button class="remover">Remove!</button>
        </div>
        
        
        
            <script src="app.js"></script>
    </body>
    
    
    
    
</html>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Do not make unnecessary calls to the server when changing the display property of an HTML object

How can I prevent a server request for the pdf file? I've experimented with using visibility=hidden and width=0. <object class='pdfClass' data='"+conventionId+"/showPdf.html' width='100%' height='600'>< ...

Tick the checkbox to choose all checkboxes within a gridview

Here is a simple code I created to check all the checkboxes within a gridview. function checkAll() { if ($("#selectAllCheckbox").is(':checked')) { $("#searchResultsGrid tr").each(function () { debugger ...

What is the mechanism by which sending data directly to the response object displays content to the user?

What exactly does the .pipe(res) segment of the code snippet from that article do at the end of the stream? fs.createReadStream(filePath).pipe(brotli()).pipe(res) I have a basic understanding that the first part reads the file and the second compresses i ...

Selecting an entire row in a Kendo grid

Is there a way to configure kendoGrid to highlight the entire row when clicked on? I have tried setting: scrollable: { virtual: true } and disabled paging, but it doesn't seem to work as intended. You can view an example here: Kendo UI Dojo When ...

How can I invoke TypeScript methods within a jQuery event handler in the ngAfterViewInit lifecycle hook?

I am currently utilizing Angular 4. I need to invoke methods from a typescript file within the ngAfterViewInit method. declare var $; @Component({ selector: 'app-details', templateUrl: './details.component.html', styleUrls: [&apo ...

Don't forget to keep track of when the user has closed

How can I ensure that the cache retains the user's action of closing the div? Currently, when I close the div and refresh the page, it reverts back to its original state. Is there a way to make this change persistent? Experience it live: Here is the ...

"Utilizing multiple class names in Next.js to enhance website styling

Looking for a way to apply multiple classNames in Next.js, especially when dealing with variable classnames? I'm following the component level CSS approach. Take a look at my code and what I aim to achieve: import styles from "./ColorGroup.mod ...

Unable to locate desired view

I have encountered an issue while trying to develop a SPA app. Whenever I launch my application, it gets stuck in an infinite loop which eventually leads to a crash. The framework I am using is ExpressJS 4.3.0 Here is the architecture of my app: public - ...

How can I use Vue.js @scroll to create a dynamic CSS property?

I am developing a vuejs component for my project and I am looking to implement a zoom functionality on scroll within a div, similar to Google Maps. <div @scroll="zoomOnScroll"> <Plotly :data="info" :layout="layout" :display-mode-bar="false"&g ...

Enhance User Experience with ngDialog Modal's Multi-pane Feature for Angular

Looking at the ngDialog example, they showcase a modal with multiple 'panes' that can be scrolled through: . After going through the ngDialog guide, I couldn't find a straightforward way to achieve this. Any suggestions on how to add a butt ...

Change the color of the dropped div in fullcalendar

Here is the code for my customized calendar: $(renderTo).fullCalendar({ timeFormat: 'HH:mm', axisFormat: 'HH:mm', defaultView:view, firstHour: 7, firstDay: 1, titleFormat: { ...

Automatically Save Forms with CKEditor

Trying to implement an autosave feature for a form using CKEditor. The goal is to have all inputs autosaved. <script> //hide preview box $('document').ready(function() { $('#preview').hide(); //Default setting }); //save i ...

Randomize elements with the click of a button

Every time the page refreshes, the words shuffle around. For instance, "May I# know# your name?" shuffles to "know May I your name". To display the correct sentence with "#" as "May I know your name?", click the SHUFFLE button to trigger the shuffling. HT ...

Is hard coding permissions in the frontend considered an effective approach?

I'm in the process of creating an inventory management system that allows admin users to adjust permissions for other employees. Some permissions rely on others to function properly, and I need to display different names for certain permissions on the ...

During the Jasmine test, an error was encountered when trying to call a factory function that includes both a local and another function. The error message displayed

I have a factory with two functions and two local methods. I have written a Jasmine test case in which I expect the local method updateDetails and the factory function SavePref.savePref to be called when SavePref.saveDetails(values, prop); is invoked, as s ...

Unconventional issues involving ajax and fundamental data submission

Upon submitting the ajax request, I need to send three data parameters to process.conversation.php: method, s_state, and c_id. The values for s_state and c_id are retrieved from two input fields. After testing with alert(s_state) and alert(c_id), both vari ...

Is there a way to dynamically insert page breaks in jspdf to ensure that tables do not split across multiple pages?

I am currently working on developing a website that can generate PDFs from database information, using PHP and MySQL to create tables with variable lengths. Sometimes, these tables may even span across multiple pages. If the first table takes up too much ...

Adjust background color as you scroll

Is there a way for me to smoothly change the background color to a solid color as I scroll? I want the transition to happen seamlessly. Check out this link for an example <div class="sticky-nav"> </div> .sticky-nav{ position: fixed; widt ...

How can I retrieve the reference number of an item by clicking a button within a list item in an unordered

Presented here is a collection of data points and a button nested within an ul <ul> <li class="mix" category-1="" data-value="600.35" style="display:block;"> <figure> <figcaption> <h3> ...

Choose the data attribute value and incorporate it into the select dropdown options

I'm brand new to Vue.js. Specifically, the requirement is that the backend will input time slot values into the data-times attributes in array format. My task is to extract and update these time slots based on the selected location. If "Location 1" ...