2009-06-05 2 views
17

Я пытаюсь создать изменяемый размер текстового поля (многострочный ASP.NET TextBox/HTML textarea) и использовать пользовательский интерфейс JQuery, чтобы сделать его изменяемым по размеру, но, похоже, сталкивается с несколькими проблемами, связанными с пользовательским перетаскиванием ручки.Пользовательские изменяемые размеры ручек в пользовательском интерфейсе JQuery

Документация JQuery по методу Resizable (в частности, что на опции handles) предполагает, что я могу установить любую из ручек для использования пользовательского элемента HTML. Мне удалось получить текстовое поле с изменяемым размером, прекрасно работающим с помощью стандартных изменяемых по умолчанию ручек, но попытка установить пользовательские (т. Е. Элемент HTML, который я определил в разметке) создает следующую проблему: размерный контейнер оставляет правильное пространство для ручка div внизу (для южного дескриптора), но оставляет пустое пространство и показывает элемент ниже (за пределами) изменчивого контейнера (проверяется с помощью Firebug).

Вот мой разметки (ASP.NET/XHTML) и JavaScript-код:

<asp:TextBox runat="server" ID="codeTextBox" TextMode="MultiLine" Wrap="false" Rows="15"> 
</asp:TextBox> 
<div class="resizable-s" style="width: 100%; height: 22px; background: red;"> 
</div> 

<script type="text/javascript"> 

    $(function() { 
     var codeTextBox = $("#<%= codeTextBox.ClientID %>"); 

     codeTextBox.resizable({ 
      handles: { s : $(".resizable-s") }, 
      minHeight: 80, 
      maxHeight: 400 
     }); 
    }); 

</script> 

Конечно, я не могу сделать изменяемую ручку DIV (класс resizable-s) дитя TextBox/textarea, но это не должно быть проблемой в соответствии с документами JQuery.

Судя по результатам поиска, который я сделал, я не единственный человек, у которого была эта проблема. (К сожалению, в документах JQuery нет примера использования настраиваемых изменяемых размеров ручек, поэтому мы все не уверены в правильности кода.) Если кто-нибудь может предложить исправить это или действительно подтвердить, что это ошибка JQuery, это было бы очень оценено.

ответ

24

От небольшого копания, которое я сделал в коде jquery-ui, я думаю, что могу подтвердить, что пользовательский дескриптор за пределами изменяемого размера элемента не работает.

Проблема в том, что события мыши инициализируются для изменяемого размера элемента (или элемента оболочки в случае textarea). Если дескриптор не является дочерним объектом, где обрабатываются события мыши, это не вызовет событие mousedown на дескрипторе, что не сделает его перетаскиваемым.

Как доказательство концепции, я немного поработал в jquery-ui, пока не получил вещи (вроде) работы. Никаких гарантий относительно кода, но он должен указать, какие изменения должны произойти, чтобы заставить его работать.

Вокруг линии 140 в ui.resizable.js я изменил:

this._handles = $('.ui-resizable-handle', this.element) 
    .disableSelection(); 

к

this._handles = $('.ui-resizable-handle') 
    .disableSelection(); 

Затем я добавил следующий код (часть mouseInit от ui.core.js, вероятно, следует использовать всю функцию) в ui.resizable.js (около линии 180) после того, как mouseInit вызываются для элемента перезначительного:

... 
    //Initialize the mouse interaction 
    this._mouseInit(); 

    // Add mouse events for the handles as well - ylebre 
    for (i in this.handles) { 
     $(this.handles[i]).bind('mousedown.resizable', function(event) { 
     return self._mouseDown(event); 
     }); 
    } 

Это позволяет мне создать ручку изменения размера, которая не является дочерним элементом изменяемого размера элемента. Моя ручка - это div с id 'south' и прикрепляется к изменяемому размеру элементу. Вот HTML Snippit:

<textarea id="resizable" class="ui-widget-content"> 
    <h3 class="ui-widget-header">Resizable</h3> 
</textarea> 
<div id="south" class="ui-resizable-handle">south</div> 

И Javascript код:

$("#resizable").resizable(
     {handles: {s: document.getElementById("south")}} 
    ); 

Надеется, что это помогает!

+0

Спасибо за исследование этого. Я не ожидал взлома, чтобы исправить файлы JS, но было бы здорово иметь его! К сожалению, я попытался использовать ваши изменения, но не повезло. «Южный» div отображается как очень маленький текст и совсем не ведет себя как дескриптор (установка «font-size: 100%;» делает текст четко видимым, но не более). Возможно, есть и другие изменения? – Noldorin

+0

Совершенно верно, я пропустил одну линию, с которой я вмешивался. Я поставил высоту/ширину/цвет фона в CSS для южного div в моих собственных тестах - это облегчает поиск дескриптора. Только с размером шрифта 100% работает, поэтому я не добавлял CSS-правила к анализу. – ylebre

+0

Странно ... Я все еще не получаю никаких результатов, и я дважды проверял, соответствует ли мой код тому, что вы разместили одинаково. Есть идеи? Возможно, вы сможете загрузить свою тестовую страницу и изменить файл ui.resizable.js? – Noldorin

3

Да, похоже на ошибку. Вот полный пример, для тех, кто пытается локально:

<!DOCTYPE html> 
<html> 
<head> 
    <link rel="stylesheet" href="http://jqueryui.com/latest/themes/base/ui.all.css" type="text/css"/> 
    <script src="http://jquery-ui.googlecode.com/svn/tags/latest/jquery-1.3.2.js" type="text/javascript"></script> 
    <script src="http://jquery-ui.googlecode.com/svn/tags/latest/ui/ui.core.js" type="text/javascript"></script> 
    <script src="http://jquery-ui.googlecode.com/svn/tags/latest/ui/ui.resizable.js" type="text/javascript"></script> 
    <style type="text/css"> 
    #resizable { width: 100px; height: 100px; background: silver; } 
    #southgrip { width: 100px; height: 10px; background-color: blue; } 
    </style> 
    <script type="text/javascript"> 
    $(function() { 
     $('#resizable').resizable({ 
     handles: { 's': $('#southgrip') }, 
     minHeight: 80, 
     maxHeight: 400 
     }); 
    }); 
    </script> 
</head> 
<body> 

<div id="resizable"></div> 
<div id="southgrip"></div> 

</body> 
</html> 

This jQuery UI bugможет быть связано.

Другие вещи, которые я пробовал:

  • Заменить 'последний' с '1.6' и 'Jquery-1.3.2' с 'Jquery-1.2.6', чтобы попробовать с более старой версии JQuery UI, чтобы увидеть если это регресс. Не похоже.
  • Добавить ui-resizable-s и/или ui-resizable-handle Классы CSS на #southgrip. Нет кубиков. Однако, если #southgrip находится внутри #resizable, он работает. Но это не решает вашу проблему.
  • Использование { 's': $('#southgrip').get(0) } для опции handles. Нет кубиков.
+1

Кстати, в то время как вы выяснить, почему JQuery UI не работает, вы можете просто использовать версию библиотеки интерфейса изменчивой 'textarea': http://interface.eyecon.ro/demos/resize_textarea.html –

+0

Спасибо за ответ ... Это действительно кажется ошибкой. Если я не могу получить работу с взломом ylebre (решение jQueryUI по-прежнему немного предпочтительнее), я обязательно поеду с библиотекой интерфейса, поскольку это похоже на то, что я хочу. – Noldorin

+0

Я бы не предложил использовать взломанную версию, которую я опубликовал, - это скорее доказательство того, что на самом деле проблема с кодом jquery-ui и в каком направлении может быть произведено решение. Я бы не рекомендовал использовать этот код в любом месте :) – ylebre

0

У меня была такая же проблема через 4 года после. Это так, они никогда не фиксировали это. Хотя я использовал интерфейс, но с 2007 года он не обновлялся. Итак, я решил исправить ошибку самостоятельно и сделать запрос в проекте jQuery UI в Github. https://github.com/jquery/jquery-ui/pull/1134 Надеюсь, они согласятся с этим и скоро слияют. Я добавил тест, поэтому я уверен, что он будет работать в любом случае, потому что все тесты изменения размера из JQuery UI работают с этой модификацией.

Я начал использовать ylebre-код, но это не сработало. Поэтому я внес некоторые изменения.

0

Наконец-то нашел чрезвычайно эффективное решение после нескольких часов попыток преодолеть эту досадную ошибку. Просто добавьте элемент handle в класс ui. Функция ниже была протестирована и отлично работает с южными и западными ручками. Надеюсь, это поможет!

function resizables(element, handle, type){ 

var height = handle.height(); 
var place = type =="s"? "bottom":"top"; 
var css = {}; 
     css["height"] = height+"px"; 
     css[place] = -height+"px"; 


element.resizable({handles: type}); 
var jqclass = element.find(".ui-resizable-"+type); 

     handle.css({"cursor": type+"-resize"}); 
     jqclass.append(handle); 
     jqclass.css(css); 
} 

Когда вы вызываете функцию, как показано ниже, ваш пользовательский дескриптор будет размещен в нужном месте и будет работать, вероятно. PS: функция работает с дескрипторами «n» и «s».

resizables($("#draggable"), $("#handle"), 's'); 
-1

У меня была аналогичная проблема, но моя потребность в том, чтобы установить hadlers динамически на несколько элементов:

  $.each($(".imagecontainer"),function() { 
       $(this).resizable({ 
        handles: {se: $(this).closest(".spaciator").find(".ui-resizable-se")} 
       }); 
      };