Jquery Sortable List with getJSON method - javascript

I am working on a tutorial that uses getJSON to add list items to the DOM. There also needs to be the JqueryUI sortable plugin to sort the lists. For some reason unknown to me the plugin does not work. What am I missing here? Should the sortable function be inside the getJSON callback? Any suggestions would be great.
here is my code I have so far:
$(function () {
$('body h1').append('My Todo List');
$.getJSON('todo.json', function(data) {
var html = '<ul id="sortable" class="ui-sortable">';
$.each(data, function(index) {
var todo = data[index];
if (todo.done === false) {
todo.done = (" ")
} else {
todo.done = ("(DONE)")
}
html += '<li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>' + todo.who + " needs to " + todo.task + " by " + todo.dueDate + " " + todo.done + '</li>';
});
html += '</ul>';
$('body #container').append(html);
});
});
HTML File:
<!DOCTYPE html>
<html>
<head>
<title>Jquery ToDo List</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script src="todo.js"></script>
<script>
$(function () {
$("#sortable").sortable("refresh");
$("#sortable").disableSelection("refresh");
});
</script>
<style>
#sortable { list-style-type: none; margin: 0; padding: 0; width: 60%; }
#sortable li { margin: 0 3px 3px 3px; padding: 0.4em; padding-left: 1.5em; font-size: 14px; height: 18px; }
#sortable li span { position: absolute; margin-left: -1.3em; }
</style>
</head>
<body>
<h1></h1>
<div id="container">
</div>
</body>
</html>
JSON
[
{"task":"get milk","who":"Scott","dueDate":"2013-05-19","done":false},
{"task":"get broccoli","who":"Elisabeth","dueDate":"2013-05-21","done":false},
{"task":"get garlic","who":"Trish","dueDate":"2013-05-30","done":false},
{"task":"get eggs","who":"Josh","dueDate":"2013-05-15","done":true}
]

you have to call the sortable after appending the data. In your $.getJSON callback call the sortable again like given below. jquery will wire the sortable only if the element is present in the DOM when the dom is ready. you are adding the elements dynamically so you have to call the sortable again after adding the elements into the DOM.
$.getJSON('todo.json', function(data) {
var html = '<ul id="sortable" class="ui-sortable">';
$.each(data, function(index) {
var todo = data[index];
if (todo.done === false) {
todo.done = (" ")
} else {
todo.done = ("(DONE)")
}
html += '<li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>' + todo.who + " needs to " + todo.task + " by " + todo.dueDate + " " + todo.done + '</li>';
});
html += '</ul>';
$('body #container').append(html);
});
$( "#sortable" ).sortable();
$( "#sortable" ).disableSelection();
});
Edit
Here is the bin http://jsbin.com/IPubElE/1/
demo uses the in-memory data but it should work fine even inside the callback method.

Related

jQuery Draggable - Create draggable and start dragging on html5 native Drag And Drop api event

Okay, basically what I want to try to achieve, is when a dragover event fires from HTML5 Drag And Drop API, I wish to create a jQuery draggable object, and start following the mouse around, while the dragend event fires from the HTML5 Drag And Drop API.
The reason I want to do this, is the following:
I have an application which uses a plugin, that has a functionality, which is dependent on the jQuery.ui draggable to function (it is the FullCalendar Scheduler plugin, version 3)
I want to achieve a new functionality in the application, with which the client can drag something from browser window A, and drop it in the above mentioned plugin in browser window B.
As the above mentioned plugin is not working with the native HTML5 Drag and Drop API, and the jQuery.ui draggable is not capable of dragging elements from one browser window to the other, I think my only option is to mix these two plugins.
My proposed solution to this problem was, using the native HTML5 Drag and Drop API, and when the dragged element reaches over a dropzone, creating a new draggable element in browser window B, and simulating a mousedown event on it, so it starts following the cursor. When the dragend event would fire, I planned to plain and simply fire the mouseup event on the draggable element also, and from here on the scheduler plugin can do it's magic.
To try to test this out, with a single browser window at first, I've tried to achieve the first part of my above solution, ie: when the dragover fires, create the jQuery.ui draggable and simulate a mousedown on it, then it should start following the mouse. I can't achieve this behaviour.
I made a fiddle, where you can see what I tried so far (I am not posting the whole code here, as it is rather long): JSFiddle
Basically, the error I am getting at the Fiddle, with both options that I tried, is a type.indexOf is not a function error.
I also asked and received some help on the following question, from where the proposed solution works fine when starting the drag operation with a click event, but it isn't working with any other event type. I pressume, I can simulate a mousedown.draggable event, only from a MouseEvent, and the dragend event is not a MouseEvent.
Long story short, I would need help in obtaining the result I am looking for, at least for the first part of my proposed solution!
There does not appear to be a good answer for this. First, not all browsers support the same DnD terminology or functionality. Such as FireFox fires a dragenter event on drop and Chrome does not seem to detect a drop event when the object is from another window.
Here is my testing so far. To use, copy the content into a Text file and save as HTM or HTML. Then Open the file locally in your browser. Open another Window and open the second HTM. now you have two windows you can drag to and from.
wina-1.htm
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Window A</title>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<style>
.items {
position: relative;
}
.items > div {
margin-right: 5px;
width: 150px;
height: 150px;
padding: 0.5em;
border-radius: 6px;
display: inline-block;
}
#log {
width: 100%;
height: 5em;
overflow-y: auto;
}
[draggable].idle {
background-color: rgba(255,0,0,0.75);
}
[draggable].selected {
background-color: rgba(255,0,0,0.95);
}
</style>
</head>
<body>
<pre id="log"></pre>
<div class="items ui-widget">
<div id="draggable" class="ui-widget-content idle" draggable="true">
<p>Drag me around</p>
</div>
<div id="static" class="ui-widget-content">
<p>I can't be moved</p>
</div>
</div>
<script>
var srcEl;
function log(s){
var now = new Date();
var t = now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds()
+ "." + now.getMilliseconds();
var l = document.getElementById("log");
l.append(t + ": " + s + "\r\n");
l.scrollTop = l.scrollHeight;
}
function dragStart(e){
log("Drag Start: " + e.target.nodeName + "#" + e.target.id);
srcEl = e.target;
if(e.dataTransfer == undefined){} else {
e.dataTransfer.effectAllowed = "copyMove";
log("Event dataTransfer.effectAllowed: " +
e.dataTransfer.effectAllowed);
log("Source Element: " + srcEl.nodeName + "#" + srcEl.id);
}
this.classList.add("selected");
}
function dragOver(e){
e.preventDefault();
log("Drag Over: " + e.target.nodeName + (e.target.id != "" ? "#" +
e.target.id : ""));
return false;
}
function dragLeave(e){
log("Drag Leave: " + e.target.nodeName + (e.target.id != "" ? "#" +
e.target.id : ""));
}
function dragStop(e){
log("Drag End: " + e.target.nodeName + "#" + e.target.id);
this.classList.remove("selected");
}
log("Init");
var item = document.getElementById("draggable");
item.addEventListener('dragstart', dragStart, false);
item.addEventListener('dragover', dragOver, false);
item.addEventListener('dragleave', dragLeave, false);
window.addEventListener('dragleave', dragLeave, false);
var items = document.querySelectorAll('.items > div');
[].forEach.call(items, function(el) {
el.addEventListener('dragover', dragOver, false);
});
</script>
</body>
</html>
As you can see, this is using raw JavaScript. I was tinkering with jQuery UI, and I kept the stylesheet just for easy theming. We have a section to print out log details, a draggable, and a static item.
winb-1.htm
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Window B</title>
<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>
<style>
.drag-item {
width: 100px;
height: 100px;
background-color: red;
}
body {
position: relative;
}
div.drag-helper {
width: 100px;
height: 100px;
background-color: red;
z-index: 1002;
position: relative;
}
#log {
width: 100%;
height: 5em;
line-height: 1em;
font-size: 1em;
overflow-y: auto;
}
#dropzone {
background-color: green;
width: 95%;
height: 340px;
}
</style>
</head>
<body>
<pre id="log"></pre>
<div id="dropzone"></div>
<script>
jQuery(function($) {
function log(s){
var now = new Date();
var t = now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds
() + "." + now.getMilliseconds();
$("#log").append(t + ": " + s + "\r\n").scrollTop($("#log").prop
("scrollHeight"));
}
function dragEnter(e){
e.preventDefault();
log("Drag Enter triggered: " + $(e.target).prop("nodeName") +
($(e.target).attr("id").length ? "#" + $(e.target).attr("id") : ""));
}
function dragOver(e){
log("Drag Over triggered: " + $(e.target).prop("nodeName") +
($(e.target).attr("id").length ? "#" + $(e.target).attr("id") : ""));
e.dataTransfer.dropEffect = 'move';
e.preventDefault();
}
function handleDrop(e){
if (e.stopPropagation) {
e.stopPropagation();
}
log("Drop Triggered: " + $(e.target).attr("id"));
return false;
}
function dragEnd(e){
log("Drag End Triggered: " + $(e.target).prop("nodeName") +
($(e.target).attr("id").length ? "#" + $(e.target).attr("id") : ""));
}
log("Init");
$("#dropzone").on({
dragenter: dragEnter,
dragover: dragOver,
drop: handleDrop,
mouseup: handleDrop,
dragend: dragEnd
});
$(window).on({
dragenter: dragEnter,
dragover: dragOver,
drop: handleDrop,
dragend: dragEnd
});
});
</script>
</body>
</html>
Window B uses jQuery as the intention was to convert the element into a jQuery UI Draggable.
First thing to know, there is no way to do in transit. Since the Source element is not a part of the target DOM, it cannot be done. It can be added and initialized as a Draggable in the drop event. Essentially what will happen is a new element will be created at that time assigned all the data.
Second, data transfer is unreliable and I would avoid DataTransfer as your data container. I would advise using localStorage. This is similar to a cookie and is a lot more reliable.
For example, I created the following Data object:
{
id,
type,
attr: {
id,
class,
width,
height
},
content
}
Here are some example functions:
function collectData(obj){
return {
id: obj.attr("id"),
type: obj.prop("nodeName"),
attr: {
id: obj.attr("id"),
class: obj.attr("class"),
width: obj.width(),
height: obj.height()
},
content: obj.text().trim()
};
}
function saveData(k, d){
localStorage.setItem(k, JSON.stringify(d));
}
function getData(k){
return JSON.parse(localStorage.getItem(k));
}
function makeEl(d, pObj){
return $("<" + d.type +">", d.attr).html("<p>" + d.content + "</p>").appendTo(pObj);
}
$("#draggable").on('dragstart', function(e){
saveData("drag-data", collectData($(this)));
});
$("#dropzone").on('drop', function(e){
var item = makeEl(getData('drag-data'), $(this));
item.addClass("clone").position({
my: "center",
of: e
}).draggable();
});
In theory, this should all work. In practice, I have hit a ton of roadblocks. I would suggest something like a click-to-copy type of action. Where the User clicks an item in Window A (selecting it) and then clicks where they want it to be in Window B. Again using localStorage, the item could be cloned into the new location.
wina-3.htm
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Draggable - Default functionality</title>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<style>
.items {
position: relative;
}
.items > div {
margin-right: 5px;
width: 150px;
height: 150px;
padding: 0.5em;
border-radius: 6px;
display: inline-block;
}
#log {
width: 100%;
height: 5em;
overflow-y: auto;
}
[draggable].idle {
background-color: rgba(255,0,0,0.5);
}
[draggable].selected {
background-color: rgba(255,0,0,0.95);
}
</style>
</head>
<body>
<pre id="log"></pre>
<div class="items ui-widget">
<div id="draggable" class="ui-widget-content idle" draggable="true">
<p>Click on me</p>
</div>
<div id="static" class="ui-widget-content">
<p>I can't be moved</p>
</div>
</div>
<script>
var intv;
function log(s){
var now = new Date();
var t = now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds() + "." + now.getMilliseconds();
var l = document.getElementById("log");
l.append(t + ": " + s + "\r\n");
l.scrollTop = l.scrollHeight;
}
function collectData(el){
return {
id: el.id,
type: el.nodeName,
attr: {
id: el.id,
class: el.className,
width: el.width,
height: el.height
},
content: el.innerText
};
}
function saveData(k, v){
localStorage.setItem(k, JSON.stringify(v));
}
function getData(k){
return JSON.parse(localStorage.getItem(k));
}
function clearData(k){
localStorage.setItem(k, null);
}
function selElem(e){
var trg = e.target.nodeName + (e.target.id != "" ? "#" + e.target.id : "");
if(e.target.classList.contains("selected")){
log("Deselect element: " + trg);
e.target.classList.remove("selected");
} else {
log("Element Selected: " + trg);
e.target.classList.add("selected");
saveData("select-data", collectData(e.target));
}
intv = setInterval(function(){
if(getData("select-data") == null){
document.getElementsByClassName("selected")[0].classList.remove("selected");
log("Unselected");
clearInterval(intv);
}
}, 1000);
}
log("Init");
var item = document.getElementById("draggable");
item.addEventListener('click', selElem);
</script>
</body>
</html>
winb-3.htm
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Window B</title>
<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>
<style>
.drag-item {
width: 100px;
height: 100px;
background-color: red;
}
body {
position: relative;
}
#log {
width: 100%;
height: 5em;
line-height: 1em;
font-size: 1em;
overflow-y: auto;
}
#dropzone {
background-color: green;
width: 95%;
height: 340px;
position: relative;
}
.cloned {
position: absolute;
width: 150px;
height: 150px;
padding: 0.5em;
border-radius: 6px;
display: inline-block;
background-color: rgba(255,0,0,0.75);
}
</style>
</head>
<body>
<pre id="log"></pre>
<div id="dropzone"></div>
<script>
jQuery(function($) {
function log(s){
var now = new Date();
var t = now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds
() + "." + now.getMilliseconds();
$("#log").append(t + ": " + s + "\r\n").scrollTop($("#log").prop
("scrollHeight"));
}
function getData(k){
console.log("Getting Data: '" + k + "'", localStorage.getItem(k));
return JSON.parse(localStorage.getItem(k));
}
function clearData(k){
log("Clear Data");
localStorage.setItem(k, null);
}
function makeEl(dObj, pObj){
console.log(dObj, pObj);
return $("<" + dObj.type + ">", dObj.attr).html("<p>" + dObj.content +
"</p>").appendTo(pObj);
}
function handleDrop(e){
if (e.stopPropagation) {
e.stopPropagation();
}
var trg = $(e.target);
log("Drop Triggered: " + trg.prop("nodeName") + "#" + trg.attr("id"));
var d, item;
if(e.target.id == "dropzone" && (e.type == "click" || e.type ==
"mouseup")){
log("Click Detected - Collecting Data");
d = getData("select-data");
console.log("Data", d);
d.attr.id = "clone-" + ($("#dropzone .cloned").length + 1);
log("Making Element: " + d.type + "#" + d.attr.id);
item = makeEl(d, trg);
item.removeClass("selected").addClass("cloned").position({
my: "center",
of: e
}).draggable();
clearData("select-data");
return true;
}
return false;
}
log("Init");
$("#dropzone").on({
mouseup: handleDrop,
click: handleDrop
});
});
</script>
</body>
</html>
I know this is not the answer you're looking for, and for that you need to try to ask the real question. You seem to keep asking around the question.
Hope this helps.

How to save results to localStorage

I am new in HTML and jQuery, and this was my first implementation, and I am not sure it's correct, I need your help, I tried to make simple counter to begin counting per click, and to store the results in localStorage, this is all I could do
but it didn't work, may you tell me what I've done wrong?
Thanks
$(function() {
$('.container li').click(function() {
var btn = $(this).attr("data-page");
var element = $('.counter[data-page="' + btn + '"]').html();
element++
$('.counter[data-page="' + btn + '"]').html(element);
localStorage.setItem('save', $('.counter[data-page="' + btn + '"]').html());
if (localStorage.getItem('save')) {
$('.counter[data-page="' + btn + '"]').html(localStorage.getItem('save'));
}
});
});
ul {
padding: 0;
margin: 0;
list-style: none;
}
a {
text-decoration: none;
background: blue;
color: #fff;
padding: 10px;
}
ul li {
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="container">
<li data-page="facebook">
4100
</li>
<li data-page="twitter">
4100
</li>
</ul>
You need to init first your buttons with values from localStorage. Then you don't need to retrieve them again, you just need to manipulate the value inside the html and to set the new counter in the localStorage.
Also you need to have one counter by button in your localStorage
// Just to make this snippet work,
// because localStorage is forbiden here
// database = localStorage
database = {
store: {},
getItem: function(key) {
return this.store[key];
},
setItem: function(key, val) {
this.store[key] = val;
},
}
$(function() {
$(".counter").each((_, element) => {
const $btn = $(element);
const key = `save-${$btn.attr("data-page")}`;
$btn.html(database.getItem(key) || 0);
});
$(".container li").click(function() {
const $btn = $(this).find(".counter");
const key = `save-${$btn.attr("data-page")}`;
const counter = (+$btn.html()) + 1;
$btn.html(counter);
database.setItem(key, counter);
});
});
ul {
padding: 0;
margin: 0;
list-style: none;
}
a {
text-decoration: none;
background: blue;
color: #fff;
padding: 10px;
}
ul li {
display: inline-block;
}
<ul class="container">
<li data-page="facebook">
4100
</li>
<li data-page="twitter">
4100
</li>
</ul>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You need to load the data from the local storage when the page loads. Right now it only loads after saving, which has no effect.
Each element is also saving to the same part of the local storage, so they will be the same every time the page loads. You need to save to an index based on the data-page.
Here you go with one more solution https://jsfiddle.net/thrh78u0/
$(function() {
$('.container li').click(function() {
var btn = $(this).attr("data-page");
var element = $('.counter[data-page="' + btn + '"]').html();
element++
$('.counter[data-page="' + btn + '"]').html(element);
localStorage.setItem('save' + btn, element);
if (localStorage.getItem('save')) {
$('.counter[data-page="' + btn + '"]').html(localStorage.getItem('save'));
}
});
});
ul {
padding: 0;
margin: 0;
list-style: none;
}
a {
text-decoration: none;
background: blue;
color: #fff;
padding: 10px;
}
ul li {
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="container">
<li data-page="facebook">
4100
</li>
<li data-page="twitter">
4100
</li>
</ul>
Hope this will help you.
Try this simple one:
$('.container li').click(function() {
if (localStorage.count) {
localStorage.count++
} else {
localStorage.count = 1;
}
})
Updated script using different variables for different counters. It loads counters values from localStorage or sets them to 0 if not available. It also uses two separate variables to store the values.
I used your code so you can see what is different and what you missed in your solution
$(function() {
var cntfb = localStorage.getItem('save-facebook');
$('.counter[data-page="facebook"]').html(cntfb ? cntfb : 0);
var cnttw = localStorage.getItem('save-twitter');
$('.counter[data-page="twitter"]').html(cnttw ? cnttw : 0);
$('.container li').click(function() {
var btn = $(this).attr("data-page");
var element = $('.counter[data-page="' + btn + '"]').html();
element++;
$('.counter[data-page="' + btn + '"]').html(element);
localStorage.setItem('save-' + btn, $('.counter[data-page="' + btn + '"]').html());
if (localStorage.getItem('save-' + btn)) {
$('.counter[data-page="' + btn + '"]').html(localStorage.getItem('save-' + btn));
}
});
});

Custom html tab implementation problems

my use case : create tab like experience. clicking on add button creates a (horz tab button) and a corresponding div, which is linked via onclick listener, dynamically.
problems :
on clicking add button, values from previous tabs are reset (which is obvious wrt to the way $tabs_prev & $menu_prev is populated) and
their respective js goes away (which I can't understand, why?)
a remove tab implementation (because the way I've coded these tabs, removing a tab and corresponding div isn't really simple, so, any clues in this direction, maybe?)
code : fiddle : http://jsfiddle.net/g58fzs75/1/
HTML:
<body>
<input id="hidden" type="hidden" value="1"></input>
<div id="template_tabBtn" style="display:none">
<input type="button" value="add" onclick="addTab()"></input>
</div>
<ul id="menu">
</ul>
<div id="tabs">
</div>
<div id="template_tabBar" style="display:none">
<li>
<input type="button" id="tab_btn" class="template_tabBar" value="Tab" onclick="tabClick(this)"></input>
</li>
</div>
<div id="template_tabs" style="display:none">
<div id="tabs" class="template_tabs tab_div" value="1">
<input type="text" id="txt" class="template_tabs" value="alert"></input>
<input type="button" id="btn" class="template_tabs" value="alert"></input>
</div>
</div>
</body>
CSS:
<style>
ul#menu {
padding: 0;
}
ul#menu li {
display: inline;
}
ul#menu li input {
background-color: black;
color: white;
padding: 10px 20px;
text-decoration: none;
border-radius: 4px 4px 0 0;
}
ul#menu li input:hover {
background-color: orange;
}
</style>
jQuery :
<script src="http://code.jquery.com/jquery-1.9.1.js" type="text/javascript"></script>
<script>
$tabs_prev = "";
$menu_prev = "";
$add_btn = "";
$current_tabID = "";
function tabClick(id) {
showCurrent($(id).attr('id'));
}
function addTab() {
var tabCount = parseInt($('#hidden').val()) + 1;
$('#hidden').val(tabCount);
run(tabCount);
showCurrent($('#tabs-' + tabCount).attr('id'));
}
$(document).ready(function() {
$add_btn = "<li>" + $('#template_tabBtn').html() + "</li>";
run(1);
});
function run(tabCount) {
//$tabs_prev += main($('#template_tabs'),tabCount);//alert("tabs\n"+$tabs_prev);
$menu_prev += main($('#template_tabBar'), tabCount); //alert("menu\n"+$menu_prev);
$('#tabs').html($('#tabs').html() + main($('#template_tabs'), tabCount));
$('#menu').html($menu_prev + $add_btn);
logic(tabCount);
}
function main(target, tabCount) {
$htmlBackup = $(target).html();
$('.' + $(target).attr('id')).each(function() {
$(this).attr('id', $(this).attr('id') + "-" + tabCount).removeClass($(target).attr('id'));
$(this).attr('value', $(this).attr('value') + "-" + tabCount);
});
$html = $(target).html();
$(target).html($htmlBackup);
return $html;
}
function logic(tabCount) {
$('#btn-' + tabCount).click(function() {
alert($('#txt-' + tabCount).val());
});
}
function showCurrent(current_id) {
$('.tab_div').each(function() {
var id = $(this).attr('id');
var id_num = id.substr(id.lastIndexOf('-') + 1, id.length);
var current_id_num = current_id.substr(current_id.lastIndexOf('-') + 1, current_id.length);
if (id_num == current_id_num) {
$("#tabs-" + id_num).show();
$('#tab_btn-' + id_num).css({
"background-color": "orange"
});
} else {
$("#tabs-" + id_num).hide();
$('#tab_btn-' + id_num).css({
"background-color": "black"
});
}
});
}
</script>
The reason why your javascript is disappearing is because resetting the innerHTML deletes the onclick handlers on the elements. Why: the original elements are destroyed, including references to events and new elements are created.
The code responsible for this:
$('#tabs').html($('#tabs').html() + main($('#template_tabs'), tabCount));
Please use jQuery's appending of an element by cloning the template tab:
$('#tabs').append($('#template_tabs').clone(true));
Append appends htmlstrings or elements to an parent element. It's a buffed up version of the documents native 'appendChild'.
clone clone the template element (makes a copy). You can do this in your function main and return it to the append function.
function main(tabCount)
{
var node = $('#template_tabs').clone(true));
//do things with the node, like setting an onclick handler, or id.
//example
node.setAttribute("id", "tab" + tabCount);
}
Removing can be done also:
function removeNode(node)
{
//provide a node via jQuery
//example: removeNode($("#tab2")) <-- now tab2 will be removed from the DOM.
node.remove();
}

How to make a tooltip for incoming list items

I am trying to make a tooltip with JQuery for incoming list items. People will enter some text in a textfield, hit enter and those values will be added to a visible list on the site. I want to make a tooltip for every list item that will be added to the list. I want the text that people fill in in the textfield to be added in the tooltip, is this possible? And how can I do this? Thanks! This is what I have so far..
<div id="tooltip"></div>
<input type="text" id="input" placeholder="Voer item in" /> <button id="button">Toevoegen</button>
<ul id="boodschappenlijst">
</ul>
----------------------------------------------------------------------------
$(document).ready(function(e) {
$('#button').on('click', function (){
var toevoegen = $('#input').val();
var verwijderen = 'Verwijderen'
<!--add list item-->
$('#boodschappenlijst').prepend('<li>' + toevoegen + '' + '\t' + verwijderen + '</li>');
});
<!--remove list item-->
$('#boodschappenlijst').on('click', '.verwijderen', function(){
$(this).parent('li').remove();
});
<!-textfield empty-->
$('#input').on('click', function (){
$(this).val('')
});
$('#boodschappenlijst').hover(
function (){
$('#tooltip').css('display', 'block')
},
function (){
$('#tooltip').css('display', 'none')
};
);
}) ;
----------------------------------------------------------------
#tooltip {
position: absolute;
top: 100px;
right: 300px;
border: 1px solid #000000;
border-radius: 5px;
color: black;
width: 100px;
display: none;
}
The tooltip appears, but I want the text that people fill in in the textfield to be added in the tooltip. If you need some more information just ask. Thanks in advance (verwijderen = remove, toevoegen = add)
There are two main changes you need to make:
You need to store toevoegen with the li in a structured way.
You need to attach the hover event to the li, not the ul - or more specifically any lis which are added to the ul in future.
For 1. you can use the jquery data() to store the tooltip value:
var li = $('<li>' + toevoegen + '' + '\t' + verwijderen + '</li>');
li.data('tooltip', toevoegen);
$('#boodschappenlijst').prepend(li);
For 2. you will need to use on() instead of hover() to ensure that new lis get the event attached:
$('#boodschappenlijst').on('mouseenter', 'li', function () {
var toevoegen = $(this).data('tooltip');
$('#tooltip').css('display', 'block').html(toevoegen);
}).on('mouseleave', 'li', function () {
$('#tooltip').css('display', 'none').html('');
});
Here is the full thing, tidied up:
$(document).ready(function (e) {
$('#button').on('click', function () {
var toevoegen = $('#input').val();
var verwijderen = 'Verwijderen'
//add list item
var li = $('<li>' + toevoegen + '' + '\t' + verwijderen + '</li>');
li.data('tooltip', toevoegen);
$('#boodschappenlijst').prepend(li);
});
// remove list item
$('#boodschappenlijst').on('click', '.verwijderen', function () {
$(this).parent('li').remove();
});
// textfield empty
$('#input').on('click', function () {
$(this).val('');
});
$('#boodschappenlijst').on('mouseenter', 'li', function () {
var toevoegen = $(this).data('tooltip');
$('#tooltip').css('display', 'block').html(toevoegen);
}).on('mouseleave', 'li', function () {
$('#tooltip').css('display', 'none').html('');
});
});
#tooltip {
position: absolute;
top: 100px;
right: 300px;
border: 1px solid #000000;
border-radius: 5px;
color: black;
width: 100px;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="tooltip"></div>
<input type="text" id="input" placeholder="Voer item in" /> <button id="button">Toevoegen</button>
<ul id="boodschappenlijst"></ul>
UPDATED ANSWER.
Working example
$(document).ready(function(e) {
var myToolTip = $('#tooltip');
$('#button').on('click', function (){
var toevoegen = $('#input').val();
var verwijderen = 'Verwijderen'
$('#boodschappenlijst').prepend('<li class=\'hoverTarget\' title=\''+toevoegen+' \'>' + toevoegen + '' + '\t' + verwijderen + '</li>');
$('.hoverTarget').hover(
function (_evt){
console.log("e",_evt);
console.log("e",_evt.currentTarget.attributes['title']);
myToolTip.html(_evt.currentTarget.attributes['title'].value);
myToolTip.css('display', 'block')
},
function (){
myToolTip.css('display', 'none')
}
);
});
$('#boodschappenlijst').on('click', '.verwijderen', function(){
$(this).parent('li').remove();
});
$('#input').on('click', function (){
$(this).val('')
});
}) ;
Add title attribute to your line item
$('#boodschappenlijst').prepend('<li title=\''+toevoegen+'\'>' + toevoegen + '' + '\t' + verwijderen + '</li>');

owl carousel plugin doesn't work inside a event click

i need to initialize the owl carousel inside a click event like the following code, it works in first time when I click, but when I click it again (on event div) it simply doesn't work. how can I accomplish that? is there a way to reset the owl carousel?
I added my full code to the last part of this post to understand better my pb and to test it.
Could you please help me on this? I really need this.
thanks in advance,
CAFC
source owl carousel : http://owlgraphic.com/owlcarousel/demos/customJson.html
$('#XX').click(function(e) {
e.PreventDefault;
$("#owl-demo").owlCarousel({
jsonPath: 'json/customData2.json',
jsonSuccess: customDataSuccess
});
function customDataSuccess(data) {
var content = "";
for (var i in data["items"]) {
var img = data["items"][i].img;
var alt = data["items"][i].alt;
content += "<img src=\"" + img + "\" alt=\"" + alt + "\">"
}
$("#owl-demo").html(content);
}
});
my full code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Owl Carousel - Dynamic content via JSON</title>
<!-- Owl Carousel Assets -->
<link href="../owl-carousel/owl.carousel.css" rel="stylesheet">
<link href="../owl-carousel/owl.theme.css" rel="stylesheet">
<script src="../assets/js/jquery-1.9.1.min.js"></script>
<script src="../owl-carousel/owl.carousel.js"></script>
<!-- Demo -->
<style>
#owl-demo .item {
background: #a1def8;
padding: 10px 0px;
display: block;
margin: 5px;
color: #FFF;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
text-align: center;
}
</style>
<script>
$(document).ready(function() {
$('#XX').click(function(e) {
$("#owl-demo").owlCarousel({
jsonPath: 'json/customData2.json',
jsonSuccess: customDataSuccess
});
function customDataSuccess(data) {
var content = "";
for (var i in data["items"]) {
var img = data["items"][i].img;
var alt = data["items"][i].alt;
content += "<img src=\"" + img + "\" alt=\"" + alt + "\">"
}
$("#owl-demo").html(content);
}
});
});
</script>
</head>
<body>
<div id="owl-demo"></div>
<div id='XX'>Click HERE!</div>
</body>
</html>
Here ya go:
JS:
$(document).ready(function () {
var owl = false;
$('#XX').click(function (e) {
if (owl) {
$("#owl-demo").data('owlCarousel').reinit({
jsonPath: '/echo/json',
jsonSuccess: customDataSuccess
});
} else {
owl = true;
}
$("#owl-demo").owlCarousel({
jsonPath: '/echo/json',
jsonSuccess: customDataSuccess
});
function customDataSuccess(data) {
console.log('loading Data');
data = testJSON;
var content = "";
for (var i in data["items"]) {
var img = data["items"][i].img;
var alt = data["items"][i].alt;
content += "<img src=\"" + img + "\" alt=\"" + alt + "\">";
}
$("#owl-demo").html(content);
}
});
});
The methods of reinit are found at the bottom of the documentation under 5. Owl Data methods
Demo: http://jsfiddle.net/robschmuecker/pLvdx8xx/

Categories