Restore previous state JavaScript - 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.

Related

Comparison bewteen types in JavaScript

I found this code (on HTML5), and there is nothing wrong with it, it work just fine, but i dont get the whole process it make(the code create a virtual keyboard that writes on a textfield the letters you click)
the part i dont get it:
var i,c;
function init(){
i=document.getElementById('keyboard').getElementsByTagName('input');
for(c=0;c<i.length;c++) {
if(i[c].type==='button') {
i[c].addEventListener('onclick',makeClickHandler(c));
}
}
My mains doubt are the i[c]
Thanks in advance
var i,c; // global var declaration usually not clever
function init(){ // he creates a js function
var keyboardelement=document.getElementById('keyboard');
var inputfield=keyboardelement.getElementsByTagName('input');
for( var c=0;c<inputfield.length;c++) {
if(inputfield[c].type==='button') { // he runs over the dom tree
// under keyboard to find his buttons...
// now he adds on each of the buttons a OWN click handler which
//calls the
// routine "makeClickHandler" -wrong wording should be known as
// ClickHandler or maybee not s below
inputfield[c].addEventListener('onclick',makeClickHandler(c));
}
}
that is what he made and what i call not that clever cause now he has to implement or make for each button own routine to handle this. Maybee that is why he chose the wording makeclickhanler cause h creates them dynamically.
This here do it all including the evnet handler a "nice" display and a bit action. It will display the text you click together.
<html><body>
<form name="keyboard">
//could also be dynamically created but...
<div id="out"><div>
<input type="button" value="a" class="kbdbutton">
<input type="button" value="b" class="kbdbutton">
<input type="button" value="c" class="kbdbutton">
<input type="button" value="d" class="kbdbutton">
</form>
usually i would add also a ID attribute but
<script>
// get all buttons in one call
var kbd_btn=documentGetElementsByClassName("kbdbutton")
for (var i=0; I< kbd_btn.length;i++){
kbd_btn[i].id = kbd_btn[i].value;
}
// NOW every key has its own *corresponding* id free of charge
// which also makes the button interesting for a global event handler
// act like a man and use ONE handler
document.addEventListener("click", function(event) {}
var id=event.target.id;
if (id){ // not all click events have a id
console.log(id);
display=document.getElementById("out")
switch(id) {
case "a":
alert("a clicked")
case default:
display.innerHTML=display.innerHTML+id;
}
}
)
</script>
</body></html>
if i would a just few lines more and use the evil eval function i would have a nice complete pocket calculator...

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.

innerHTML.replace not working in firefox but in IE

I want to rename the onclick method of a button. First my Button has following code:
<input id="my_button" class="update field-button" type="button" onclick="add( this )" value="ADD Something" title="ADD Item" name="my_button"></input>
Then I want something like this:
<input id="my_button" class="update field-button" type="button" onclick="remove( this )" value="ADD Something" title="ADD Item" name="my_button"></input>
I do the rename with this statement:
parentNode.innerHTML = parentNode.innerHTML.replace( /(onclick="?)[A-Za-z0-9\-]+(\([^)]*\)"?)/, "$1remove$2" );
parentNode is a var:
var parentNode = removeButton.parentNode;
In the Internet Explorer it works, but not in firefox
This is not the way to achieve your desired functionality, click handlers can be bound entirely with javascript.
Try the following:
document.getElementById('my_button').onclick = function() {
var toggle = false;
return function (e) {
toggle = !toggle;
toggle ? add(this) : remove(this);
};
}();
Though I would recommend the rich's answer and put that logic into the clickhandler, it might be interesting what your problem is.
Firefox does your replacement correctly and calls the buttons native remove-method as the click handler has the buttons's scope. So
onclick="remove( this )"
is the same as
onclick="document.getElementById('my_button').remove();"
and the button gets removed from the dom.

how to create an editable input on click event

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");
});

Add Event Listeners via an Array and FOR Loop

Been having a bit of a problem for the last couple of days. I'm trying to streamline my code as much as possible and I have now got to the stage where I am trying to add Event Listeners via JavaScript so my HTML looks tidier.
-HTML Segment-
<input type="button" id="googleSearchButton" />
<input type="button" id="youtubeSearchButton" />
<input type="button" id="wikiSearchButton" />
<input type="button" id="facebookSearchButton" />
<input type="button" id="twitterSearchButton" />
<input type="button" id="tumblrSearchButton" />
<input type="button" id="dropboxSearchButton" />
JavaScript Segment
var contIDArray = ["google", "youtube", "wiki", "facebook", "twitter", "tumblr", "dropbox"];
window.load = initAll();
function initAll(){
applyProperties();
}
function applyProperties(){
for (var i = 0; i < contIDArray.length; i++){
addEventListeners(contIDArray[i] + "SearchButton");
}
}
function addEventListeners(id){
document.getElementById(id).addEventListener("click", testAlert(id), false);
}
function testAlert(id){
alert(id + " clicked")
}
The Theory
As, I hope, you can see, the FOR loop will loop until it runs out of values in the container Array. Each time it will output the place in the Array followed by "SearchButton". For example, the first time it loops it will output "googleSearchButton", the second time "youtubeSearchButton" and so forth.
Now, I know that the FOR loop works for applying properties because I use it to apply Button values and text box placeholder text in other segments of my project.
I have made it add a simple test function ("testAlert()") and set it to pass the id of the element that called it. I have set it up so once the event listeners have been added I can simply click on each button and it will alert its id and tell me that it has been clicked.
The Problem
Now, theoretically, I thought this would work. But it seems that the FOR loops fires the "addEventListeners" function, which, in turn, adds the event listener to fire "testAlert" on click. But it just fires the "testAlert" function as soon as it adds the event listener and does not fire when you click.
I apologise if this seems a bit much to take in, I always overdo the length of my explanation. Hopefully you'll be able to see what I'm trying to accomplish from my code, rather than my explanation.
Help would be much appreciated. :)
You're close here, but there are a few things wrong.
First, you can't just do id.addEventListener. You need to do document.getElementById(id).addEventListener. id is just a string, you need a DOMElement.
Second, when you do testAlert(id), you're running the function, then assigning its return value (undefined) as the event listener. You need to pass a function. Like so:
id.addEventListener("click", function(){
testAlert(this.id); // this is the DOMElement you clicked on
}, false);
Though I suggest adding a class to all your buttons, and then adding the event like that.
<input type="button" id="googleSearchButton" class="searchButton" />
<input type="button" id="youtubeSearchButton" class="searchButton" />
<input type="button" id="wikiSearchButton" class="searchButton" />
<input type="button" id="facebookSearchButton" class="searchButton" />
<input type="button" id="twitterSearchButton" class="searchButton" />
<input type="button" id="tumblrSearchButton" class="searchButton" />
<input type="button" id="dropboxSearchButton" class="searchButton" />
And then:
var buttons = document.getElementsByClassName('searchButton');
for(b in buttons){
if(buttons.hasOwnProperty(b)){
buttons[b].addEventListener("click", function(){
testAlert(this.id); // this is the DOMElement you clicked on
}, false);
}
}
NOTE: addEventListener and getElementsByClassName may not be available in all browsers (by that I mean they might not work in IE). This is why a lot of websites use a JavaScript library, like jQuery. jQuery handles all the cross-browser stuff for you. If you want to use jQuery, you could do this:
$('.searchButton').click(function(){
testAlert(this.id);
});
NOTE 2: In JavaScript, functions are variables, and can be passed as parameters.
document.getElementById(id).addEventListener('click', testAlert, false);
Notice how there are no () after testAlert, we are passing the function itself, when you do testAlert() you're passing its return value. If you do it this way, testAlert will need to be modified a bit:
function testAlert(){
alert(this.id + " clicked")
}
Change:
function addEventListeners(id){
id.addEventListener("click", testAlert(id), false);
}
for:
function addEventListeners(id){
document.getElementById(id).addEventListener("click", testAlert(id), false);
}
Otherwise you're applying addEventListener on a string.
In any case, replace addEventListener with an assignment to the event, like onClick.
id looks like a string to me. So instead do something like this:
function addEventListeners(id){
var obj = document.getElementById(id);
obj.addEventListener("click", testAlert(id), false);
}
Also, here is the working code:
http://jsfiddle.net/ZRZY9/2/
obj.addEventListener("click", function() { testAlert(id); }, true);
As Rocket mentions above "you're calling it and setting the event to the return value undefined".
The bad news is addEventListener() is currently not supported in Internet Explorer 7.
I ran through your code. The initial problem that I came across was that you were trying to find the elements in the document before they were created. window.onLoad fires before the page is complete. I tested this using the body tag's onload attribute and it works that way.
So, it's a combination of the aforementioned issue of your trying to find the element by using the "id" string and the function firing before the page was completely loaded.
Anyway, glad you got it working!
This is the javascript I had at the end:
<script>
var contIDArray = ["google", "youtube", "wiki", "facebook", "twitter", "tumblr", "dropbox"];
function initAll(){
applyProperties();
}
function applyProperties(){
for (var i = 0; i < contIDArray.length; i++){
var newString = contIDArray[i] + "SearchButton"
addEventListeners(newString);
}
}
function addEventListeners(id){
document.getElementById(id).addEventListener("click", testAlert, false);
}
function testAlert(){
alert(this.id + " clicked")
}
</script>

Categories

Resources