I've just copied the demo code from the site http://www.jstree.com/ of jstree and tried to add the option of new node. There is no error but it don't add new node.
This is my code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jsTree test</title>
<!-- 2 load the theme CSS file -->
<link rel="stylesheet" href="dist/themes/default/style.min.css" />
</head>
<body>
<!-- 3 setup a container element -->
<div id="jstree">
<!-- in this example the tree is populated from inline HTML -->
<ul>
<li>Root node 1
<ul>
<li id="child_node_1">Child node 1</li>
<li>Child node 2</li>
</ul>
</li>
<li>Root node 2</li>
</ul>
</div>
<button>demo button</button>
<!-- 4 include the jQuery library -->
<script src="dist/libs/jquery.js"></script>
<!-- 5 include the minified jstree source -->
<script src="dist/jstree.min.js"></script>
<script>
$(function () {
// 6 create an instance when the DOM is ready
$('#jstree').jstree();
// 7 bind to events triggered on the tree
$('#jstree').on("changed.jstree", function (e, data) {
console.log(data.selected);
});
// 8 interact with the tree - either way is OK
$('button').on('click', function () {
$('#jstree').jstree(true).select_node('child_node_1');
//$('#jstree').jstree().create_node(null,'AAA','last'); first option
//$("#jstree").jstree("create_node", $("j1_3"), "after", { "data": "Hello");
$('#jstree').jstree('select_node', 'child_node_1');
$.jstree.reference('#jstree').select_node('child_node_1');
});
});
</script>
</body>
</html>
Look at remarked lines. No error but don't add rhe new node. Does somebody have any idea?
try this..
$('#jstree').jstree("create_node", "parent_id", function(e,data){
console.log('hi', data);
});
Related
I am developing a chat app, and my issue raises when I try to add new elements to a list of chat rooms, see them, and interact with them without reloading the page.
I am adding HTML elements to a list with JavaScript.
Then I try to querySelectorAll elements in the list.
The elements that were loaded from the server on page load can be selected.
But the newly created elements with JavaScript don't seem to get selected.
Here is how I try to select my elements and, when clicked, execute some code for each of them:
document.querySelectorAll('.select-room').forEach(p => {
p.onclick = () => { <my code here> })
The elements that are already on the list get selected just fine and my code executes alright.
But when I add a new element with JavaScript. Even though the HTML of it looks just the same as the HTML of other existing elements, including the class by which it gets selected, the result is I can only select those after reloading the page.
Is there a way I can listen for changes made to the DOM, so that after adding with JavaScript new elements with the same class, they will be selected like the others without having to reload the page?
Here is a Minimal, Complete, Reproducible Example of my problem:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>mcr problem</title>
<script>
document.addEventListener("DOMContentLoaded", () => {
// Clicking element in the list shows an alert.
document.querySelectorAll(".clickable").forEach(li => {
li.onclick = () => {alert("interaction!")};
});
// Clicking on button adds new element to the list
document.querySelector("#add-btn").onclick = () => {
newLi = document.createElement("li");
newLi.classList.add("clickable");
newLi.innerHTML = "New Item";
document.querySelector("#parent-list").append(newLi);
};
});
</script>
</head>
<body>
<h1>List of items</h1>
<button id="add-btn">Add</button>
<ul id="parent-list">
<li class="clickable" id="post-1">Item 1</li>
<li class="clickable" id="post-2">Item 2</li>
<li class="clickable" id="post-3">Item 3</li>
</ul>
</body>
</html>
Reasons why alert was not getting called DOMContentLoaded
This event triggers when the DOM tree forms i.e. the script is loading. Scripts start to run before all the resources like images, CSS, and JavaScript loads. You can attach this event either to the window or the document objects
and at that time the query selector has only 3 node of class .clickable so it apply only on those 3 elements.
In javascript DOMNodeInserted
It fires when the script inserts a new node in the DOM tree using appendChild(), replaceChild(), insertBefore(), etc.
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll(".clickable").forEach((li) => {
li.onclick = () => commonAlertMethod();
});
// Clicking on button adds new elemnt to the list
document.querySelector("#add-btn").onclick = () => {
newLi = document.createElement("li");
newLi.classList.add("clickable");
newLi.innerHTML = "New Item";
document.querySelector("#parent-list").append(newLi);
};
});
document.addEventListener("DOMNodeInserted", () => {
// Clicking element in the list shows an alert.
document.querySelectorAll(".clickable").forEach((li) => {
li.onclick = () => commonAlertMethod();
});
});
function commonAlertMethod() {
alert("interaction!");
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>List of items</h1>
<button id="add-btn">Add</button>
<ul id="parent-list">
<li class="clickable" id="post-1">Item 1</li>
<li class="clickable" id="post-2">Item 2</li>
<li class="clickable" id="post-3">Item 3</li>
</ul>
</body>
</html>
I am trying to get the sidenav to work for the Materializecss framework.
MATERIALIZECSS http://next.materializecss.com/getting-started.html
SIDENAV DEMO http://next.materializecss.com/sidenav.html
MY CODEPEN https://codepen.io/gregoryksanders/pen/RxoyqB
<head>
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-alpha.2/css/materialize.min.css">
<!--Let browser know website is optimized for mobile-->
<meta name="viewport" content="width=device-width, initial-scale=1.0"/
</head>
<body>
<ul id="slide-out" class="sidenav">
<li><i class="material-icons">cloud</i>First Link With Icon</li>
<li>Second Link</li>
<li><div class="divider"></div></li>
<li><a class="subheader">Subheader</a></li>
<li><a class="waves-effect" href="#!">Third Link With Waves</a></li>
</ul>
<i class="material-icons">menu</i>
<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-alpha.2/js/materialize.min.js"></script>
</body>
3 Days trying to figure this out :/ so any help is welcomed.
The problem is that you should initialize the side-nav in Javascript code like this
var elem = document.querySelector('.sidenav');
var instance = new M.Sidenav(elem);
// with jquery
$(document).ready(function(){
$('.sidenav').sidenav();
});
now your code will work perfect
var elem = document.querySelector('.sidenav');
var instance = new M.Sidenav(elem);
// Initialize collapsible (uncomment the lines below if you use the dropdown variation)
// var collapsibleElem = document.querySelector('.collapsible');
// var collapsibleInstance = new M.Collapsible(collapsibleElem, options);
// Or with jQuery
$(document).ready(function(){
$('.sidenav').sidenav();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-alpha.2/js/materialize.min.js"></script>
<head>
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-alpha.2/css/materialize.min.css">
<!--Let browser know website is optimized for mobile-->
<meta name="viewport" content="width=device-width, initial-scale=1.0"/
</head>
<body>
<ul id="slide-out" class="sidenav">
<li><div class="user-view">
<div class="background">
<img src="images/office.jpg">
</div>
<img class="circle" src="images/yuna.jpg">
<span class="white-text name">John Doe</span>
<span class="white-text email">jdandturk#gmail.com</span>
</div></li>
<li><i class="material-icons">cloud</i>First Link With Icon</li>
<li>Second Link</li>
<li><div class="divider"></div></li>
<li><a class="subheader">Subheader</a></li>
<li><a class="waves-effect" href="#!">Third Link With Waves</a></li>
</ul>
<i class="material-icons">menu</i>
<!-- Compiled and minified JavaScript -->
</body>
On the materialize website, this code is given to initialize Sidenav bar
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('.sidenav');
var instances = M.Sidenav.init(elems, options);
});
but You modify This code and remove option in var instance and now code look like and you should paste this code in your script tag or your javascript file
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('.sidenav');
var instances = M.Sidenav.init(elems);
});
Now I explain what is the problem in upper code that given on the materialize website
in code, variable instances give 2 arguments 1st argument is elems and 2nd argument is the option that is not defined in your code so you remove the option argument in this code to solve this problem
Initialization is the most important thing when using materialize.js, for example i want to initialize a carousel.
// Javascript
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('.carousel');
var instances = M.Carousel.init(elems, options);
});
// Or with jQuery
$(document).ready(function(){
$('.carousel').carousel();
});
I am using this as a template for JS which selects proper nav using JQuery, with this API reference.
My current code:
index.php
<html>
<head>
<title>ChillSpot Alpha 1.2.3</title>
<link rel="stylesheet" type="text/css" href="common/style.css">
<script type="text/javascript" src="common/jquery-1.11.2.min.js"></script>
<script type="text/javascript" src="background.js"></script>
<script type="text/javascript" src="common/navHighlight.js"></script>
<script type="text/javascript"> $( document ).ready( getImage );</script>
<script type="text/javascript"> $( document ).ready( setNavigation );</script>
</head>
<?php
include 'common/header.html';
?>
//More code, snipped from example: not relevant
common/navHighlight.js
<!--
function setNavigation() {
var path = window.location.pathname;
path = path.replace(/\/$/, "");
path = decodeURIComponent(path);
$(".menuList a").each(function () {
var href = $(this).attr('href');
if (path.substring(0, href.length) === href) {
$(this).closest('li').removeClass('tab');
$(this).closest('li').addClass('tab selected');
}
});
}
//-->
common/header.html
<div class="menu">
<ul class = "menuList">
<li class="tab">Home</li>
<li class="tab">Communications</li>
<li class="tab">ChillCraft</li>
<li class="tab">Forum</li>
<li class="tab">Updates</li>
<li class="tab">About</li>
</ul>
</div>
<div class="content">
... this isnt working. What is different in my situation that causes the example to fail? All "li" elements end up with class "tab", none have "tab selected".
I'm not sure if this is actually what's wrong, but I do notice that the href's in their example all start with / while yours do not. Relative pathing could be why yours isn't working.
So if you change your html to this you might be fine:
<div class="menu">
<ul class = "menuList">
<li class="tab">Home</li>
<li class="tab">Communications</li>
<li class="tab">ChillCraft</li>
<li class="tab">Forum</li>
<li class="tab">Updates</li>
<li class="tab">About</li>
</ul>
</div>
My approach on these cases is as follows:
Add a unique id to each of your tabs (in addition to the class you already have)
On each specific file (index.php, common.php, forum.php, etc) create an object with your selected tab:
var selected = $('#forumTab');
Execute a function where you ensure to be removing the active class from all tabs and add it only to your current tab:
$('.tab').removeClass('active');
selected.addClass('active');
I have added a textillate effect to text on a second jquery mobile page. When I click on the page 2 button in the navbar, the animation works correctly when page 2 is displayed. When I click on the page 1 button in the navbar followed by clicking on page 2 button, the text is displayed without animation. I presume there is javascript code to re-initialize the effect but I am at a loss what it is.
<!DOCTYPE html>
<html>
<head>
<title>put title here</title>
<meta name="viewport" content="width=device-width"/>
<link rel="stylesheet" href="jquery.mobile-1.4.3.min.css" />
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery.mobile-1.4.3.min.js"></script>
<script type="text/javascript" src="jquery.lettering.js"></script>
<script type="text/javascript" src="jquery.textillate.js"></script>
<link rel="stylesheet" href="animate.min.css"/>
</head>
<body bgcolor="#ffffff">
<!-- Start of page-->
<div data-role="page" id="page1">
<div data-role="navbar" id="nbar3" data-iconpos="left">
<ul>
<li>Page 1</li>
<li>Page 2</li>
</ul>
</div> <!-- end of navbar -->
</div><!-- end of page -->
<!-- Start of page-->
<div data-role="page" id="page2">
<script type="text/javascript">
$('#page2').on('pagecreate', function() {
$('.anim0').textillate({
});
});
</script>
<div data-role="navbar" id="nbar4" data-iconpos="left">
<ul>
<li>Page 1</li>
<li>Page 2</li>
</ul>
</div> <!-- end of navbar -->
<div class="anim0" data-in-effect="fadeInLeftBig" style="font-family:Arial; font-size:34px; color:#000000; position:absolute; top:37px; left:196px;">hello</div>
</div><!-- end of page -->
</body>
</html>
In Textillate documentation, it is not mentioned if you can reinitialize same text again. However, you can simply destroy it and then reinitialize it.
To destroy it, you need to first save text in a var and then remove Textillate data stored into that target div by using .removeData(). And then replace all animated elements within target div with original text. You can use either pagecontainerbeforehide or pagecontainerhide to do the aforementioned steps.
To reinitialize it, just call .textillate() on pagecontainerbeforeshow or pagecontainershow.
$(document).on('pagecontainerbeforeshow', function (e, data) {
/* initialize */
$('.anim0', data.toPage).textillate();
}).on("pagecontainerhide", function (e, data) {
/* store text */
var text = $(".anim0 ul li", data.prevPage).text();
/* remove data and add original text back */
$(".anim0", data.prevPage).removeData().html(text);
});
Demo
I'm creating a web application which loads tabs using AJAX. My problem is that if I have multiple tabs, jQuery reloads a tab every time I click it again (after visiting another tab).
Here is my code:
index.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Air Office - New file</title>
<!-- jQuery -->
<script type="text/javascript" src="jqueryui/js/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="jqueryui/js/jquery-ui-1.7.2.custom.min.js"></script>
<link rel="stylesheet" href="jqueryui/css/custom-theme/jquery-ui-1.7.2.custom.css" />
<!-- Scripts -->
<script type="text/javascript" src="JS/main.js"></script>
</head>
<body>
<input type="button" onclick="newDoc();" value="New document" />
<div id="mainTabs">
<ul>
</ul>
</div>
</body>
</html>
main.js:
$(document).ready(function()
{
//Create tabs
$("#mainTabs").tabs({load: function()
{
//Make accordion from template selector
$(".selectTemplate").accordion();
}}).find(".ui-tabs-nav").sortable({axis:'x'});
//Create new document tab
newDoc();
});
function newDoc()
{
//Create new tab
$("#mainTabs").tabs('add', 'newdocument.html', 'New Document');
}
newdocument.html:
<div>
<h1>Please select a template</h1>
<div class="selectTemplate">
<h3>Document</h3>
<div>
<ul class="selectTemplateTable">
<li>Blank</li>
<li>Letter</li>
<li>Envelope</li>
<li>Business card</li>
</ul>
</div>
<h3>Spreadsheets</h3>
<div>
<ul class="selectTemplateTable">
<li>Blank</li>
<li>Check list</li>
<li>Budget</li>
</ul>
</div>
<h3>Presentations</h3>
<div>
<ul class="selectTemplateTable">
<li>White</li>
<li>Black</li>
<li>Nature</li>
<li>Space</li>
</ul>
</div>
<h3>Form</h3>
<div>
<ul class="selectTemplateTable">
<li>Survey</li>
<li>Exam</li>
</ul>
</div>
</div>
</div>
How can I fix this?
Thanks,
I found out that I must use cache. I'll answer my own q to help others.
Add cache: true to the tabs() flags:
//Create tabs
$("#mainTabs").tabs({load: function()
{
//Make accordion from template selector
$(".selectTemplate").accordion();
}, cache: true})