jQuery - Wrong technic or a bug - javascript

I have an HTML page where I want to change the text of an H3 tag based on the selected element of a jQuery accordion. A small demo is available at this link.
<div id="acc1" class="basic">
<h3>aaa</h3>
<div></div>
<h3>bbb</h3>
<div></div>
<h3>ccc</h3>
<div></div>
</div>
<h3 class="ui-widget-header">xyz</h3>
$(document).ready(function () {
$("#acc1").accordion({
heightStyle: "fill",
active: false,
autoheight: false,
collapsible: true,
alwaysOpen: false,
activate: function (event, ui) {
var idx = $("#acc1").accordion("option", "active");
var txt = $("#acc1 > h3:nth-child(" + (idx + 1) + ") > a").text();
$("h3.ui-widget-header").text((idx + 1) + " ---> " + txt);
}
});
});
The acc1 is collapsed at beginning and soon an element gets a click, the jQuery function reads its text and assigns it to the H3 tag. But just the first click, after the page was loaded, works fine. After that only wrong values are assigned.
My way to do this is wrong or the jQuery is buggy?
Used stuff: jQuery v1.9.0, jQuery UI v1.9.2
Regards,
grafl

here is my solution :
$(document).ready(function () {
$("#acc1").accordion({
heightStyle: "fill",
active: false,
autoheight: false,
collapsible: true,
alwaysOpen: false,
activate: function (event, ui) {
}
});
$("h3").click(function(){
var txt = $(this).find('a').text();
$(".ui-widget-header").html(txt);
});
});
JSFIDDLE DEMO

:nth-child considers all siblings, not just the ones matching the tag you've qualified. So h3:nth-child(2) (for instance) means "an h3 element that is also the second child in its parent," not "the second h3 element in its parent."
For the latter, you can use jQuery's pseudo-selector :eq (which uses 0-based indexes), or the .eq function (which also does).
So change this line:
var txt = $("#acc1 > h3:nth-child(" + (idx + 1) + ") > a").text();
to:
var txt = $("#acc1 > h3").eq(idx).children("a").text();
Updated Fiddle
or:
var txt = $("#acc1 > h3:eq(" + idx + ") > a").text();
Updated Fiddle

Related

Jquery UI drop event plain/text between text in Div contentEditable

I'm sorry for my bad English but I try to make the question understandable.
In the snippet (Or the jsfiddle) We can find two draggable items:
foo (If you drag it and drop in the Div content editable the [% foo %] text appear where we drop it between the text)
foo2 (This have the Jquery UI drag style (it follows the cursor))
I want to achieve the functionalitty of foo With jquery UI style. But when I try : event.dataTransfer.setData("text/plain", "[%" + event.srcElement.innerHTML + "%]"); It looks like event is not define if I try to define the function like this:
drag: function(ui, event)
The motion of the foo2 Stop work (It mean is a error in the code)
Here is the snippet:
//$( "#foo2" ).draggable();
$( "#foo2" ).draggable({
start: function(ui) {
event.preventDefault();
},
drag: function(ui) {
},
stop: function(ui) {
}
});
var btn = document.getElementById("foo");
btn.onclick = function(event) {
event.preventDefault();
};
btn.ondragstart = function(event) {
event.dataTransfer.setData("text/plain", "[%" + event.srcElement.innerHTML + "%]");
};
<span draggable="true" id="foo" class="btn btn-primary">Foo</span>
<div style="background:red" contenteditable="true" >Put foo between this and this</div>
<a id="foo2" class="btn btn-primary">Foo2</a>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
The same demo: http://jsfiddle.net/fbprfj5c/1/
Thanks for all your help, recommendations or tips :)
Update:
In response to Gaetano:
I like your idea, and is my fault for no tell all the details. You get the main idea but the tricky way of get the the Width of character and calculate the position with that i can do a similar function to achieve the same effect with a more larger div (in the y axis). But in the div can be more elements than characters. I"ll start with your idea, But i think is a shame open another question for this. In another hand you resolve the problem But that "hacky"/simulation to get the caret position i try to improve (I try before without achieve it), So let"s wait a little is someone have an idea
You may use Droppable for the div element and connect your foo2 draggable element to the droppable.
$('div[contenteditable="true"]').droppable({
drop: function( e, ui ) { // 6.413793103448276
var charWidth = getCharWidth(this);
var position = Math.round(ui.offset.left / charWidth);
position = (position - 1 >= 0) ? position - 1 : position;
$(this).text(function(idx, txt) {
return txt.substr(0, position) + "[%" + ui.draggable.text() + "%]" + txt.substr(position + 1);
})
}
});
$( "#foo2" ).draggable({
connectToSortable: 'div[contenteditable="true"]',
revert: "invalid",
helper: "clone"
});
var btn = document.getElementById("foo");
btn.onclick = function(event) {
event.preventDefault();
};
btn.ondragstart = function(event) {
event.dataTransfer.setData("text/plain", "[%" + event.srcElement.innerHTML + "%]");
};
function getCharWidth(ele) {
var f = window.getComputedStyle(ele)['font'],
o = $('<div>' + ele.textContent + '</div>')
.css({'position': 'absolute', 'float': 'left', 'white-space': 'nowrap', 'visibility': 'hidden', 'font': f})
.appendTo($('body')),
w = o.width() / ele.textContent.length;
o.remove();
return w;
}
<link href="https://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
<span draggable="true" id="foo" class="btn btn-primary">Foo</span>
<div style="background:red" contenteditable="true" >Put foo between this and this</div>
<a id="foo2" class="btn btn-primary">Foo2</a>

Removing a div on button click - issue: removing all divs

On a button click event a new div is created. A user can create as many divs as possible. Once a div is created it becomes draggable thanks to the help of the jqueryui draggable PLUGIN. I have set another on click button event that removes the created div. The problem is that when clicking the user clicks the remove button it removes all divs. How can append a button to each div that specifically removes that div? JSFIDDLE
Jquery
/** Remove newly created div **/
$(".remove").click(function(){
$(".draggable").remove();
});
var z = 1;
$('#button').click(function (e) {
/** Make div draggable **/
$('<div />', {
class: 'draggable ui-widget-content',
text: $('textarea').val(),
appendTo: '.middle-side',
draggable: {
containment: 'parent',
start: function( event, ui ) {
$(this).css('z-index', ++z);
}
}
}).addClass('placement');
/** Contain draggable div **/
$('.middle-side').parent().mousemove(function(e){
var offset = $(this).offset();
var relX = e.pageX - offset.left;
var relY = e.pageY - offset.top;
$('.placement').css({'top': relY + 30,'left': relX + 10, 'position': 'absolute'});
})
});
HTML
<textarea rows="4" cols="50" placeholder="Enter Text Here!"></textarea><br/>
<input type="button" id="button" value="Add Div with Text" />
<button class="remove">Remove div</button><br/>
<div>
<div class="middle-side empty"></div>
</div>
Turn the text property to html:
html: '<span class="close">[X]</span><span class="text">' + $('textarea').val() + '</span>',
Then write click event for .close elements:
$('body').on('click', '.draggable .close', function () {
$(this).closest('.draggable').remove();
});
jsFiddle Demo.
Modify your Add Div Button and Remove Button event like this:
$(".remove").click(function(){
$(".currentDiv").remove();
});
var z = 1;
$('#button').click(function (e) {
$(".currentDiv").removeClass("currentDiv");
/** Make div draggable **/
$('<div />', {
class: 'draggable ui-widget-content',
text: $('textarea').val(),
appendTo: '.middle-side',
draggable: {
containment: 'parent',
start: function( event, ui ) {
$(this).css('z-index', ++z);
},
drag: function() {
$(".currentDiv").removeClass("currentDiv");
$(this).addClass("currentDiv");
},
}
}).addClass('placement currentDiv');
In this way when you create a new div, all currentDiv classes are removed in this line:
$(".currentDiv").removeClass("currentDiv");
Then the currentDiv class is added in created div in last line. So always the last created div has currentDiv class.
Then add this block at the end of your JS:
$('body').on('click', '.draggable', function () {
$(".currentDiv").removeClass("currentDiv");
$(this).addClass("currentDiv");
});
The above block cause that when you click on each draggable element, it selected as current div so Remove button, remove that.
Check JSFiddle Demo
In demo i have also add a background-color:red for currentDiv, you can remove it.
You can simply add this after draggable event :
var closeBtn = '<a href="#xcv" onclick="$(this).unwrap();$(this).remove();" >close</a>';
$('.placement').append(closeBtn);
JSFIDDLE DEMO

Add class to current page using iScroll

As the title suggests, I'm trying to add a class to the current 'snapped-to' element. With this:
var verticalScroll;
verticalScroll = new IScroll('#wrapper', {
snap: true
});
verticalScroll.on('scrollEnd', function(){
alert(this.currentPage);
});
I get this alert when the scrolling is done:
[object Object]
So I was thinking I could use something like this to add a class:
verticalScroll.on('scrollEnd', function(){
var newPage = this.currentPage;
$(newPage).addClass('current');
});
But no joy. Done lots of searches to try and find the same situation. It must be something fairly simple.
Yeah, it's a little bit tricky. Some time ago I tried to add an "active" class to the link and the page. I ended up with this:
after scroll ended:
myScroll.on('scrollEnd', function () {
addActiveClass();
});
the function:
function addActiveClass() {
// get current page with iScroll
var currentSection = myScroll.currentPage.pageY;
// get current link and page
var activeLink = $('nav a[href="' + currentSection + '"] span');
var activeSection = $('section[class="' + currentSection + '"]');
// remove active class from all links and pages
$('nav a span, section').removeClass('active');
// add active class to current link and page
$(activeLink).addClass('active');
$(activeSection).addClass('active');
}
Only one thing that annoys me, you have to give every section a page number as a class:
<section class="0"> … <section>
<section class="1"> … <section>
<section class="2"> … <section>
Same with links:
But maybe could be added dynamically somehow.
And don't forget option:
snap: 'section'
jsfiddle demo
var workCase;
function loadcase() {
workCase = new IScroll('#work-case', {
mouseWheel: true,
resizeScrollbars: true,
snap: 'section',
interactiveScrollbars: true,
mouseWheelSpeed: 10,
scrollX: true,
scrollY: false,
momentum: true,
snapSpeed: 800,
scrollbars: 'custom',
wheelAction: 'scroll'
});
workCase.on('scrollEnd', function() {
var sectionIndex = Number(this.currentPage.pageY);
var iScrollConteiner = $('#work-case').children()[0];
var dataNumber = $(iScrollConteiner)[0].children[sectionIndex].className;
var activeSection = $('section[class="' + dataNumber + '"]');
$('section').removeClass('active');
$(activeSection).addClass('active');
});
}

jQuery Selectable not working in IE or Chrome

I have a jQuery selectable list that has a handle to select an item from one list and put it in another "selected" list. This works fine in Firefox but does not work at all in Chrome and IE. I am not able to click an item to move it to the selected list. See my fiddle in Firefox, which works fine, and then view it in IE or Chrome and notice that it no longer works as expected. (click the plus sign to add a column to the selected list).
jQuery code to move to selected list:
$(function () {
$(".list")
.find("li")
.addClass("ui-corner-all")
.prepend("<div class='handle'><span class='ui-icon ui-icon-plus'></span></div>")
.selectable({
handle: ".handle",
stop: function () {
var result = $("#select-result");
$("ul li div").click(function () {
var index = $("ul li div").index(this);
var listLiText = $("ul.list li").eq(index).text();
var listLiID = $("ul.list li").eq(index).attr('id');
$("ul.list li").eq(index).css('background-color', '#669966');
$("ul.list li").eq(index).css('color', '#FFFFFF');
if ($("#select-result #" + listLiID).length == 0) {
result.append('<li id="' + listLiID + '">' + listLiText + '</li>');
}
sortColumns();
});
}
});
});
JS Fiddle (try first in FF then in IE or Chrome):
http://jsfiddle.net/kmbonin82/NkgC2/17/
I found your problem: You are using an "click" after you have already "stopped" the click event on selectable. You cannot click after it has stopped a selectable click. If you comment out the click, as below, then it fixes your main problem. Then, you need to change your selectors from "ul li div" to ".list li" because you are not selecting from your "list".
stop: function () {
var result = $("#select-result");
//$(".list li").click(function () { -----------PROBLEM-----------
var index = $(".list li").index(this); //Changed to .list li
var listLiText = $(".list li").eq(index).text(); //Changed to .list li
var listLiID = $(".list li").eq(index).attr('id'); //Changed to .list li
$(".list li").eq(index).css('background-color', '#669966'); //Changed to .list li
$(".list li").eq(index).css('color', '#FFFFFF'); //Changed to .list li
if ($("#select-result #" + listLiID).length == 0) {
result.append('<li id="' + listLiID + '">' + listLiText + '</li>');
}
sortColumns();
//});
}
Your updated JS Fiddle: http://jsfiddle.net/NkgC2/30/
Your code should execute after the page is ready:
(function($) {
$(document).ready(function() {
// your code here
});
})(jQuery);

expand collapse using jquery for tree node not working

I am making tree with the help of jquery in the tree whenever there is more than one child for a particular child i want to gave a toggle effect.it means that there should be a plus icon on click of it tree should expand and minus image should come on click of minus tree should collapse and plus image should come.
how to develop this any working example of tree node will be helpful
In this manner i have used your function
function createSpanImageNode(spnNew) {
var spnImage = document.createElement("span");
spnImage.id = spnNew + "_" + "spn1";
$(spnImage).addClass('SpanPlus');
spnImage.setAttribute('onclick', 'toogleNode("' + spnImage.id + '")');
return spnImage;
}
function toogleNode(spnID) {
debugger;
var dv = $("#" + spnID).parents("div:first");
var chkUl = $(dv).find('ul').length;
if (chkUl > 0) {
if ($("#" + spnID).hasClass('SpanPlus'))
$("#" + spnID).removeClass('SpanPlus').addClass('SpanMinus');
else
$("#" + spnID).removeClass('SpanMinus').addClass('SpanPlus');
$(dv).find('ul').animate({ height: 'toggle' });
}
}
the two actions that it should perform are
1)remove the class with the span and add the class with minus.
2)it should toggle the ul.
both is not working????
http://api.jquery.com/toggle/
<script type="text/javascript">
$(document).ready(function () {
$('.navbar .dropdown-item').on('click', function (e) {
var $el = $(this).children('.dropdown-toggle');
var $parent = $el.offsetParent(".dropdown-menu");
$(this).parent("li").toggleClass('open');
if (!$parent.parent().hasClass('navbar-nav')) {
if ($parent.hasClass('show')) {
$parent.removeClass('show');
$el.next().removeClass('show');
$el.next().css({"top": -999, "left": -999});
} else {
$parent.parent().find('.show').removeClass('show');
$parent.addClass('show');
$el.next().addClass('show');
$el.next().css({"top": $el[0].offsetTop, "left": $parent.outerWidth() - 4});
}
e.preventDefault();
e.stopPropagation();
}
});
$('.navbar .dropdown').on('hidden.bs.dropdown', function () {
$(this).find('li.dropdown').removeClass('show open');
$(this).find('ul.dropdown-menu').removeClass('show open');
});
});
for full menu you can find here
http://blog.adlivetech.com/how-to-make-vertical-menu-with-plus-minus-toggle/

Categories