Home > Back-end >  Jquery target content and place inside div
Jquery target content and place inside div

Time:10-19

I'm working on a project that uses a basic wysiwyg editor to handle content. The editor is a little to basic to work with custom designs. So my idea was to create some shortcodes to inject html using jquery.

The setup for the html is pretty basic:

<p>[images start]</p>
   <img src="some-image.jpg"/>
   <div >Content and other tags</div>
<p>[images end]</p>

<p>[images start align="right"]</p>
   <img src="some-image1.jpg"/>
   <img src="some-image2.jpg"/>
<p>[images end]</p>

<p>[images start align="left"]</p>
   <img src="some-image.jpg"/>
   <div >Content and other tags</div>
<p>[images end]</p>

The <p> wraps are made automatically because of the wysiwyg. The "shortcode" is something i made up to start targeting the content with. It's made for the users to have some extra styling options. The current setup works fine when it's not in a loop and there is only one of a kind. But there are more to be targeted and formatted.

// Foreach P that contains 'images start' text
$('p:contains("[images start")').each(function(){

  // Get start and end tag
  var start = $(this);
  var end = $(this).nextAll('p:contains("[images end]")');
  
  // Get content between tags
  var content = start.nextUntil(end);
  
  // Create a new div to place content in
  start.after('<div ></div>');
  
  // Place content
  $('.images-multiple').html(content);
  
  // Just tests to see it target the shortcodes
  start.css('color','green');
  end.css('color','red');

});

The general idea is to wrap the content between the shortcodes in a div with a class, and delete the shortcodes from the DOM. Preferable with the align value inserted somewhere to target it with css.

Maybe this is not a good approach, but due to limitations I can only insert javascript/jquery, no server side support.

CodePudding user response:

You can use index in your each loop to differentiate .images-multiple elements.

To set text alignment use element.text().includes().

// Foreach P that contains 'images start' text
$('p:contains("[images start")').each( function(index) {
  const content = $(this).nextUntil($(this).nextAll('p:contains("[images end]")'))
  
  if ($(this).text().includes('align="right"')) {
    $(this).before('<div  data-index="'   index   '" style="text-align: right;"></div>');
  } else if ($(this).text().includes('align="center"')) {
    $(this).before('<div  data-index="'   index   '" style="text-align: center;"></div>');
  } else {
    $(this).before('<div  data-index="'   index   '" style="text-align: left;"></div>');
  }
  
  $(content).appendTo( $('.images-multiple[data-index="'   index   '"]') )
  
  $(this).next('p:contains("[images end]")').remove()
  $(this).remove()
})
.images-multiple {
  background-color: yellow;
  margin: 10px;
  padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<p>[images start]</p>
   <img src="some-image.jpg"/>
   <div >Content and other tags</div>
<p>[images end]</p>

<p>[images start align="right"]</p>
   <img src="some-image1.jpg"/>
   <img src="some-image2.jpg"/>
<p>[images end]</p>

<p>[images start align="center"]</p>
   <img src="some-image.jpg"/>
   <div >Content and other tags</div>
<p>[images end]</p>

This will output the following structure:

enter image description here

  • Related