javascript - create - jquery events w3schools
Obtención del valor de selección(desplegable) antes del cambio (16)
Lo que quiero lograr es que siempre que se cambie el menú desplegable <select>
quiero el valor del menú desplegable antes del cambio. Estoy usando la versión 1.3.2 de jquery y usando el evento de cambio, pero el valor que estoy superando está después del cambio.
<select name="test">
<option value="stack">Stack</option>
<option value="overflow">Overflow</option>
<option value="my">My</option>
<option value="question">Question</option>
</select>
Digamos que actualmente la opción Mi está seleccionada ahora cuando la cambio para apilar en el evento onchange (es decir, cuando la cambié para apilar) quiero su valor anterior, es decir, mi esperado en este caso.
¿Cómo se puede lograr esto?
Edición: En mi caso, tengo varios cuadros de selección en la misma página y quiero que se aplique lo mismo a todos ellos. También todos mis selecciones se insertan después de cargar la página a través de ajax.
¿Qué hay de usar un evento jQuery personalizado con una interfaz de tipo de reloj angular?
// adds a custom jQuery event which gives the previous and current values of an input on change
(function ($) {
// new event type tl_change
jQuery.event.special.tl_change = {
add: function (handleObj) {
// use mousedown and touchstart so that if you stay focused on the
// element and keep changing it, it continues to update the prev val
$(this)
.on(''mousedown.tl_change touchstart.tl_change'', handleObj.selector, focusHandler)
.on(''change.tl_change'', handleObj.selector, function (e) {
// use an anonymous funciton here so we have access to the
// original handle object to call the handler with our args
var $el = $(this);
// call our handle function, passing in the event, the previous and current vals
// override the change event name to our name
e.type = "tl_change";
handleObj.handler.apply($el, [e, $el.data(''tl-previous-val''), $el.val()]);
});
},
remove: function (handleObj) {
$(this)
.off(''mousedown.tl_change touchstart.tl_change'', handleObj.selector, focusHandler)
.off(''change.tl_change'', handleObj.selector)
.removeData(''tl-previous-val'');
}
};
// on focus lets set the previous value of the element to a data attr
function focusHandler(e) {
var $el = $(this);
$el.data(''tl-previous-val'', $el.val());
}
})(jQuery);
// usage
$(''.some-element'').on(''tl_change'', ''.delegate-maybe'', function (e, prev, current) {
console.log(e); // regular event object
console.log(prev); // previous value of input (before change)
console.log(current); // current value of input (after change)
console.log(this); // element
});
Bueno, ¿por qué no almacena el valor seleccionado actual, y cuando se cambia el elemento seleccionado, se almacenará el valor anterior? (y puedes actualizarlo nuevamente como desees)
Combine el evento de enfoque con el evento de cambio para lograr lo que desea:
(function () {
var previous;
$("select").on(''focus'', function () {
// Store the current value on focus and on change
previous = this.value;
}).change(function() {
// Do something with the previous value after the change
alert(previous);
// Make sure the previous value is updated
previous = this.value;
});
})();
Ejemplo de trabajo: http://jsfiddle.net/x5PKf/766
Esta es una mejora en la respuesta de @thisisboris. Agrega un valor actual a los datos, por lo que el código puede controlar cuando se cambia una variable establecida en el valor actual.
(function()
{
// Initialize the previous-attribute
var selects = $( ''select'' );
$.each( selects, function( index, myValue ) {
$( myValue ).data( ''mgc-previous'', myValue.value );
$( myValue ).data( ''mgc-current'', myValue.value );
});
// Listen on the body for changes to selects
$(''body'').on(''change'', ''select'',
function()
{
alert(''I am a body alert'');
$(this).data(''mgc-previous'', $(this).data( ''mgc-current'' ) );
$(this).data(''mgc-current'', $(this).val() );
}
);
})();
Estoy usando el evento "en vivo", mi solución es básicamente similar a Dimitiar, pero en lugar de usar "enfoque", mi valor anterior se almacena cuando se activa "clic".
var previous = "initial prev value";
$("select").live(''click'', function () {
//update previous value
previous = $(this).val();
}).change(function() {
alert(previous); //I have previous value
});
Hay varias formas de lograr el resultado deseado, esta es mi manera humilde de hacerlo:
Deje que el elemento mantenga su valor anterior, así que agregue un atributo ''previousValue''.
<select id="mySelect" previousValue=""></select>
Una vez inicializado, ''previousValue'' podría ahora ser usado como un atributo. En JS, para acceder al valor anterior de esta selección:
$("#mySelect").change(function() {console.log($(this).attr(''previousValue''));.....; $(this).attr(''previousValue'', this.value);}
Una vez que haya terminado de usar ''previousValue'', actualice el atributo al valor actual.
Me gustaría contribuir con otra opción para resolver este problema; Ya que las soluciones propuestas anteriormente no resolvieron mi escenario.
(function()
{
// Initialize the previous-attribute
var selects = $(''select'');
selects.data(''previous'', selects.val());
// Listen on the body for changes to selects
$(''body'').on(''change'', ''select'',
function()
{
$(this).data(''previous'', $(this).val());
}
);
}
)();
Esto usa jQuery para que def. Es una dependencia aquí, pero se puede adaptar para que funcione en javascript puro. (Agregue un oyente al cuerpo, verifique si el objetivo original era una función de selección, ejecución, ...).
Al adjuntar el detector de cambios al cuerpo, puede estar bastante seguro de que esto se activará después de escuchas específicos para las selecciones, de lo contrario, el valor de ''datos anteriores'' se sobrescribirá antes de que pueda leerlo.
Por supuesto, esto es asumiendo que usted prefiere usar oyentes separados para su conjunto anterior y valor de verificación. Encaja perfectamente con el patrón de responsabilidad única.
Nota: Esto agrega esta funcionalidad ''anterior'' a todas las selecciones, así que asegúrese de ajustar los selectores si es necesario.
Mejor solución:
$(''select'').on(''selectric-before-change'', function (event, element, selectric) {
var current = element.state.currValue; // index of current value before select a new one
var selected = element.state.selectedIdx; // index of value that will be selected
// choose what you need
console.log(element.items[current].value);
console.log(element.items[current].text);
console.log(element.items[current].slug);
});
Sé que este es un hilo viejo, pero pensé que podría agregar un poco más. En mi caso, quería transmitir el texto, val y algunos otros datos attr. En este caso, es mejor almacenar toda la opción como un valor anterior en lugar de solo el valor.
Código de ejemplo a continuación:
var $sel = $(''your select'');
$sel.data("prevSel", $sel.clone());
$sel.on(''change'', function () {
//grab previous select
var prevSel = $(this).data("prevSel");
//do what you want with the previous select
var prevVal = prevSel.val();
var prevText = prevSel.text();
alert("option value - " + prevVal + " option text - " + prevText)
//reset prev val
$(this).data("prevSel", $(this).clone());
});
EDITAR:
Olvidé agregar .clone () en el elemento. al no hacerlo, cuando intenta retirar los valores, termina por extraer la nueva copia de la selección en lugar de la anterior. El uso del método clone () almacena una copia de la selección en lugar de una instancia de la misma.
Seguimiento del valor a mano.
var selects = jQuery("select.track_me");
selects.each(function (i, element) {
var select = jQuery(element);
var previousValue = select.val();
select.bind("change", function () {
var currentValue = select.val();
// Use currentValue and previousValue
// ...
previousValue = currentValue;
});
});
Utilice el siguiente código, lo he probado y está funcionando
var prev_val;
$(''.dropdown'').focus(function() {
prev_val = $(this).val();
}).change(function(){
$(this).unbind(''focus'');
var conf = confirm(''Are you sure want to change status ?'');
if(conf == true){
//your code
}
else{
$(this).val(prev_val);
$(this).bind(''focus'');
return false;
}
});
Voy por la solución de Avi Pinto que usa jquery.data()
Usar el enfoque no es una solución válida. Funciona la primera vez que cambia las opciones, pero si permanece en ese elemento seleccionado, y presiona la tecla "arriba" o "abajo". No volverá a pasar por el evento de enfoque.
Así que la solución debería ser más parecida a la siguiente,
//set the pre data, usually needed after you initialize the select element
$(''mySelect'').data(''pre'', $(this).val());
$(''mySelect'').change(function(e){
var before_change = $(this).data(''pre'');//get the pre data
//Do your work here
$(this).data(''pre'', $(this).val());//update the pre data
})
mantenga el valor desplegable actualmente seleccionado con el jquery elegido en una variable global antes de escribir la función de acción desplegable ''en cambio''. Si desea establecer un valor anterior en la función, puede utilizar la variable global.
//global variable
var previousValue=$("#dropDownList").val();
$("#dropDownList").change(function () {
BootstrapDialog.confirm('' Are you sure you want to continue?'',
function (result) {
if (result) {
return true;
} else {
$("#dropDownList").val(previousValue).trigger(''chosen:updated'');
return false;
}
});
});
por favor, no use una var global para esto - almacene el valor anterior en los datos aquí es un ejemplo: http://jsbin.com/uqupu3/2/edit
el código para ref:
$(document).ready(function(){
var sel = $("#sel");
sel.data("prev",sel.val());
sel.change(function(data){
var jqThis = $(this);
alert(jqThis.data("prev"));
jqThis.data("prev",jqThis.val());
});
});
Acabo de ver que tiene muchas selecciones en la página; este enfoque también le funcionará, ya que para cada selección almacenará el valor anterior en los datos de la selección.
$("#dropdownId").on(''focus'', function () {
var ddl = $(this);
ddl.data(''previous'', ddl.val());
}).on(''change'', function () {
var ddl = $(this);
var previous = ddl.data(''previous'');
ddl.data(''previous'', ddl.val());
});
(function() {
var value = $(''[name=request_status]'').change(function() {
if (confirm(''You are about to update the status of this request, please confirm'')) {
$(this).closest(''form'').submit(); // submit the form
}else {
$(this).val(value); // set the value back
}
}).val();
})();