How to execCommand from li? - javascript

I'm losing focus on contentEditable when my menu li option is clicked so when I try to execCommand the selection no longer exists and does not affect the selection. How can I solve this without adding an input?
Updated:
** jsFiddle **
HTML
<div contenteditable=true>
paragraph1<br/>
paragraph2<br/>
paragraph3
</div>
<div contenteditable=true>
paragraph4<br/>
paragraph5<br/>
paragraph6
</div>
<input type=button id=show value=ToggleMenu>
<ul id=submenu>
<li>p</li>
<li>h1</li>
<li>h2</li>
</ul>
Javascript
$("#show").on("click",function(){
$("#submenu").toggle();
});
$("#submenu").on("click","li",function(){ //when this is clicked, editable div loses focus.
document.execCommand("formatBlock", false, $(this).text());
console.log($(this).text(), "was clicked");
});

You could do something like the following:
use mousedown instead of click
prevent the default event behaviour
get the relevant <li>'s content
call document.execCommand()
Demo: http://jsfiddle.net/timdown/SNTyY/13/
Code:
var $submenu = $("#submenu");
$("#show").on("click",function(){
$submenu.toggle();
});
$submenu.mousedown("li",function(e){
var li = e.target;
e.preventDefault();
document.execCommand("formatBlock", false, $(li).text());
});
$submenu.click(function(e) {
e.preventDefault();
});

One issue with your code is that it is not HTML compliant. For example, the sub menu should be
<ul id = 'submenu'>
<li>p</li>
<li>h1</li>
<li>h2</li>
</ul>
Instead of using li as a selector for your click event, try
$("#submenu").on("click", "li", function(){
document.execCommand("formatBlock", false, $(this).text());
alert($(this).text());
});
This throws an alert box on a click event, so you know the click is registering.
Fiddle

Related

Dynamically create button and then remove that button when clicked in jquery

lHi,
I have some divs in a html doc and when I click the div I am adding a button. eg attached:
HTML:
<div class="week">
<div class="day wk1" id="day1">
<label for="day1">Test</label>
</div>
<div class="day wk1" id="day2">
<label for="day2">Test</label>
</div>
When I add a button by clicking on the div, no problem.
Add Button:
$(".day").click(function (e) {
e.preventDefault();
var check = $("#day7").width() - 2;
var insert = $(this).prop("id");
insert = `#${insert}`;
var par = $('<br class="break"><button class="testing">').html('Shift Manual Insert').width(check).css("background-color", "green");
par.appendTo(insert);
// console.log(insert);
});
When I remove the button by clicking on it it does remove it but simultaneously adds a new button as per the code above and below.
Remove Button:
$(".day").on('click','.testing', function(e){
e.preventDefault();
$(".break").remove;
$(this).remove();
});
I am sure I am doing something silly but for the life of me, I cannot figure it out? Please ignore my incorrect use of id's and classes, this is purely a test to gain experience.
Any help will be most appreciated.
Kind regards
Wayne
The event is getting propagated from the click handler on dom with .testing class to it's parent that is dom with .day class. .day have another click handler which add the element.So after removing the element again $(".day").click(function(e) { is getting fired which is adding back the button element
Replacee.preventDefault(); with e.stopPropagation(); in the click handler of .testing
$(".day").click(function(e) {
console.log('x')
e.preventDefault();
var check = $("#day7").width() - 2;
var insert = $(this).prop("id");
insert = `#${insert}`;
var par = $('<br class="break"><button class="testing">').html('Shift Manual Insert').width(check).css("background-color", "green");
par.appendTo(insert);
// console.log(insert);
});
$(".day").on('click', '.testing', function(e) {
e.stopPropagation();
$(".break").remove;
$(this).remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="week">
<div class="day wk1" id="day1">
<label for="day1">Test</label>
</div>
<div class="day wk1" id="day2">
<label for="day2">Test</label>
</div>
Your button is present inside the div. So when you click the button, your div click event is also fired. This is due to event bubbling. Check https://www.w3schools.com/jquery/event_stoppropagation.asp
$(".day").on('click','.testing', function(e){
e.stopPropagation();
e.preventDefault();
$(".break").remove;
$(this).remove();
});

Fire click event of li before hiding ul

I have a textbox and then an unordered list like below:
<div>
<input type="text" />
<button>Go</button>
</div>
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
</ul>
Now in the blur event of textbox:
$('input').on('blur', function() {
$('ul').hide();
});
The above code works just fine.
I am trying to make something like combobox.
So, my desired behavior is :
When Textbox loses focus, suggestions should hide (which is shown above)
When Clicked on a suggestion, its click event should fire and then text of that suggestion should be filled in textbox and then all suggestions should hide
So, for the second functionality, when I click on any li the click event of li should fire and then ul should be hidden.
var items = ["Apple", "Banana", "Celery", "Peach", "Plum"];
$('input').on('input', function() {
var text = $(this).val();
$('ul').show().empty().append(items.filter(function(item) {
return item.match(new RegExp(text, 'i'));
}).map(function(text) {
return $('<li>').text(text);
}));
});
$('input').on('blur', function() {
$('ul').fadeOut();
});
$('ul').on('click', 'li', function() {
$('input[type=text]').val($(this).text());
$('ul').hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>
<input type="text" />
<button>Go</button>
</div>
<ul>
</ul>
Simply update the textbox and then hide the ul within the same click event of the li.
$("li").on("click", function() {
$("input[type=text]").val(this.text());
$("ul").hide();
});
Sorry if the jQuery isn't perfect--I don't use it that often. This should help, anyway.

A button toggle some <li> from a <ul>

I have this JSFiddle. I have a ul list and some li inside. I want pressind a button to toggle the 2 first li. I tried to put <li class="s1"> and then
$( "button" ).click(function() {
$("ul.s1").click(function() {
$(this).slideToggle(300);
return false;
});
});
<button>button</button>
<ul>
<li class="s1">1</li>
<li class="s1">1</li>
<li>9023698</li>
<li>8993127</li>
<li>9037891</li>
</ul>
but nothing happens..
Firstly, you don't need to give the li their own click event if you want them to slide on click of the button. Secondly, the selector for the li elements is incorrect. Thirdly the jsFiddle you setup didn't include jQuery. Try this:
$("button").click(function () {
$("ul .s1").slideToggle(300);
});
Example fiddle
$( "button" ).click(function() {
$("ul .s1").slideToggle(300);
return false;
});
A space between ul and class should fix it.
And you don't need the click handler for list element.

How to implement mouseleave in jquery

I have a small problem with sliding in jquery. On hover (mouse over), I need my navigation list item to show its content by sliding down and on mouse out it should slide up.
HTML:
<ul class="nav nav-tabs nav-stacked">
<li id = "mousehover">
<a style="background-color:#f78144; color: #000; text-align: center;" href="#">Time Table
</a>
</li>
</ul>
<div id = "hovercontent">
Contents 1
</div>
Javascript:
<script type="text/javascript">
$(document).ready(function(){
$("#mousehover").mouseenter(function(){
$("#hovercontent").slideDown("slow");
});
$("#hovercontent").mouseleave(function(){
$(this).slideUp("slow");
});
});
</script>
Here the problem is when I hover on the list the div slides down, but only after I hover on the div and get out of the nav the div is sliding up. I need the div to slide up even if I mouse out of the list with out entering the div. How can this be done?
Better to use mouseover and mouseout will do it for you..
$("#hovercontent").bind("mouseout", function() {
$(this).slideUp("slow");
});
Try this and put it in the doc ready this way: http://jsfiddle.net/ptVbs/
$("#mousehover").hover(function() {
$("#hovercontent").slideDown("slow");
}, function() {
if (!$("#hovercontent").hover()) {
$("#hovercontent").slideUp("slow");
}
});
$("#hovercontent").mouseleave(function() {
$(this).slideUp("slow");
});
you can try it out in fiddle.
Check out http://www.quirksmode.org/js/events_mouse.html. In your eventhandlers, check for the relatedTarget as described there. Use console.log in the eventhandlers to track what's happening. Unfortunately, I can't help further without having the CSS for the classes you use... maybe you could provide a testcase in JSBin at http://jsbin.com/ ?
try this
$(document).ready(function(){
$("#mousehover").mouseover(function(){
$("#hovercontent").slideDown("slow");
});
$("#hovercontent ,#mousehover").mouseleave(function(){
$('#hovercontent').slideUp("slow");
});
});
try it with event.type on 'hover'
You attach an 'hover' event Handler on your #mousehover content, and with event.type you see what event type is going on. With the Event 'hover' you get mouseenter and mouseleave
$(document).ready(function(){
​$('#mousehover').on('hover',function(event){
switch(event.type){
case 'mouseenter': $("#hovercontent").slideDown("slow");
break;
case 'mouseleave': $("#hovercontent").slideUp("slow");
break;
}
});​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
});
I recommend using a class:
HTML:
<ul class="nav nav-tabs nav-stacked">
<li id = "mousehover" class="menu1">
<a style="background-color:#f78144;color:#000;text-align:center;" href="#">Time Table</a>
</li>
</ul>
<div id = "hovercontent" class="menu1">
Contents 1
</div>
JS:
<script>
$(document).ready(function(){
$("#mousehover").mouseenter(function(){
$("#hovercontent").slideDown("slow");
});
$(".menu1").mouseout(function(){
$("#hovercontent").slideUp("slow");
});
});​
</script>

Delegate/Live Failure. Can't bind events after Prepending an element

EDIT--- I realized that the problem here was that the click handler that was bound to the element had to be unbound before I could bind another click handler handler.
I want to allow the user to select/unselect items by click on the element in question. The elements start in an "options" box and if clicked, move to a "selected box". If they are then clicked in the selected box, the elements move back to the original options box.
Can't figure out why delegate() and live() are not working here. I assume this has to do with prependTo() or appendTo().
$('#amen_options .options p').click(function(e){
$(this).appendTo('#amen_selected .options');
e.stopPropagation();
e.preventDefault();
});
/*
$("body").delegate('#amen_selected p', 'click', function(e){
#(this).appendTo('#amen_options .options');
e.stopPropagation();
e.preventDefault();
});
*/
$('div#amen_selected div.options p').live('click',function(e){
$(this).appendTo('#amen_options .options');
e.stopPropagation();
e.preventDefault();
});
Here's the markup:
<div>
<div id="amen_options">
<h3>Click to Select</h3>
<div class="options">
<p data-option="">One</p>
<p data-option="">Two</p>
<p data-option="">Etc...</p>
</div>
</div>
<div id="amen_selected">
<h3>Selected</h3>
<div class="options">
</div>
</div>
The first click works (sending p elements from options to selected box). Once in selected, though, no event handlers are binding. The firebug console isn't showing an error. Normally, I'd assume that this is a markup problem, but I've checked it repeatedly.
Thanks!
It looks like delegate() works good.
http://jsfiddle.net/fLXgU/1/
$('body').delegate('#amen_options .options p', 'click', function(e) {
$(this).appendTo('#amen_selected .options');
return false;
});
$('body').delegate('#amen_selected .options p', 'click', function(e) {
$(this).appendTo('#amen_options .options');
return false;
});

Categories

Resources