I am attempting to use the Kendo UI MVVM framework with the Kendo UI drag and drop mechanic; But I am having a very difficult time finding out how to get the data dropped out of the draggable object.
My code is something like this ...
var viewModel = kendo.observable {
Cart : [],
Items : [
{
Id : "item/10",
Name: "CD ROM"
},
{
Id : "item/11",
Name: "DVD ROM"
}
};
So then I have a rough template binding...
<script id="products-template" type="text/x-kendo-template">
<li class="draggable">
<div data-bind="text: Name"></div>
</li>
</script>
Then this gets called up in a list...
<div id="shopping-items-available">
<ul data-template="products-template" data-bind="source: Items">
</ul>
</div>
Then there is a standard "drop target" (taken from the kendo docs)
<div id="droptarget">Start dragging.</div>
with the following CSS
#droptarget {
border: 1px solid #959595;
height: 198px;
width: 300px;
font-size: 36px;
border-radius: 37px;
text-align: center;
line-height: 198px;
color: #a1a1a1;
text-shadow: 0 1px 1px #fff;
margin: 0 0 30px 220px;
cursor: default;
background: #dddddd;
background: -moz-linear-gradient(top, #dddddd 0%, #c1c1c1 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#dddddd), color-stop(100%,#c1c1c1));
background: -webkit-linear-gradient(top, #dddddd 0%,#c1c1c1 100%);
background: -o-linear-gradient(top, #dddddd 0%,#c1c1c1 100%);
background: -ms-linear-gradient(top, #dddddd 0%,#c1c1c1 100%);
background: linear-gradient(top, #dddddd 0%,#c1c1c1 100%);
}
Now in the javascript, I turn the shopping-items-available div into a draggable.
$("body").kendoDraggable({
hint: function (target) {
return $(target).clone().addClass("draggable");
},
filter: ".draggable"
});
and lastly, I initialize the drop target.
$("#droptarget").kendoDropTarget({
drop: droptargetOnDrop
});
but in my code, I cannot seem to get the actual data about the item that was dropped.
function droptargetOnDrop(e) {
console.log(e);
$("#droptarget").text("You did great!");
$(".draggable").removeClass("hollow");
}
The data of the item being dropped is received by droptargetOnDrop as e.draggable.currentTarget.
If you want to move the item to the target area, you should do something like:
$("#droptarget").append(e.draggable.currentTarget);
NOTE Doing this, you will be moving the item. If you want to append a copy, you should append a clone of the node:
$("#droptarget").append($(e.draggable.currentTarget).clone());
EDIT: For getting the data item without using a kendoDataSource I propose to change the template to:
<script id="products-template" type="text/x-kendo-template">
<li class="draggable" data-id="${Id}">
<div data-bind="text: Name"></div>
</li>
</script>
This saves the Id (or any information that allows you to find the element latter) in the DOM being dragged. Then in the handler we retrieve the Id and search the item corresponding to that Id.
function droptargetOnDrop(e) {
var dom = e.draggable.currentTarget;
var id = $(dom).data("id");
var items = viewModel.Items;
for (var i = 0; i < items.length; i++) {
if (items[i].Id == id) {
alert("Found : " + JSON.stringify(items[i]));
break;
}
}
}
EDIT If you decide to use kendoListView you should define your template as:
<script id="products-template" type="text/x-kendo-template">
<li class="draggable">
<div>${Name}</div>
</li>
</script>
The HTML container for the list would be:
Then initialize the ListView as:
var list = $("#shopping-items-available > ul").kendoListView({
template : $("#products-template").html(),
dataSource: viewModel.Items
}).data("kendoListView");
and finally the droptargetOnDrop function:
function droptargetOnDrop(e) {
var dom = e.draggable.currentTarget;
var item = list.dataSource.getByUid(dom.data("uid"));
alert("Found : " + JSON.stringify(item));
}
Related
I have a modal image that when clicked, will open full-screen with the text displayed from the alt tag in the image. I grabbed the code off another site so need to change it to add a download link within the modal so when the link is clicked it will download a file. Is this possible in the below code?
Code below:
<img id="myImg1" src="test.png" alt="Hello" width="95" height="146">
<!-- The Modal -->
<script
<div id="myModal1" class="modal">
<span class="close">x</span>
<img class="modal-content" id="img01">
<div id="caption">
<div id="caption1"></div>
</div>
</div>
<script>
// Get the modal
var modal = document.getElementById('myModal1');
// Get the image and insert it inside the modal - use its "alt" text as a caption
var img = document.getElementById('myImg1');
var modalImg = document.getElementById("img01");
var captionText = document.getElementById("caption1");
img.onclick = function(){
modal.style.display = "block";
modalImg.src = this.src;
captionText.innerHTML = this.alt;
}
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.display = "none";
}
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
</script>
Any assistance would be much appreciated.
[![<!DOCTYPE html>
<html>
<head>
<style>
#myImg {
border-radius: 5px;
cursor: pointer;
transition: 0.3s;
}
#myImg:hover {opacity: 0.7;}
/* The Modal (background) */
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
padding-top: 100px; /* Location of the box */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.9); /* Black w/ opacity */
}
/* Modal Content (image) */
.modal-content {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
}
/* Caption of Modal Image */
#caption {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
text-align: center;
color: #ccc;
padding: 10px 0;
height: 150px;
}
/* Add Animation */
.modal-content, #caption {
-webkit-animation-name: zoom;
-webkit-animation-duration: 0.6s;
animation-name: zoom;
animation-duration: 0.6s;
}
#-webkit-keyframes zoom {
from {-webkit-transform:scale(0)}
to {-webkit-transform:scale(1)}
}
#keyframes zoom {
from {transform:scale(0)}
to {transform:scale(1)}
}
/* The Close Button */
.close {
position: absolute;
top: 15px;
right: 35px;
color: #f1f1f1;
font-size: 40px;
font-weight: bold;
transition: 0.3s;
}
.close:hover,
.close:focus {
color: #bbb;
text-decoration: none;
cursor: pointer;
}
/* 100% Image Width on Smaller Screens */
#media only screen and (max-width: 700px){
.modal-content {
width: 100%;
}
}
</style>
</head>
<body>
<h2>Image Modal</h2>
<p>In this example, we use CSS to create a modal (dialog box) that is hidden by default.</p>
<p>We use JavaScript to trigger the modal and to display the current image inside the modal when it is clicked on. Also note that we use the value from the image's "alt" attribute as an image caption text inside the modal.</p>
<img id="myImg" src="img_fjords.jpg" alt="Trolltunga, Norway" width="300" height="200">
<!-- The Modal -->
<div id="myModal" class="modal">
Download
<span class="close">×</span>
<img class="modal-content" id="img01">
<div id="caption"></div>
</div>
<script>
// Get the modal
var modal = document.getElementById('myModal');
// Get the image and insert it inside the modal - use its "alt" text as a caption
var img = document.getElementById('myImg');
var modalImg = document.getElementById("img01");
var captionText = document.getElementById("caption");
img.onclick = function(){
modal.style.display = "block";
modalImg.src = this.src;
captionText.innerHTML = this.alt;
}
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")\[0\];
// When the user clicks on <span> (x), close the modal
span.onclick = function() {
modal.style.display = "none";
}
</script>
</body>
</html>
I want my app to have no title bar but still be closeable, draggable, minimizable, maximizable, and resizable like a regular window. I can do this in OS X since there is a [titleBarStyle] 1 option called hidden-inset that I can use but unfortunately, it's not available for Windows, which is the platform that I'm developing for. How would I go about doing something like this in Windows?
Above is an example of what I'm talking about.
Assuming you don't want window chrome, you can accomplish this by removing the frame around Electron and filling the rest in with html/css/js. I wrote an article that achieves what you are looking for on my blog here: http://mylifeforthecode.github.io/making-the-electron-shell-as-pretty-as-the-visual-studio-shell/. Code to get you started is also hosted here: https://github.com/srakowski/ElectronLikeVS
To summarize, you need to pass frame: false when you create the BrowserWindow:
mainWindow = new BrowserWindow({width: 800, height: 600, frame: false});
Then create and add control buttons for your title bar:
<div id="title-bar">
<div id="title">My Life For The Code</div>
<div id="title-bar-btns">
<button id="min-btn">-</button>
<button id="max-btn">+</button>
<button id="close-btn">x</button>
</div>
</div>
Bind in the max/min/close functions in js:
(function () {
var remote = require('remote');
var BrowserWindow = remote.require('browser-window');
function init() {
document.getElementById("min-btn").addEventListener("click", function (e) {
var window = BrowserWindow.getFocusedWindow();
window.minimize();
});
document.getElementById("max-btn").addEventListener("click", function (e) {
var window = BrowserWindow.getFocusedWindow();
window.maximize();
});
document.getElementById("close-btn").addEventListener("click", function (e) {
var window = BrowserWindow.getFocusedWindow();
window.close();
});
};
document.onreadystatechange = function () {
if (document.readyState == "complete") {
init();
}
};
})();
Styling the window can be tricky, but the key use to use special properties from webkit. Here is some minimal CSS:
body {
padding: 0px;
margin: 0px;
}
#title-bar {
-webkit-app-region: drag;
height: 24px;
background-color: darkviolet;
padding: none;
margin: 0px;
}
#title {
position: fixed;
top: 0px;
left: 6px;
}
#title-bar-btns {
-webkit-app-region: no-drag;
position: fixed;
top: 0px;
right: 6px;
}
Note that these are important:
-webkit-app-region: drag;
-webkit-app-region: no-drag;
-webkit-app-region: drag on your 'title bar' region will make it so that you can drag it around as is common with windows. The no-drag is applied to the buttons so that they do not cause dragging.
I was inspired by Shawn's article and apps like Hyper Terminal to figure out how to exactly replicate the Windows 10 style look as a seamless title bar, and wrote this tutorial (please note: as of 2022 this tutorial is somewhat outdated in terms of Electron).
It includes a fix for the resizing issue Shawn mentioned, and also switches between the maximise and restore buttons, even when e.g. the window is maximised by dragging the it to the top of the screen.
Quick reference
Title bar height: 32px
Title bar title font-size: 12px
Window control buttons: 46px wide, 32px high
Window control button assets from font Segoe MDL2 Assets (docs here), size: 10px
Minimise:
Maximise:
Restore:
Close:
Window control button colours: varies between UWP apps, but seems to be
Dark mode apps (white window controls): #FFF
Light mode apps (black window controls): #171717
Close button colours
Hover (:hover): background #E81123, colour #FFF
Pressed (:active): background #F1707A, colour #000 or #171717
Note: in the tutorial I have switched to PNG icons with different sizes for pixel-perfect scaling, but I leave the Segoe MDL2 Assets font characters above as an alternative
I use this in my apps:
const { remote } = require("electron");
var win = remote.BrowserWindow.getFocusedWindow();
var title = document.querySelector("title").innerHTML;
document.querySelector("#titleshown").innerHTML = title;
var minimize = document.querySelector("#minimize");
var maximize = document.querySelector("#maximize");
var quit = document.querySelector("#quit");
minimize.addEventListener("click", () => {
win.minimize();
});
maximize.addEventListener("click", () => {
win.setFullScreen(!win.isFullScreen());
});
quit.addEventListener("click", () => {
win.close();
});
nav {
display: block;
width: 100%;
height: 30px;
background-color: #333333;
-webkit-app-region: drag;
-webkit-user-select: none;
position: fixed;
z-index: 1;
}
nav #titleshown {
width: 30%;
height: 100%;
line-height: 30px;
color: #f7f7f7;
float: left;
padding: 0 0 0 1em;
}
nav #buttons {
float: right;
width: 150px;
height: 100%;
line-height: 30px;
background-color: #222222;
-webkit-app-region: no-drag;
}
nav #buttons #minimize,
nav #buttons #maximize,
nav #buttons #quit {
float: left;
height: 100%;
width: 33%;
text-align: center;
color: #f7f7f7;
cursor: default;
}
nav #buttons #minimize:hover {
background-color: #333333aa;
}
nav #buttons #maximize:hover {
background-color: #333333aa;
}
nav #buttons #quit:hover {
background-color: #ff0000dd;
}
main {
padding-top: 30px;
overflow: auto;
height: calc(100vh - 30px);
position: absolute;
top: 30px;
left: 0;
padding: 0;
width: 100%;
}
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<nav>
<div id="titleshown"></div>
<div id="buttons">
<div id="minimize"><span>‐</span></div>
<div id="maximize"><span>□</span></div>
<div id="quit"><span>×</span></div>
</div>
</nav>
<main>
<div class="container">
<h1>Hello World!</h1>
</div>
</main>
</body>
</html>
Ran into this problem and my solution was to keep the frame but set the title to blank i.e.
document.querySelector("title").innerHTML ="";
That solved my problem i.e. I got a window which can be closed, maximized or minimized without a title on it.
After learning JS for about a month now and completing around 4 courses I am still unable to work out how to change an image when clicking a thumbnail! What I want to do is simple, I just want to change the Main Image when a thumbnail is clicked! In this example there are two thumbnail images in a div and a main image above them. I just want to change the main image when a thumbnail is clicked. I know this is DOM Manipulation and think it is: document.getElementById.....?
I have make a small page so that I can learn / try different things and and finally giving up and asking for help! The code is as follows:
#MainContainer {
position: relative;
margin:0px auto;
width: 500px;
height: 400px;
border: 1px solid black;
}
#MainImage {
position: absolute;
top: 10px;
left: 50px;
width: 398px;
height: 265px;
background: url(MainImage01.jpg);
border: 1px solid black;
}
#TNBodyContainer {
position: absolute;
top: 290px;
left: 100px;
border: 1px solid black;
width: 268px;
height: 88px;
}
#TNOne {
position: relative;
width: 133px;
height: 88px;
background: url(SmallImage01.jpg);
}
#TNTwo {
position: relative;
left:135px;
width: 133px;
height: 88px;
background: url(SmallImage02.jpg);
}
<body>
<div id="MainContainer">
<div id="MainImage"></div>
<div id="TNBodyContainer">
<div id="TNOne">
<div id="TNTwo"></div>
</div>
</div>
Thank you very much for any help.
Margate
You need to add some scripting to change the image when either of the thumbnails are clicked. This function is called when the page is loaded. Change the image names to suit.
This should be placed in the section of the html page.
<script>
window.onload = function() {
var mainImg = document.getElementById('Main');
document.getElementById('TNOne').onclick = function() {
mainImg.src = 'main1.jpg';
//alert('one clicked');
};
document.getElementById('TNTwo').onclick = function() {
mainImg.src = 'main2.jpg';
//alert('two clicked');
};
};
</script>
The two thumbnail divs become <img> tags with the same IDs.
Similarly the main <img> is defined also (with id="Main"). Now the elements
are clickable.
<div id="MainContainer">
<div id="MainImage">
<img id="Main" src="MainImage01.jpg"</img>
</div>
<div id="TNBodyContainer">
<img id="TNOne" src="thumb1.jpg"></img>
<img id="TNTwo" src="thumb2.jpg"></img>
</div>
</div>
Finally CSS for the thumbnails, here float is used to keep the thumbnails in the same line within the TNBodyContainer div.
TNOne {
width: 133px;
height: 88px;
float:left;
}
#TNTwo {
width: 133px;
height: 88px;
float:left;
}
To change the image in the CSS background property, you need to use
document.getElementById("MainImage").style.background
The right way to go is to add event listeners:
document.getElementById("TNOne").addEventListener("click", function (event) {
setImage(event);
}, false);
document.getElementById("TNTwo").addEventListener("click", function (event) {
setImage(event);
}, false);
}
They both call the same function, but with event it is possible to see which one "clicked" with "event.target.id".
You can then decide what you want to do with for instance a switch statement. basically saying: if event.target.id == "TNOne".
You can see all this I made you a fiddle: http://jsfiddle.net/djwave28/32pQD/3/
There are some slight changes in your HTML and CSS too.
In my kendo mobile app I have some listviews that require more than one action. I need something like what is show in the Link Items & Detail Buttons demo but more flexible. In my case, I need to cover the following scenarios (all sections clickable):
[icon][text of the item]
[text of the item][icon]
[icon][text of the item][icon]
...where [icon] is some font icon.
I've started on a solution but before I go any further, I want some feedback to make sure I am not overlooking a better approach or something already built into Kendo.
Each "part" of the <LI> needs to perform a distinct action when clicked. To handle this, I have a click binding on the <UL>. I also have a data-command-name attribute on each element in the <LI> template so that I know what the user tapped/clicked.
I have put together a fiddle but jsFiddle is reformatting the HTML part when it loads (I think because of the template script tags). Once you load the fiddle please replace the HTML with the following to get it working:
HTML
<div id="itemsView" data-role="view" data-model="vm">
The red, silver and blue sections along with the X & Y are not part of the design, they are there just to make my intent more obvious.
<ul data-role="listview" data-bind="source: items, click: clickHandler"
data-template="itemsTemplate"></ul>
<script id="itemsTemplate" type="text/x-kendo-template">
<div class = "left-column" data-command-name="left (red)" > X </div>
<div class="right-column" data-command-name="right (blue)">Y</div >
<div class = "content-column" data-command-name="content (silver)"> #=Name# </div>
</script>
</div>
CSS
div.left-column {
float: left;
width: 25px;
margin-top: -5px;
padding-top: 5px;
margin-left: -5px;
padding-left: 5px;
cursor: default;
background-color: red;
}
.content-column {
margin-top: -5px;
margin-left: 25px;
margin-bottom: 0;
margin-right: 25px;
padding-top: 5px;
cursor: default;
background-color: silver;
}
.right-column {
float: right;
width: 25px;
margin-top: -5px;
padding-top: 5px;
cursor: default;
background-color: blue;
}
JavaScript
var vm = kendo.observable({
items: [{
Selected: false,
Name: "Item1"
}, {
Selected: false,
Name: "Item2"
}, {
Selected: false,
Name: "Item2"
}],
clickHandler: function (e) {
var cmd = e.target.context.attributes["data-command-name"]
if (cmd) {
alert(cmd.value);
}
},
});
kendoApp = new kendo.mobile.Application(document.body, {
transition: "slide",
platform: 'android'
});
Here is the fiddle: http://jsfiddle.net/8Kydw/
So to summarize my questions:
1) Is there a better/built-in way of doing this?
2) If not, any tips on the CSS? For instance, why in Android is the height of the list items smaller than prior to my customization?
1) I think the strategy that you are using is completely fine and acceptable for Kendo UI Mobile.
2) Kendo UI Mobile applies some pretty specific styling in the way of line-height and a few other items that will affect how the list item is displayed if you then customize margin or padding with your own CSS. I wouldn't worry too much about it though.
I am implementing a scrollable for a portfolio gallery.
(scrollable = scrollable plugin from http://flowplayer.org/tools/index.html )
There will be one item visible at a time.
By default, scrollable positions the prev/next buttons outside of the image area and clicking on the current image advances the scrollable content.
I would like to have the prev/next render within the image area.
I would like to have an image caption appear when mousing over the lower part of the image.
Mock-up:
http://i303.photobucket.com/albums/nn160/upstagephoto/mockups/scrollable_mockup.jpg
Any ideas on how to achieve one or both of these?
Thank you!
The main part of your approach will be like this in your html:
<div id="mainContainer">
<div class="scrollable">
<div class="items">
<div class="scrollableEl">
<img src="yourimage.jpg" />
<div class="caption">Your caption</div>
</div>
<div class="scrollableEl">
<img src="yourimage2.jpg" />
<div class="caption">Your caption 2</div>
</div>
... so on ...
</div>
</div>
«
«
</div>
And like so in your CSS:
.scrollable {
position:relative;
overflow:hidden;
width: 660px;
height:90px;
}
.scrollable .items {
width:20000em;
position:absolute;
}
.items .scrollableEl {
float:left;
positon: relative;
}
.items .scrollableEl .caption {
display:none;
position: absolute;
bottom: 0;
height: 100px;
width: 660px;
}
.items .scrollableEl:hover .caption { /*this will show your caption on mouse over */
display:none;
}
.next, .prev {
position: absolute;
top: 0;
display: block;
width: 30px;
height: 100%;
}
.next {
right: 0;
}
.prev {
left: 0;
}
#mainContainer {
position: relative;
}
The javascript should be fairly standard. Hope this helps!
DEMO: http://jsbin.com/ijede/2 SOURCE: http://jsbin.com/ijede/2/edit
$(function() {
// 5 minute slide show ;-)
$('.next,.prev').click(function(e) {
e.preventDefault();
var pos = parseInt($('.current').attr('id').split('_')[1]);
var tot = $('.slides a').size() - 1;
var click = this.className;
var new_pos = (click == 'next') ? pos + 1: pos - 1;
var slide = ( click == 'next') ?
(pos < tot ? true : false) : (pos > 0 ? true : false);
if (slide) $('.current').toggle(500,function() {
$(this).removeClass('current');
});
$('#pos_' + new_pos).toggle(500,function() {
$(this).attr('class', 'current');
});
});
//cross-browser div :hover
$('.next,.prev').hover(function() {
$(this).children().children().fadeIn(500);
},function() {
$(this).children().children().fadeOut(500);
});
//auto add unique id to each image
$('.slides a').each(function(e) {
$(this).attr('id', 'pos_' + e);
if (!e) $(this).attr('class', 'current');
});
});
CSS on source!
NOTE: since read the plugin doc require more time for me than make a slideshow from scratch, i have maked a fresh one!
hope you like it!