innerHTML.replace not working in firefox but in IE - javascript

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.

Related

jquery if $this has not ClassName do action

I see many answers but none of them seem to be working.
All my buttons have the "Trev" class. I want to check if the clicked class, also contains the "Namdons" class, and if so, do some code. However if not, do some code.
Some code that half works is:
$(".Trev").click
(
function(e)
{
if($(this).hasClass("Namdons"))
{
console.log("Namdons");
}
else
{
console.log("Asdf");
}
e.preventDefault();
}
);
However the "else" condition is not executing.
I've tried:
$(".Trev").click
(
function(e)
{
if($(this).hasClass("Namdons"))
{
console.log("Namdons");
}
if(!$(this).hasClass("Namdons")) //added apostrophe
{
console.log("Asdf");
}
e.preventDefault();
}
);
as per these pages:
How to check if an element does NOT have a specific class?
How do I use hasClass to detect if a class is NOT the class I want?
The "not" command does not apply as I'm only wanting to procure a single element and not select a bunch of them. Explained more on those pages.
HTML:
<div class="Trev Width50" onclick="Button('buttonname')"></div>
and
<button onclick="Namdons()" class="Namdons Trev TextAlignCenter">ButtonTitle</button>
also tried changing the Width50 div to a button:
<button class="Trev Width50" onclick="Button('buttonname')"></button>
There also doesn't seem to be an "elseif" in javascript is that correct?
Thanks.
Since you tag javascript i put example in vanilla js. I leave it for you to translate it to jQuery. I also put notes inside:
const trev = document.querySelectorAll('button.trev'); // get button with .trev style
for (var i=0; i < trev.length; i++) { // itterate them
trev[i].addEventListener('click', function() { // add click event
if (this.classList.contains('Namdons')) {alert('This is .Namdons');} // if it has .Namdons alert it
else {alert('This is NOT .Namdons');} // it not alert that
});
}
<button class="Trev TextAlignCenter">ButtonTitle</button>
<button class="Namdons Trev TextAlignCenter">ButtonTitle</button>
<button class="Trev TextAlignCenter">ButtonTitle</button>
<button class="Namdons Trev TextAlignCenter">ButtonTitle</button>
<button class="Trev TextAlignCenter">ButtonTitle</button>
Read more about classList on MDN

AngularJS - how to add a conditional to bootstrap modal target?

So I have a modal that appears when a button is clicked - however I want the modal ONLY to appear when certain conditions are met (which are defined in my controller).
HTML CODE:
<button class="btn btn-primary-outline" type="button" data-uk-modal="{target:'#previewModal'
}" ng-click="previewOfferBefore()">Preview</button>
The above works (modal with the id 'previewModal' pops out on click). So my approach is to add the conditional in the controller and define the value of the "target" in there using Angular data binding.
ie:
<button class="btn btn-primary-outline" type="button" data-uk-modal="{target: {{ previewLink
}}}" ng-click="previewOfferBefore()">Preview </button>
Then the controller would have:
$scope.previewOfferBefore = function() {
if (/*some conditions here*/) {
$scope.previewLink = '#'; /*don't let a modal pop up */
}
else {
$scope.previewLink = '#previewModal' /*let the modal pop up */
}
}
One approach I tried as well is using ng-href instead of bootstrap's data-uk-modal and that also didn't work. I know my controller function is fine since when I place {{ previewLink }} inside a p html tag it prints out the right id I want. So the issue is how I'm binding the data inside the button class.
If you're okay with the button being disabled or greyed out, then one solution would be to use ng-disabled. Your controller would look something like this;
$scope.previewOfferBefore = function() {
if (/*some conditions here*/) {
$scope.canClick= true;
}
else {
$scope.canClick= false;
}
}
and your html would then become;
<button ng-disabled="canClick" class="btn btn-primary-outline" type="button" data-uk-modal="{target:'#previewModal'
}" ng-click="previewOfferBefore()">Preview</button>
Then your button will become unclickable if it hits the false case on the if statement.
You could simply have two buttons and use ng-if or ng-show to just show one of them depending on your expression. You can simply use angular inside.
<button ng-show="previewLink !== '#'" type="button" data-uk-modal="{target: '#previewLink'}" ng-click="previewOfferBefore()">
Preview
</button>
<button ng-show=""previewLink === '#'"" type="button" data-uk-modal="{target: '#'" ng-click="previewOfferBefore()">
Preview
</button>
Alternative:
I would try ng-attr to get your angular expression into the attribute like
ng-attr-uk-modal="{{'target:' + value}}"
and bind value to the target you need. I haven't tried this, might need some adjustments.

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.

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>

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