tags:

views:

35

answers:

2

I'm trying to replace inputs with spans containing the input values in such a way as to be able to switch them back upon clicking a button. I figure this would be most easily done in two stages - adding <span>[input value]</span> in front of the inputs, and then hiding the inputs. The only problem is I'm having trouble with the first part. I'm trying things like

$('#container').find('input')
    .parent()
    .prepend('<span></span>') // this effectively creates: <span></span><input value=____>

However, inside the prepend statement $(this) seems to be undefined, so I can't do

    .prepend('<span>'+$(this).children('input').val()+'</span>')

Since there are several inputs, I can't simply put the input value into a variable. How would I do this?

+4  A: 

For the updated question:

You can do something like this (basing this on comments, an edit per row):

$('input', context).each(function() {
  $("<span />", { text: this.value, "class":"view" }).insertAfter(this);
  $(this).hide();
});

You can view a more detailed demo here, with per-row edit toggling.


For the original question:

You'll want to use .replaceWith() for this:

$('#container').find('input').each(function() {
  $(this).replaceWith("<span>" + this.value + "</span>");
});

The .each() creates a closure in which this refers to the input element, so you can use this.value for example.

To make sure encoding is taken care of, expand it a bit to use .text(), like this:

$('#container').find('input').each(function() {
  $(this).replaceWith($("<span />").text(this.value));
});​

You can try a demo here

Nick Craver
Thanks, that worked very well. However, it actually -replaced- the inputs. I'd like to be able to get them back at the click of a button, hence my idea of hiding them. Sorry for the confusion, my question is updated
Mala
@Nick: +1: Those demos are always useful, a lot of effort put in, simply great man :)
Sarfraz
Excellent effort, but it does not address the concerns of the OP. `replaceWith` literally removes elements from the DOM, and the OP needs to toggle back and forth.
Josh Stodola
@Josh: To be fair, I had worded my question badly, and only updated it after this response. See my first comment
Mala
@Mala - You can use `.prepend()` or `.append()` in the same matter, is this a global button to turn them on/off? Like an edit mode? If that's the case give me minute to update.
Nick Craver
@Nick: No, it's sort of semi-global. I have a table of fields, and each row has its own edit button.
Mala
I reversed my vote (before it locked me out!!)
Josh Stodola
@Nick: Thanks for the suggestion. Replacing ".replaceWith" with ".parent().append" worked a charm :)
Mala
@Mala - If this gives you any additional info, here's a more detailed version that's per-row style: http://jsfiddle.net/NCHJB/3/ I'm not sure of your exact markup, but maybe some useful ideas in there.
Nick Craver
Thanks for the new demo, the markup is very similar to what I have. The only snag I have left is that one of the inputs is a checkbox, whose value is always 1 regardless of whether or not it is checked.
Mala
@Mala - This will always be the case with the value, what would you want to display? You could add a `if (this.type =="checkbox") text = this.checked ? "Yes" : "No"` in there, depending on what you wanted displayed.
Nick Craver
Thanks for all your help! I'm having a little trouble figuring out where to put that as I'm not entirely sure what it does
Mala
@Mala - Welcome :)
Nick Craver
ah nevermind, i got it :) I'm just not entirely used to that ?_:_ format but I figured it out
Mala
+1  A: 

Seems to me like the easiest solution would be to change the inputs to readonly and remove the border (and possibly change background color, depending on your UI), which essentially makes them appear as a regular <span> label.

function spanify() {
  $('#container input')
    .attr("readonly", "readonly")
    .css("borderWidth", "0");
}

function despanify() {
  $('#container input')
    .removeAttr("readonly")
    .css("borderWidth", "auto");
}

Is that feasible?

Josh Stodola
+1 good thought, but no, for my particular purpose this is not sufficient.
Mala
@Mala Yeah, it was a long shot. This certainly isnt good enough if you have anything other than regular textboxes.
Josh Stodola