Ce que je veux réaliser, c’est que chaque fois que la liste déroulante <select>
est modifiée, je souhaite connaître la valeur de la liste déroulante avant modification. J'utilise la version 1.3.2 de jquery et j'utilise l'événement on change, mais la valeur que j'obtiens là-bas est après le changement.
<select name="test">
<option value="stack">Stack</option>
<option value="overflow">Overflow</option>
<option value="my">My</option>
<option value="question">Question</option>
</select>
Disons que l'option actuelle My est sélectionnée maintenant lorsque je la modifie en pile dans l'événement onchange (c'est-à-dire lorsque je l'ai modifiée en pile). Je veux la valeur précédente, c'est-à-dire mon attendu dans ce cas.
Comment cela peut il etre accompli ?
Edit: Dans mon cas, je vais avoir plusieurs cases de sélection dans la même page et je veux que la même chose soit appliquée à tous. De plus, toutes mes sélections sont insérées après le chargement de la page via ajax.
Combinez l’événement focus avec l’événement change pour obtenir ce que vous voulez:
(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;
});
})();
Exemple de travail: http://jsfiddle.net/x5PKf/766
veuillez ne pas utiliser de variable globale pour cela - stockez la valeur précédente dans les données Voici un exemple: http://jsbin.com/uqupu3/2/edit
le code pour 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());
});
});
viens de voir que vous avez plusieurs sélections sur la page - cette approche fonctionnera également pour vous, car pour chaque sélection, vous enregistrerez la valeur précédente sur les données de la sélection.
Je choisis la solution Avi Pinto qui utilise jquery.data()
Utiliser le focus n'est pas une solution valable. Cela fonctionne la première fois que vous modifiez les options, mais si vous restez sur cet élément, appuyez sur la touche "haut" ou "bas". Cela ne passera plus par l'événement focus.
Donc, la solution devrait être plus ressemble à ce qui suit,
//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
})
Suivre la valeur à la main.
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;
});
});
$("#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());
});
J'utilise l'événement "live", ma solution est fondamentalement similaire à celle de Dimitar, mais au lieu d'utiliser "focus", ma valeur précédente est enregistrée lorsque "click" est déclenché.
var previous = "initial prev value";
$("select").live('click', function () {
//update previous value
previous = $(this).val();
}).change(function() {
alert(previous); //I have previous value
});
Je sais que c'est un vieux fil, mais je pense pouvoir ajouter un petit extra. Dans mon cas, je voulais transmettre le texte, val et quelques autres données attr. Dans ce cas, il est préférable de stocker l’option entière en tant que valeur précédente plutôt que simplement en val.
Exemple de code ci-dessous:
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());
});
MODIFIER:
J'ai oublié d'ajouter .clone () sur l'élément. en ne le faisant pas lorsque vous essayez d'extraire les valeurs, vous finissez par extraire la nouvelle copie de la sélection plutôt que la précédente. L'utilisation de la méthode clone () stocke une copie de la sélection au lieu d'une instance de celle-ci.
conservez la valeur déroulante actuellement sélectionnée avec la requête sélectionnée dans une variable globale avant d'écrire la fonction d'action de modification "à la modification" . Si vous souhaitez définir la valeur précédente dans la fonction, vous pouvez utiliser la variable globale.
//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;
}
});
});
Pourquoi ne pas utiliser un événement jQuery personnalisé avec une interface de type montre angulaire;
// 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
});
Pourquoi ne stockez-vous pas la valeur actuellement sélectionnée et lorsque l’élément sélectionné est modifié, l’ancienne valeur est stockée? (et vous pouvez le mettre à jour à nouveau si vous le souhaitez)
(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();
})();
Utiliser le code suivant, je l'ai testé et son fonctionnement
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;
}
});
Je voudrais contribuer une autre option pour résoudre ce problème; puisque les solutions proposées ci-dessus n'ont pas résolu mon scénario.
(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());
}
);
}
)();
Ceci utilise jQuery pour que def. C'est une dépendance ici, mais cela peut être adapté pour fonctionner en JavaScript pur. (Ajoutez un écouteur au corps, vérifiez si la cible d'origine était une fonction select, execute, ...).
En attachant l'écouteur de modification au corps, vous pouvez être presque certain que cela déclenchera après des écouteurs spécifiques pour les sélections, sinon la valeur de 'data-previous' sera écrasée avant même de pouvoir la lire.
Ceci suppose bien sûr que vous préférez utiliser des écouteurs distincts pour votre set-previous et votre valeur de contrôle. Cela correspond parfaitement au modèle de responsabilité unique.
Remarque: Ceci ajoute cette fonctionnalité "précédente" à all selects, assurez-vous donc de régler les sélecteurs au besoin.
Il y a plusieurs façons d'obtenir le résultat souhaité, voici mon humble façon de le faire:
Laissez l'élément conserver sa valeur précédente, ajoutez donc un attribut 'previousValue'.
<select id="mySelect" previousValue=""></select>
Une fois initialisé, 'previousValue' peut maintenant être utilisé comme attribut. En JS, pour accéder à la PreviousValue de cette sélection:
$("#mySelect").change(function() {console.log($(this).attr('previousValue'));.....; $(this).attr('previousValue', this.value);}
Une fois que vous avez terminé avec 'previousValue', mettez à jour l'attribut avec la valeur actuelle.
Meilleure solution:
$('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);
});
Ceci est une amélioration de la réponse de @thisisboris. Il ajoute une valeur actuelle aux données afin que le code puisse contrôler le moment où une variable définie sur la valeur actuelle est modifiée.
(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() );
}
);
})();
Je devais révéler un div différent en fonction de la sélection
Voici comment procéder avec les syntaxes jquery et es6
HTML
<select class="reveal">
<option disabled selected value>Select option</option>
<option value="value1" data-target="#target-1" >Option 1</option>
<option value="value2" data-target="#target-2" >Option 2</option>
</select>
<div id="target-1" style="display: none">
option 1
</div>
<div id="target-2" style="display: none">
option 2
</div>
JS
$('select.reveal').each((i, element)=>{
//create reference variable
let $option = $('option:selected', element)
$(element).on('change', event => {
//get the current select element
let selector = event.currentTarget
//hide previously selected target
if(typeof $option.data('target') !== 'undefined'){
$($option.data('target')).hide()
}
//set new target id
$option = $('option:selected', selector)
//show new target
if(typeof $option.data('target') !== 'undefined'){
$($option.data('target')).show()
}
})
})