Does jQuery have an event that will capture the creation of dynamically created DOM content? Or is there some way of doing this in jQuery?
The web page in which I am injecting jQuery into creates text boxes dynamically. I have no control over that. I would however like to check every 3 seconds whether a new text box has been created and then populate it with a value.
The text boxes look like the following:
<input id="AplEducationTbl:EstName:0" type="text" onchange="return false">
<input id="AplEducationTbl:EstName:1" type="text" onchange="return false">
So there are a couple of problems. The id uses a colon, which I don't know how to escape in jQuery. The onchange returns false, which prevents me from hooking on my events.
Using:
setTimeout(function(){
/* What do I put here? */
}, 3000);
Can you use event delegation and search for IDs starting with AplEducationTbl:EstName?
$(document).on("change", "input[id^=AplEducationTbl\\:EstName]", function() {
console.log("Change");
});
jsFiddle
I would however like to check every 3 seconds whether a new text box has been created
To this you have to use setInterval() method instead:
var len = $('input[id^="AplEducationTbl:EstName"]').length;
setInterval(function () {
if ($('input[id^="AplEducationTbl:EstName"]').length > len) {
console.log('changed.');
len = $('input[id^="AplEducationTbl:EstName"]').length;
} //^^^^----------------------------------------update the value of len
}, 3000);
The id uses a colon, which I don't know how to escape in jQuery.
For this either you can use two forward slashes \\ as suggested by other answer and other way to use a string representation put that id value in quotes like this:
$('input[id^="AplEducationTbl:EstName"]')
//-----------^-----------------------^------put the value in quotes like this
//------------------------------------------and you are good to go.
Related
I have multiple <textarea>, sometime they are blank and sometime they are filled with text.
I want to insert a simple text code such as "<check>" which will automatically change to a check (\u2713).
Presently, my code is like this:
<textarea name="1-S" onchange="check(this.value)">
<check> //an input written by a user
</textarea>
<textarea name="1-NI" onchange="check(this.value)">
<check> //an input written by a user
</textarea>
<textarea name="1-C" onchange="check(this.value)">
<check> //an input written by a user
</textarea>
(This block of <textarea> gets repeated, but of course, with different name in each one.)
<script type="text/javascript">
function check(str){
var res = str.replace("<check>", "\u2713");
????
}
</script>
The output will then replace <check> into actual check symbol (\u2713)
The challenge is, I don't want to have to add ID to every <textarea> and then write a script for each one. So is there a way for me to use this one script to apply to all <textarea>???
Many thanks in advance!
You could use the getElementsByTagName method to create an array of your text area tags.
Since you're using jQuery:
$("textarea").each(function(index, textarea) {
// do replacement here
});
Note that you need to use HTML entities to put <check> into a textarea: <check>
Also, you can put a checkmark in without any Javascript like this: ✓
Yes. You can bind an event handler to all elements of a type using jquery.
$('textarea').on('change', function() {
var text = $(this).val();
if (text.match(/\<check\>/)) {
$(this).val(text.replace(/\<check\>/, "\u2713"));
}
});
The benefit of doing it this way is that you can remove your inline 'onchange' handlers from the html and consolidate your validation logic strictly to JavaScript.
To replace the actual textarea content you need to update the value of the textarea with the result of your String-replace regexp. var text = $(this).val() is just assigning the content of the textarea to the variable text, it's not a reference to the innerHTML portion of your textarea.
On a sidenote if you'd like to allow users to use shortcodes in a form, prefer square bracket syntax, e.g., [check].
I'm trying to allow users to edit the text of a paragraph in a website. I take a paragraph and replace the <p> tags with <textarea> tags using the .replaceWith() function. When I try to take the value of the textarea, it returns blank. Here's a JSfiddle.
HTML:
<p><a class="edit">Edit</a>I'm going to change this into a textarea field and retrieve the value.</p>
JS:
$(document).ready(function() {
$('.edit').hide();
var object = $('p');
object.on("mouseenter", function() {
$('.edit').show();
object.on('click','.edit',function(){
var oldText = object.text();
oldText = oldText.substr(4); // Exclude the word 'Edit'
object.replaceWith($("<textarea>").val(oldText).css("width",object.css('width')).css('height',object.css('height')));
var value = object.val();
alert("Value: "+value);
});
});
});
I'm a programming beginner, so if you have style or implementation tips, feel free to share. This is just my gut reaction to solving the problem; there may be a simpler way to accomplish the same thing.
EDIT: I should also mention that in my website, each paragraph comes from a database table that I'm displaying using an AJAX function. When the user is done editing, he can click a button, and the website will take the new value of the textarea field and UPDATE *table* SET *text*=newText WHERE *text* LIKE oldText;
Try just using contenteditable='true' instead of changing to a textarea. It will make the <p> editable.
Like this:
<p contenteditable='true'><a class="edit">Edit</a>
I'm going to change this into a textarea field and retrieve the value.</p>
If you want to make your text area editable when someone clicks 'Edit', you can create a function that sets the contenteditable attribute to true and then gives focus to the <p> element.
Your code is not trying to get the value of the <textarea>. Your call:
object.replaceWith( ... )
does not change the value of the variable "object" — it's still the jQuery object for the <p> tag, but after that it's out of the DOM. <p> tags don't have a "value" property.
It's almost always a bad idea to set up event handlers inside another event handler (well, an event handler for interaction events anyway). Event handlers accumulate, so each "mouseenter" event will add another "click" handler.
ckersch is right about an easier method being to use contenteditable, but if you're looking to a solution for your specific problem, change your selector from this:
var value = object.val();
To this:
var value = $("textarea").val();
Full code:
$(document).ready(function() {
$('.edit').hide();
var object = $('p');
object.on("mouseenter", function() {
$('.edit').show();
object.on('click','.edit',function(){
var oldText = object.text();
oldText = oldText.substr(4); // Exclude the word 'Edit'
object.replaceWith($("<textarea>").val(oldText).css("width",object.css('width')).css('height',object.css('height')));
var value = $("textarea").val();
alert("Value: "+value);
});
});
});
Fiddle
There are many ways you could make it more robust, including adding a class or id to your textarea, and then using it to be selected, such as this way:
object.replaceWith($("<textarea class='selectMe'>").val(oldText).css("width",object.css('width')).css('height',object.css('height')));
var value = $(".selectMe").val();
You are using the method replaceWith() wrong. The argument must be a string or a function that returns a string, not a jquery selector. Also, you should place the onclick event outside of the mouseenter event (this is valid for any event, never nest them)
$(document).ready(function() {
function makeTextarea(e) {
e.preventDefault();
var edit = $(e.currentTarget);
var parent = edit.parent();
edit.remove();
parent.replaceWith('<textarea>' + parent.text() + '</textarea>');
}
$('.edit').on('click', makeTextarea);
});
Fiddle: http://jsfiddle.net/U57v2/4/
"When the document is ready listen for clicks on .edit class. When clicked store a reference to the parent element (<p>) and then remove the edit element. Finally replace the parent element (<p>) with a textarea with the contents of the <p> element."
ckersh is absolutely right about the contenteditable, but if you're looking for a specific answer to your code, there are a few things you could improve.
There are a couple of issues with your code. First, you're rebinding the on('click') handler every time you mouse over the paragraph, so if you mouse over 5 times, you're executing the anonymous function 5 times. You only need to bind the on routine once. Second, the variable object never changes, so when you replace it with a textarea, you need a new selector to get the value.
I've updated your fiddle with the enhancements I've mentioned above. I also added a mouseleave event, because I figure you want to hide the "Edit" button when you leave the paragraph. The updated javascript can be seen below:
$(document).ready(function () {
$('.edit').hide();
var object = $('p');
object.on("mouseenter", function () {
$('.edit').show();
}).on("mouseleave", function () {
$('.edit').hide();
}).on("click", '.edit', function () {
var oldText = object.text();
oldText = oldText.substr(4); // Exclude the word 'Edit'
object.replaceWith($("<textarea>").val(oldText).css("width", object.css('width')).css('height', object.css('height')));
var value = $("textarea").val();
alert("Value: " + value);
});
});
My first SO question! Here's what I am trying to do:
I'm rewriting a tool that generates some code a user can paste directly into Craigslist and other classified ad posting websites. I have created a list of websites (they populate from a database with PHP) the user can choose from with a radio button, and I want their choice to populate as bare text (not a link) between some <p></p> elements in a textarea. I'm using jQuery for this.
Textarea before the user chooses:
<p id="thing"></p>
Textarea after the user chooses:
<p id="thing">www.somewebsite.com</p>
HTML
<input type="radio" name="sitechoice" value="www.websiteone.com">www.websiteone.com<br />
<input type="radio" name="sitechoice" value="www.secondwebs.com">www.secondwebs.com
<textarea>
Some stuff already in here
Here is the website you chose:
<p id="thing"></p>
More stuff already here.
</textarea>
JS
$(document).ready(function () {
$("input").change(function () {
var website = $(this).val();
alert(website);
$("#thing2").html(website);
});
});
JS Fiddle (With comments)
If you see the JS Fiddle, you can see that I put another p element on the page outside the textarea, and it updates just fine, but the one inside the textarea does not. I have read many other like questions on SO and I'm starting to think that I can't change an element that's between textarea tags, I can only change the entire textarea itself. Please, lead me to enlightenment!
You actually can fairly easily manipulate the text contents of the textarea like it is part of the DOM, by transforming its contents into a jQuery object.
Here is a jsFiddle demonstrating this solution: http://jsfiddle.net/YxtH4/2/
The relevant code, inside the input change event:
// Your normal code
var website = $(this).val();
$("#thing2").html(website);
// This turns the textarea's val into a jQuery object ...
// And inserts it into an empty div that is created
var textareaHtml = $('<div>' + $("#textarea").val() + '</div>');
// Here you can do your normal selectors
textareaHtml.find("#thing").html(website);
// And this sets the textarea's content to the empty div's content
$("#textarea").val(textareaHtml.html());
The empty div wrapping your HTML is so that you can easily retrieve it as a string later using jQuery's .html() method, and so the parse does not fail if additional text is entered around the p element inside the textarea.
The real magic is $($("#textarea").val()), which takes your textarea's text and parses it into an HTML node contained in a jQuery object.
It can't do it the way that you are thinking (i.e., manipulate it as if it were a DOM element), but it is still accessible as the value of the textarea, so you can retrieve it like that, use basic string manipulation to alter it, and then set the updated string as the new value of the textarea again.
Something like this . . . first give the <textarea> an id value:
<textarea id="taTarget">
Some stuff already in here
Here is the website you chose:
<p id="thing"></p>
More stuff already here.
</textarea>
Then alter your script like this:
$(document).ready(function () {
$("input").change(function () {
var website = $(this).val();
var currentTAVal = $("#taTarget").val();
$("#taTarget").val(currentTAVal.replace(/(<p id="thing">)([^<]*)(<\/p>)/, "$1" + website + "$3"));
});
});
Unless you need the <p> element in there, you might consider using a more simple placeholder, since it won't actually act as an HTML element within the textarea. :)
EDIT : Fixed a typo in the .replace() regex.
I know that this answer is a little bit late, but here it goes =)
You can do exactly the way you want to do. But for that, you need to implement a small trick.
by having this HTML
<input type="radio" name="sitechoice" value="www.websiteone.com">www.websiteone.com
<br />
<input type="radio" name="sitechoice" value="www.secondwebs.com">www.secondwebs.com
<p id="thing2"></p>
<textarea id="textarea">
<p id="thing"></p>
</textarea>
you can edit textarea content, as a DOM by implementing something like the function changeInnerText
$(document).ready(function () {
$("input").change(function () {
var website = $(this).val(); // Gets value of input
changeInnerText(website);
//$("#thing").html(website); // Changes
//$("#thing2").html(website); // Does not change
});
var changeInnerText = function(text) {
var v = $("#textarea").val();
var span = $("<span>");
span.html(v);
var obj = span.find("#thing")[0];
$(obj).html(text);
console.log(obj);
console.log(span.html());
$("#textarea").val(span.html());
}
});
As you can see, I just get the information from the textarea, I create a temporary variable span to place textarea's content. and then manipulate it as DOM.
Instead of attempting to insert the text into the <p> element, insert the text into <textarea> element and include the <p> tag. Something like this should do the trick:
Change:
$("#thing").html(website);
to:
$("textarea").html('<p id="thing">'+website+'</p>');
And here is a fiddle: http://jsfiddle.net/nR94s/
I am trying to use jQuery / javascript to remove a class from a named input element if a checkbox is ticked.
I have several checkboxes, each with a accompanying hidden (on page load) text input field.
The checkbox and text input field are named "question_X" and "question_X_description" respectively. (where X is a number 0 to 100, say)
As such I'm trying to define a variable in my code that is defined as "this element's name"+"_description", and then use that to define the suitable element to remove the class from.
Here is what I've tried:
$('input:checkbox').change(function(){
var x = $(this).attr('name').'_description';
if($(this).is(":checked")) {
$('input[name="x"]').removeClass("hidden");
} else {
$('input[name="x"]').addClass("hidden");
}
});
However, nothing happens when the any checkbox is checked. Am I referencing my variable correctly?
Use your console, It will have error messages.
First issue
var x = $(this).attr('name').'_description';
^^^
That is not how you build a string in JavaScript. JavaScript does not use . to join strings. It uses +
var x = $(this).attr('name') + '_description';
Second issue
$('input[name="x"]').
You are not looking for the string you built, you are looking for an element with the name x
Needs to be
$('input[name="' + x + '"]').
$('input[name="x"]').removeClass("hidden");
Will be looking for:
<input name="x" />
Try
$(name="'+x+'").removeClass("hidden");
Use document.getElementById('element_name')
Example of HTML element:
<input type="text" id="element_name">
I am counting the number of inputs on the current document that have value. It works fine, except for when I have dynamically added more inputs. I can't get there values.
For example I may have
<input id="participant-1"/>
<input id="participant-2"/>
...
Dynamically created after button click
<input id="participant-15" />
I'll get the value of each one in a for loop like
for(var i =1 ; i <25; i++)
{
...$('input#participant-' + i).val();
}
Now when I run a for loop to check the value of each one of these inputs it only gets the values of the inputs that weren't dynamically created. I have looked at the other questions on here and I still can't see how to apply something like .on() to what I am trying to accomplish.
NEW FOLLOW UP QUESTION
ok, now I think this is where I need more clarification concerning how to use the .on.
I have a jsfiddle here: JsFiddle example
where I create new elements and on blur of all text boxes I would like to calculate how many of the elements have value and log it. Now it currently will respond from blur event with elements who were static. It doesn't work for dynamically created elements
Give it a common class:
<input class="textbox" id="participant-1"/>
<input class="textbox" id="participant-2"/>
And get it like:
var values = [];
$('.textbox').each(function(){
values.push($(this).val());
});
console.log(values)
And to answer the edit:
The Syntax should be : $(container_selector).on(event_type, target_selector, callback)
JSFiddle Demo
$('.name').on('blur', 'input', calculate_total);
Could also consider the use of the CSS attribute selector.
http://www.w3.org/TR/CSS2/selector.html#attribute-selectors
$("input[id|=participant]").each(function(){
// something
});
Using a class selector will save time here.
<input id="participant-1" class="participant"/>
<input id="participant-2" class="participant"/>
Then use a simple count call...
var count = $('.participant').length
alert ('You have ' + count + ' Counted Inputs');
//result is 2
Hope you find this useful