laker001 laker001 - 3 months ago 17
HTML Question

Turning a span into an input box using jquery

I want to turn a certain number of span elements into input boxes, whenever i click the edit button, and back to span when i click another one,but i'm facing some issues:

Here's my fiddle:

Fiddle

And my code:

HTML:

<span id="1">hedh</span>
<br />
<span id="2">2222eh3222222</span>
<br />
<span id="3">333333eh33333</span>
<br />
<span id="4">44444eher44444</span>
<br />
<span id="5">555555edgt5555</span>
<br />

<button id="edit_properties">Edit</button>
<button id="unedit_properties">Save</button>


JavaScript:

var switchToInput = function(id_value) {
var $input = $("<input>", {
val: $(this).text(),
type: "text"
});
$input.attr("ID", id_value);
$(this).replaceWith($input);
$input.select();
};
var switchToSpan = function(id_value) {
var $span = $("<span>", {
text: $(this).val()
});
$span.attr("ID", id_value);
$(this).replaceWith($span);
$span.on("click", switchToInput);
}
$("#edit_properties").on("click", function() {

switchToInput(1);
switchToInput(2);
switchToInput(3);
switchToInput(4);
switchToInput(5);

});
$("#unedit_properties").on("click", function() {

switchToSpan(1);
switchToSpan(2);
switchToSpan(3);
switchToSpan(4);
switchToSpan(5);

});

Answer

You have several issues with your code:

  • The </br> elements should be <br />
  • Numeric id attribute values cause issues in certain browsers. You should change them to alphanumeric.
  • When you click the edit button you get an error in the console:

    Uncaught TypeError: Cannot read property 'createDocumentFragment' of undefined

  • The scope of this will be the window not the span

The last point is the major issue with your code.

To fix this you can put a common class on all the span/input elements, and provide a function to replaceWith() that builds the appropriate element to perform the replacement. Try this:

$("#edit_properties").on("click", function() {
  $('.editable-span').replaceWith(function() {
    return $("<input>", {
      val: $(this).text(),
      type: "text",
      id: this.id,
      class: 'editable-input'
    });
  });
});

$("#unedit_properties").on("click", function() {
  $('.editable-input').replaceWith(function() {
    return $("<span>", {
      text: this.value,
      id: this.id,
      class: 'editable-span'
    });
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="s1" class="editable-span">hedh</span><br />
<span id="s2" class="editable-span">2222eh3222222</span><br />
<span id="s3" class="editable-span">333333eh33333</span><br />
<span id="s4" class="editable-span">44444eher44444</span><br />
<span id="s5" class="editable-span">555555edgt5555</span><br />

<button id="edit_properties">Edit</button>
<button id="unedit_properties">Save</button>

Alternatively you could not bother with the edit or save buttons at all and just set the contenteditable="true" attribute on the span elements.