2

Possible Duplicate:
Change the tag name but keep all the attributes

Is it possible to replace an <a> tag with a <span> tag and keep all of it's attributes?

I have this HTML, and when someone clicks on Edit I want to convert all edit links to span's

<a href="javascript:void(0);" class="edit" data-id="123">Edit</a>

Once the user is done editing (by either pressing Save or Cancel) I then want to convert all the span tags back into links.

$(".edit").live("click", function(){
    $(".edit").addClass("inactive-link");
});
Community
  • 1
  • 1
Get Off My Lawn
  • 34,175
  • 38
  • 176
  • 338

6 Answers6

3

This should suit your needs:

function switchTag(e, toTag) {
    var outerHTML = e.outerHTML;
    outerHTML = outerHTML.replace(/^<([a-z])(.*?)>(.*?)<\/\1>$/ig, "<" + toTag + "$2>$3</" + toTag + ">");
    e.outerHTML = outerHTML;
};

Example of use:

$(".edit").click(function() {
    switchTag(this, "span");
});

Demo available ;)

sp00m
  • 47,968
  • 31
  • 142
  • 252
1

As FAngel indicates, style changes are much simpler in this case. I'm going to go ahead and use event delegation instead of .live in my example because .live will be removed in later jQuery versions:

$(document).on('click', '.edit', function (e) {
   //add inactive class to *this* link
   $(this).addClass('inactive-link');

   //stop default link behavior, i.e. opening a new page
   e.preventDefault();
});
Explosion Pills
  • 188,624
  • 52
  • 326
  • 405
  • Will this disable all edit links? because that is what I want. – Get Off My Lawn Jan 14 '13 at 18:56
  • @RyanNaddy yes, every `.edit` link that is clicked will call `e.preventDefault()` – Explosion Pills Jan 14 '13 at 19:00
  • @ExplosionPills `e.preventDefault()` is useless in order to prevent onclick handler execution. While it is good as a replacement for `href="javascript:void(0);"`, it will not prevent execution of attached events. – Viktor S. Jan 14 '13 at 19:32
  • @FAngel I may have misunderstood .. if he wants to prevent other attached handlers from firing he should use `e.stopImmediatePropagation()` – Explosion Pills Jan 14 '13 at 19:33
1
$(".edit").live("click", function(e){
    if(!$(e.target).hasClass("inactive-link")) { //suppose $(this) will work instead of $(e.target), but do not remember for sure
         $(".edit").addClass("inactive-link");// after this is done - this function will not execute anymore for .edit elements because of previouse if statement
         //code to start editing
    }
});

Just check if clicked element has class inactive-link. And remove it after editing is done.

Basically, there is no "disable" feature for links. But you can unbind event handlers while in edit mode, or check if links has some class, like in my code above.

Also, please note that live is deprecated and you should better use .on (if you have some latest jQuery, v1.7 and higher). Here you can find how to replace live with on

Viktor S.
  • 12,736
  • 1
  • 27
  • 52
0
// Replacement Tag
var replacementTag = 'span';

$('a').each(function() {
    var outer = this.outerHTML;

    // Replace opening tag
    var regex = new RegExp('<' + this.tagName, 'i');
    var newTag = outer.replace(regex, '<' + replacementTag);

    // Replace closing tag
    regex = new RegExp('</' + this.tagName, 'i');
    newTag = newTag.replace(regex, '</' + replacementTag);

    $(this).replaceWith(newTag);
});

Link http://jsfiddle.net/tTAJM/19/

Ramesh
  • 21
  • 4
0

I would use two containers : links and edit-links

When edit button is pressed, I would populate div edit-links with all the <a> tags from container links converted to <span>

When save button is pressed, I would re-create all the <a> tags in the links container.

$('#myButtonEdit').click(function(){        
    $('#links').hide();
    $('#edit-links').empty();

    //loop on all <a> tags to create <span> in edit-links div
    $('a').each(function(){
        $('#edit-links').append('<span id="'+this.id+'" class="'+$(this).attr('class')+'">'+$(this).attr('href')+'</span>');
    });
});

$('#myButtonSave').click(function(){

    $('#edit-links').hide();
    $('#links').empty();

    //loop on all <span> tags to create <a> in links container
    $('#edit-links span').each(function(){
        $('#links').append('<a id="'+this.id+'" class="'+$(this).attr('class')+'" href="'+$(this).html()+'">'+$(this).html()+'</span>');
    });
});
sdespont
  • 13,915
  • 9
  • 56
  • 97
0

Besides I don't like the way you want to solve your problem, here is one possible solution:

function replaceElement(el, tagName) {
  var attrs = {
    text: el.innerHTML
  };
  $.each(el.attributes, function() {
    attrs[this.nodeName] = this.nodeValue;
  });
  $(el).replaceWith($("<" + tagName + " />", attrs));
}

$("a.edit").on("click", function() {
  replaceElement(this, "span");
});

DEMO: http://jsfiddle.net/rxzdK/

Here new element will contain all attributes from the replaced element. However you should consider that <span> shouldn't have src attribute according to the standards.

VisioN
  • 143,310
  • 32
  • 282
  • 281