2015-06-11 4 views
0

У меня есть дублирование кода, чтобы добавить выпадающие фильтры к моему DataTable (с помощью JQuery DataTables плагина), который выглядит примерно так:Как сжать этот повторяющийся код и сделать его динамическим?

// filter based on company type 
$.fn.dataTable.ext.search.push(
    function(settings, data, dataIndex) { 
     selectedType = $('#companyType').val(); 
     if(selectedType.toLowerCase() === "all"){ 
      return true;  
     } 
     if(selectedType.toLowerCase() === data[2].toLowerCase()){ 
      return true;      
     } 
     return false; 
    } 
); 

// filter based on status type 
$.fn.dataTable.ext.search.push(
    function(settings, data, dataIndex) { 
     selectedType = $('#status').val(); 
     if(selectedType.toLowerCase() === "all"){ 
      return true;  
     } 
     if(selectedType.toLowerCase() === data[3].toLowerCase()){ 
      return true;      
     } 
     return false; 
    } 
); 

// filter based on account type 
$.fn.dataTable.ext.search.push(
    function(settings, data, dataIndex) { 
     selectedType = $('#accountType').val(); 
     if(selectedType.toLowerCase() === "all"){ 
      return true;  
     } 
     if(selectedType.toLowerCase() === data[9].toLowerCase()){ 
      return true;      
     } 
     return false; 
    } 
); 

Как вы можете видеть, только различие между этими функциями является elementID (из выпадающее окно фильтра) и индекс столбца. Я хотел бы разделить дублирующий код и сделать его многоразовым, используя цикл или функцию.

Я попытался с помощью объекта ключ-значение в JavaScript, а затем Перебор добавить фильтр для каждого:

<!--- Create object that stores key-value pairs for all dropdown filters; key is column index, value is filter element ID ---> 
var dropDownFilters = { 2: "companyType", 3: "status", 9: "accountType" } 
<!--- Loop through dropdown filters and set filter for each ---> 
for(var key in dropDownFilters){ 
    $.fn.dataTable.ext.search.push(
     function(settings, data, dataIndex) { 
      selectedType = $('#' + dropDownFilters[key]).val(); 
      if(selectedType.toLowerCase() === "all"){ 
       return true;  
      } 
      if(selectedType.toLowerCase() === data[key].toLowerCase()){ 
       return true;      
      } 
      return false; 
     } 
    );  
} 

Это не работает должным образом, как это только создает функцию фильтра с последними значениями (9 и тип учетной записи), поэтому третий фильтр работает, а другие нет.

Я могу сделать то, что я ищу, чтобы выполнить через серверный код ColdFusion на нагрузке:

<cfset dropDownFilters = [ { colIndex=2, elementID = "companyType" }, 
          { colIndex=3, elementID = "status"}, 
          { colIndex=9, elementID = "accountType"} ] /> 
<cfloop from="1" to="#ArrayLen(dropDownFilters)#" index="i"> 
    $.fn.dataTable.ext.search.push(
     function(settings, data, dataIndex) { 
      selectedType = $('#<cfoutput>#dropDownFilters[i].elementID#</cfoutput>').val(); 
      if(selectedType.toLowerCase() === "all"){ 
       return true;  
      } 
      if(selectedType.toLowerCase() === data[<cfoutput>#dropDownFilters[i].colIndex#</cfoutput>].toLowerCase()){ 
       return true;      
      } 
      return false; 
     } 
    ); 
</cfloop> 

Однако это чувствует себя неуклюжей. Я бы предпочел выполнить это с помощью чистого javascript, нет причин привлекать ColdFusion.

Как я могу реорганизовать этот повторяющийся код с помощью цикла или функции (и что предпочтительнее)?

ответ

1

Вы можете создать function для повторного использования кода. Дублирование кода является одним из antipattern в программировании.

function prepare(selector, index) 
{ 
    $.fn.dataTable.ext.search.push(
     function(settings, data, dataIndex) { 
      selectedType = $(selector).val(); 
      if(selectedType.toLowerCase() === "all"){ 
       return true;  
      } 
      if(selectedType.toLowerCase() === data[index].toLowerCase()){ 
       return true;      
      } 
      return false; 
     } 
    ); 
} 

, а затем ваш код будет выглядеть следующим образом:

prepare('#companyType', 2); 
prepare('#status', 3); 
prepare('#accountType', 9); 
+0

если добавить, как использовать этот FUNC в коде OP я думаю, что это будет принято отвечать –

+0

Спасибо! Не знаю, почему я так об этом думал. Это потрясающе – froadie

Смежные вопросы