I'm trying to set a script to dynamically change a textarea content.
After some Googling I got this :
$(document).ready(function() {
// This is a first text modification that works fine
$('textarea#modifyme').val('Some useless text');
// Catching a select change
$('select#changemyvalue').bind('change keyup input',function() {
// This alert triggers but twice
alert('I know you want to change text');
// This is not displaying...
$('textarea#modifyme').val('I do not want to be display');
});
});
First value setting is good, but when it comes to select change detection it gets a bit odd.
Alert is triggering twice, and the second value setting is not functioning.
Any help greatly appreciated! Thanks.
Thanks to your answers I've fixed the double trigger, but still the secon .val('sometext') is not triggering.
I'm trying to apply this to a textarea displaying as a wysiwyg editor, I can only change the text on load (first .val('xx') call).
I also notice that if I invert these 2 lines :
// This alert triggers now only once
alert('I know you want to change text');
// This is not displaying...
$('textarea#modifyme').val('I do not want to be display');
To :
// This is not displaying...
$('textarea#modifyme').val('I do not want to be display');
// This alert does not trigger if placed here
alert('I know you want to change text');
Code seem to break at the first line, preventing 'alert' to display.
Is the nature of wysiwyg editor preventing text change after page load?
Here is the short version of html code :
<select name="" id="selectMe">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<textarea class="textarea callhtml5" name="changeMe" id="changeMe"></textarea>
<!-- Bootstrap WYSIHTML5 -->
<script src="path to wysihtml5 bootstrap"></script>
<script>
$(".callhtml5").wysihtml5();
</script>
<script>
$(document).ready(function() {
$('textarea#changeMe').val('Initial text setup');
$('select#selectMe').bind('change keyup',function() {
alert('Test');
$('textarea#changeMe').val('Final text setup');
});
});
<script>
Solved this problem by using :
$('.wysihtml5-sandbox').contents().find('body').html("I got you modified");
Instead of this method :
$('textarea#changeMe').val('Final text setup');
It's because of keyup and input. If you bind both events the callback executes two times.
To over come this use these two bind input. You can omit the keyup.
One thing I would like to mention about input event is that it can't be captured. What I mean is it won't let you capture event.
Just noticed that the element is <select> element so better to use change keyup. You should avoid using input event as you are not putting text values in it but changing it with mouse or keys.
You need to either take out change or input from .bind(). Both events are triggering thus running the function twice.
Hope this helped! :)
As of jQuery 1.7, the .on() method is the preferred method for attaching event handlers to a document. For earlier versions, the .bind() method is used for attaching an event handler directly to elements. http://api.jquery.com/bind/
You could probably change your code like this to work.
$(document).ready(function() {
$('textarea#modifyme').val('Some useless text');
$('select#changemyvalue').on('change', 'keyup', 'input',function() {
alert('I know you want to change text');
$('textarea#modifyme').val('I do not want to be display');
});
});
EDIT: Instead to using three things, one would work properly. Use input or keyup
You Remove keyup input on your Script
Try This Jquery like this
$(document).ready(function() {
$('textarea#modifyme').val('Some useless text');
$('select#changemyvalue').on('change', function(e) {
// This alert triggers but twice
alert('I know you want to change text');
// This is not displaying...
$('textarea#modifyme').val('I do not want to be display');
});
});
You can add event parameter to your handler and check what event is raised
As you can see below: first - input event, then - change event
So you should select just one of them.
This interesting, but seems input event for select raised just in Chrome.
Sample:
$(document).ready(function() {
$('textarea#modifyme').val('Some useless text');
$('select#changemyvalue').on('change keyup input', function(e) {
console.log('Now raised: '+e.type+' event');
$("#events").append('Now raised: '+e.type+' event <br/>');
// This is not displaying...
$('textarea#modifyme').val('I do not want to be display');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea name="" id="modifyme" cols="30" rows="10"></textarea>
<select name="" id="changemyvalue">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<div id="events"></div>
Related
Let me show what I mean on an example with bootstrap-select:
HTML
Show Select options
<div id="gap"></div>
Destroy Select
<div id="searchSelect">
<select name="searchName" id="idSelect" data-live-search="true" data-size="10">
<option value="John">John</option>
<option value="Janet">Janet</option>
</select>
</div>
JS:
$("#idSelect").selectpicker();
$("#link").click(function(e) {
e.preventDefault();
$("#searchSelect").show();
setTimeout(function () {
$('#idSelect').selectpicker('toggle');
});
});
$("#link2").click(function(e) {
e.preventDefault();
$('#idSelect').selectpicker('destroy');
$("#searchSelect").hide();
alert("Select destroyed");
});
$("#idSelect").on("hide.bs.select", function () {
alert("onHide fired");
});
When you run for the first time, this event works fine:
$("#idSelect").on("hide.bs.select", function () {
but after you destroy the element and initialize again, the event won't fire anymore, is there a way to assign the event again to the element?
The best way to see what I mean is to go through:
take look at JSFIDDLE
Click the button "Show Select options"
Click outside the dropdown menu, it will close and it will show the alert message.
Click the button "Destroy Select"
Repeat step 1,2 it will close but it won't show the alert message.
Change to using a delegated event handler:
$(document).on("hide.bs.select", "#idSelect", function () {
alert("onHide fired");
});
Jsfiddle: https://jsfiddle.net/n1zz8kkw/17/
This works by listing for the event on a non-changing ancestor, then applying the filter (#idSelect) to the items in the bubble chain, then applying the function to the matching element that caused the event. The upshot is that the element does not need to exist except at event time.
document is the best default if nothing else is closer. body has a bug, so best to avoid and document always exists, so a delegated handler on document does not even need to be inside a doc ready handler :)
Please run this sample in Google Chrome browser.
Stack Snippet
$(function() {
$(":input").select(function() {
$("div").text("Something was selected").show().fadeOut(1000);
alert("Selected");
});
$("button").click(function() {
$(":input").select();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<button>Click To Select</button>
<input type="text" value="Some text">
<div></div>
Here why jQuery select event listener is triggering multiple times? Does anyone know the reason behind this? And is there any workaround solution for this without using timeout?
The $(":input") selector is selecting the button too, so it causes recursion. Either use just $("input"), or $(":input:not(button)").
I noticed when the three events are fired, the first doesn't have originalEvent property, so we definitely can dismiss it, and the second two has very similar (however not identical) timestamp. You can store the last timestamp in some variable and in event listener compare it with the event's timestamp. If the rounded values of these two are the same, you can dismiss this event.
$(function() {
var lastTimeStamp;
$("input").select(function(event) {
if (!event.originalEvent ||
lastTimeStamp === Math.round(event.timeStamp)) return;
lastTimeStamp = Math.round(event.timeStamp);
$("div").text("Something was selected").show().fadeOut(1000);
alert("Selected");
});
$("button").click(function() {
$("input").select();
});
});
See updated JS Fiddle.
It appears the issue is a combination of:
the :input selector gets the input and the button, hence multiple events triggered.
even when using just input as the selector there is some odd event propagation being triggered on related elements which is raising the select event handler multiple times.
To avoid both of the above, use input as the selector and also use preventDefault() in the event handler. stopPropagation() may also be required, depending on your HTML stucture.
$(function() {
$('input').select(function(e) {
// e.stopPropagation(); // optional
e.preventDefault();
$('#message').text("Something was selected").show().fadeOut(1000);
console.log('Selected');
});
$('button').click(function() {
$('input').select();
});
});
Working example
UPDATE: We were all fooled. The select() function needs a prevent default.
Rory McCrossan figured it out. Well done mate.
Incidentally, I'm not sure what the benefit of select() actually is! Something like focus() or on('focus',) might make more sense. Not Sure what the context is however. The below still follows:
Why waste time using generalised tag/type selectors which may change? Use an ID, and pick out only the one you want.
If you want to detect multiple, use a class. If you want to use multiple, but figure out which one you clicked, use a class and an ID. Bind with the class, and identify using $this.attr('id').
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<button>Click To Select</button>
<input type="text" value="Some text" id="pick-me">
<div></div>
$(function() {
$("#pick-me").select(function(event) {
event.preventDefault();
$("div").text("Something was selected").show().fadeOut(1000);
alert("Selected");
});
$("button").click(function() {
$("#pick-me").select();
});
});
I have a form as follows:
<form>
<label for="input">Input:</label>
<input type="text" id="input" maxlength="3"></input>
<button type="button" id="lock" onMouseDown="toggleInput()"></button>
</form>
And javascript code:
function toggleInput(){
if ($("#input").disabled){
$("#input").disabled = false;
}
else {
$("#input").disabled = true;
};
}
What I basically want to do is to check what state (enabled/disabled) the textbox is in, and then toggle the state accordingly. I don't know if the javascript portion even uses the correct syntax to check if the textbox is disabled, but it's what I could think of.
Thanks in advance!
EDIT: Reason as to why I've chosen to use onmousedown instead of onclick to execute the event with the button:
I have chosen to use onmousedown instead of onclick as it makes the app I'm building feel less clunky due to the presence of this feature with onclick: When you click on a button and then drag the cursor away from the button while holding the mouse button down, and subsequently lift your finger off the mouse button when the cursor is in an area away from the button on the webpage, the event will not be executed. Hence, I've chosen to use onmousedown as this is overcome.
Use .prop(), Get the value of a property for the first element in the set of matched elements or set one or more properties for every matched element
$("#input").prop('disabled',!$("#input").prop('disabled'))
DEMO
I am not sure why you are using onMouseDown. Use click instead
$("#lock").on("click", function() {
$("#input").prop('disabled',!$("#input").prop('disabled'))
});
DEMO with click
To do it with jQuery try this:
$("#input").prop("disabled", function(i, v) { return !v; });
Your existing code doesn't work because DOM elements have a .disabled property, but jQuery objects do not.
I'm not sure why you're using onmousedown instead of onclick for the button, but either way if you're going to use jQuery I'd recommend removing the inline event attribute in favour of binding the handler with jQuery:
$("#lock").on("click", function() {
$("#input").prop("disabled", function(i, v) { return !v; });
});
(You'd need to include that code either in a script block at the end of the body or in a document ready handler.)
Demo: http://jsfiddle.net/a7f8v/
You should append the event handler with jQuery instead of an onMouseDown event. The syntax could look like this:
<label for="input">Input:</label>
<input type="text" id="input" maxlength="3"></input>
<button type="button" id="lock"></button>
JavaScript:
$(document).ready(function() {
$("#lock").click(function() {
var input = $("#input");
input.prop('disabled',!input.is(':disabled'))
});
});
Example
I have a hidden select element with an onchange call to a javascript function.
When a user clicks a button on my page I run the below code and my select form is shown:
$("#moreDetails2").show();
$('#moreDetails2').trigger("create");
After it is shown however, it will not execute its JavaScript function. I have tested it not hidden and it works.
<div id = \"moreDetails2\">
<select onchange=\"moreDetails2($userID,'$id')\">
<option value=\"0\">More Options</option>
<option value=\"1\"> View Taste Profile</option>
<option value=\"2\"> Add Taste Tags</option>
</select>
</div>
Looking in inspect element in chrome, I do not get any errors.
jQuery Mobile don't play well with onchange="... or onclick="... event binding, you will need to do it by manually like this:
$(document).on('pagebeforeshow', '#index', function(){
$(document).on('click', '#test-button', function(){
$("#moreDetails2").show();
$("#moreDetails2 select").css('display','block').selectmenu('refresh');
});
$("#moreDetails2 select").on( "change", function(event, ui) {
moreDetails2('aaaa');
});
});
function moreDetails2(text) {
alert(text);
}
And here's a working jsFiddle example created from your code: http://jsfiddle.net/Gajotres/DpdXY/
Using the same name as a global function name and an element identifier will cause problems in Chrome, Safari, and IE (not Firefox).
Try changing your event handler function name to "moreDetailsTwo" or something.
Chrome, Safari, and IE create global symbols (that is, window properties) for each element with an "id" value. I suspect that that's clobbering your binding of the "moreDetails2" function.
<select onchange="alert();">
<option>d</option>
<option>de</option>
<option>dewe</option>
<option>dewee</option>
</select>
I want the onchange event of a <select> element to display an alert but it's not working.
Any ideas what's wrong?
I'm assuming your issue is that the alert() call displayed undefined instead of the value of the <select>.
If you want to see the value of the <select>, do this instead:
<select onchange="alert(this.value);">
<option>d</option>
<option>de</option>
<option>dewe</option>
<option>dewee</option>
</select>
jsfiddle example
Or, if you actually are using jQuery, you can do it like this:
//This is an anonymous function that calls itself with the jQuery object as an argument
//This allows you to use the `$` when making jQuery calls but the code
//will run without modification if jQuery is in noConflict() mode
(function($) {
//This is the important part
//Here, we bind to the change event and alert the value
$('select').change( function(e) {
alert($(this).val());
});
})(jQuery)
jsfiddle example 2
That should work but you can also try this provided you include jQuery on your page
$(function(){
$("select").change(function(){
alert($(this).val());
});
});
You should give a string as a parameter in your alert function if you want it to work...