Tips for replacing the text of an li element while preserving its child elements

I attempted to implement functionality similar to a Trello Card when editing a card, where users are prompted with options to edit, move, or copy the card.

Here is an example of my code:

$(document).ready(function() {
  $('i').click(function() {
    text = $(this).parentsUntil('ul').text();
    $('body').addClass('bckg');
    console.log(text);
    // alert(text);
    $(this).parentsUntil('li').append('<textarea class="textarea">' + text + '</textarea><ul class="opts"><li><a href="#">Edit</a></li><li><a href="#">change icon</a></li><li><a href="#">delete</a></li></ul><br><br><br><button class="btn btn-success">Save</button>');
  });
  $('body').on('blur', 'textarea', function() {
    textarea = $(this).val()
    $(this).parentsUntil('ul').text(textarea);
    $(this).remove();
    // $(this).sibling('button').remove();
    $('body').removeClass('bckg');
    console.log(textarea);
  })
})
.textarea {
  position: absolute;
  left: 0px;
  z-index: 100;
  float: left;
}

.opts {
  position: absolute;
  left: 150px;
  top: 0px;
  z-index: 100;
  list-style-type: none;
  /*background: #FFF;*/
}

.opts li {
  padding: 15px;
  background: rgba(0, 0, 0, .8);
}

.bckg {
  background: rgba(0, 0, 0, .6);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">

<ul>
  <li style="position: relative;">Option1 <a href="JavaScript:void(0)"><i class="fa fa-pencil" aria-hidden="true"></i></a></li>
  <li style="position: relative;">Option2 <a href="JavaScript:void(0)"><i class="fa fa-pencil" aria-hidden="true"></i></a></li>
  <li style="position: relative;">Option3 <a href="JavaScript:void(0)"><i class="fa fa-pencil" aria-hidden="true"></i></a></li>
</ul>

The script above functions as intended in replacing the <li> text with the text from the <textarea>. However, after the jQuery Event .blur(), I encounter an issue where I lose the edit icon <i> that has an event handler bound to it. This prevents me from calling it again from the second time onward. What changes can I make to keep the edit icon along with its event handler intact even after changing the text? Thank you.

Answer №1

This code snippet demonstrates how to handle nested ul elements;

$(document).ready(function() {
 
})
var child;
 $('body').on('click','i',function() {
   $('body').addClass('bckg');
   var text = $(this).closest("li").clone()    //clone the element
    .children() //select all the children
    .remove()   //remove all the children
    .end()  //again go back to selected element
    .text();
    child = $(this).closest("li").children();
    $(this).closest("li").append('<textarea class="textarea">' + text + '</textarea><ul class="opts"><li><a href="#">Edit</a></li><li><a href="#">change icon</a></li><li><a href="#">delete</a></li></ul><br><br><br><button class="btn btn-success">Save</button>');
  });
  
  $('body').on('blur', 'textarea', function() {
    textarea = $(this).val()
    var appendItem =  textarea;
  $(this).closest("li").text('').empty().append(appendItem).append(child);

    $('body').removeClass('bckg');
  })
.textarea {
  position: absolute;
  left: 0px;
  z-index: 100;
  float: left;
}

.opts {
  position: absolute;
  left: 150px;
  top: 0px;
  z-index: 100;
  list-style-type: none;
  /*background: #FFF;*/
}

.opts li {
  padding: 15px;
  background: rgba(0, 0, 0, .8);
}

.bckg {
  background: rgba(0, 0, 0, .6);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">

<ul>
 <li style="position: relative;">Option1 <a href="JavaScript:void(0)"><i class="fa fa-pencil" aria-hidden="true"></i></a> <ul> <li style="position: relative;">Option1 <a href="JavaScript:void(0)"><i class="fa fa-pencil" aria-hidden="true"></i></a></li> </ul> </li>
</ul>

Answer №2

Take a look at the solution below:

$(document).ready(function() {
 
})

 $('body').on('click','i',function() {
   $('body').addClass('bckg');
   var text = $(this).parent().parent().text();
    $(this).parent().parent().append('<textarea class="textarea">' + text + '</textarea><ul class="opts"><li><a href="#">Edit</a></li><li><a href="#">change icon</a></li><li><a href="#">delete</a></li></ul><br><br><br><button class="btn btn-success">Save</button>');
  });
  
  $('body').on('blur', 'textarea', function() {
    textarea = $(this).val()
    var appendItem =  textarea + '<a href="JavaScript:void(0)"><i class="fa fa-pencil" aria-hidden="true"></i></a>'
    
    $(this).parent().text('').empty().append(appendItem);

    $('body').removeClass('bckg');
  })
.textarea {
  position: absolute;
  left: 0px;
  z-index: 100;
  float: left;
}

.opts {
  position: absolute;
  left: 150px;
  top: 0px;
  z-index: 100;
  list-style-type: none;
  /*background: #FFF;*/
}

.opts li {
  padding: 15px;
  background: rgba(0, 0, 0, .8);
}

.bckg {
  background: rgba(0, 0, 0, .6);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">

<ul>
  <li style="position: relative;">Option1 
    <a href="JavaScript:void(0)">
      <i class="fa fa-pencil" aria-hidden="true"></i>
    </a>
  </li>
  
  <li style="position: relative;">Option2 <a href="JavaScript:void(0)"><i class="fa fa-pencil" aria-hidden="true"></i></a></li>
  <li style="position: relative;">Option3 <a href="JavaScript:void(0)"><i class="fa fa-pencil" aria-hidden="true"></i></a></li>
</ul>

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

(Display a loading animation while resolving in Angular-ui-router)

Here is a two part inquiry: When utilizing the resolve property within $stateProvider.state() to retrieve specific server data before controller loading, is there a method to display a loading animation during this process? I am facing an issue wit ...

ReactJS error: Unrecognized property <problem>

Issue: I am facing a problem where the 'completed' property set to a boolean in my to-do list is not getting checked when using toDoData.map (item =>). Within my ToDoData.js file, I have defined a property called "completed" with true or fals ...

JS Code for Optimal Viewing on Mobile Devices

I'm struggling with creating 3 image columns in 2 columns on mobile. It seems like there is a JS issue related to the minslide:3 and maxslide:3 conditions... When viewed on mobile, it's displaying 3 slides instead of 2. How can I adjust it to sh ...

I am facing an issue with Ajax in Laravel, as it is displaying a page not

I'm having trouble sending OTP with Laravel and Ajax. Whenever I try to call the Ajax function, it displays an error saying "Page not found"... HTML: ` <div id="first_step"> <div class="col-md-4" ...

Click the add button to include an identical form element below, with the help of Angular Js

Looking for assistance with implementing a feature in Angular Js. I have two forms, form1 and form2, and an add button. On clicking the add button, I want to dynamically add form2 below form1. Any help from experienced Angular Js developers would be greatl ...

Returning to the top of the page after scrolling with window.scroll

Hey there, I'm trying to make it so that when I visit my website and there is a hashtag in the URL, the page scrolls to that specific section. Here is the JavaScript code I have implemented: document.addEventListener('DOMContentLoaded', () = ...

Is there a way to customize the background color when the Bootstrap 4 toggle switch is in the "checked" position?

I'm struggling to find a way to adjust the background color of the "checked" state for this toggle switch in Bootstrap 4. It utilizes an additional library for toggling between dark and light modes - you can find it here on github. While that function ...

Tips for expanding the grid elements on a Cartesian plane created using Bootstrap4 and Flex!

I am looking to create a Cartesian plane using Bootstrap 4 and Flex. The end goal is to achieve a layout similar to the image linked below: https://i.sstatic.net/THmwV.jpg The plane will consist of a 10x10 grid, with a row for the x labels and a column f ...

What is the best way to store and present data dynamically in D3.js?

Currently, I'm engaged in a project involving my Raspberry Pi that focuses on a sensor collecting data continuously. My objective is to save this data in a specific format such as SQL, CSV, JSON, or any other suitable option, and then present it visua ...

Collecting all Material-UI components into a single document

Currently, I am engaged in a Meteor project that utilizes Material UI and ReactJS. I wish to streamline the process by creating a single file that imports all necessary Material UI components for my project. This way, instead of adding individual exports ...

Activate CSS transition only when not in active state

I have a situation where I want to change the background color immediately upon hovering over an element, and then revert back to the original color when no longer hovering. The CSS for this is straightforward: #el { background-color: black; } #el:hov ...

Tips for truncating text within a textarea

I need help with trimming text inside a textarea and displaying the result. For example: " 1234 " should become "1234" Unfortunately, my current code is not working as expected. It doesn't trim the text and returns nothing. This is the HTML ...

Unexpected behavior with if statements in jQuery

Having recently started using jQuery, I am embarking on the creation of a survey. Each question within the survey resides in its own div and is unveiled upon clicking the "Next" button. Currently, all divs are hidden except for the current one. My approach ...

What is the reason that filter_input does not work for retrieving form data when $_GET functions without any issues?

Currently, I am utilizing the get method along with a form to save the status of checkboxes into an array. I have made an effort to utilize a filter_input line to grab details from each checkbox one by one and store it in an array. Everything seems to wor ...

Ways to extract specific HTML from a jQuery element

When fetching html from a website, how can I extract specific html content instead of getting all of it? I have attempted the following method: Before appending data to the target below container.html(data); I would like to perform something like data.f ...

Tips for locking the button in the navigation bar while scrolling

I noticed that when I have 6 fields in my navbar, with 5 of them being links and one as a dropdown, the scrolling of the page causes all fields to remain fixed except for the dropdown field.Check out this image description for reference https://i.stack.im ...

CustomJS TextBox callback to adjust range of x-axis: Bokeh

I'm currently working on a web page that features a plot powered by an AjaxDataSource object. However, I am facing a challenge with implementing a TextInput widget that can modify the xrange of this plot. Here is a snippet of my code: source = AjaxDa ...

Using React.PureComponent, the list component efficiently renders each item with optimized performance

We've developed a reusable list component in ReactJS. To address performance concerns, we decided to incorporate the shouldComponentUpdate method to dictate when our list component should re-render. public shouldComponentUpdate(nextProps: TreeItemInt ...

Svelte: How to Create a Dynamic Component that Reacts to Changes in Variables

How can I make my "Body" Svelte component rerender whenever the value of "view.current" changes in order to display the corresponding .svelte view/component? App.svelte <script> import Header from "./components/Header.svelte"; ...

Halt the execution of JavaScript code

I'm having trouble making this conditional if statement work properly... The line " if ( !$section.id == "no-transition" ) " seems to be incorrect. My goal is to prevent JavaScript from executing on sections with the id "no-transition". Could someo ...