Converting Span to Input - javascript

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/

Related

Issues displaying a dynamically updated HTML input value

I'm struggling to get the behaviour I need - as follows:
A HTML form is pre-populated with a value via jQuery. When the user focuses on the input field I want the form to clear. On blur from the form, the form should repopulate the form with the existing value.
I have a solution that clears and repopulates the form but it fails as soon as anything is typed in.
This is what I have so far:
var x = "Default";
$(function () {
$("input").attr({
"value": x
});
$("input").focus(function () {
$("input").attr({
"value": ""
});
});
$("input").blur(function () {
$("input").attr({
"value": x
});
});
});
https://jsfiddle.net/thepeted/p74kfdt8/6/
If I look in developer tools, I can see the input value is changing dynamically in the DOM, but in the case that the user has typed something in to the form, the display no longer updates.
I'd love to understand why this is happening (ie, why it works in one case and not the other). Also, if there is a better way of approaching the problem.
As pointed out by Stijn, best practice would be to use the placeholder attibute.
However if you do want to use a function for it. I would check on the focus if the value is the default value or not. If so, empty the input, if not, don't do anything.
On blur, you also only want to place the default value back if the value is empty... so check for that aswell.
var x = "Default";
$(function() {
$('input[type=text]').val(x);
$('input[type=text]').on('focus', function() {
var elem = $(this);
if (elem.val() == x)
elem.val('');
}).on("blur", function() {
var elem = $(this);
if (elem.val() == '')
elem.val(x);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" />
Your edited jsfiddle.
updated code:
$("input").blur(function () {
$("input").val(x);
});
Personnaly, I'd use the placeholder attribute as everyone pointed out. If you too are facing the need to support older browsers and some others that do not support the placeholder attribute, use this snippet I've made:
$('input[placeholder]').each(function(){
var $this = $(this);
$this.val($this.attr('placeholder')).css('color','888888');
$this.focus(function(){
if($(this).val() == $(this).attr('placeholder'))
$(this).val('').css('color','');
});
$this.blur(function(){
if($(this).val() == '')
$(this).val($(this).attr('placeholder')).css('color','888888');
});
});
This script will find all inputs with a placeholder attribute, give it's value to the input, and add the correct events. I've left the css calls just to show you where to put the codes to mimic the greyed text like modern browsers do.
Try this code
var x = "Default";
$(function () {
$("input").val(x);
$("input").focus(function () {
$("input").val("");
});
$("input").blur(function () {
$("input").val(x);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="text"/>

How can I fix my JS and jQuery to properly validate input?

I am completely brand new to JS and jQuery. I have written a basic html form to calculate values and am wanting to validate each input and test to see if it contains a non-zero value but I can't figure it out. I have spent much time searching before posting this. Remember I am completely new so take it easy on me, please. Here is my script to test the inputs.
$('#ppm_Pt').on('change', function () {
var input = $(this);
var is_num = input.val();
if (is_num)
{
$('#Calculate').prop("disabled", false)
}
else
{
$('#Calculate').prop("disabled", true)
}
});
I can get this to work to check if there is any input for ppm_Pt, but instead I am wanting to check all inputs of type number in my html form and instead of just checking for any value I want to test against nulls and 0 values. I know there is a way. I have tried using the each() method but was unsuccessful. Please help. Thanks.
You are doing an ID selection on an element if this is your form you would probably do something like:
$('#ppm_Pt').on('change', 'input', function () {
var input = $(this);
var is_num = input.val();
if (is_num !== '')
{
$('#Calculate').prop("disabled", true);
}
else
{
$('#Calculate').prop("disabled", false);
}
});

Jquery - How to copy an input that has a value on load

I have a website url field that has the value set for returning visitors who have previously filled out the form. If they change the value, then ('keyup blur paste', function() will copy it to a div. If they do not change the value, the ('keyup blur paste', function() does not copy the value to the div
I would like to figure out how to add to this script a function that would also copy the value to the div if they do not change it, because blur only works if they click in the input before they submit the form.
Here is my current script:
$(function () {
$('#Website').on('keyup blur paste', function() {
var self = this;
setTimeout(function() {
var str = $(self).val();
$("#viewer").text(str.replace(/^http\:\/\//, ''));
}, 0)
})
});
If I get you correctly, you want to populate the div on load as well as on keyup/blur/paste? Something like this?
$(function () {
$('#Website').on('keyup blur paste', function() {
var self = this;
setTimeout(function() {
var str = $(self).val();
$("#viewer").text(str.replace(/^http\:\/\//, ''));
}, 0)
});
// just add the line below
$("#viewer").text($('#Website').val().replace(/^http\:\/\//, ''));
});
I've updated the fiddle you created to demonstrate this working: http://jsfiddle.net/8kn4V/2/
on your page load...
$('#mydiv').html('whatever the value of the cookie');
is that what you need? as they mentioned in the comments above, your question is a little confusing.
use val() for input , select and textareas, and use text() for general elements like divs.
First solution
It seems now you are using a timeout of 0. That is not necessary at all, I think. So please check out this Fiddle:
$('#website').on("keyup blur paste", function () {
var s = $(this).text();
$("#viewer").text(s.replace(/^http\:\/\//, ''));
});
Edited solution
Now it seems you also want code that update #viewer from #website even when not triggered.
Here is a second fiddle — I hope you'll give credit if this solves the problem as it stands currently.
Relevant code:
function viewerupdate(me){
var s = me.text();
$("#viewer").text(s.replace(/^http\:\/\//, ''));
}
$('#website').on("keyup blur paste", function () { viewerupdate($(this)) });
var current_viewer = $('#viewer').text();
$('#submit').click(function(){ // assumes in the case that no change was made, that the submission is done through #submit
if($('#viewer').text() == current_viewer )
viewerupdate($('#website'));
});

How can I update a input using a div click event

I've got the following code in my web page, where I need to click on the input field and add values using the number pad provided! I use a script to clear the default values from the input when the focus comes to it, but I'm unable to add the values by clicking on the number pad since when I click on an element the focus comes from the input to the clicked number element. How can I resolve this issue. I tried the following code, but it doesn't show the number in the input.
var lastFocus;
$("#test").click(function(e) {
// do whatever you want here
e.preventDefault();
e.stopPropagation();
$("#results").append(e.html());
if (lastFocus) {
$("#results").append("setting focus back<br>");
setTimeout(function() {lastFocus.focus()}, 1);
}
return(false);
});
$("textarea").blur(function() {
lastFocus = this;
$("#results").append("textarea lost focus<br>");
});
Thank you.
The first thing I notice is your selector for the number buttons is wrong
$('num-button').click(function(e){
Your buttons have a class of num-button so you need a dot before the class name in the selector:
$('.num-button').click(function(e){
Secondly, your fiddle was never setting lastFocus so be sure to add this:
$('input').focus(function() {
lastFocus = this;
...
Thirdly, you add/remove the watermark when entering the field, but ot when trying to add numbers to it (that would result in "Watermark-text123" if you clicked 1, then 2 then 3).
So, encalpsulate your functionality in a function:
function addOrRemoveWatermark(elem)
{
if($(elem).val() == $(elem).data('default_val') || !$(elem).data('default_val')) {
$(elem).data('default_val', $(elem).val());
$(elem).val('');
}
}
And call that both when entering the cell, and when clicking the numbers:
$('input').focus(function() {
lastFocus = this;
addOrRemoveWatermark(this);
});
and:
$('.num-button').click(function(e){
e.preventDefault();
e.stopPropagation();
addOrRemoveWatermark(lastFocus);
$(lastFocus).val($(lastFocus).val() + $(this).children('span').html());
});
You'll see another change above - you dont want to use append when appends an element, you want to just concatenate the string with the value of the button clicked.
Here's a working branch of your code: http://jsfiddle.net/Zrhze/
This should work:
var default_val = '';
$('input').focus(function() {
lastFocus = $(this);
if($(this).val() == $(this).data('default_val') || !$(this).data('default_val')) {
$(this).data('default_val', $(this).val());
$(this).val('');
}
});
$('input').blur(function() {
if ($(this).val() == '') $(this).val($(this).data('default_val'));
});
var lastFocus;
$('.num-button').click(function(e){
e.preventDefault();
e.stopPropagation();
var text = $(e.target).text();
if (!isNaN(parseInt(text))) {
lastFocus.val(lastFocus.val() + text);
}
});
Live demo
Add the following function:
$('.num-button').live( 'click', 'span', function() {
$currObj.focus();
$currObj.val( $currObj.val() + $(this).text().trim() );
});
Also, add the following variable to global scope:
$currObj = '';
Here is the working link: http://jsfiddle.net/pN3eT/7/
EDIT
Based on comment, you wouldn't be needing the var lastFocus and subsequent code.
The updated fiddle lies here http://jsfiddle.net/pN3eT/28/

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