2009-06-05 11 views
17

Sto tentando di creare una casella di testo ridimensionabile (ASP.NET multilinea/HTML textarea) e utilizzare l'interfaccia utente di JQuery per renderlo ridimensionabile, ma sembra che si verifichino alcuni problemi relativi al trascinamento personalizzato maniglie.Maniglie ridimensionabili personalizzate nell'interfaccia utente JQuery

La documentazione di JQuery sul metodo Resizable (in particolare quella sull'opzione handles) suggerisce che è possibile impostare uno qualsiasi degli handle per utilizzare un elemento HTML personalizzato. Sono riuscito a far funzionare perfettamente la casella di testo ridimensionabile usando i manici ridimensionabili di default, ma provare a impostare quelli personalizzati (cioè un elemento HTML che ho definito in markup) crea il seguente problema: il contenitore ridimensionabile lascia la giusta quantità di spazio per la maniglia div nella parte inferiore (per la maniglia Sud), ma lascia lo spazio vuoto e mostra l'elemento sottostante (esterno) del contenitore ridimensionabile (verificato utilizzando Firebug).

Ecco il mio markup (ASP.NET/XHTML) e il codice 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> 

Naturalmente, non posso fare il manico div ridimensionabile (classe resizable-s) un bambino del TextBox/textarea, ma questo non dovrebbe essere un problema secondo i documenti di JQuery.

A giudicare dalla ricerca che ho fatto, non sono l'unica persona che ha avuto questo problema. (Sfortunatamente, i documenti di JQuery non riescono a dare un esempio dell'uso di maniglie ridimensionabili personalizzate, quindi non abbiamo tutti la certezza di avere il codice giusto.) Se qualcuno potrebbe suggerire una correzione a questo, o addirittura confermare che si tratta di un bug di JQuery, sarebbe molto apprezzato

risposta

24

Da un po 'di scavo ho fatto nel codice jquery-ui, penso di poter confermare che un handle personalizzato al di fuori dell'elemento ridimensionabile non funziona.

Il problema è che gli eventi del mouse sono inizializzati per l'elemento ridimensionabile (o un elemento wrapper nel caso di textarea). Se l'handle non è figlio di dove vengono gestiti gli eventi del mouse, non attiverà l'evento mouse sull'handle, quindi non lo renderà trascinabile.

Come prova del concetto, ho applicato un po 'di patch in jquery-ui fino a quando non ho ottenuto le cose per (tipo) di lavoro. Nessuna garanzia sul codice, ma dovrebbe indicare che tipo di modifiche dovrebbero accadere per farlo funzionare.

Intorno linea 140 in ui.resizable.js ho cambiato:

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

a

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

Poi ho aggiunto il seguente codice (parte di mouseInit da ui.core.js, probabilmente dovrebbe utilizzare l'intera funzione) in ui.resizable.js (attorno alla riga 180) dopo il mouseInit viene chiamato per l'elemento ridimensionabile:

... 
    //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); 
     }); 
    } 

Questo mi consente di creare un handle di ridimensionamento che non è figlio dell'elemento ridimensionabile. Il mio handle è un div con id 'south' ed è collegato all'elemento ridimensionabile. Ecco l'snippit HTML:

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

E il codice javascript:

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

Spero che questo aiuti!

+0

Grazie per aver indagato su questo. Non mi aspettavo un trucco per correggere i file JS, ma sarebbe bello averne uno! Sfortunatamente, ho provato a integrare le tue modifiche, ma senza fortuna. Il div "sud" appare come un testo molto piccolo e non si comporta affatto come un handle (impostando 'font-size: 100%;' rende il testo chiaramente visibile, ma non più). Forse ci sono altri cambiamenti che hai fatto? – Noldorin

+0

Completamente a destra, ho perso una riga con cui mi sono immischiato. Ho messo altezza/larghezza/colore di sfondo nel CSS per il Sud Sud nei miei test - che rende più facile trovare la maniglia. Solo con la dimensione del font al 100%, però, non ho aggiunto le regole CSS all'analisi. – ylebre

+0

Strano ... Continuo a non ottenere risultati e ho ricontrollato che il mio codice corrisponda a quello che hai postato identicamente. Qualche idea? Sarebbe possibile caricare la tua pagina di prova e modificare il file ui.resizable.js? – Noldorin

3

Sì, sembra un insetto per me. Ecco un esempio completo, per coloro che cercano a livello locale:

<!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 bugpossono essere correlato.

Altre cose che ho provato:

  • Sostituire 'ultima' con '1.6' e 'jquery-1.3.2' con 'jquery-1.2.6' di provare con una versione precedente di jQuery UI per vedere se è una regressione. Non sembra.
  • Aggiungi ui-resizable-s e/o ui-resizable-handle Classi CSS a #southgrip. Niente da fare. Tuttavia, se #southgrip è all'interno di #resizable, funziona. Ma questo non risolve il tuo problema.
  • Utilizzo di { 's': $('#southgrip').get(0) } per l'opzione handles. Niente da fare.
+1

BTW, mentre si sta cercando di capire il motivo per cui jQuery UI non funziona, può essere utile per utilizzare semplicemente la versione della libreria dell'interfaccia di textize ridimensionabile: http://interface.eyecon.ro/demos/resize_textarea.html –

+0

Grazie per la risposta ... Sembra infatti che ora sia un bug. Se non riesco a far funzionare la soluzione di hacking di ylebre (una soluzione jQueryUI è ancora leggermente preferibile), andrò sicuramente con la libreria di interfaccia, in quanto sembra essere proprio quello che voglio. – Noldorin

+0

Non suggerirei di usare la versione hacked up che ho postato - è più una prova che c'è effettivamente un problema con il codice jquery-ui e in quale direzione potrebbe essere prodotta una soluzione. Non consiglierei di portare quel codice in produzione ovunque :) – ylebre

0

Ho avuto lo stesso problema 4 anni dopo. Non hanno mai risolto quello. Ho pensato di usare Interface ma non ha avuto aggiornamenti dal 2007. Così ho deciso di correggere il bug da solo e di fare una richiesta di pull nel progetto dell'interfaccia utente jQuery in Github. https://github.com/jquery/jquery-ui/pull/1134 Spero che lo accetti e lo unisca presto. Ho aggiunto un test quindi sono sicuro che funzionerà in ogni caso perché tutti i test di ridimensionamento dell'interfaccia utente di Jquery funzionano con questa modifica.

Ho iniziato a utilizzare il codice ylebre ma non ha funzionato. Quindi ho apportato alcune piccole modifiche.

0

Finalmente trovato una soluzione estremamente efficace dopo ore di tentativi di superare questo fastidioso bug. Semplicemente, aggiungi l'elemento maniglia nella classe ui. La funzione sotto è stata testata e funziona bene con le maniglie Sud e Ovest. Spero possa aiutare!

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); 
} 

Quando si chiama la funzione come di seguito, l'handle personalizzato verrà posizionato nella posizione corretta e funzionerà probabilmente. PS: la funzione funziona con le maniglie 'n' e 's'.

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

Ho avuto un problema simile, ma il mio bisogno era quello di impostare le hadlers in modo dinamico a più elementi:

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