-1

I use a tag to identify messages. This tag like DHHS1709PJ. You can see in the below HTML, it is sometimes the id of an element, sometimes the value of an element, sometimes in the href or aria-controls. I have been strugling to find a way to parse this entire block as a string so I can use a regex and replace each instance of the tag, whether it is an attribute or a value.

I have the following HTML:

  <li id='msg-DHHS1709PJ' class="draggable">
    <div class="panel panel-primary">
      <div class="panel-heading">
        <h3 class="panel-title"> Message
          <a id="DHHS1709PJ" class="pull-right cancel" href="#">
            <i class="fa fa-times-circle"></i>
          </a>
          <a class="pull-right" data-toggle="collapse" data-perform="panel-collapse" href="#body-DHHS1709PJ" aria-expanded="true" aria-controls="body-DHHS1709PJ">
            <i class="panel-toggle fa fa-minus"></i>
          </a>
        </h3>
        <span>Voiced by: Joe</span>
      </div>
      <div id="body-DHHS1709PJ" class="panel-wrapper collapse in">
      <div class="panel-body">
        Message Copy
      </div>
      </div>
    </div>
  </li>

Is this possible? or will I have to write a block of code for every scenario? (For instance, write one block of code to check for the aria-controls attribute, then another to check if any element has the tag as its value, etc) It seems to me it'd be best to just iterate over the whole thing with a regex and see if any matches are found, and if so, replace them with my new tag.

I'm using JQuery UI's Draggable function to drag the above HTML list item from one unordered list to another unordered list. Using the Helper function, i'm cloning the entire list item, but i need to change all the tags when it gets dropped so that i don't have two identical list items.

Here's the jQuery i have so far... I've gotten up to the point where I need to iterate over everything and check to see if the tag exists. But as mentioned above i'm having trouble writing code which looks at both the values of the elements and the attributes of the elements at the same time.

$( ".draggable" ).draggable({
  connectToSortable: ".new-campaign",
  handle: ".panel-heading",
  cancel: ".panel-toggle",
  containment: "document",
  delay: 150,
  opacity: .75,
  revert: "invalid",
  helper: function(e) {
    workspace = $( '#workspace' ).html(); // the relevant part of the DOM
    clone = $(this).clone(true,true); // make the clone
    tag = clone.find('#msg-tag').text(); // extract the tag
    var_created = false; // trigger for while loop
    while (var_created == false) {
      if ( $(workspace).find( "#msg-"+tag ).length) { // current way i'm checking to see if the tag is already in the DOM
        // a matching tag in the workspace has been found
        // proceed with new tag creation and discovery
      tag += '-new';  
      }
      else {
        var_created = true;
      }

    }

    return clone;
  }

});

EDIT with FINAL code

I ended up having to move this function to the receive portion of my sortable:

  receive: function(e, ui){
    var workspace = $( '#workspace' ).html();
    var tag = $(ui.item).find('#msg-tag').text();
    var new_tag = tag;
    var var_created = false;
    var count = 1;
    while (var_created == false) {
      if ( $(workspace).find( "#"+new_tag ).length) {
        new_tag += "-x"+count;
        count += 1;
      }
      else {
        var re = new RegExp(tag, "g")
        $(this).html($(this).html().replace(re, new_tag));
        $( '#body-'+new_tag ).closest('li').attr('id', new_tag);
        var_created = true;
      }
    }
    $(this).find('.cancel').show(); 
    $(this).find('.panel').removeClass('panel-primary').addClass('panel-info');
    ui.item.find('.panel').removeClass('panel-primary').addClass('panel-success');
  }
});
Chockomonkey
  • 3,895
  • 7
  • 38
  • 55
  • 1
    Parse it where? On the server? In your text editor? Is this the HTML of a page sent to a browser? Is it some text in a JavaScript program? –  Nov 20 '15 at 17:53
  • http://api.jquery.com/html/ – forgivenson Nov 20 '15 at 17:53
  • 1
    There are just too many assumptions that need to be made in order to answer. But let's pretend that this gets turned into a DOM in a web browser (just to try to give some definition), assuming the placement of each tag can't change, I would at least give each element a separate `data-` attribute that tells you where the tag exists. So like `data-tag-loc="id"` and `data-tag-loc="href"`. Then you can select all elements that have a `data-tag-loc` attribute, and easily tell where the tag is. –  Nov 20 '15 at 17:59
  • 1
    `var tag_elems = document.querySelectorAll("[data-tag-loc]");` then loop the collection and do `var tag_val = elem.getAttribute(elem.getAttribute("data-tag-loc"));` –  Nov 20 '15 at 18:01

1 Answers1

1

At the highest level,

$(document.body).html($(document.body).html().replace(regex, replacement));

might do what you want.

However, be aware that you could lose any event handlers or other data attached to DOM elements.

Alternatively, if you want to replace all attributes, you could consider iterating each DOM element's attributes: https://stackoverflow.com/a/2224987/1059070

$('*').each(function(i, e) {
  $.each(e.attributes, function(i, attrib){
    $(e).attr(attrib.name, attrib.value.replace(regex, replacement));
  });
});
Community
  • 1
  • 1
arcyqwerty
  • 10,325
  • 4
  • 47
  • 84