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...
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.
type = "text"; line, put input.name = "the name you want"; . You might take that name from an attribute on the source element.
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.
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>
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With