Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Turn text element into input field type text when clicked and change back to text when clicked away

I am trying to create a form with fields changing on fly.

Start with simple text and when someone clicks on this text it transfers into editable text input field. When someone clicks away it turns back into non-editable text.

I gave it a go but it does not seem to work properly. Works fine on first couple of clicks but then it's loosing inputId and is mixing 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 quite new in JavaScript so it may not be 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 live example on fiddle https://jsfiddle.net/7jz510hg/

I will appreciate any help as it's giving me a headache...

like image 947
zachu Avatar asked Oct 21 '15 19:10

zachu


People also ask

How do I use Onchange input tag?

Definition and UsageThe onchange attribute fires the moment when the value of the element is changed. Tip: This event is similar to the oninput event. The difference is that the oninput event occurs immediately after the value of an element has changed, while onchange occurs when the element loses focus.

How do you change the input field of text in HTML?

type = "text"; line, put input.name = "the name you want"; . You might take that name from an attribute on the source element.

How do I make a text field editable?

Answer: Use the HTML5 contenteditable Attribute You can set the HTML5 contenteditable attribute with the value true (i.e. contentEditable="true" ) to make an element editable in HTML, such as <div> or <p> element.


2 Answers

First of all, you shouldn't need to use onclick in the html itself.

And here's another approach you might 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>
like image 121
Yura Avatar answered Oct 02 '22 17:10

Yura


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

The issue was by not defining the inputIdWithHash and elementValue variables with var they became global variables.

var inputIdWithHash
var elementValue

Then since they had global scope the old values of them were available to the document click handler. You want them locally scoped within that turnTextIntoInputField function.

And an update maintaining values: https://jsfiddle.net/7jz510hg/2/

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

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

This uses latest jquery, event namespacing so we can attach more than one click event to the document therefore allowing us to click between the fields and not lose anything. The previous fiddle would mess up if you clicked directly on fields instead of click field, click document, click field.

like image 34
AtheistP3ace Avatar answered Oct 02 '22 17:10

AtheistP3ace