0

I am doing custom collapse using jquery, but my way of writing is to repeat code. Is there any way not to repeat code? Plz help...

$('#muqfeas878zalh4vxayb1rkqyfjctk1v .block-title').wrap("<div class='click-wrapper-one'></div>");
$('#muqfeas878zalh4vxayb1rkqyfjctk1v .block-title').after("<div class='drop-arrow-down'></div>");
$('#muqfeas878zalh4vxayb1rkqyfjctk1v .block-title').addClass("drop-arrow-down-title");
$('#muqfeas878zalh4vxayb1rkqyfjctk1v .click-wrapper-one').on('click', function(e) {
  $(this).toggleClass("collapsed");
  $(this).parent().toggleClass("active drop-arrow-down");
  $(".field-hanger").toggle();
  e.preventDefault();
});

again I have to write same code for next block by changing some class. And there are so many blocks like this.

$('#gwe1osm3ylp7imv4bbu1fquivij15wk6 .block-title').wrap("<div class='click-wrapper-two'></div>");
$('#gwe1osm3ylp7imv4bbu1fquivij15wk6 .block-title').after("<div class='drop-arrow-down'></div>");
$('#gwe1osm3ylp7imv4bbu1fquivij15wk6 .block-title').addClass("drop-arrow-down-title");
$('#gwe1osm3ylp7imv4bbu1fquivij15wk6 .click-wrapper-two').on('click', function(e) {
  $(this).toggleClass("collapsed"); 
  $(this).parent().toggleClass("active drop-arrow-down");
  $(".field-door-type").toggle();
  e.preventDefault();
});

Thanks in advance.

Mukunda Bhatta
  • 581
  • 3
  • 14

1 Answers1

5

I would wrap the code in a function that accepts the ID and the index:

function prepBlockTitles(id, togglerClass, index) {
    var blockTitles = $(id + ' .block-title');

    blockTitles.wrap("<div class='click-wrapper-"+index+"'></div>");
    blockTitles.after("<div class='drop-arrow-down'></div>");
    blockTitles.addClass("drop-arrow-down-title");
    $(id + ' .click-wrapper-'+index).on('click', function(e) {
      $(this).toggleClass("collapsed");
      $(this).parent().toggleClass("active drop-arrow-down");
      $(togglerClass).toggle();
      e.preventDefault();
    });
}

Then you can put all your IDs in an array and loop over it and pass the id and index to the function.

Alexander Nied
  • 12,804
  • 4
  • 25
  • 45
  • Abstraction is our friend =] – RobDigital Feb 01 '18 at 16:14
  • 2
    @AlexanderNied this is the correct answer and you beat me to the punch. I was just about to post something similar. However, the only addition is I would also name the function as well. – user9263373 Feb 01 '18 at 16:15
  • @Andreas - _excellent_ point-- no I was just answering quickly during work bc I saw this. I'll update, thanks. – Alexander Nied Feb 01 '18 at 16:16
  • @AlexanderNied what about the .field-hanger class?, That class also different for every block. – Mukunda Bhatta Feb 01 '18 at 16:17
  • @MukundaBhatta -- my apologies, I missed that-- you could make an array that stores an object with the id and the toggled class, like: `[{id: "#muqfeas878zalh4vxayb1rkqyfjctk1v", toggleClass: ".field-hanger"}, {id: "#gwe1osm3ylp7imv4bbu1fquivij15wk6", toggleClass: ".field-door-type"}]`. Then you could iterate over this and pass both into the function, which would then be updated with a `toggleClass` argument. – Alexander Nied Feb 01 '18 at 16:21
  • @Andreas -- yep, sorry, my jQuery is rusty. Got it now. – Alexander Nied Feb 01 '18 at 16:23
  • @Andreas -- I feel like I should figure out a way to funnel you some of the vote points I got on this... :) – Alexander Nied Feb 01 '18 at 16:32
  • Thanks everyone for the advice on tuning this-- I *think* the various issues raised have all been addressed now in the answer as posted above. – Alexander Nied Feb 01 '18 at 16:52