Rotate the text element into text such as an input field when it is clicked, and change it to text when pressed

I am trying to create a form with variable fields.

Start with plain text, and when someone clicks on that text, it goes into an editable text input field. When someone clicks, he returns to the edited text.

I let him go, but it doesn't seem to be working properly. Works great on the first two clicks, but then it loses the inputId and mixes the buttons.

Here is the html

<p id="firstElement" onclick="turnTextIntoInputField('firstElement');">First Element</p> <p id="secondElement" onclick="turnTextIntoInputField('secondElement');">Second Element</p> 

And here is the JavaScript (using jQuery).

I am completely new in JavaScript, so it may not be the best quality code ...

 function turnTextIntoInputField(inputId) { console.log(inputId); inputIdWithHash = "#"+inputId; elementValue = $(inputIdWithHash).text(); $(inputIdWithHash).replaceWith('<input name="test" id="'+inputId+'" type="text" value="'+elementValue+'">'); $(document).click(function(event) { if(!$(event.target).closest(inputIdWithHash).length) { $(inputIdWithHash).replaceWith('<p id="'+inputId+'" onclick="turnTextIntoInputField(\''+inputId+'\')">'+elementValue+'</p>'); } }); } 

Here is a live example on the fiddle https://jsfiddle.net/7jz510hg/

I will be grateful for any help as this gives me a headache ...

+8
source share
4 answers

First of all, you do not need to use onclick in the html itself.

And here is another approach you can take:

 /** We're defining the event on the `body` element, because we know the `body` is not going away. Second argument makes sure the callback only fires when the `click` event happens only on elements marked as `data-editable` */ $('body').on('click', '[data-editable]', function(){ var $el = $(this); var $input = $('<input/>').val( $el.text() ); $el.replaceWith( $input ); var save = function(){ var $p = $('<p data-editable />').text( $input.val() ); $input.replaceWith( $p ); }; /** We're defining the callback with `one`, because we know that the element will be gone just after that, and we don't want any callbacks leftovers take memory. Next time `p` turns into `input` this single callback will be applied again. */ $input.one('blur', save).focus(); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <p data-editable>First Element</p> <p data-editable>Second Element</p> <p>Not editable</p> 
+25
source

Fiddle: https://jsfiddle.net/7jz510hg/1/

The problem was that without defining the variables inputIdWithHash and elementValue with var, they became global variables.

 var inputIdWithHash var elementValue 

Then, since they had a global scope, the old values ​​were available to the document's click handler. You want them to be locally bound to this function turnTextIntoInputField.

And the update supporting the values: https://jsfiddle.net/7jz510hg/2/

Side note: you are using jQuery 1.6, so I had to use the unbind function instead of off.

Updated script: https://jsfiddle.net/7jz510hg/3/

It uses the latest jquery, the event namespace, so we can attach more than one click event to the document, which allows us to click between the fields and not lose anything. The previous violin will go bad, if you click directly on the fields instead of the click field, click on the document, click on the field.

+3
source

Try it

 $('#tbl').on('click','.editable',function() { var t = $(this); var input = $('<input>').attr('class', 'savable').val( t.text() ); t.replaceWith( input ); input.focus(); }); $('#tbl').on('blur','.savable',function() { var input = $(this); var t = $('<span>').attr('class', 'editable').text( input.val() ); input.replaceWith( t ); }); 

http://jsfiddle.net/yp8bt6s0/

0
source

I suggest do not complicate this. I changed the text in the input field using a simple method of hiding and showing. It is very easy to implement and understand.

  $('#editable').on('click',function(){ $("#editable").css({'display':"none"}); $("#inputgroupname").css({'display':'block'}); $("#inputgroupname").focus(); $("#inputgroupname").val(groupname); }); $("#inputgroupname").focusout(function(){ $('#editable').html($("#inputgroupname").val()); $("#inputgroupname").css({'display':'none'}); $("#editable").css({'display':"block","margin-top":"2px"}); }); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <h3 class="box-title" style="margin-top:2px; margin-left:5px;" id="editable">Hello</h3> <input type="text" id="inputgroupname" style="display:none;"> 
0
source

All Articles