2014-11-06 2 views
0

Я установил «поле ввода мультимедиа» для выбора изображений с помощью медиаплеера WordPress, и я использую jQuery для захвата данных из объекта post WordPress для вставки в поле предварительного просмотра HTML. Это прекрасно работает для одного «медиа-бокса», но теперь я хочу расширить его до еще двух ящиков.Включение WET jQuery в DRY

Я мог бы дублировать код jQuery три раза, меняя только одну строку (содержащую parent var) для каждого медиа-бокса, но это чрезвычайно WET. Я изо всех сил, чтобы изменить JQuery для учета индивидуальной коробке СМИ используется ...

<script type="text/javascript"> 

    function add_image(obj) 
    { 
     var parent=jQuery(obj).parent().parent('div.image_a'); 
     var inputField = jQuery(parent).find("input.meta_image_url");   
     var fileFrame = wp.media.frames.file_frame = wp.media({ multiple: false });  

     fileFrame.on('select', function() 
     { 
      var wp_post = fileFrame.state().get('selection').first().toJSON();  

      inputField.val(wp_post.url);     
      jQuery(parent) 
       .find("div.image_preview") 
       .html('<img src="'+wp_post.url+'" height="50" width="100" />'); 
     }); 

     fileFrame.open(); 
    }; 

</script> 

и HMTL

// First media box 
<div class="image_a"> 
    <div class="image_url"> 
     <span> 
      <label>Image A URL</label> 
     </span> 
     <input type="text" 
      class="meta_image_url" 
      name="image_b" 
      value="<?php esc_html_e($img_a_url); ?>" 
     /> 
    </div> 
    <div class="image_preview"> 
     <img src="<?php esc_html_e($img_a_url); ?>" /> 
    </div> 
    <div class="image_buttons"> 
     <input class="button" type="button" value="Choose File" onclick="add_image(this)" /><br /> 
     <input class="button" type="button" value="Remove" onclick="remove_field(this)" /> 
    </div> 
</div> 


//Second media box 
<div class="image_b"> 
    <div class="image_url"> 
     <span> 
      <label>Image B URL</label> 
     </span> 
     <input type="text" 
      class="meta_image_url" 
      name="image_a" 
      value="<?php esc_html_e($img_b_url); ?>" 
     /> 
    </div> 
    <div class="image_preview"> 
     <img src="<?php esc_html_e($img_b_url); ?>" /> 
    </div> 
    <div class="image_buttons"> 
     <input class="button" type="button" value="Choose File" onclick="add_image(this)" /><br /> 
     <input class="button" type="button" value="Remove" onclick="remove_field(this)" /> 
    </div> 
</div> 

//Third media box 
<div class="image_c"> 
    <div class="image_url"> 
     ... 

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

+0

Что вы подразумеваете под мокрой и сухой? – ArtOfCode

+0

Написание всего Дважды - или в этом случае, записывая блок jQuery три раза, меняя одну строку в каждом блоке. Не повторяйте себя, будет немного более сложным блоком jQuery, но не дублируется три раза ... – myol

+0

Не могли бы вы просто добавить общий класс ко всем контейнерам, например. 'image' и изменить строку' parent' на 'var parent = jQuery (obj) .parent(). parent ('div.image');' или 'var parent = jQuery (obj) .parents ('div.image «);'. Затем я лично изменил бы текущие классы ('image_a',' image_b', 'image_c') вместо id. – martincarlin87

ответ

2

Вы всегда можете добавить второй параметр функции add_image:

<script type="text/javascript"> 

function add_image(obj, parentSelector) 
{ 
    var parent=jQuery(obj).parent().parent(parentSelector); 
    var inputField = jQuery(parent).find("input.meta_image_url");   
    var fileFrame = wp.media.frames.file_frame = wp.media({ multiple: false });  

    fileFrame.on('select', function() 
    { 
     var wp_post = fileFrame.state().get('selection').first().toJSON();  

     inputField.val(wp_post.url);     
     jQuery(parent) 
      .find("div.image_preview") 
      .html('<img src="'+wp_post.url+'" height="50" width="100" />'); 
    }); 

    fileFrame.open(); 
}; 

</script> 

Затем вы можете изменить атрибуты вашей OnClick:

onclick="add_image(this, 'div.image_a')" 
+0

Так чисто. Не могу поверить, что я пропустил это. – myol

1

Это кажется большим кандидатом на jQuery plugin. С плагином у вас будет хороший, многоразовый компонент, который, похоже, является тем, что вы ищете.

Вот код, который может вам начать:

$.fn.addImage = function() { 
    // this -> context refers to selected elements. 
    return this.each(function(){  // Returning this allows you to chain like other jQuery plugins 
     var $this = $(this), 
      $input = $this.find('input.meta_image_url') 

     var fileFrame = wp.media.frames.file_frame = wp.media({ multiple: false });  

     fileFrame.on('select', function(){ 
      var wp_post = fileFrame.state().get('selection').first().toJSON();  

      $input.val(wp_post.url);     
      $this.find('div.image_preview') 
       .html('<img src="' + wp_post.url + '" height="50" width="100" />'); 
     }); 

     fileFrame.open(); 
    }); 
}; 

Добавить общий класс (скажем, .add-image) для ваших элементов, и вы бы назвали ваш плагин, как это:

$('.add-image').addImage(); 

EDIT: Я не использовал файлы WordPress для плагинов файлов, поэтому YMMV, но повторяющийся код, основанный на выборе и работе с набором элементов, как правило, является отличным местом для плагина.

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