refactoring when two functions share some similarity

I have two tabs in my app one is a player tab and another is a coaching tab. I have a function1 in the player tab and function2 in the coaching tab.

function1

var beforeList = $('#players').val()
$('#players').change(function () {
  var afterList = $(this).val()
  var selectedPlayer = ''

  if (!beforeList) {
    selectedPlayer = afterList[0] 
    $('parent option[value=' + selectedPlayer + ']').add()
    $('#injuredPlayer option[value=' + selectedPlayer + ']').add()
  } else if (!afterList) {
    selectedPlayer = beforeList[0] 
    $('parent option[value=' + selectedPlayer + ']').remove()
    $('#injuredPlayer option[value=' + selectedPlayer + ']').remove()
  } else if (beforeList.length > afterList.length) {
    selectedPlayer = getselectedPlayer(beforeList, afterList) 
    $('parent option[value=' + selectedPlayer + ']').remove()
    $('#injuredPlayer option[value=' + selectedPlayer + ']').remove()
  } else if (beforeList.length < afterList.length) {
    selectedPlayer = getselectedPlayer(afterList, beforeList) 
    $('parent option[value=' + selectedPlayer + ']').add()
    $('#injuredPlayer option[value=' + selectedPlayer + ']').add()
  }

  if (afterList) {
    for (var i = 0; i < afterList.length; i++) {
      var optionInParentB = ($('#dad option[value=' + afterList[i] + ']').length > 0)
      var optionInParentA = ($('#mom option[value=' + afterList[i] + ']').length > 0)
      var optionInInjuredPlayer = ($('#injuredPlayer option[value=' + afterList[i] + ']').length > 0)
      if (!optionInParentB) {
        $('<option/>', {value: afterList[i], html: afterList[i]}).appendTo('#dad')
      }
      if (!optionInParentA) {
        $('<option/>', {value: afterList[i], html: afterList[i]}).appendTo('#mom')
      }
      if (!optionInInjuredPlayer){
        $('<option/>', {value: afterList[i], html: afterList[i]}).appendTo('#injuredPlayer')
      }
    }
  } else {
    $('#mom').empty()
    $('#dad').empty()
    $('#injuredPlayer').empty()
  }

  beforeList = afterList
})

function2

var beforeList = $('#coach').val()
$('#coach').change(function () {
  var afterList = $(this).val()
  var selectedCoach = ''

  if (!beforeList) {
    selectedCoach = afterList[0] 
    $('#injuredCoach option[value=' + selectedCoach + ']').add()
  } else if (!afterList) {
    selectedCoach = beforeList[0] 
    $('#injuredCoach option[value=' + selectedCoach + ']').remove()
  } else if (beforeList.length > afterList.length) {
    selectedCoach = getselectedCoach(beforeList, afterList) 
    $('#injuredCoach option[value=' + selectedCoach + ']').remove()
  } else if (beforeList.length < afterList.length) {
    selectedCoach = getselectedCoach(afterList, beforeList) 
    $('#injuredCoach option[value=' + selectedCoach + ']').add()
  }

  if (afterList) {
    for (var i = 0; i < afterList.length; i++) {
      var optionInInjuredCoach = ($('#injuredCoach option[value=' + afterList[i] + ']').length > 0)
      if (!optionInInjuredCoach){
        $('<option/>', {value: afterList[i], html: afterList[i]}).appendTo('#injuredCoach')
      }
    }
  } else {
    $('#injuredCoach').empty()
  }

  beforeList = afterList
})

When I look at both the functions I see they are very similar, the only difference is that the player tab has parents and the coaching tab does not. I was wondering if the functions are fine as they are or if they should be refactored. Is it bad practice if I just leave them as they are? If I am to refactor I was not sure how I can make a function generic enough to accommodate the differences of two tabs. I would love thoughts and as I am new to JS please forgive me if I have misspoken.

Answers:

Answer

jQuery tends to fail silently if it doesn't find an element (because it doesn't exist in the document or because it's hidden at function runtime). If this is ok with you and you don't get errors, all good.

Otherwise, move some of that duplicated code out to a new named function and pass an argument to it, and use that to determine whether to act on those elements. Something like this:

// define the function
function doCommonStuff(doDad) {
    if (doDad) {
        // do Dad stuff
    }
}

// call the function
doCommonStuff(true);

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.