Jquery toggle text button with bootstrap icon inside - javascript

Im working with Boostrap 3 and Jquery and Im trying toggle the text inside a button with an boostrap icon span, but doesnt know how to do. This is what I tried: The html code:
<button type='button' class='btn btn-success btn-md'>
<span class='glyphicon glyphicon-edit'></span> Edit</button>
Jquery code:
$(this).text(function(i, text){
return text === "<span class='glyphicon glyphicon-edit'></span> Close" ? "<span class='glyphicon glyphicon-edit'></span> Edit" : "<span class='glyphicon glyphicon-edit'></span> Close"
})
So...How could be this works?
1) An example with the toggle text button but keeping the same icon.
2) Another example with the toggle text button but toggle the icon class
Thanks.

Instead of === you can use indexOf because:
$(this).text() === "↵ Edit"
Like you can see there is an extra char (newline) and you cannot rely on this.
The snippet with the jQuery.html is:
$('button').on('click', function(e) {
$(this).html(function(i, text){
return (text.indexOf("Close") != -1) ? "<span class='glyphicon glyphicon-edit'></span> Edit" : "<span class='glyphicon glyphicon-edit'></span> Close"
})
})
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<button type='button' class='btn btn-success btn-md'>
<span class='glyphicon glyphicon-edit'></span> Edit</button>
Or, in JS you may write:
this.childNodes[2].textContent = (this.childNodes[2].textContent.indexOf("Close") != -1) ?
' Edit' : ' Close';
The snippet:
$('button').on('click', function(e) {
this.childNodes[2].textContent = (this.childNodes[2].textContent.indexOf("Close") != -1) ? ' Edit' : ' Close';
})
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<button type='button' class='btn btn-success btn-md'>
<span class='glyphicon glyphicon-edit'></span> Edit</button>

How about this:
<button class="btn btn-primary toggle-text" data-toggle="collapse" href="#collapseExample">
<span class='glyphicon glyphicon-edit'></span><span>Edit</span><span class="hidden">Close</span>...
$('.hidden').removeClass('hidden').hide();
$('.toggle-text').click(function() {
$(this).find('span').each(function() { $(this).toggle(); });
});
http://jsfiddle.net/bcwhh8cp/

You should use html() instead of text()
$(this).html(function(i, text){
return text === "<span class='glyphicon glyphicon-edit'></span> Close" ? "<span class='glyphicon glyphicon-edit'></span> Edit" : "<span class='glyphicon glyphicon-edit'></span> Close"
})

Related

Button with Glyphicon is smaller than button with text

I have the current page (with glyphicons in buttons as download buttons).
As seen in the picture the final column with the glyphicons don't quite line up. I tried replacing the glyphicons with just a "test" in the button and they seem to line up perfectly.
This is the line of code that has to do with one of the buttons for that column.
document.getElementById('column_4').innerHTML += '<div class="col-md-auto"> <button type="button" id =' + array13[prop] + ' name = "Rec_Status" onclick="gotovendor(0)" value = ' + array13[prop] + ' class="list-group-item" onclick="myFunction7(this.value)"><span class="glyphicon glyphicon-tasks" aria-hidden="true"></span></button></div>';
How do I have the buttons with glyphicons in the first image align like the buttons in the second image? I tried using padding, but it doesn't look like a good solution.
Below is the the same code with padding.
document.getElementById('column_4').innerHTML += '<div class="col-md-auto"> <button type="button" id =' + array13[prop] + ' name = "Rec_Status" style = "padding: 0.625vw;" onclick="gotovendor(0)" value = ' + array13[prop] + ' class="list-group-item" onclick="myFunction7(this.value)"><span class="glyphicon glyphicon-tasks" aria-hidden="true"></span></button></div>';
Try to add some padding/font-size/line-height.
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-glyphicons.css" rel="stylesheet">
<button style="padding:5%;font-size:20px" type="button" class="btn btn-default"><span class="glyphicon glyphicon-tasks" aria-hidden="true"></span></button>
Try this
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<button class="btn btn-primary">Button</button>
<button class="btn btn-primary"><i class="fa fa-bars"></i></button>

jQuery each combined with replaceWith issue

I am trying to loop through each element with a class and then wrap it with a div, and then continue to the next one.
Currently using this...
$('.img-editable').each(function(i) {
if ($(this).prop("tagName") == "IMG") {
$(this).replaceWith('<span class="img-edit-container">'+this.outerHTML+'<button class="btn btn-default btn-sm img-edit popover-trigger"><i class="fa fa-file-image-o"></i></button></span>');
} else {
$(this).replaceWith('<span class="img-edit-container bg-img-edit-container">'+this.outerHTML+'<button class="btn btn-default bg-img-edit img-edit popover-trigger"><i class="fa fa-file-image-o"></i></button></span>');
}
});
It works in simple cases. But the challenge is when there is nested elements like this...
<div class="img-editable>
<div id="something else">
<div class="img-editable"></div>
</div>
</div>
Then it falls apart and the inner element doesn't get wrapped correctly.
My belief is the each() function is looping the outermost elements and when it matches the first one then it performs the replaceWith() and then continues. But by the time the loop gets to the next one (inner), the reference to second inner element that matches is no longer there (according to the browser).
I also tried this...
var setupImgWrapper = function(elem) {
if (elem.prop("tagName") == "IMG") {
elem.replaceWith('<span class="img-edit-container">'+this.outerHTML+'<button class="btn btn-default btn-sm img-edit popover-trigger"><i class="fa fa-file-image-o"></i></button></span>');
elem.children('.img-edtiable').each(function(i) {
setupImgWrapper($(this));
});
} else {
elem.replaceWith('<span class="img-edit-container bg-img-edit-container">'+this.outerHTML+'<button class="btn btn-default bg-img-edit img-edit popover-trigger"><i class="fa fa-file-image-o"></i></button></span>');
elem.children('.img-edtiable').each(function(i) {
setupImgWrapper($(this));
});
}
}
$('.img-editable').each(function(i) {
setupImgWrapper($(this));
});
This completely failed.
I would love to know how we can overcome this? Is there a way to maintain the DOM reference after replaceWith() is performed, or can we update it?
TL;DR After performing replaceWith in loop on selected elements, descendant element references seem to break and these elements aren't updated successfully.
Thanks!
Solution As Accepted Below
$('.img-editable').each(function(i) {
if ($(this).prop("tagName") == "IMG") {
$(this).wrap('<span class="img-edit-container"></span>');
$(this).after('<button class="btn btn-default btn-sm img-edit popover-trigger"><i class="fa fa-file-image-o"></i></button>');
} else {
$(this).wrap('<span class="img-edit-container bg-img-edit-container"></span>');
$(this).after('<button class="btn btn-default bg-img-edit img-edit popover-trigger"><i class="fa fa-file-image-o"></i></button>');
}
});
There is a .wrap() method provided by jQuery that does exactly what you need.
Here's a demo
$('body > div').each(function() {
$(this).wrap('<div class="wrapper" />');
});
.wrapper {
border: 1px solid tomato;
margin-bottom: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Normal Element</div>
<div>
<span>Simple inline element</span>
</div>
<div>
<div>
<h1>More Stuff</h1>
</div>
</div>
If .img-editable > ... > .img-editable breaks your code, you should prefer a better selector that fit your needs. I can assist you with that, just post a comment to this answer and we'll figure something out. :)
Try wrapall api along with each
$( ".img-editable" ).wrapAll( "<span class='img-edit-container'/>");
$(".img-edit-container .img-editable").each( function(){
if ( $( this ).prop("tagName") == "IMG" )
{
$(this).parent().append ( '<button class="btn btn-default btn-sm img-edit popover-trigger"><i class="fa fa-file-image-o"></i></button>' );
}
else
{
$(this).parent().append ( '<button class="btn btn-default bg-img-edit img-edit popover-trigger"><i class="fa fa-file-image-o"></i></button>' );
}
});
or even simpler
$( ".img-editable" ).wrapAll( "<span class='img-edit-container'/>");
$(".img-edit-container").append( '<button class="btn btn-default bg-img-edit img-edit popover-trigger"><i class="fa fa-file-image-o"></i></button>' );
$(".img-edit-container img.img-editable").siblings( "button" ).toggleClass( "btn-sm" ).toggleClass( "bg-img-edit" );

jQuery toggle button text and Icon

I am trying to toggle both the icon and the button text on a button and each function works independently, but they will not work when run consecutively. Seems that the function to toggle the button text is removing my icon altogether.
<button type="button" id="toggle-list-details">
<i class="fa fa-list fa-lg"></i>
List View
</button>
$("#toggle-list-details").click(function() {
$(this).text(function(i, text){
return text === " List View" ? " Details View" : " List View";
});
$(this).find('i').toggleClass('fa-list fa-th-list');
)};
When you do
$(this).text(function(i, text){
this reffers to <button type="button" id="toggle-list-details">, so it replaces all inner content with plain text.
To avoid this, you can do smth like this:
<button type="button" id="toggle-list-details">
<i class="fa fa-list fa-lg"></i>
<span class="text">List View</span>
</button>
$("#toggle-list-details").click(function() {
$(this).find('span').text(function(i, text){
return text === " List View" ? " Details View" : " List View";
});
$(this).find('i').toggleClass('fa-list fa-th-list');
)};

Bootstrap data-toggle="button" not working with <span>

I'm using the 'data-toggle'-option from Bootstrap for a button. In the button I have a with glypicons and sometext. However, when you click on the text it works, but when you click on the glyphicon it doesn't trigger the data-toggle.
Since the data-toggle does not work in JSFiddle I cannot post a link to it.
HTML:
<button type="button" id="showHide" class="btn btn-default" data-toggle="button"><span class="glyphicon glyphicon-eye-open"></span> show</button>
JavaScript:
document.getElementById("showHide").onclick = function () {
if ($("#showHide").text() == " show") {
document.getElementById("showHide").innerHTML = "<span class=\"glyphicon glyphicon-eye-close\"></span> hide";
document.getElementById("showHide").blur();
} else {
document.getElementById("showHide").innerHTML = "<span class=\"glyphicon glyphicon-eye-open\"></span> show";
document.getElementById("showHide").blur();
}
}
I've looked online but haven't found a solution or someone with the same problem.
It appears the span is being replaced before the toggle event is propogated. You can use the button method to activate the toggle rather than the data attribute.
<button type="button" id="showHide" class="btn btn-default"><span class="glyphicon glyphicon-eye-open"></span> show</button>
document.getElementById("showHide").onclick = function () {
if ($("#showHide").text() == " show") {
document.getElementById("showHide").innerHTML = "<span class=\"glyphicon glyphicon-eye-close\"></span> hide";
jQuery("#showHide").button('toggle');
document.getElementById("showHide").blur();
} else {
document.getElementById("showHide").innerHTML = "<span class=\"glyphicon glyphicon-eye-open\"></span> show";
jQuery("#showHide").button('toggle');
document.getElementById("showHide").blur();
}
}
View Fiddle

If an event is unbined , can't we restore it?

I'm making the twitter follow button , when you click on it it turns to following, when hover again it turns to unfollow , when click on unfollow , it becomes follow and here even if the mouse goes out nothing happens , my problem is something happens here .. (last step)
HTML:
<div class="col-xs-2 menu followBlock">
<button type="button" class="btn btn-primary btn-lg" data-follow="follow">
<span class="glyphicon glyphicon-plus"></span> Follow
</button>
</div>
JS:
$(".followBlock").on('click', "button[data-follow=follow]", function(e) {
$btn = $(this);
$btn.html("<span class='glyphicon glyphicon-ok'></span> Following").removeClass('btn-primary').addClass('btn-success');
$("button[data-follow=follow]").attr("data-follow", "unfollow");
$btn.hover(function(e) {
$(this).html("<span class='glyphicon glyphicon-minus'></span> Unfollow").removeClass('btn-success').addClass('btn-danger');
}, function(e) {
$(this).html("<span class='glyphicon glyphicon-ok'></span> Following").removeClass('btn-danger').addClass('btn-success');
})
});
$(".followBlock").on('click', "button[data-follow=unfollow]", function(e) {
$btn = $(this);
$btn.html("<span class='glyphicon glyphicon-plus'></span> Follow").removeClass('btn-danger').addClass('btn-primary');
});
The jsfiddle that explains my problem:
jsfiddle.net/TQ5nn/1/
Help please
try this
$(".followBlock").on('click', "button[data-follow=unfollow]", function(e) {
$btn = $(this);
$btn.html("<span class='glyphicon glyphicon-plus'></span> Follow").removeClass('btn-danger').addClass('btn-primary');
$btn.unbind('mouseenter mouseleave');
$btn.attr('data-follow', 'follow');
});
jsfiddle

Categories

Resources