I have this code (in jQuery Impormptu):
var statesdemo = {
state0: {
title: 'Name',
html:'<label>name <input type="text" name="name" value=""></label><br />',
buttons: { Next: 1 },
submit:function(e,v,m,f){
console.log(f);
e.preventDefault();
$.prompt.goToState('state1');
}
},
state1: {
title: 'choice',
html:'<label>choice: <select name="travel" multiple>'+
'<option value="1" selected>1</option>'+
'<option value="2">2</option>'+
'</select></label>',
buttons: { Back: -1, Done: 1 },
focus: 1,
submit:function(e,v,m,f){
console.log(f);
e.preventDefault();
if(v==1) {$.prompt.close();}
if(v==-1) $.prompt.goToState('state0');
}
}
};
and with simple jquery I have this snippet:
$('#id').bind("dblclick", function() {
console.log('target id: ' + event.target.id);
f = $.prompt(statesdemo);
});
how can I get the user input when the prompt is finished?
the $.prompt does not return anything.
Also, the problem is that the $.prompt is a non blocking function. so the programs continues without waiting the user input.
try something like this
$('#my_a').click(function() {
f = $.prompt(statesdemo);
if(f.name!==undefined){
console.log(f.name);
}
if(f.travel!==undefined){
console.log(f.travel);
}
});
I've created a demo with an extra button that logs user input.
You can achieve this by creating an object to contain user input within Impromptu objects.
var userInput = {};
Next, create a function that takes a form input change event, and assigns the input's current value to a property in the object we just created with the same name as the input.
function registerUserInput( changeEvent ){
var input = changeEvent.target;
userInput[ input.name ] = $( input ).val();
};
Then we create an event listener on the body for all change events that occur within an Impromptu wrapper (.jquibox)
$( 'body' ).on( 'change', '.jqibox *', registerUserInput );
From this point onwards if ever an input within an Impromptu changes, its value will be recorded in the userInput object. So, to get the name input in your example:
userInput.name
Related
I have a form with a conditional field that is only shown if the user selects a radio button for "other." If I remove the conditional on this field, my original javascript function works; however, with the conditional I can not get it to fire correctly.
The form has an event "cf.add" that fires when a conditional field is made visible, and using this jquery I get a correct response in the console:
jQuery( document ).on( 'cf.add', function(){
console.log('cf.add triggered' );
});
And if I remove the conditional so that this field is rendered when the page is rendered, I get the correct response in this field, which is to add a '$':
$("#fld_3169487_4").on("blur", handleChange);
function handleChange() {
var myValue = document.getElementById("fld_3169487_4").value;
if (myValue.indexOf("$") != 0)
{
myValue = "$" + myValue;
}
document.getElementById("fld_3169487_4").value = myValue;
}
I've tried putting this second function within the first, but no luck. I feel like I'm adding them in the incorrect order when I try to combine the two, I'm not sure what I'm doing wrong though.
I've also tried to call the function handleChange() on the 'cf.add' trigger, but that did not work for me either.
After some playing around, I figured it out:
jQuery( document ).on( 'cf.add', function(){
var otherField = $("#fld_3169487_3");
otherField.focus();
var dollarValue;
$(otherField).on("blur", function() {
dollarValue = otherField.val();
if (dollarValue.indexOf("$") != 0) {
dollarValue = "$ " + dollarValue;
}
$(otherField).val(dollarValue);
});
});
Since cf.add is an custom even that is published by your form, you can have other elements subscribe to the event:
$("#fld_3169487_4").on('cf.add', function(event){
if ($(this).val().indexOf("$") != 0)
{
$(this).val("$" + $(this).val());
}
});
Using $(this), we can target just the field the event is attached to. Additionally, data from the event publisher can be passed to the subscribers via the event argument.
Here's my code: http://codepen.io/kikibres/pen/mVYOaR
I’m trying to recode the select options to display the “X” button when it’s selected and when one click on the “X” button, it reset back to the original select value. Additionally, I wanted the "x" button to work only on their own dropdown menu instead of all dropdown menus.
I’m trying to make it more similar to http://www.mtommaneycentre.com.au/stores/. As you can see, when you click on an option in “A-Z” select field, an “X” button appears and when you click on the “X” button, it reset to the original “A-Z” select option….
How do one do that?
HTML
<div class="filtermenu">
<form class="controls" id="Filters">
<fieldset class="select-style">
<select>
<option value="">All</option>
<option value=".triangle">Triangle</option>
<option value=".square">Square</option>
<option value=".circle">Circle</option>
</select>
<button class="btn-clear">x</button>
</fieldset>
<fieldset class="select-style">
<select>
<option value="">All</option>
<option value=".blue">Blue</option>
<option value=".white">White</option>
<option value=".green">Green</option>
</select>
<button class="btn-clear">x</button>
</fieldset>
<fieldset>
<button class="filter" data-filter=".triangle">Triangle</button>
</fieldset>
<fieldset>
<input type="text" placeholder="Enter Name" val="" data-filter="" id="filter--text" />
</fieldset>
<button id="Reset">Clear Filters</button>
</form>
</div>
Javascript
The code that reset all options is
self.$reset.on('click', function(e){
e.preventDefault();
in
var dropdownFilter = {
// Declare any variables we will need as properties of the object
$filters: null,
$reset: null,
groups: [],
outputArray: [],
outputString: '',
// The "init" method will run on document ready and cache any jQuery objects we will need.
init: function(){
var self = this; // As a best practice, in each method we will asign "this" to the variable "self" so that it remains scope-agnostic. We will use it to refer to the parent "dropdownFilter" object so that we can share methods and properties between all parts of the object.
self.$filters = $('#Filters');
self.$reset = $('#Reset');
self.$container = $('#Container');
self.$filters.find('fieldset').each(function(){
var $this = $(this);
self.groups.push({
$buttons : $this.find('.filter'),
$inputsSelect : $this.find('select'),
$inputsText : $this.find('input[type="text"]'),
active : ''
});
});
self.bindHandlers();
},
// The "bindHandlers" method will listen for whenever a select is changed.
bindHandlers: function(){
var self = this;
// Handle select change
self.$filters.on('click', '.filter', function(e){
e.preventDefault();
var $button = $(this);
// If the button is active, remove the active class, else make active and deactivate others.
$button.hasClass('active') ?
$button.removeClass('active') :
$button.addClass('active').siblings('.filter').removeClass('active');
self.parseFilters();
});
// Handle dropdown change
self.$filters.on('change', function(){
self.parseFilters();
});
// Handle key up on inputs
self.$filters.on('keyup', 'input[type="text"]', function() {
var $input = $(this);
console.log($input.val());
$input.attr('data-filter', '[class*="'+$input.val().replace(/ /, '-')+'"]');
if ($input.val() == '')
$input.attr('data-filter', '');
console.log($input.attr('data-filter'));
self.parseFilters();
});
// Handle reset click
self.$reset.on('click', function(e){
e.preventDefault();
self.$filters.find('.filter').removeClass('active');
self.$filters.find('.show-all').addClass('active');
self.$filters.find('select').val('');
self.$filters.find('input[type="text"]').val('').attr('data-filter', '');
self.parseFilters();
});
},
// The parseFilters method pulls the value of each active select option
parseFilters: function(){
var self = this;
// loop through each filter group and grap the value from each one.
for(var i = 0, group; group = self.groups[i]; i++){
var activeButtons = group.$buttons.length ? group.$buttons.filter('.active').attr('data-filter') || '' : '';
var activeSelect = group.$inputsSelect.length ? group.$inputsSelect.val() || '' : '';
var activeText = group.$inputsText.length ? group.$inputsText.attr('data-filter') : '';
group.active = activeButtons+activeSelect+activeText;
console.log(group.active);
}
self.concatenate();
},
// The "concatenate" method will crawl through each group, concatenating filters as desired:
concatenate: function(){
var self = this;
self.outputString = ''; // Reset output string
for(var i = 0, group; group = self.groups[i]; i++){
self.outputString += group.active;
}
// If the output string is empty, show all rather than none:
!self.outputString.length && (self.outputString = 'all');
console.log(self.outputString);
// ^ we can check the console here to take a look at the filter string that is produced
// Send the output string to MixItUp via the 'filter' method:
if(self.$container.mixItUp('isLoaded')){
self.$container.mixItUp('filter', self.outputString);
}
}
};
// On document ready, initialise our code.
$(function(){
// Initialize dropdownFilter code
dropdownFilter.init();
// Instantiate MixItUp
$('#Container').mixItUp({
controls: {
enable: false // we won't be needing these
},
callbacks: {
onMixFail: function(){
alert('No items were found matching the selected filters.');
}
}
});
});
At the moment there isn't attached any event handler to your "x" buttons, so if you click on them, it just refreshes the page, that's why it resets all filters, because it reinitialize all the code.
You should add this code to your plugin
$('.btn-clear').on('click', function(event) {
event.preventDefault();
$(this).prev().val("").change();
});
The event.preventDefault() will prevent to run the default event when you click on the button, which is to refresh the page in this case.
The next line will points to the previous DOM element of the clicked element (which is the <select>) and changes to the option which has the value: "", and after it triggers a change() event to tell your written code that the select's value is changed, so it should reload the figures with new filters.
I saved it here: http://codepen.io/anon/pen/EPzWEQ?editors=1010
Of Course you should implement it to your plugin, I just wrote it to the bottom of the code to make it work.
EDIT:
If you want to make invisible the X buttons if there is no filter selected, just make a 'change' event handler on the select, and check if value is "" then hide the button, else show it. It should be look like this:
$('select').change(function() {
if ($(this).val() == "") {
$(this).next().hide();
} else {
$(this).next().show();
}
});
I have an input text in jQuery I want to know if it possible to get the value of that input text(type=number and type=text) before the onchange happens and also get the value of the same input input text after the onchange happens. This is using jQuery.
What I tried:
I tried saving the value on variable then call that value inside onchange but I am getting a blank value.
The simplest way is to save the original value using data() when the element gets focus. Here is a really basic example:
JSFiddle: http://jsfiddle.net/TrueBlueAussie/e4ovx435/
$('input').on('focusin', function(){
console.log("Saving value " + $(this).val());
$(this).data('val', $(this).val());
});
$('input').on('change', function(){
var prev = $(this).data('val');
var current = $(this).val();
console.log("Prev value " + prev);
console.log("New value " + current);
});
Better to use Delegated Event Handlers
Note: it is generally more efficient to use a delegated event handler when there can be multiple matching elements. This way only a single handler is added (smaller overhead and faster initialisation) and any speed difference at event time is negligible.
Here is the same example using delegated events connected to document:
$(document).on('focusin', 'input', function(){
console.log("Saving value " + $(this).val());
$(this).data('val', $(this).val());
}).on('change','input', function(){
var prev = $(this).data('val');
var current = $(this).val();
console.log("Prev value " + prev);
console.log("New value " + current);
});
JsFiddle: http://jsfiddle.net/TrueBlueAussie/e4ovx435/65/
Delegated events work by listening for an event (focusin, change etc) on an ancestor element (document* in this case), then applying the jQuery filter (input) to only the elements in the bubble chain then applying the function to only those matching elements that caused the event.
*Note: A a general rule, use document as the default for delegated events and not body. body has a bug, to do with styling, that can cause it to not get bubbled mouse events. Also document always exists so you can attach to it outside of a DOM ready handler :)
Definitely you will need to store old value manually, depending on what moment you are interested (before focusing, from last change).
Initial value can be taken from defaultValue property:
function onChange() {
var oldValue = this.defaultValue;
var newValue = this.value;
}
Value before focusing can be taken as shown in Gone Coding's answer. But you have to keep in mind that value can be changed without focusing.
Just put the initial value into a data attribute when you create the textbox, eg
HTML
<input id="my-textbox" type="text" data-initial-value="6" value="6" />
JQuery
$("#my-textbox").change(function () {
var oldValue = $(this).attr("data-initial-value");
var newValue = $(this).val();
});
I have found a solution that works even with "Select2" plugin:
function functionName() {
$('html').on('change', 'select.some-class', function() {
var newValue = $(this).val();
var oldValue = $(this).attr('data-val');
if ( $.isNumeric(oldValue) ) { // or another condition
// do something
}
$(this).attr('data-val', newValue);
});
$('select.some-class').trigger('change');
}
I found this question today, but I'm not sure why was this made so complicated rather than implementing it simply like:
var input = $('#target');
var inputVal = input.val();
input.on('change', function() {
console.log('Current Value: ', $(this).val());
console.log('Old Value: ', inputVal);
inputVal = $(this).val();
});
If you want to target multiple inputs then, use each function:
$('input').each(function() {
var inputVal = $(this).val();
$(this).on('change', function() {
console.log('Current Value: ',$(this).val());
console.log('Old Value: ', inputVal);
inputVal = $(this).val();
});
my solution is here
function getVal() {
var $numInput = $('input');
var $inputArr = [];
for(let i=0; i < $numInput.length ; i++ )
$inputArr[$numInput[i].name] = $numInput[i].value;
return $inputArr;
}
var $inNum = getVal();
$('input').on('change', function() {
// inNum is last Val
$inNum = getVal();
// in here we update value of input
let $val = this.value;
});
The upvoted solution works for some situations but is not the ideal solution. The solution Bhojendra Rauniyar provided will only work in certain scenarios. The var inputVal will always remain the same, so changing the input multiple times would break the function.
The function may also break when using focus, because of the ▲▼ (up/down) spinner on html number input. That is why J.T. Taylor has the best solution. By adding a data attribute you can avoid these problems:
<input id="my-textbox" type="text" data-initial-value="6" value="6" />
If you only need a current value and above options don't work, you can use it this way.
$('#input').on('change', () => {
const current = document.getElementById('input').value;
}
My business aim was removing classes form previous input and add it to a new one.
In this case there was simple solution: remove classes from all inputs before add
<div>
<input type="radio" checked><b class="darkred">Value1</b>
<input type="radio"><b>Value2</b>
<input type="radio"><b>Value3</b>
</div>
and
$('input[type="radio"]').on('change', function () {
var current = $(this);
current.closest('div').find('input').each(function () {
(this).next().removeClass('darkred')
});
current.next().addClass('darkred');
});
JsFiddle: http://jsfiddle.net/gkislin13/tybp8skL
if you are looking for select droplist, and jquery code would like this:
var preValue ="";
//get value when click select list
$("#selectList").click(
function(){
preValue =$("#selectList").val();
}
);
$("#selectList").change(
function(){
var curentValue = $("#selectList").val();
var preValue = preValue;
console.log("current:"+curentValue );
console.log("old:"+preValue );
}
);
I have a Jquery event which does not trigger every time:
http://jsfiddle.net/LphjL/
My code:
thisWebsite = websiteInitialization ();
function websiteInitialization () {
companyName = "name";
var thisWebsite = new websiteConstructor(companyName);
return thisWebsite;
}
function websiteConstructor(companyName) {
this.companyName=companyName;
}
function ajaxUpdateDB(websiteElement, value) {
return $.post('/echo/html/',{html: "<p>Text echoed back to request</p>",delay: 3}
,function(a){}
,"json"
);
}
function updateDatabase(websiteElement, value) {
var promise = ajaxUpdateDB(websiteElement, value);
promise.complete(function () {
thisWebsite[websiteElement] = value;
});
}
$(document).ready(function() {
$(".websiteElement").change(function() {
updateDatabase( $(this).attr('id'), $(this).val() );
});
$("#infos").click(function() {
htmlCode = "<input class='websiteElement' id='companyName' type='text' value='"+thisWebsite.companyName+"'>";
$("#panel-content").html(htmlCode);
});
$("#homepage").click(function() {
htmlCode = "homepage";
$("#panel-content").html(htmlCode);
});
});
As you can see in the jsfiddle, the first time the input field is updated the Ajax is triggered, but:
if you click on 'Homepage', then click back on 'Generic infos' and update the input field again this time the Ajax is NOT triggered: $(".websiteElement").change event is not called the second time.
You need to bind the event using event delegation, or rebind the event after you replace the element. Below is the event delegation option:
$("#panel-content").on("change",".websiteElement",function() {
updateDatabase( $(this).attr('id'), $(this).val() );
});
If the event is bound directly on the element, the event will be lost when the element is replaced/removed.
For example say i have a text box and a hidden div called suggestions
$("#suggestinput").on({
keyup: function(){
$("#suggestions").addClass("active");
},
blur: function () {
$("#suggestions").removeClass('active');
}
//another event to know if input is empty while on focus, then removeClass('active');
});
The first event is when the user types in the input show suggestion, the second one is blur, so when the user unfocuses on the input the suggestions el will hide, i want a third event to check while on focus if the input is empty remove active class.
Working example is here thanks: http://jsfiddle.net/HSBWt/
Try this - http://jsfiddle.net/HSBWt/1/
$("#suggestinput").on({
keydown: function(){
$("#suggestions").addClass("active");
},
blur: function () {
$("#suggestions").removeClass('active');
},
keyup: function () {
if ( $(this).val() == "" ) {
$("#suggestions").removeClass('active');
}
}
});