Unable to pass string in to jquery function - javascript

I wish to grab the current value of a search input and then clear the input box on focus, store the string and pass it into a function to re-populate the input box on blur.
$("input#search").bind('focus', function() {
var search_text = document.getElementById('search').value;
$("input#search").val("");
}).bind('blur', function(search_text) {
$("input#search").val(search_text);
});
Currently, this successfully grabs the value on focus and clears the input box, but on blur, it populates the input with [object Object].
Am I correctly passing the string on line 4?

Firstly, don't use bind(). It was deprecated a long time ago. Use on() instead.
With regard to your issue, you can't directly pass a parameter to the anonymous handler function in the manner you're attempting. As it stands your search_text variable will hold the blur event.
To fix this you could store the variable in a data attribute on the #search element itself. Try this:
$("input#search").on('focus', function() {
$(this).data('search-text', this.value).val('');
}).on('blur', function(search_text) {
$(this).val($(this).data('search-text'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="search" value="foo bar" />
Also, the behaviour you're creating here is similar to the placeholder attribute. It may be worth investigating that to see if it meets your needs.

Use .on() of jQuery to register event.
var search_text;
$("input#search").on('focus', function() {
search_text = document.getElementById('search').value;
$("input#search").val("");
});
$("input#search").on('blur', function() {
$("input#search").val(search_text);
});
Alternate could be ,
$("input#search").on('focus', function() {
var search_text = document.getElementById('search').value;
$("input#search").val("");
$(this).on('blur', function() {
$("input#search").val(search_text);
});
});

No. Here is how you would do, declaring the variable before the event listeners so that it's in the scope:
var search_text;
$("input#search").bind('focus', function() {
search_text = document.getElementById('search').value;
$("input#search").val("");
}).bind('blur', function() {
$("input#search").val(search_text);
});
The convention in JavaScript for naming variables in Camel Case, so you would rather use searchText (not that it really matters).

Related

jQuery nested functions

I am still new to JavaScript and jQuery, so I am confused as to why the following code is not working as I anticipated. All I am trying to do is save input on a button click (id=recordInput) and display it with another button click (id=displayInput). What I observe is that tempInput is stored, (the code works until that point) but assignment of displayInputs onclick attribute is not executed. My question is, can you not nest a $().click() call inside of another &().click() call?
<script>
$(document).ready(function () {
$('#recordInput').click(function(event) {
var tempInput = $('#testInput').val();
&('#displayInput').click(function(event) {
console.log(tempInput);
});
});
});
</script>
My thinking is this in pseudocode:
assign recordInput onclick attribute to the following function:
store tempInput
set displayInput onclick to alert the tempInput value
what is wrong with my thinking?
NOTE: I did not include any html tags but all of the ids are referenced correctly
It's not working because you have put & instead of $ here
$('#displayInput').click(function(event) {
Fixing this may work, but you shouldn't set event handlers this way. Because every time your first handler function is called it will set an event handler for the second one. You can try with your console.log and you will see that the number of console.log is increasing by every click on #recordInput. So you should better set it like this :
var tempInput;
$('#recordInput').click(function(event) {
tempInput = $('#testInput').val();
});
$('#displayInput').click(function(event) {
console.log(tempInput);
});
I would change
$(document).ready(function () {
$('#recordInput').click(function(event) {
var tempInput = $('#testInput').val();
&('#displayInput').click(function(event) {
console.log(tempInput);
});
});
});
to
$(function(){
var testInput = '';
$('#recordInput').click(function(){
testInput = $('#testInput').val();
});
$('#displayInput').click(function(){
if(testInput !== ''){
console.log(testInput);
}
});
});
You are using & instead of $. Of course, you don't have to format the code exactly like I did.

Select element by passing variable in function - jQuery

I am trying to select all input fields inside a certain element. I pass this element to a function, but I don't know how to go from there:
$('._save, .btn-success').click(function(){
saveForm($('.dashboard_container'));
});
//This functions has to select all the input fields inside the given element
function saveForm(that) {
var input = $(that, 'input'); //This does not seem to work
input.each(function(){
//Do something
})
}
How to chain a variable and a selector together?
The contextual selector takes the parameters the other way around to what you've used:
function saveForm($that) {
var $input = $('input', $that);
$input.each(function(){
//Do something
})
}
You could also use the find() method as you're passing in a jQuery object:
var $input = $that.find('input');
If you need to find all input field inside some element x then you can use .find(input).
For example:
//This functions has to select all the input fields inside the given element
function saveForm(that) {
var input = $(that).find("input"); //This does not seem to work
input.each(function(){
//Do something
})
}
And you can achieve it without using .find as well (the way you were trying to do)
$('._save, .btn-success').click(function(){
saveForm('.dashboard_container');
});
//This functions has to select all the input fields inside the given element
function saveForm(that) {
var input = $(that + ' input'); //This does not seem to work
input.each(function(){
//Do something
})
}

Converting Span to Input

I am developing web app, I have such a requirement that whenever user click on text inside span i need convert it into input field and on blur i need to convert it back to span again. So i am using following script in one of my jsp page.
Java Script:
<script type="text/javascript">
function covertSpan(id){
$('#'+id).click(function() {
var input = $("<input>", { val: $(this).text(),
type: "text" });
$(this).replaceWith(input);
input.select();
});
$('input').live('blur', function () {
var span=$("<span>", {text:$(this).val()});
$(this).replaceWith(span);
});
}
JSP Code:
<span id="loadNumId" onmouseover="javascript:covertSpan(this.id);">5566</span>
Now my problem is, everything works fine only for the first time. I mean whenever i click on the text inside span for the first time it converts into input field and again onblur it coverts back from input field to normal text. But if try once again to do so it won't work. Whats wrong with above script?
Would be good to change your dom structure to something like this (note that the span and the input are side by side and within a shared parent .inputSwitch
<div class="inputSwitch">
First Name: <span>John</span><input />
</div>
<div class="inputSwitch">
Last Name: <span>Doe</span><input />
</div>
Then we can do our JS like this, it will support selecting all on focus and tabbing to get to the next/previous span/input: http://jsfiddle.net/x33gz6z9/
var $inputSwitches = $(".inputSwitch"),
$inputs = $inputSwitches.find("input"),
$spans = $inputSwitches.find("span");
$spans.on("click", function() {
var $this = $(this);
$this.hide().siblings("input").show().focus().select();
}).each( function() {
var $this = $(this);
$this.text($this.siblings("input").val());
});
$inputs.on("blur", function() {
var $this = $(this);
$this.hide().siblings("span").text($this.val()).show();
}).on('keydown', function(e) {
if (e.which == 9) {
e.preventDefault();
if (e.shiftKey) {
$(this).blur().parent().prevAll($inputSwitches).first().find($spans).click();
} else {
$(this).blur().parent().nextAll($inputSwitches).first().find($spans).click();
}
}
}).hide();
I understand you think that element replacement is a nice thing, however, I would use a prompt to get the text. Why? It is a lot easier and actually a bit prettier for the user as well. If you are curious on how to do it, I show you.
html:
<span class='editable'>foobar</span>
js:
$(function()
{
$('span.editable').click(function()
{
var span = $(this);
var text = span.text();
var new_text = prompt("Change value", text);
if (new_text != null)
span.text(new_text);
});
});
http://jsfiddle.net/qJxhV/1/
First, you need to change your click handler to use live() as well. You should take note, though, that live() has been deprecated for quite a while now. You should be using on() in both cases instead.
Secondly, when you replace the input with the span, you don't give the element an id. Therefore, the element no longer matches the selector for your click handler.
Personally, I would take a different (and simpler) approach completely. I would have both the span and in the input in my markup side by side. One would be hidden while the other is shown. This would give you less chance to make mistakes when trying to recreate DOM elements and improve performance since you won't constantly be adding/removing elements from the DOM.
A more generic version of smerny's excellent answer with id's can be made by slightly altering two lines:
$input.attr("ID", "loadNum"); becomes $input.attr("ID", $(this).attr("ID")); -- this way, it simply takes the current id, and keeps it, whatever it is.
Similarly,
$span.attr("ID", "loadNum"); becomes $span.attr("ID", $(this).attr("ID"));
This simply allows the functions to be applied to any div. With two similar lines added, both id and class work fine. See example.
I have done little change in code, By using this input type cant be blank, it will back to its real value.
var switchToInput = function () {
var $input = $("<input>", {
val: $(this).text(),
type: "text",
rel : jQuery(this).text(),
});
$input.addClass("loadNum");
$(this).replaceWith($input);
$input.on("blur", switchToSpan);
$input.select();
};
var switchToSpan = function () {
if(jQuery(this).val()){
var $text = jQuery(this).val();
} else {
var $text = jQuery(this).attr('rel');
}
var $span = $("<span>", {
text: $text,
});
$span.addClass("loadNum");
$(this).replaceWith($span);
$span.on("click", switchToInput);
}
$(".loadNum").on("click", switchToInput);
jsFiddle:- https://jsfiddle.net/svsp3wqL/

jQuery bind to Paste Event, how to get the content of the paste

I have a jquery token tagit plugin and I want to bind to the paste event to add items correctly.
I'm able to bind to the paste event like so:
.bind("paste", paste_input)
...
function paste_input(e) {
console.log(e)
return false;
}
How can I obtain the actual pasted content value?
There is an onpaste event that works in modern day browsers. You can access the pasted data using the getData function on the clipboardData object.
$("#textareaid").bind("paste", function(e){
// access the clipboard using the api
var pastedData = e.originalEvent.clipboardData.getData('text');
alert(pastedData);
} );
Note that bind and unbind are deprecated as of jQuery 3. The preferred call is to on.
All modern day browsers support the Clipboard API.
See also: In Jquery How to handle paste?
How about this: http://jsfiddle.net/5bNx4/
Please use .on if you are using jq1.7 et al.
Behaviour: When you type anything or paste anything on the 1st textarea the teaxtarea below captures the cahnge.
Rest I hope it helps the cause. :)
Helpful link =>
How do you handle oncut, oncopy, and onpaste in jQuery?
Catch paste input
EDIT:
Events list within .on() should be space-separated. Refer https://api.jquery.com/on/
code
$(document).ready(function() {
var $editor = $('#editor');
var $clipboard = $('<textarea />').insertAfter($editor);
if(!document.execCommand('StyleWithCSS', false, false)) {
document.execCommand('UseCSS', false, true);
}
$editor.on('paste keydown', function() {
var $self = $(this);
setTimeout(function(){
var $content = $self.html();
$clipboard.val($content);
},100);
});
});
I recently needed to accomplish something similar to this. I used the following design to access the paste element and value. jsFiddle demo
$('body').on('paste', 'input, textarea', function (e)
{
setTimeout(function ()
{
//currentTarget added in jQuery 1.3
alert($(e.currentTarget).val());
//do stuff
},0);
});
Another approach:
That input event will catch also the paste event.
$('textarea').bind('input', function () {
setTimeout(function () {
console.log('input event handled including paste event');
}, 0);
});
On modern browsers it's easy: just use the input event along with the inputType attribute:
$(document).on('input', 'input, textarea', function(e){
if (e.originalEvent.inputType == 'insertFromPaste') {
alert($(this).val());
}
});
https://codepen.io/anon/pen/jJOWxg
$(document).ready(function() {
$("#editor").bind('paste', function (e){
$(e.target).keyup(getInput);
});
function getInput(e){
var inputText = $(e.target).html(); /*$(e.target).val();*/
alert(inputText);
$(e.target).unbind('keyup');
}
});
This work on all browser to get pasted value. And also to creating common method for all text box.
$("#textareaid").bind("paste", function(e){
var pastedData = e.target.value;
alert(pastedData);
} )
You could compare the original value of the field and the changed value of the field and deduct the difference as the pasted value. This catches the pasted text correctly even if there is existing text in the field.
http://jsfiddle.net/6b7sK/
function text_diff(first, second) {
var start = 0;
while (start < first.length && first[start] == second[start]) {
++start;
}
var end = 0;
while (first.length - end > start && first[first.length - end - 1] == second[second.length - end - 1]) {
++end;
}
end = second.length - end;
return second.substr(start, end - start);
}
$('textarea').bind('paste', function () {
var self = $(this);
var orig = self.val();
setTimeout(function () {
var pasted = text_diff(orig, $(self).val());
console.log(pasted);
});
});
It would appear as though this event has some clipboardData property attached to it (it may be nested within the originalEvent property). The clipboardData contains an array of items and each one of those items has a getAsString() function that you can call. This returns the string representation of what is in the item.
Those items also have a getAsFile() function, as well as some others which are browser specific (e.g. in webkit browsers, there is a webkitGetAsEntry() function).
For my purposes, I needed the string value of what is being pasted. So, I did something similar to this:
$(element).bind("paste", function (e) {
e.originalEvent.clipboardData.items[0].getAsString(function (pStringRepresentation) {
debugger;
// pStringRepresentation now contains the string representation of what was pasted.
// This does not include HTML or any markup. Essentially jQuery's $(element).text()
// function result.
});
});
You'll want to perform an iteration through the items, keeping a string concatenation result.
The fact that there is an array of items makes me think more work will need to be done, analyzing each item. You'll also want to do some null/value checks.
I do it like so, this would work on most browsers used by humans
$("#couponCode").bind("change keyup input paste",function () {
const value= document.getElementById("couponCode").value;
});

If on .focusout form contains no value, revert to original value?

I'm trying to get my <input.../> fields to go blank on focus, and if on focus out they're still blank, revert them to their original values.
I would've thought this would work, but apparently not:
$('input').focus( function() {
var init_value = $(this).val();
$(this).val('');
});
$('input').focusout( function() {
var new_value = $(this).val();
if(new_value == "") {
$(this).val(init_value);
}
});
Any alterations/advice to get it working would be most appreciated ;)!
You should consider using the HTML5 placeholder attribute as a first option.
http://diveintohtml5.ep.io/forms.html#placeholder
With jQuery, you could modify your original script like this:
$('input').focus(function() {
$(this).val('');
});
$('input').focusout(function() {
if($(this).val('')){
$(this).val('Enter something');
}
});
Example: http://jsfiddle.net/jasongennaro/8bJcQ/
EDIT
Here is a revised script to deal with the situation as mentioned in your comment:
As for the jQuery option, that simply wouldn't do as it needs the
original value= value. I have perhaps 8 different text fields, the
instructions for which are the value, e.g. "Enter your email address",
"Enter your url", etc :(.
$('input').each(function(){
var a = $(this).attr('value');
$(this).focus(function() {
$(this).val('');
});
$(this).focusout(function() {
if($(this).val('')){
$(this).val(a);
}
});
});
Example 2: http://jsfiddle.net/jasongennaro/8bJcQ/3/
There is an easier method of doing this assuming a modern browser is used. Simply add the attribute placeholder="some text" and the browser will handle all this for you. If you must support older browsers, try this:
var init_value;
$('input').focus( function() {
init_value = $(this).val();
$(this).val('');
});
$('input').blur( function() {
var new_value = $(this).val();
if(new_value == "") {
$(this).val(init_value);
}
});
Your problem was the scope of init_value. You defined it inside an anonymous function, and could not access that value from a second anonymous function. To fix this you simply need to define init_value outside the scope of each event handler.
Also notice how I used .blur() instead of .focusout(). The jQuery API explains the difference between the two.

Categories

Resources