Reputation: 2097
Hi all im trying out using botstraps "collapse" element for spoiler bbcode tags and it looks great, but I do have one issue.
If you have more than one collapse on a page and click any of them, it always opens/closes the first one.
Is there a way to make it only open/close the one you click on?
Right now it just replaces this:
"/\[spoiler\](.+?)\[\/spoiler\]/is"
With this:
'<div class="panel-group" id="accordion"><div class="panel panel-default"><div class="panel-heading"><h4 class="panel-title"><a data-toggle="collapse" data-parent="#accordion" href="#collapseOne">Spoiler, click to open</a></h4></div><div id="collapseOne" class="panel-collapse collapse"><div class="panel-body">$1</div></div></div>'
Is there just a simple way to make it only open the one you click on?
This is my code right now:
// Spoiler
$pattern = '/\[spoiler\](.+?)\[\/spoiler\]/is';
$replace = '<div class="panel-group" id="accordion"><div class="panel panel-default"><div class="panel-heading"><h4 class="panel-title"><a data-toggle="collapse" data-parent="#accordion" href="#collapseOne">Spoiler, click to open</a></h4></div><div id="collapseOne" class="panel-collapse collapse in"><div class="panel-body">$1</div></div></div>';
while(preg_match($pattern, $body))
{
$body = preg_replace($pattern, $replace, $body);
}
Upvotes: 0
Views: 332
Reputation: 381
If you look closely, you can see "#collapseOne"
in the open link's href, and id="collapseOne"
in the spoiler div. If you replace it with this same replacement string for every spoiler tag, every tag will have the same href and Id. It will most likely open the first one due to default browser behavior
You should keep a variable that increments the numer of times a spoiler has been parsed, and insert that in both the link's href and the spoiler-div's id.
If we look at the code you provided, you could do it like this:
// Spoiler
$pattern = '/\[spoiler\](.+?)\[\/spoiler\]/is';
$spoilCount = 0;
while(preg_match($pattern, $body))
{
$replace = '<div class="panel-group" id="accordion"><div class="panel panel-default"><div class="panel-heading"><h4 class="panel-title"><a data-toggle="collapse" data-parent="#accordion" href="#collapse'. $spoilCount . '">Spoiler, click to open</a></h4></div><div id="collapse' . $spoilCount . '" class="panel-collapse collapse in"><div class="panel-body">$1</div></div></div>';
$body = preg_replace($pattern, $replace, $body, 1);
$spoilCount++;
}
It is however better to use a callback function (with preg_replace_callback) to replace and then increment the count. This is (i would assume) better for performance.
Upvotes: 4
Reputation: 9411
The issue is with the ID of the div id="accordion"
An ID must be unique in the document so it cannot appear multiple times. If it does it generally fires the first one it finds.
You will need to apply the accordion event on a class instead
Upvotes: 1