how to create an editable input on click event - javascript

So I have a page that I want to use to allow users to see what in currently in the database and edit them by clicking on the box.
I have a pretty hacky method that works for text imputs but for a drop down box or date selector completely falls apart.
my HTML
<td name='joineddate133'>
<input type='date'
id='joind133'
name='joinda133
value='2012-03-15'
class='toedit'
readonly='readonly'
onclick='enablejoindate(this.id)'
size='20' />
< /td>
The current Javascript
<script>
function enablejoindate(joindatid){
$(function(){
$("input:text[id="+ joindatid +"]").removeAttr("class");
$("input:text[id="+ joindatid +"]").removeAttr("readonly");
$("input:text[id="+ joindatid +"]").addClass("inlineditjoind");
});
}
</script>
The inlinedit class is used as a marker so the jquery can find it easily to post and the toedit class currently just hides the attributes.
Obviously this solution isn't great and I would like to try and work out a better way to maybe create an input on the double click function etc.

You could have all fields as readonly and hidden until focussed:
$("table").on("focus", "input, select", function(){
$(this)
.prop("readonly", false)
.removeClass("toedit");
});
$("table").on("blur", "input, select", function(){
$(this)
.prop("readonly", true)
.addClass("toedit")
.siblings("span").text($(this).val());
});
$("table").on("click", "td", function(){
$(this).children().focus();
});
DEMO (updated again)

You should take a look at X-editable.
<a
href="#"
id="joinda133"
data-type="date"
data-viewformat="dd.mm.yyyy"
data-pk="1"
data-placement="right"
data-original-title="Date you've joined"
>25.02.2013</a>

Since you are using jQuery, use a jQuery event. It's best to set readonly to false with the prop() method:
$('input[type=date]').on('click', function(){
$(this)
.removeClass("toedit")
.prop("readonly", false)
.addClass("inlineditjoind");
});
JSFiddle

Have a look to the DEMO JSFiddle
JS/JQUERY -
$("#joind133").on('click',function(){
$(this).removeProp("readonly")
.removeClass("toedit")
.addClass("inlineditjoind");
});
HTML -
<td name='joineddate133'>
<input type='date' id='joind133' name='joinda133' value='2012-03-15' class='toedit' readonly='readonly' size='20'/>
</td>
UPDATE ON REQUEST FOR MAKING IT GENERIC BINDING
$("input[type='date']").on('click',function(){
$(this).removeProp("readonly")
.removeClass("toedit")
.addClass("inlineditjoind");
});

Related

jQuery display property not changing but other properties are

I'm trying to make a text editable on clicking it. Below is the code I'm trying. When the title is clicked it shows an input box and button to save it.
<div class="block">
<div class="title">Title</div>
<div class="title-edit">
<input type="text" name="title" value="Title">
<button>Save</button>
</div>
</div>
I have changed other properties like color or changing the text of the elements and its working, but it is not applying the display property or .show()/.hide() function on the title or edit elements.
Below is my jQuery
$(function(){
$('.block').on('click', editTitle);
$('.title-edit button').on('click', saveTitle);
});
function saveTitle(){
var parent = $(this).closest('.block');
var title = $('.title', parent);
var edit = $('.title-edit', parent);
$(title).show();
$(edit).hide();
}
function editTitle(){
$('.title-edit', this).show();
$('.title', this).hide();
}
Here's the jsfiddle
https://jsfiddle.net/ywezpag7/
I've added
$(title).html('abcd');
to the end to show that other properties/functions are working, but just not the display.
For checking the html change on title element you will have to check the source through developer tools cause the title element is hidden.
Where am I going wrong?
Your problem is in the function saveTitle. The first line must stop the event propagation otherwise after this function the editTitle function is called.
The snippet:
$(function(){
$('.block').on('click', editTitle);
$('.title-edit button').on('click', saveTitle);
});
function saveTitle(e){
// this line
e.stopPropagation();
var parent = $(this).closest('.block');
var title = $('.title', parent);
var edit = $('.title-edit', parent);
title.show();
edit.hide();
title.text($('.title-edit input').val());
}
function editTitle(e){
$('.title-edit', this).show();
$('.title', this).hide();
}
.title-edit{
display:none
}
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<div class="block">
<div class="title">Title</div>
<div class="title-edit">
<input type="text" name="title" value="Title">
<button>Save</button>
</div>
</div>
The issue as mentioned already is that your click events are fighting. In your code, the title-edit class is within the block, so when you click on the save button it triggers events for both clicks.
The easiest and, imho, cleanest way to resolve this is to switch your click event to be called on .title, and .title-edit button. You can also simplify the code beyond what you've got there.
$(function(){
$('.title').click(editTitle);
$('.title-edit button').click(saveTitle);
});
function saveTitle(){
$('.title').show();
$('.title-edit').hide();
$(title).html('abcd');
}
function editTitle(){
$('.title-edit').show();
$('.title').hide();
}
https://jsfiddle.net/ywezpag7/7/
I tried debug your code, and I had seen, that then you click to "Save" button, handled both functions, saveTitle() and editTitle(), and in that order. Therefore, the elements initially hidden, and then shown.

jquery button value to title

I have a lot buttons all over a site with a value (the text of the button) and each has, for example a bootstrap class of '.btn-default':
<input type="button" value="Clear" class="form-control input-sm btn-default" onclick="doingSomethingElseEtc();">
How might I use jQuery to get the value of the button and bind it to a title attribute to each button, so if you moused over the button, you'd get the default browser tooltip containing the string from the button value, etc..?
For example, just to get the gist of what I'm asking:
$('.btn-default').attr('title', $(".btn-default").val());
I'm trying to touch the code as little as possible, etc..
Thank you!
You can use each to iterate each button and set the titles.
$('.btn-default').each(function(i,obj){
$(obj).attr('title', $(obj).val());
});
No need for any arguments, or variables, or other whatzit. :-)
$('.btn-default').each(function () {
$(this).attr('title', $(this).val());
});
Demo
Your idea will work too, if you're adding a function to the attr like this:
$('.btn-default').attr('title', function() {
//console.log($(this).val(), $(this).text());
return $(this).val() || $(this).text();
});
This will add to each button with class btn-default the title attribute.
I think it's also good to get the text because your button could be defined with input value=".." or with <button>text</button>
Please have a look at the demo below and in this jsFiddle.
$('.btn-default').attr('title', function() {
//console.log($(this).val(), $(this).text());
return $(this).val() || $(this).text();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" value="Clear" class="form-control input-sm btn-default" onclick="doingSomethingElseEtc();">
<button class="btn-default">test1</button>
<button class="btn-default">test2</button>
When you read the value of a collection of elements, jQuery only returns the value of the first one in the set. So you need to iterate over all of them and set the title on each one.
$('.btn-default').each( function () {
var elem = $(this);
elem.attr('title', elem.val());
});
Downside to this is if there is a lot of elements, it will be slow. Also you need to do this on document ready.

Change label color on active inputbox

Do someone know why this not work?
I want to change the color of the label from a input box when the box is active.
The JavaScript:
$("input").focus(function() {
var inputID = document.activeElement.id;
document.getAnonymousElementByAttribute('label','for', inputID).setAttribute('class', 'active');
});
The HTML:
<label for="username">Username</label>
<input name="username" id="username" type="text"><br>
<label for="passwort">Passwort</label>
<input name="passwort" id="passwort" type="password"><br>
<input type="submit" class="button" value="login">
The CSS:
.active{
color: #FFA500 !important;
}
I hope someone can help me :)
With your current HTML:
$('input').focus(function(){
$(this).prev().addClass('active');
}).blur(function(){
$(this).prev().removeClass('active');
});
JS Fiddle demo.
Or, with on() (assuming you're using jQuery 1.7, or above):
$('input').on('focus blur', function(e){
var prev = $(this).prev();
prev[e.type == 'focus' ? 'addClass' : 'removeClass']('active');
});
JS Fiddle demo.
More abstracted (so the HTML stucture doesn't matter), selecting by the for attribute:
$('input').on('focus blur', function(e){
var label = $('label[for="' + this.id + '"]');
label[e.type == 'focus' ? 'addClass' : 'removeClass']('active');
});
JS Fiddle demo.
References:
addClass().
Attribute-equals ([attribute="value"]) selector.
blur().
focus().
on().
prev().
removeClass().
$('input').on('click', function(){
$(label).toggleClass('active');
});
Your overcomplicating things, keep it simple, sometimes a developers most useful tool is the backspace key.
Try input:focus instead of .active in your CSS code. Omit !important as well.
input:focus{
color: #FFA500;
}
You mix jQuery functions with non-jQuery. Try to use only jQuery functions to handle your task. In my example below I changed .focus() to .on('focus',callback) which is same but just more understandable. In jQuery you should get target of your event and wrap it by $(). You also can use this but I try not to use it by several reasons. Then you can apply any of many jQuery methods:
$("input").on('focus', function(ev) {
var t = $(ev.target);
t.addClass('active');
});
See here for a very basic example: http://jsfiddle.net/zn5fB/
And here, for an event-triggered example: http://jsfiddle.net/zn5fB/1/
Setting a style with JavaScript usually follows the following format:
document.getElementById("abc").style.[css property name in camel case] = "[value]";
You will find that it is very common to use a library such as jQuery to make this (and many other things) a little easier. With jQuery, you can write code like:
// find all elements with the tag name "bar" that are direct
// descendants of an element with the class name "foo"
$(".foo > BAR").css("color", "red");

JS Events not attaching to elements created after load

Problem: Creating an Element on a button click then attaching a click event to the new element.
I've had this issue several times and I always seem to find a work around but never get to the root of the issue. Take a look a the code:
HTML:
<select>
<option>567</option>
<option>789</option>
</select>
<input id="Add" value="Add" type="button"> <input id="remove" value="Remove" type="button">
<div id="container">
<span class="item">123</span>
<br/>
<span class="item">456</span>
<br/>
</div>
JavaScript
$(".item").click(function () {
if ($("#container span").hasClass("selected")) {
$(".selected").removeClass("selected");
}
$(this).addClass("selected");
});
$("add").click(function() {
//Finds Selected option from the Select
var newSpan = document.createElement("SPAN");
newSpan.innerHTML = choice;//Value from Option
newSpan.className = "item";
var divList = $("#container");
divList.appendChild(newSpan);//I've tried using Jquery's Add method with no success
//Deletes the selected option from the select
})
Here are some methods I've already tried:
Standard jQuery click on elements with class "item"
Including using the `live()` and `on()` methods
Setting inline `onclick` event after element creation
jQuery change event on the `#Container` that uses Bind method to bind click event handler
Caveat: I can not create another select list because we are using MVC and have had issues retrieving multiple values from a list box. So there are hidden elements that are generated that MVC is actually tied to.
Use $.on instead of your standard $.click in this case:
$("#container").on("click", ".item", function(){
if ( $("#container span").hasClass("selected") ) {
$(".selected").removeClass("selected");
}
$(this).addClass("selected");
});
It looks to me like you want to move the .selected class around between .item elements. If this is the case, I would suggest doing this instead:
$("#container").on("click", ".item", function(){
$(this)
.addClass("selected")
.siblings()
.removeClass("selected");
});
Also note your $("add") should be $("#add") if you wish to bind to the element with the "add" ID. This section could also be re-written:
$("#add").click(function() {
$("<span>", { html: $("select").val() })
.addClass("item")
.appendTo("#container");
});

Restore previous state JavaScript

Say I want to modify a text by clicking on it, which turns to a input text field along with two buttons, save and cancel like below (the click event has been omitted and I am using the replaceWIth() from jQuery).
Before transformation:
<span>text<input type="button" value="delete"</span>
After transformation:
<input type="text"><input type="button" value="save"><input type="button" value="cancel">
what I want to do is if the I click on the cancel button, nothing happens and the "after transformation" part can be restore to the original part like how it looked before
<span>text<input type="button" value="delete"</span>
any way to do that? I thought I should somehow "save" before transforming like "snap" a picture or something. Any idea?
Waited till the India vs WI match was done before posting :)
This is what you want : http://jsfiddle.net/G8Kaj/4/
It uses live so that it'll work multiple times. It also works if there are multiple rows of because it simple picks up the parent and doesn't rely on there being only 1 row.
<span class='text'>text<input type="button" class='deleteButton' value="delete"></span>
$('span.text').live('click', function(){
var $this = $(this);
$this.data('oldText', $this.html());
var newText = '<input class="theText" type="text"><input class="saveButton" type="button" value="save"><input class="cancelButton" type ="button" value="cancel">';
$this.html(newText);
});
$('.cancelButton').live('click', function(e){
var $this = $(this);
var parent = $this.parent('span');
parent.html(parent.data('oldText'));
e.stopPropogation();
});
$('.saveButton').live('click', function(){
//do something on save
e.stopPropogation();
});
$('.theText, .deleteButton, cancelButton').live('click', function(){
e.stopPropogation();
});
Uses the jqery data object to store the old state on a per span basis.
Try this:
<span id="before">text<input type="button" value="delete" id="delete"/></span>
<span id="after">
<input type="text">
<input type="button" value="save" id="save"/>
<input type="button" value="cancel" id="cancel"/>
</span>
<script>
$('document').ready(function() {
// Initially hide
$('#after').css('display','none');
$('#delete').click(function() { showAfter(); });
$('#save').click(function() { hideAfter(); });
$('#cancel').click(function() { hideAfter(); });
function showAfter() {
$('#after').css('display','block');
$('#before').css('display','none');
}
function hideAfter() {
doSomething();
$('#after').css('display','none');
$('#before').css('display','block');
}
function doSomething() {
alert('I just did something!');
}
});
</script>
You are trying to implement inline-editing. This is a task better done with a JavaScript library. Most JavaScript library has modules (or plugins) that can do inline-editing -- text to textboxes, numbers to spinner boxes etc. I would not recommend recreating something that teams of library programmers have already spent hours debugging on all conceivable browser platforms.
For example, the Dojo Toolkit has dijit.inlineEditBox that needs very little coding and does most of what you want. It uses a hidden textbox to hold the previous value.
jQuery has the Edit-in-Place plugin.

Categories

Resources