JS Tree Context Menu Plugin - javascript

Initially my JS Tree is
<div id="jstree">
<ul>
<li>Name=
<ul>
<li>Deepanshu</li>
</ul>
</li>
</ul>
</div>
If I edit the name field from Deepanshu to some numeric value, on clicking a submit button, a rest api call happens (which essentially returns the same html back with a pop up saying invalid value). In the html that is returned by the rest call, the js tree is the same as it was before hitting the rest call. Now, if I right click on the node Name or the node Deepanshu either to Edit, Delete, Create new node, etc. the context menu doesn’t appear.
Javascript which I am using is
<script>
$(function () {
$('#jstree').jstree({
"core" : {
"check_callback" : true
},
"plugins" : [
"state", "types", "contextmenu"
]
});
$('#jstree').on('changed_jstree', function (e, data) {
console.log(data.selected);
});
});
</script>
It would be great if someone can help me out with this.

Check your html filed.. An example usage for html filed
<div id="plugins2" class="demo plugin-demo">
<ul>
<li data-jstree='{"opened":true}'>Root node
<ul>
<li>Context click me</li>
</ul>
</li>
</ul>
After, create your JSTree
<script>
$(function () {
$("#plugins2")
.jstree({
"core" : {
'force_text' : true,
"check_callback" : true
},
"plugins" : [ "contextmenu" ]
});
});
</script>
Keep in mind; when you use JSTree be careful for id fields

Related

Is it possible to add a certain javascript to a new html page in framework7?

I'm new to framework7 and i'm creating a new page in my framework7 app. I want to be able to add a certain javascript code like this <script type="text/javascript" src="sample.js"></script> into a new page html file using framework7 . For example this is my new page which consists of just a "try" button.
<template>
<div class="page">
<div class="navbar">
<div class="navbar-inner">
<div class="title">{{title}}</div>
</div>
</div>
<div class="page-content">
<button class="sample">try</button>
</div>
</div>
</template>
<script type="text/javascript" src="Exp.js"></script>
So in the new page as you can see I've added <script type="text/javascript" src="Exp.js"></script> which is a javascript file named Exp.js which looks like this
\\ "try" button event listener
document.querySelector('.sample').addEventListener("click", function () {
alert(works);
});
So what it does is Whenever i click the "try" button in the page , it should alert "works", but this does not work.
Is there any way that i can add javascript files like this? or is not possible in framework7 to add javascript files like that? please do help me with an answer
And this is my framework7 app initialize js file.
var myApp = new Framework7({
// App root element
root: '#app',
// App Name
name: 'My App',
// App id
id: 'com.myapp.test',
// Enable swipe panel
panel: {
swipe: 'left',
},
// Add default routes
routes: [
{
path: '/about/',
url: 'about.html',
},
{
path: '/Expenses/',
componentUrl: 'Expenses.html',
},
],
// ... other parameters
});
// Add view
var mainView = myApp.views.create('.view-main', {
// Because we want to use dynamic navbar, we need to enable it for this view:
stackPages: true,
});
Ok, your question is now clearer. See the component page below for the Expense.html file. This is the "more official" way of doing things in Framework7. It may be a little new, depending on what your javascript background is. You have a component file that has the html template, javascript functions and data.
The script part is where you define data and methods to be used in your component page. I have created a function called alertWorks which basically does what you were trying to do. Then I have called that function using the "#click" notation on the button. This is how I have added my event handler to the click event of the button. I have also gone a little step further to create some data for the title variable that you used at the top of the page. This is just basic bare bones, but should help to introduce you to F7.
<template>
<div class="page">
<div class="navbar">
<div class="navbar-inner">
<div class="title">{{title}}</div>
</div>
</div>
<div class="page-content">
<button class="sample" #click="alertWorks">try 1</button>
</div>
</div>
</template>
<script>
return {
data: function () {
return {title: "Button Page"};
},
methods: {
alertWorks(e) {
alert('works');
},
}
}
</script>
And then your router would look something like this
routes: [
{
path: '/about/',
url: 'about.html',
},
{
path: '/Expenses/',
componentUrl: 'Expenses.html',
},
],
See the docs explanation here.

Vue.js #click not execute function when a:href link is exist

I'm trying to create notfication, when the notification clicked and linked to his path will decrease the notification length.
<li class="header">You have {{ notificationsCount()}} notif</li> <li>
<ul class="menu">
<li v-for="(notification, index) in notif" :notification="notification" :key="notification.id">
<a :href="notification.data.path"
#click="markAsRead(notification.id)"
#mouseup.right="markAsRead(notification.id)"
class="text-aqua">{{ notification.data.message }}
</a>
</li>
</ul>
methods: {
notificationsCount() {
return this.notif.length
},
markAsRead(index, id) {
if (this.notif.length){
axios.delete(`/notifications/${id}`)
.then(() => {
this.notif.splice(index, 1);
this.notificationsCount();
});
}
}
}
The problem is when a :href link is exist, notificationcount not decrease, but when a :href filled with(#) or i used #click.prevent its work to execute the function and notificationcount decreased. how to solve it?
inside tag i have two trigger #click & #mouseup.right for handle when open new tab. and when i click right its work well and notification decreased because execute through #mouseup.right but when execute through #click its not work. i have to reload once again for decrease notification count
This works as expected. You can see the counter change before it leaves. When you leave the page, the program is erased. When you come back to the page, it is restarted. If you want data values to persist, you will need to use some kind of persistent storage like localStorage or a database. You have axios, but I can't use that in my example here.
Following a link to another page is going to unload the current page, so you don't have much chance to see the change happen. Also, you're not correctly finding the item to splice out.
new Vue({
el: '#app',
data: {
notif: [{
id: 1,
data: {
path: 'http://www.google.com',
message: 'Go to google'
}
}]
},
computed: {
notificationsCount() {
return this.notif.length;
}
},
methods: {
markAsRead(item) {
const index = this.notif.indexOf(item);
this.notif.splice(index, 1);
}
}
});
<script src="https://unpkg.com/vue#latest/dist/vue.js"></script>
<div id="app">
Count: {{notificationsCount}}
<ul class="menu">
<li v-for="(notification, index) in notif" :key="notification.id">
<a :href="notification.data.path" #click="markAsRead" class="text-aqua">{{ notification.data.message }}
</a>
</li>
</ul>
</div>
Your problem is the axios request is not finish yet and page is already redirected to the path. You can refactor the redirect function after axios request is finish.
...
<a
#click="markAsRead(notification)"
#mouseup.right="markAsRead(notification)"
class="text-aqua">{{ notification.data.message }}
</a>
...
markAsRead(index, notification) {
if (this.notif.length){
axios.delete(`/notifications/${id}`)
.then(() => {
this.notif.splice(index, 1);
this.notificationsCount();
window.location = notification.data.path
});
}
}
You don't need bind click and mouseup together, choose either click or mouseup.

AngularJS ui-sref external (absolute) link

I wrote a little angular app. I've got an array of menu items which I print in my template:
<nav id="menu">
<ul>
<li ng-repeat="i in menuItems"
ui-sref="{{ i | removeSpacesThenLowercase }}"
ui-sref-active="active">{{ i }}</li>
</ul>
</nav>
And in my app.js I declared my states using ui-router like:
.state('camera', {
url: '/selection',
templateUrl: '/views/selection.html',
uiShade: 'light back',
back: 'intro'
})
Internal URLs work just fine, but what if I want to do this?
.state('facebook', {
url: 'https://www.facebook.com/'
})
This obviously doesn't work. What would be the best approach to have some external (absolute) links in my template without having two separate arrays?
Ui-sref refers to a state. Your views are states. Externals sites aren't states, it's just some outside links.
I suggest you to refactor your menu generator to handle different type of menu entries :
state based link (link generated through ui-sref)
standard link (link generated through href, for external links, emails, etc)
Then you just have to populate menuItems with an array of different objects
I fixed this in my application using ng-if.
Example menu items:
$scope.navItems = [{
id: 1,
title: 'Internal Link',
href: null,
sref: 'internal-state'
},
{
id: 2,
title: 'External Link',
href: 'https:/google.co.uk',
sref: null
}];
Then in the HTML I set the ng-repeat on the <li> but include an <a> for href and one for sref, each with an ng-if.
<li ng-repeat="item in navItems">
<a ng-if="item.sref" ui-sref="{{item.sref}}">{{ item.title }}</a>
<a ng-if="item.href" href="{{item.href}}">{{ item.title }}</a>
</li>
I fixed this by creating a second array for the external links and an ng-click function.
$scope.elink = function(element) {
if (confirm("You're leaving the app, are you sure?")) {
window.location = element;
}
};

Rivets.js iterating over collection

I was trying to perform iteration binding in Rivets.js as described in the documentation. However it seems that no binding occurs.
The template is defined as follows:
<section id="rivets">
<ul>
<li data-each-todo="list.todos">
<input type="checkbox" data-checked="todo.done">
<span data-text="todo.summary"></span>
</li>
<ul>
</section>
The binding is performed by:
var model = {
list: {
todos: [
{ done: true, summary: "Todo 1" },
{ done: false, summary: "Todo 2" }
]
}
}
rivets.bind(document.getElementById('rivets'), model)
I have created a fiddle for this issue. What am I missing?
My bad - the first paragraph of Rivets.js documentation made me use wrong name of Rivets.js attributes (data- instead of rv-).

KockoutJS External Template Engine and custom binding

I use in my application KockoutJS External Template Engine to be able to load external templates files(so i can use them again in many pages). It's works good and i could use templates in another folder and data displayed correctly
My problem is that i want to call some function after my template is fully rendered and i used this solution with custom bindings (thanks to #RP Niemeyer).
The problem is that custom binding is executed before the template html is fully rendered when using external template file.
But using template which is existed inside my html page the custom binding is executed after the template html is fully rendered.
My template:
<script type="text/html" id="report-template">
<li>
<ul data-bind="template: { name: 'report-template', foreach: childItems }">
</ul>
</li>
</script>
and that's how i call my custom binding jsTree
<div id="reports-tree">
<ul data-bind="template: { name: 'report-template', foreach: $root.ReportsViewModel.Reports }, jsTree: $root.ReportsViewModel.Reports"></ul>
</div>
and that's my custom binding code:
ko.bindingHandlers.jsTree = {
update: function (element, valueAccessor) {
var reports = ko.utils.unwrapObservable(valueAccessor());
if (reports.length > 0) {
$(element).parent().jstree({
"themes": {
"theme": "default",
"dots": false,
"icons": true,
"utl": "/jstree-style.css"
},
"plugins": ["themes", "html_data"]
});
}
}
}
This answer suggests that you can use setTimeout to your advantage: It moves your custom binding to the end of the execution queue.
ko.bindingHandlers.jsTree = {
update: function (element, valueAccessor) {
setTimeout(function () {
var reports = ko.utils.unwrapObservable(valueAccessor());
if (reports.length > 0) {
$(element).parent().jstree({
"themes": {
"theme": "default",
"dots": false,
"icons": true,
"utl": "/jstree-style.css"
},
"plugins": ["themes", "html_data"]
});
}
}, 0);
}
};
I'm not sure how well this works with a recursive binding, though.

Categories

Resources