0

I have the following Javascript code to toggle content between -a- & -ea-. When this runs, I have a "View answer" link in my HTML. Now, I want to behavior like: between -example- & -endexample- , I should have a "View example" link, between -sample- & -endsample-, I should have a "View Sample" link and so on.

The fiddle https://jsfiddle.net/eoc74009/6/

    $(document).ready(funciton(){
    initToggleContent();
});

initToggleContent = function(){
    var p_content = $(".content").html();
    p_content = p_content.replace(new RegExp("-a-","g"),"<div class='hidden toggle-content'>")
  p_content = p_content.replace(new RegExp("-ea-","g"),"</div><hr>")
  $(".content").html(p_content);
  $("<a class='toggle-button'>View Answer</a>").insertBefore(".toggle-content");
  $(document).on('click',".toggle-button",function(){
    $(this).next(".toggle-content").toggleClass("hidden");
    if($(this).html()==="View Answer"){
        $(this).html("Hide Answer");
    }
    else{
    $(this).html("View Answer");
    }
  });

}
4
  • Can include html at Question ? "have tried putting the code in jsfiddle" include link to jsfiddle tried ? Commented Dec 31, 2015 at 15:50
  • jsfiddle.net/eoc74009/4 Commented Dec 31, 2015 at 15:51
  • No element at html at jsfiddle jsfiddle.net/eoc74009/4 appear to have className toggle-button ? Commented Dec 31, 2015 at 15:53
  • @guest271314 jsfiddle.net/eoc74009/6 It works now. Commented Dec 31, 2015 at 16:06

2 Answers 2

1

You can use this code:

p_content = p_content.replace(/-([^\-]+)-([\s\S]*)-end\1-/gm, function(_, name, content) {
   return '<a class="toggle-button" data-name="' + name +
    '">View ' + name + '</a>' +
    '<span class="hidden toggle-content">' +
    content + '</span><hr>';
});

span instead of div because div can't be inside p tag.

Regex explanation:

-([^\-]+)- will match dash, any number of not dashes and a dash

([\s\S]*) will match anything including newline characters

-end\1- will match dash end and prevouisly matched name

parentesis are used as capturing group so you can reference them in replace.

And modifed click handler:

$(document).on('click',".toggle-button",function(){
    $(this).next(".toggle-content").toggleClass("hidden");
    var name = $(this).data('name');
    if($(this).html()==="View " + name){
        $(this).html("Hide " + name);
    }
    else{
        $(this).html("View " + name);
    }
});

JSFIDDLE

Sign up to request clarification or add additional context in comments.

4 Comments

Works perfectly! Though I did not get what you did with the regex there.
We have a problem. If we have a p or div or span tag between my -answer- & -endanswer-, the function cannot take content. jsfiddle.net/eoc74009/12
@learner it work if you don't put -answer- in p tags because that will break html you can have crossing tags <p><a>answer</a><span></p><p></p></span> jsfiddle.net/eoc74009/14
I can't change my html (as it is generated via WYSIWYG). It will convert each line to a p tag. My html would like here jsfiddle.net/eoc74009/15 .
0

I went a little silly on this and kept iterating an the answer to come up with a more frameworky solution, this allows you to create your own html snippets that look kind of like jsx, and rely's on css checkboxes to toggle the content rather than binding js which can get cumbersome if not managed properly.

https://jsfiddle.net/eoc74009/9/

var
  $content = $('.content'),
  __id = makeNumberIterator(),
  text = $content.html();

// this object holds the bbcode functions
var codes = {
  sample: bbcode('sample', function(content, id) {
    return (
      '<section class="sample">' +
        '<input type="checkbox" class="sample-checkbox" id="sample-' + id + '">' +
        '<label for="sample-' + id + '" class="sample__label">Sample</label>' +
        '<div class="sample__content"><h3>' + content + '</h3></div>' +
      '</section>'
    );
  }),
  link: bbcode('a', function(content, id) {
    return (
      '<section class="toggle">' +
        '<input type="checkbox" class="toggle__checkbox" id="toggle-' + id + '">' +
        '<label for="toggle-' + id + '" class="toggle__label">Answer</label>' +
        '<div class="toggle__content">' + content + '</div>' +
      '</section>'
    )
  })
}

$content.html(replaceWithCodes(text, codes));

/**
 * replaceWithCodes
 *
 * this funtion will call each of the bbcodes functions to replace the content
 *
 * @param {string} 	content 	html content from the page
 * @param {Object}	codes 		object of the bbcode functions
 */
function replaceWithCodes(content, codes) {
  for (var key in codes) {
    content = codes[key](content);
  }
  return content;
}

/**
 * bbcode
 *
 * this is a factory for a function to replace your -bbcode- with a template
 *
 * @param {string} 		code 			bbcode to find in text without hyphens
 * @param {Function} 	template 	jsx style function template, recieves content and id
 *
 * @returns {string} 						replaced template
 */
function bbcode(code, template) {
  return function(input) {
    var reg = new RegExp('-' + code + '-([^-]+)-end' + code + '-', 'gm');
    return input.replace(reg, function(_, content) {
      return template(content, __id());
    });
  }
}

/**
 * makeNumeberIterator
 *
 * this is a helper function to get a function which returns
 * an incrementing number
 *
 * @param {Number} 	initial 	initial value to iterate from
 */
function makeNumberIterator(initial) {
  var ii = initial || 0;
  return function() {
    return ii++;
  }
}
* {
  box-sizing: border-box;
}
.sample,
.toggle {
  margin: 1em 0;
}
input[type=checkbox] {
  -webkit-appearance: none;
  appearance: none;
}
input[type=checkbox] ~ label {
  background: #3cf;
  color: white;
  padding: .3em 1em;
  margin: 1em 0;
}
input[type=checkbox] ~ label:before {
  content: "View ";
}
input[type=checkbox] ~ .toggle__content,
input[type=checkbox] ~ .sample__content {
  display: none;
  padding: 1em;
  .3em;
}
input[type=checkbox]:checked ~ label:before {
  content: "Hide ";
}
input[type=checkbox]:checked ~ .toggle__content,
input[type=checkbox]:checked ~ .sample__content {
  display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content">
  <h2>
Hello my name is bleh!
</h2>

  <p>
    -a- Happy new year man! How ya doing?! -enda- -sample- something something darkside -endsample-
  </p>

</div>

2 Comments

But in here, I have to specify whatever code I am using. To use -blah- Hello -endblah-, I have to write the bbcode of blah also.
using the above code you could make different bbcode type of text triggers, so you could have a button or link or dropdown, table etc...but yes you would have to write the extra bbcode for different elements..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.