我在使用 jQuery 时遇到问题:resizable() 和可拖动。当我在数据表上移动 div 时效果很好,当我也调整大小时,但在调整大小后,如果拖动 div,它会在顶部移动 1px,在左侧移动 1px。我可以从页面顶部的容器 div 执行此操作。rich:dataTable 上的 div 是从带有 h:outputtext/escape=false 的 jsf 生成的
我已经考虑过这个错误:http ://bugs.jqueryui.com/ticket/4696和这个http://bugs.jquery.com /ticket/2793并且我已经应用了补丁
这是我的 xhtml 代码:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>TC</title>
<h:outputScript name="jsf.js" library="javax.faces" />
<h:outputScript name="jquery.js" />
<script type="text/javascript"
src="resources/js/jquery-ui-1.10.1.custom.js" />
<h:outputScript library="js" name="jquery.json-2.4.js" />
<style type="text/css">
.ui-resizable {
position: relative;
}
.ui-resizable-handle {
position: absolute;
font-size: 0.1px;
z-index: 99999;
display: block;
}
.ui-resizable-e {
cursor: e-resize;
width: 2px;
right: 0;
top: 0;
height: 100%;
background-color: black;
}
</style>
</h:head>
<h:body>
<a4j:outputPanel rendered="false">
<rich:dataTable/>
</a4j:outputPanel>
<h:form id="formulario">
<script type="text/javascript">
function extenderHoras(div, index){
var contenedor = '#'+div.id;
var left = jQuery(contenedor).css("left");
var contenedorPadre = jQuery(contenedor).parent();
var padreDePadre = jQuery(contenedorPadre).parent();
var cantidadHijos = contenedorPadre[0].childElementCount;
jQuery(document).mousemove(function(e){
window.mouseXPos = e.pageX;
window.mouseYPos = e.pageY;
});
jQuery(contenedor).droppable({
accept: ".ui-draggable-dragging",
tolerance: 'pointer'
}).resizable({
handles: 'e',
minWidth: 41,
grid: [ 41, 0 ],
containment: contenedorPadre,
stop: function(event, ui) {
if(!index){
//Si no tiene index
var divArray = new Array();
var colorDiv = div.style.background;
var idPadreDePadre = padreDePadre[0].id;
var fila = idPadreDePadre.split(':');
index = fila[2];//Obtenemos el index
var cantidadHijosDiv = contenedorPadre[0].childElementCount; //Obtenemos Todos los hijos que se tiene en la fila
cantidadHijosDiv = cantidadHijosDiv - 1; //La lista es empieza desde 0 se le quita un elemento (tamaño -1)
var sumaTotalDiv = 0;
if(cantidadHijosDiv==0){//Si solo tiene un hijo obtenemos el tamaño de ese hijo para ponerlo como margen del div que estamos colocando
sumaTotalDiv = contenedorPadre[0].children[cantidadHijosDiv].style.width;
sumaTotalDiv = sumaTotalDiv.replace('px','');
}else{//Si tiene más de un hijo tenemos que recorrer el arreglo y sumar el tamaño de todos los div
for(var i = 0; i <= cantidadHijosDiv; i++){
var ancho = contenedorPadre[0].children[i].style.width;
sumaTotalDiv = sumaTotalDiv + parseInt(ancho.replace('px',''));
}
}
var leftUbicacion = sumaTotalDiv * -1;
var csstxt = jQuery(div.id).css('cssText') + ';top:0;left:'+leftUbicacion+' px;background-color:'+colorDiv+';height:'+ui.element.height()+'; width:'+ui.element.width()+';float:left;margin-left:'+sumaTotalDiv;
jQuery(div.id).css('cssText', csstxt);
} else {
jQuery(contenedor).css({
'width': ui.element.width(),
'height': ui.element.height(),
'top': ui.element[0].style.top,
'left': ui.element[0].style.left,
'float': 'left',
position: 'absolute'
});
};
var divArray = [{
"id":ui.element[0].id,
"width":ui.element[0].style.width,
"height":ui.element[0].style.height,
"top":ui.element[0].style.top,
"left":ui.element[0].style.left,
"right":ui.element[0].style.right,
"top":ui.element[0].style.top,
"backgroundColor":ui.element[0].style.background
}];
var json = jQuery.toJSON(divArray);
convertirJson(json, index);
}
}).draggable({
containment: contenedorPadre,
grid: [ 41, 0 ],
revert: 'valid',
stop: function(event, ui) {
if(!cantidadHijos){
//Si no tiene hijos que no haga nada, por si lo coloca en otro lado que no sea la tabla
} else {
}
}
}).removeClass("ui-draggable");
}
function arrastrarALado(div){
var contenedor = '#'+div.id;
var colorDiv = div.style.background;
jQuery(contenedor).draggable({
helper: 'clone',
revert: 'valid',
stop: function(event, ui) {
var elem = document.elementFromPoint(event.pageX, event.pageY);
event.stopPropagation();
var tag = elem.tagName;
var cantidadHijosDiv = elem.childElementCount; //Obtenemos Todos los hijos que se tiene en la fila
cantidadHijosDiv = cantidadHijosDiv - 1; //quitamos un elemento men la lista es (tamaño -1)
var sumaTotalDiv = 0;
if(cantidadHijosDiv==0){//Si solo tiene un hijo obtenemos el tamaño de ese hijo para ponerlo como margen del div que estamos colocando
sumaTotalDiv = elem.children[cantidadHijosDiv].style.width;
sumaTotalDiv = sumaTotalDiv.replace('px','');
}
else{//Si tiene más de un hijo tenemos que recorrer el arreglo y sumar el tamaño de todos los div
for(var i = 0; i <= cantidadHijosDiv; i++){
var ancho = elem.children[i].style.width;
sumaTotalDiv = sumaTotalDiv + parseInt(ancho.replace('px',''));
}
}
var divHijo = elem.children[cantidadHijosDiv];//Obtenemos el último hijo de la lista
if(!divHijo){//Si es undefined no tiene hijos o ha puesta fuera de la barra - Propenso a cambios
alert('No puede colocar la barra aquí');
} else if(divHijo.tagName=='TH'){//Si el hijo
alert('No puede colocar la barra aquí');
}
else if(divHijo.tagName=='SPAN'){//Si el hijo es un SPAN es que crea richfaces
var divHijo = elem.children[cantidadHijosDiv+1];//obtenemos el siguiente hijo, solo ocurre en el caso de que sea el span padre
divHijo = divHijo.id;
} else {//Si no usamos el nombre del ultimo div
divHijo = divHijo.id;
}
if(tag == 'TD'){
var leftUbicacion = sumaTotalDiv * -1;
var divNuevo = divHijo+cantidadHijosDiv+div.id;
//Implementando cssText de Jquery ya que no se puede insertar el estilo de forma normal al crear el div, tengo que agregarlo
var csstxt = jQuery('#'+divNuevo).css('cssText') + ';top:0;left:'+leftUbicacion+' !important;background-color:'+colorDiv+';height:25px; width:82px;float:left;margin-left:'+sumaTotalDiv;
jQuery('<div/>', {
id: divNuevo, //obtenemos el ultimo hijo, luego le ponemos la cantidad y el id del div que estoy arrastrando
//onmousedown: 'arrastrarBarra(this);',
onmouseover: 'extenderHoras(this);'
}).appendTo(elem);
jQuery('#'+divNuevo).css('cssText', csstxt);
}
}
});
}
</script>
<a4j:jsFunction name="convertirJson"
action="#{pruebasmb.obtenerDiv()}" >
<a4j:param name="divArray" assignTo="#{pruebasmb.divJSON}" ></a4j:param>
<a4j:param name="index" assignTo="#{pruebasmb.indexPersonaSeleccionada}"></a4j:param>
</a4j:jsFunction>
<div id="contenedores" style="width: 600px; height: 30px; background-color: #f0f0f0; ">
<div id="divBlue" style="width: 82px; height: 25px; background-color: blue; float: left; " onmouseover="arrastrarALado(this);"></div>
<div id="divRojo" style="width: 82px; height: 25px; background-color: red; float: left; " onmouseover="arrastrarALado(this);"></div>
<div id="divVerde" style="width: 82px; height: 25px; background-color: green; float: left; " onmouseover="arrastrarALado(this);"></div>
</div>
<a4j:commandButton action="#{pruebasmb.llenarlista()}"
value="Llenar lista" render="dataTablePersonas"></a4j:commandButton>
<br />
<br />
<a4j:outputPanel ajaxRendered="false">
<rich:dataTable var="persona" value="#{pruebasmb.personas}"
id="dataTablePersonas" rowKeyVar="index">
<f:facet name="header">
<rich:columnGroup>
<rich:column rowspan="2" >
<h:outputText value="Persona" style="padding: 0px;" />
</rich:column>
<rich:column colspan="24" style="padding: 0px;">
<h:outputText value="Horas" />
</rich:column>
<rich:column breakRowBefore="true"
style="width: 40px; padding: 0px;">
<h:outputText value="00h00" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="00h30" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="01h00" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="01h30" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="02h00" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="02h30" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="03h00" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="03h30" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="04h00" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="04h30" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="05h00" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="05h30" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="06h00" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="06h30" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="07h00" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="07h30" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="08h00" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="08h30" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="09h00" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="09h30" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="10h00" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="10h30" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="11h00" />
</rich:column>
<rich:column style="width: 40px; padding: 0px;">
<h:outputText value="11h30" />
</rich:column>
</rich:columnGroup>
</f:facet>
<rich:column>
<h:outputText value="#{persona.apellido}" />
</rich:column>
<rich:column colspan="24" style="padding: 0px; height:25px; position: relative;" >
<h:outputText value="#{pruebasmb.divDefault.get(index)}" escape="false" />
</rich:column>
</rich:dataTable>
</a4j:outputPanel>
</h:form>
</h:body>
</html>
普鲁巴豆
import java.awt.Color;
import java.io.Serializable;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
@ManagedBean(name = "pruebasmb")
@SessionScoped
public class PruebasMB implements Serializable {
private static final long serialVersionUID = 2290961655122569612L;
private List<Persona> personas = new ArrayList<Persona>();
private String valorDelSlider;
private String celdaClickeada;
private String estiloBarra;
private String indexPersonaSeleccionada;
private EstilosCss estilos = new EstilosCss();
private List<String> divDefault = new ArrayList<String>();
private String divJSON;
public void llenarlista() {
divDefault.clear();
personas.clear();
for (int i = 1; i <= 10; i++) {
Integer horasTrabajadas;
// Para generar un temporal de las horas trabajadas aleatoriamente
horasTrabajadas = (int) Math.round((Math.random() * 16));
if (horasTrabajadas == 0)
horasTrabajadas = 1;
else
horasTrabajadas = horasTrabajadas * 41;
estiloBarra = estilos.generarEstilo(horasTrabajadas.toString(), "25", "yellow", "0", "0", "0", "0", "0", "0", "left", null, null);
Persona p = new Persona("nombre" + i, "apellido" + i, i + 20, "Calle J y la " + i, estiloBarra, horasTrabajadas, (i/2));
generarBarras(p, horasTrabajadas, i);
personas.add(p);
}
}
public void obtenerDiv(){
Gson gson = new Gson();
Type type = new TypeToken<List<Div>>(){}.getType();
List<Div> div = gson.fromJson(divJSON.toString(), type);
Integer index = Integer.valueOf(indexPersonaSeleccionada);
if(index==null){
index=0;
}
valorDelSlider = div.get(0).getWidth().replace("px", "");
System.out.println("Width: "+div.get(0).getWidth());
Integer valor = Integer.valueOf(valorDelSlider);
int valorTemporal = valor;
int horasTrabajadas = personas.get(index).getHorasTrabajadas();
if (horasTrabajadas == 1) {
valor = valor - 1;
valorTemporal = valorTemporal - 1;
valor = valor / 82;
} else
valor = valor / 82;
if ((valorTemporal % 82) > 0) {
System.out.println("El total de horas es " + valor + " y media ");
} else
System.out.println("Ha realizado " + valor + " horas");
System.out.println(valor * 82);
estiloBarra = "left: 0px; background-color: yellow; height: 25px; width: " + (valor * 82) + "px; top: 0px !important; float: left;";
personas.get(index).setEstiloUsuario(estiloBarra);
}
public void generarBarras(Persona p, Integer horasTrabajadas, Integer i) {
Integer horasSegundoDiv=0;
String rgb="";
String estiloBarra2 ="";
String div ="";
for(int j = 0; j<= 2; j ++){
horasSegundoDiv = (int) Math.round((Math.random() * 16));
if (horasSegundoDiv == 0)
horasSegundoDiv = 1;
else
horasSegundoDiv = horasSegundoDiv * 41;
rgb = Color2Hex();
estiloBarra2 = estilos.generarEstilo(horasSegundoDiv.toString(), "25", rgb, "0", "0", "0", "0", "0", "0", "left", null, null);
div = div + "<div id='nombrediv" + i+"_"+j + "' style='" + estiloBarra2 + "' onmouseover='extenderHoras(this," + (i) + ");'> </div>";
}
divDefault.add(div);
}
/**
* Se genera un color al azar en rgb y se convierte a hexadecimal
*
* @return Color en hexadecimal
*/
public String Color2Hex() {
int R = (int) Math.round((Math.random() * 256));
int G = (int) Math.round((Math.random() * 256));
int B = (int) Math.round((Math.random() * 256));
Color c = new Color(R, G, B);
String rgb = Integer.toHexString(c.getRGB() & 0xffffff);
if(rgb.length()<6)
rgb = "0"+rgb;
return "#"+rgb;
}
//getter and setter
}
和 Estilos.css 我在其中生成 div 的样式
import java.io.Serializable;
public class EstilosCss implements Serializable {
private static final long serialVersionUID = -1279423720796129516L;
private String width;
private String height;
private String backgroundColor;
private String leftMargin;
private String rightMargin;
private String left;
private String right;
private String top;
private String bottom;
private String floatEstilo;
private String gradientColor1;
private String gradientColor2;
public String generarEstilo(String width, String height, String backgroundColor, String leftMargin, String rightMargin, String left, String right,
String top, String bottom, String floatEstilo, String gradientColor1, String gradientColor2) {
String estilo = "";
estilo = "width:" + width + "px; height:" + height + "px; background-color:" + backgroundColor + "; left-margin:" + leftMargin
+ "px; right-margin:" + rightMargin + "px; left:" + left + "px; right:" + right + "px; top:" + top + "px; bottom:" + bottom + "px; float:"+floatEstilo+" !important;";
//Si ingresa los colores del gradient del div
if(gradientColor1!=null&&gradientColor2!=null){
estilo = estilo + "background-image: -ms-linear-gradient(bottom, "+gradientColor1+" 0%, "+gradientColor2 +" 100%);";
estilo = estilo + "background-image: -moz-linear-gradient(bottom, "+gradientColor1+" 0%, "+gradientColor2 +" 100%);";
estilo = estilo + "background-image: -o-linear-gradient(bottom, "+gradientColor1+" 0%, "+gradientColor2 +" 100%);";
estilo = estilo + "background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, "+gradientColor1+"), color-stop(1,"+gradientColor2 +"));";
estilo = estilo + "background-image: -webkit-linear-gradient(bottom, "+gradientColor1+" 0%, "+gradientColor2 +" 100%);";
estilo = estilo + "background-image: linear-gradient(to top, "+gradientColor1+" 0%, "+gradientColor2 +" 100%);";
estilo = estilo + "filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='"+gradientColor1+"', endColorstr='"+gradientColor2 +"');";
}
return estilo;
}
//getter and setter
}