Usar Modal de twitter bootstrap

S

Hola, tengo una pagina en la que quiero dar de alta un dispositivo. un dispositivo consta de su tipo, marca, y modelo. La pagina consta de un formulario. Ahora bien, tengo unos enlaces de ingreso rápido. Si no tengo un tipo determinado quiero agregarlo a través de una nueva ventana sin necesidad de tener que salir de donde me encuentro. Aquí es donde hago uso del plugin Modal de bootstrap. El problema viene cuando intento guardar el tipo que no se encuentra registrado. Al darle al boton de guardar dentro de mi modal realmente lo que hace es pulsar el boton de mi formulario de dispositivo y por tanto me falla la BD. Pongo código e imágenes para que se entienda mejor.

{include file="includes/header.tpl"} 

{if isset($error1)}
	<p class="alert alert-error" style="margin: 1px;"><i class="icon-exclamation-sign"></i>{$error1}
{/if}
{if isset($error2)}
	<p class="alert alert-error" style="margin: 1px;"><i class="icon-exclamation-sign"></i>{$error2}
{/if}
{if isset($success)}
	<p class="alert alert-success" style="margin: 1px;"><i class="icon-ok"></i>{$success}
{/if}

<form class="form-horizontal" id="adddispositivo" action="{$ruta}dispositivo_controller/addDispositivo" method="POST">
	<fieldset>
		<legend>Nuevo dispositivo</legend>
		<div class="control-group">
			<label class="control-label" for="tipo_dispositivo">Tipo de dispositivo</label>
			<div class="controls">
				<select name="tipo_dispositivo" id="tipo_dispositivo">
					<option value=""></option>
					{section name=fila loop=$tipo}
						<option value="{$tipo[fila]['id']}">{$tipo[fila]['nombre']}</option>
					{/section}
				</select>
				<a class="btn" id="modal1" data-toggle="modal" href="#myModal1" rel="tooltip" title="Añade tipo de dispositivo"><i class="icon-plus"></i></a>
				<div class="modal hide fade in" id="myModal1" style="display: none;">
					<div class="modal-header">
						<a class="close" data-dismiss="modal">×</a>
						<h3>Ingresar nueva marca</h3>
					</div>
					<div class="modal-body">
						<form class="FormTipo">
			            <fieldset>
			                <div class="modal-body">
				                <ul class="nav nav-list">
				                <li class="nav-header">Name</li>
				                <li><input class="input-xlarge" value="" type="text" name="nombre" id="nombre"></li>
				                </ul> 
			                </div>
			            </fieldset>
            			</form>
					</div>
					<div class="modal-footer">
						<a href="#" class="btn" data-dismiss="modal">Close</a>
						<button class="btn btn-success" id="submit2">Guardar</button>
					</div>
				</div>
			</div>
		</div>
		<div class="control-group">
			<label class="control-label" for="marca_dispositivo">Marca</label>
			<div class="controls">
				<select name="marca_dispositivo" id="marca_dispositivo">
					<option value=""></option>
					{section name=mar loop=$marca}
						<option value="{$marca[mar]['id']}">{$marca[mar]['nombre']}</option>
					{/section}
				</select>
				<a class="btn" id="modal2" data-toggle="modal" href="#myModal2" rel="tooltip" title="Añade una marca"><i class="icon-plus"></i></a>
				<div class="modal hide fade in" id="myModal2" style="display: none;">
					<div class="modal-header">
						<a class="close" data-dismiss="modal">×</a>
						<h3>Cabecera de la ventana</h3>
					</div>
					<div class="modal-body">
						<p>Aqui meto un formulario</p>
					</div>
					<div class="modal-footer">
						<a href="#" class="btn">Close</a>
						<a href="#" class="btn btn-primary">Save changes</a>
					</div>
				</div>
			</div>
		</div>
		<div class="control-group">
			<label class="control-label" for="modelo_dispositivo">Modelo</label>
			<div class="controls">
				<select name="modelo_dispositivo" id="modelo_dispositivo">
				</select>
				<a class="btn" id="modal3" data-toggle="modal" href="#myModal3" rel="tooltip" title="Añade modelo"><i class="icon-plus"></i></a>
				<div class="modal hide fade in" id="myModal3" style="display: none;">
					<div class="modal-header">
						<a class="close" data-dismiss="modal">×</a>
						<h3>Cabecera de la ventana</h3>
					</div>
					<div class="modal-body">
						<p>Aqui meto un formulario</p>
					</div>
					<div class="modal-footer">
						<a href="#" class="btn">Close</a>
						<a href="#" class="btn btn-primary">Save changes</a>
					</div>
				</div>
			</div>
		</div>
		<div class="form-actions">
			<button type="submit" class="btn btn-primary">Guardar</button>
			<button class="btn">Borrar Formulario</button>
		</div>
	</fieldset>
</form>


{literal}
<script src="bootstrap-modal.js"></script>
<script src="bootstrap-tooltip.js"></script>
<script>
    $(function () {
        $('#modal1').tooltip();
    });
    $(function () {
        $('#modal2').tooltip();
    });
    $(function () {
        $('#modal3').tooltip();
    });
</script>
<script>
	$(document).ready(function(){
		$('#adddispositivo').validate({
			errorElement: "span",
			rules: 
			{
				marca: {required: true},
				modelo: {required: true},
				tipo: {required: true}
			},
			messages:
			{
				marca:"Escribe una marca correcta",
				modelo:"Escribe un modelo correcto",
				tipo:"Elige un tipo de dispositivo."
			},
			highlight: function(element) 
			{
				$(element).closest('.control-group')
				.removeClass('success').addClass('error');
			},
			success: function(element) 
			{
				element
				.text('OK!').addClass('help-inline')
				.closest('.control-group')
				.removeClass('error').addClass('success');
			}
		});
	});
</script>
<script>
$(document).ready(function(){
	// Parametros para el marca_dispositivo
	$("#marca_dispositivo").change(function () {
		$("#marca_dispositivo option:selected").each(function () {
			//alert($(this).val());
				elegido=$(this).val();
				$.post("marca_dispositivo", { elegido: elegido }, function(data){
				$("#modelo_dispositivo").html(data);
			});
		});
	})
});
</script>
<script>
 $(function() {
//twitter bootstrap script
    $("button#submit2").click(function(){
            $.ajax({
            type: "POST",
        url: "http://localhost/pfcdata/dispositivo_controller/addTipoDispositivo",
        data: $('form.FormTipo').serialize(),
            success: function(msg){
                    $("#modal1").modal('hide');
                 },
        error: function(){
            alert("failure");
            }
              });
    });
});
</script>
{/literal}


{include file="includes/footer.tpl"} 

elkaoD

#1 te he insertado las imágenes.

¿No puedes reducir algo el código de ejemplo?

1 respuesta
S

si, en cuanto tenga un hueco reduzco el código

S

#2 Aquí pego el código lo más reducido posible. He quitado todo lo que uso para la validación,para los selects dependientes y los selects de marca y modelo también los he quitado. Simplemente dejo el código que pertenece al primer select y el modal que me carga al pulsar el botón de "+" con el javascript correspondiente. Como ya dije antes el problema es que al tener un formulario principal y otro formulario secundario, si pulso el boton de enviar del formulario secundario hace el envio en el formulario principal.

<form class="form-horizontal" id="adddispositivo" action="{$ruta}dispositivo_controller/addDispositivo" method="POST">
    <fieldset>
        <legend>Nuevo dispositivo</legend>
        <div class="control-group">
            <label class="control-label" for="tipo_dispositivo">Tipo de dispositivo</label>
            <div class="controls">
                <select name="tipo_dispositivo" id="tipo_dispositivo">
                    <option value=""></option>
                    {section name=fila loop=$tipo}
                        <option value="{$tipo[fila]['id']}">{$tipo[fila]['nombre']}</option>
                    {/section}
                </select>

            <!-- Boton para sacarme el modal -->
            <a class="btn" id="modal1" data-toggle="modal" href="#myModal1" rel="tooltip" title="Añade tipo de dispositivo"><i class="icon-plus"></i></a>
            
<!-- Ventana que genero con el formulario secundario -->
<div class="modal hide fade in" id="myModal1" style="display: none;">
                    <div class="modal-header">
                        <a class="close" data-dismiss="modal">×</a>
                        <h3>Ingresar nueva marca</h3>
                    </div>
                    <div class="modal-body">
                        <form class="FormTipo">
                        <fieldset>
                            <div class="modal-body">
                                <ul class="nav nav-list">
                                <li class="nav-header">Name</li>
                                <li><input class="input-xlarge" value="" type="text" name="nombre" id="nombre"></li>
                                </ul> 
                            </div>
                        </fieldset>
                        </form>
                    </div>
                    <div class="modal-footer">
                        <a href="#" class="btn" data-dismiss="modal">Close</a>
                        <button class="btn btn-success" id="submit2">Guardar</button>
                    </div>
                </div>
            </div>
        </div>
<!-- Final de la ventana modal -->    
   
<div class="form-actions"> <button type="submit" class="btn btn-primary">Guardar</button> <button class="btn">Borrar Formulario</button> </div> </fieldset> </form> {literal} <script src="bootstrap-modal.js"></script> <script src="bootstrap-tooltip.js"></script> <script> $(function() { //twitter bootstrap script $("button#submit2").click(function(){ $.ajax({ type: "POST", url: "http://localhost/pfcdata/dispositivo_controller/addTipoDispositivo", data: $('form.FormTipo').serialize(), success: function(msg){ $("#modal1").modal('hide'); }, error: function(){ alert("failure"); } }); }); }); </script> {/literal}
1 respuesta
elkaoD

#4 lo de meter forms dentro de forms es la primera vez que lo he visto en mi vida y en un 99.99999% la causa de tu error.

2 respuestas
S

#5 Voy a ver como arreglo esto pues, :) He pensado en dejar los select de la pagina principal sin etiquetas <form></form>, y el botón de guardar hacerlo con etiquetas <a></a>. Espero que así funcione. Si alguno tiene otra opción se agradece.

1 respuesta
sasher

#6 Es lo que dice #5. Lo que tienes que hacer es sacar el modal de ahí y ponerlo fuera del form.

1 respuesta
S

#7 pero si quiero poner el botón seguido del select como esta en la imagen tengo que ponerlo dentro del form. Como podría ponerlo a continuación del select y tenerlo fuera del form?

1 respuesta
K0N1G

#8 cierra el form justo después del botón que llama al modal. Vamos, coges el modal (14-42) y lo pegas en la línea 50

1 respuesta
S

#9 Hola, ya he hecho eso y ya me hace bien la función que debe hacer. El problema ahora es que no me sale el botón que llama al modal a continuación del select correspondiente.

1 respuesta
K0N1G

#10 Que te sale, debajo?? Eso ya sería ajustar el diseño con spans y tal

1 respuesta
S

#11 Si me sale debajo de los botones del formulario

Gantorys

Puedes guardar el código de la modal en otro archivo y cargarlo con la opción remote. El archivo se te cargará en el div.modal-body (lo digo por si te interesa tenerlo más ordenado)

1 respuesta
S

#13 Tendré en cuenta eso.

Ahora estoy viendo como recargar la pagina padre cuando cierro el modal.

2 respuestas
sasher

#14

location.reload(true);
1 respuesta
elkaoD

#14 aunque lo de #15 funciona, ¿necesitas realmente recargar la página? ¿No puedes tirar de Ajax y actualizar dinámicamente? Es lo suyo.

1 respuesta
S

#16 Eso seria lo suyo, pero no tengo ni idea de Ajax

1 respuesta
elkaoD

#17 AJAX es lo más tonto del mundo, lo complicado es hacer que tu web actúe después (lo que viene a ser la lógica de negocio).

Si tienes jQuery es tan simple como usar $.ajax poniendo la URL de destino y los datos a mandar, y hacer lo que sea en las funciones de success y error.

http://api.jquery.com/jQuery.ajax/ Échale un vistazo aunque sea para un proyecto futuro porque es simple y queda resultón.

1 respuesta
S

#18 Gracias!

S

Como dijo elkaoD pretendo usar Ajax para cargar cuando cierre mi modal los datos del select correspondiente. Os muestro lo que he hecho para ver si me pueden ayudar, ya que no me hace la recarga.

{include file="includes/header.tpl"} 

<form class="form-horizontal" id="adddispositivo" action="{$ruta}dispositivo_controller/addDispositivo" method="POST">
	<fieldset>
		<legend>Nuevo dispositivo</legend>
		<div class="control-group">
			<label class="control-label" for="tipo_dispositivo">Tipo de dispositivo</label>
			<div class="controls">
				<select name="tipo_dispositivo" id="tipo_dispositivo">
					<option value=""></option>
					{section name=fila loop=$tipo}
						<option value="{$tipo[fila]['id']}">{$tipo[fila]['nombre']}</option>
					{/section}
				</select>
			</div>
		</div>
		<div class="control-group">
			<label class="control-label" for="marca_dispositivo">Marca</label>
			<div class="controls">
				<select name="marca_dispositivo" id="marca_dispositivo">
					
			</select>
		</div>
	</div>
	<div class="control-group">
		<label class="control-label" for="modelo_dispositivo">Modelo</label>
		<div class="controls">
			<select name="modelo_dispositivo" id="modelo_dispositivo">
			</select>
		</div>
	</div>
	<div class="form-actions">
		<button type="submit" class="btn btn-primary">Guardar</button>
		<button class="btn">Borrar Formulario</button>
	</div>
</fieldset>
</form>

<!--Modal 1-->
	<a class="btn" id="modal1" data-toggle="modal" href="#myModal1" rel="tooltip" title="Añade tipo de dispositivo"><i class="icon-plus"></i></a>

<div class="modal hide fade in" id="myModal1" style="display: none;">
	<div id="thanks">
		<div class="modal-header">
			<a href="" class="close" data-dismiss="modal">×</a>
			<h3>Ingresar nueva Tipo de dispositivo</h3>
		</div>
		<div class="modal-body">
			<form class="FormTipo">
				<fieldset>
					<div class="modal-body">
						<ul class="nav nav-list">
						<li class="nav-header">Nombre</li>
						<li><input class="input-xlarge" value="" type="text" name="nombre" id="nombre"></li>
						</ul> 
					</div>
				</fieldset>
			</form>
		</div>
		<div class="modal-footer">
			<a class="btn" data-dismiss="modal">Close</a>
			<button class="btn btn-primary" id="submit1">Guardar</button>
		</div>
	</div>
</div>
<!--Cierro Modal 1-->

{literal}
<script>
    $(function () {
        $('#modal1').tooltip();
    });
</script>
<script>
	$(document).ready(function(){
		// Parametros para el tipo_dispositivo
		$("#tipo_dispositivo").change(function () {
			$("#tipo_dispositivo option:selected").each(function () {
				//alert($(this).val());
					elegido=$(this).val();
					$.post("tipo_dispositivo", { elegido: elegido }, function(data){
					$("#marca_dispositivo").html(data);
					$("#modelo_dispositivo").html("");
				});
			});
		})
		// Parametros para el marca_dispositivo
		$("#marca_dispositivo").change(function () {
			$("#marca_dispositivo option:selected").each(function () {
				//alert($(this).val());
					elegido=$(this).val();
					$.post("marca_dispositivo", { elegido: elegido }, function(data){
					$("#modelo_dispositivo").html(data);
				});
			});
		})
	});
</script>
<script>
	$(function() {
	    $("button#submit1").click(function(){
	        $.ajax({
		        type: "POST",
		        url: "http://localhost/pfcdata/dispositivo_controller/addTipoDispositivoModal",
		        data: $('form.FormTipo').serialize(),
		        success: function(msg){
		        	$("#thanks").html(msg)
		            $("#modal1").modal('hide');
		            $("#tipo_dispositivo").load(); //esta linea es la que pretendo usar para recargar el Select tipo_dispositivo que es el que añado a través del modal.
		        },
		        error: function(){
		            alert("failure");
		        }
	        });
	    });
	});
</script>

{/literal}


{include file="includes/footer.tpl"} 
1 respuesta
elkaoD

#20 qué es .load() ?

1 respuesta
S

#21 .load() según he leído en la documentación es un método que me devuelve en mi código html en el elemento que le especifico (tipo_dispositivo) los datos del servidor.

1 respuesta
elkaoD

#22 ah, que es el .load() de jQuery.

Es que no se usa así, necesitas pasarle parámetros. Tal y como lo tienes estás llamando al evento .load() del elemento, ya que no le has pasado una URL.

Lee a fondo http://api.jquery.com/load/

Con eso ni necesitas $.ajax, lo hace solito (aunque yo soy más de pillar JSON y construir a mano que de devolver el HTML, por eso te recomendé $.ajax).

1 respuesta
S

#23 Vale, le volveré a echar un vistazo :)

1 respuesta
elkaoD

#24 básicamente: llámalo como $elemento.load("http://...", $('form.FormTipo').serialize()) y te aparecerá lo que devuelvas como HTML dentro del HTML de $elemento.

¡No uses URLs absolutas! Si usas relativas funcionará en localhost y en tu sitio sin tocar nada.

1 respuesta
S

#25 Y ese codigo que me has puesto debo de colocarlo cuando mi función $.ajax de éxito no?

$(function() {
            $("button#submit1").click(function(){
                $.ajax({
                        type: "POST",
                        url: "http://localhost/pfcdata/dispositiv...tivoModal",
                        data: $('form.FormTipo').serialize(),
                        success: function(msg){
                                $("#thanks").html(msg)
                            $("#modal1").modal('hide');
                            $elemento.load("http://...", $('form.FormTipo').serialize())
                        },
                        error: function(){
                            alert("failure");
                        }
                });
            });
        });

Con respecto al tema de las url relativas o absolutas es que he tenido problemas a la hora de llamar a otras librerías y por eso las uso absolutas. Se que lo mas correcto es usarlas relativas, pero de momento estoy colocándolas absolutas. En cuanto termine unas cuantas cosas de la aplicación veré si hay forma de cambiar las urls. Muchas gracias elkaoD

1 respuesta
elkaoD

#26 no, no, .load() se encarga de llamar a $.ajax por ti. Así estás usando $.ajax dos veces.

1 respuesta
S

#27 Entonces me debo de crear una nueva función jquery tal que me cargue $("div#elemento").

Es decir el siguiente fragmento:

<script>
	$(function(){
		$("div#elemento").load("http://localhost/pfcdata/dispositivo_controller/alta_dispositivo", $('form.FormTipo').serialize());
	});
</script>
1 respuesta
elkaoD

#28 no, eso lo tendrás que plantar cuando quieras cargarlo. Tal y como lo pones ahí se hace al inicio de página.

Gantorys

utiliza si no $.post, sería algo así


$.post(url, { form: $('form.FormTipo').serialize() }, function(res){
   // aquí el código que quieras (equivale a lo que metes en el 'success' de $.ajax)
});

Y en el php, tendrás en la variable $_POST['form'] el formulario serializado

Lo único que no tiene callback de error

1 respuesta