I am new to Titanium and trying to find a solution or a good explanation on how to use Titanium API when in a webview. I have included all my code for the necessary parts of this demo.
What I'm trying to do is fire the native camera functionality from win4.html (see below). The documentation is not that great in the api.
I have a pretty basic setup in my app.js:
var tabGroup = Titanium.UI.createTabGroup();
var win1 = Titanium.UI.createWindow({
title: "HTML",
backgroundColor: "#000",
url:"windows/win4.js"
});
var tab1 = Titanium.UI.createTab({
title: "HTML",
icon: "KS_nav_ui.png",
window: win1
});
var win2 = Titanium.UI.createWindow({
title: "Tab 3",
backgroundColor: "#000",
url:"windows/win3.js"
});
var tab2 = Titanium.UI.createTab({
title: "Camera",
icon: "KS_nav_ui.png",
window: win2
});
win4.js (HTML - createWebView setup):
var win = Titanium.UI.currentWindow;
var webview = Titanium.UI.createWebView({url:'win4.html'});
win.add(webview);
Ti.App.addEventListener('showCamera', function() {
tabGroup.activeTab = tab2;
});
win4.html (Pure HTML called by win4.js):
<html>
<head>
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" />
<style type="text/css">
body {
background: #87e0fd;
background: -moz-linear-gradient(top, #87e0fd 0%, #53cbf1 40%, #05abe0 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#87e0fd), color-stop(40%,#53cbf1), color-stop(100%,#05abe0));
background: -webkit-linear-gradient(top, #87e0fd 0%,#53cbf1 40%,#05abe0 100%);
background: -o-linear-gradient(top, #87e0fd 0%,#53cbf1 40%,#05abe0 100%);
background: -ms-linear-gradient(top, #87e0fd 0%,#53cbf1 40%,#05abe0 100%);
background: linear-gradient(top, #87e0fd 0%,#53cbf1 40%,#05abe0 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#87e0fd', endColorstr='#05abe0',GradientType=0 );
}
p {
text-shadow: 1px 1px 1px rgba(255,255,255,.5);
}
.container {
margin: 0 auto;
overflow: hidden;
width: 90%;
}
.left {
float: left;
}
.right {
float: right;
}
</style>
<script type="text/javascript">
function Init() {
var left = document.getElementById("left");
left.addEventListener('click', function(e) {
Ti.App.fireEvent('showCamera');
});
}
</script>
</head>
<body onload="Init()">
<div class"container">
<div id="left" class="left">
<p>
left content here
</p>
</div>
<div class="right">
<p>
right content here
</p>
</div>
</div>
</body>
</html>
win3.js (Native Camera Call):
Titanium.Media.showCamera({
success:function(event)
{
var cropRect = event.cropRect;
var image = event.media;
Titanium.Media.saveToPhotoGallery(image);
Titanium.UI.createAlertDialog({title:'Photo Gallery',message:'Check your photo gallery'}).show();
},
cancel:function()
{
},
error:function(error)
{
// create alert
var a = Titanium.UI.createAlertDialog({title:'Camera'});
// set message
if (error.code == Titanium.Media.NO_CAMERA)
{
a.setMessage('Device does not have video recording capabilities');
}
else
{
a.setMessage('Unexpected error: ' + error.code);
}
// show alert
a.show();
},
allowEditing:true
});
How can I make a click event on the #left trigger the native camera within my app?
You've defined your windows with a url to your JavaScript file, which creates a new JavaScript context for each window. Therefore, tab2 is not defined in win4's context, so when you try to switch the tab, it won't work.
Rather than placing your app listener in win4, put it in app.js. Ti.App events are global, and app.js is the only JavaScript context that knows about all the variables you want to access.
Related
I´m rendering my chat using this:
<!DOCTYPE html>
<html>
<head>
<style>
html, body {
height: 100%;
}
body {
margin: 0;
}
.main {
margin: 18px;
border-radius: 4px;
}
div[role="form"] {
background-color: black;
}
div[role="log"] {
background: gainsboro;
}
div[role="status"] {
background: darkgray;
}
#webchat {
position: fixed;
height: calc(100% - 135px);
z-index: 9999;
width: 400px;
top: 132px;
overflow: hidden;
border-color: red;
border-style: dotted;
visibility:visible;
}
</style>
</head>
<body>
<div>
<div id="heading">
<div id="heading">
<h1><img src="mylogo.png"> mychat</h1>
</div>
</div>
<div id="webchat" role="main"></div>
</div>
<script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
<script>
openchat();
function openchat() {
const styleOptions = {
userID: 'YOUR_USER_ID',
username: 'Web Chat User',
botAvatarInitials: '',
userAvatarInitials: 'You',
bubbleBackground: 'rgba(0, 255, 50, .4)',
bubbleFromUserBackground: 'rgba(125, 125, 125, .3)',
botAvatarImage: 'mylogo.png'
};
window.WebChat.renderWebChat(
{
directLine: window.WebChat.createDirectLine({
token: '*'
}),
styleOptions
},
document.getElementById('webchat')
);
}
</script>
</body>
</html>
It works fine, but now I need to publish this chat in the webpage of the company, as a popup or something like that, so using the previous script is OK but I have not options to add a title to the popup and also I need to add a minimize button. How I can set title and minimize button to my webchat inside a main page?
Tx,
I think your best bet going forward is to use the samples provided by the webchat team.
The minimizable webchat sample is a good example.
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.
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));
}
This is a newbie question about Kendo UI draggable. I tried to look at their examples but cant really get it.
I want to make a div draggable to another position. When setting this up I can drag the div, but it disappears when released, I want it to stay in the new place. I have tried this but it doesnt work.
$('.draggable').kendoDraggable({
axis: "x",
hint: Hint,
dragstart: DragStart,
drag: Drag,
dragend: DragEnd
});
function Hint (element) {
console.log("hint");
return element;
}
function DragStart(){
console.log("dragstart");
}
function Drag(){
console.log("draging");
}
function DragEnd(event) {
console.log("dragend");
console.log(event.x.location);
$('.draggable').css({'left': event.x.location});
}
I think this is what you want, and I made a Demo for it.
$('.draggable').kendoDraggable({
hint : function (original) {
return original.clone().addClass("ob-clone");
},
dragstart: function (e) {
$(e.target).addClass("ob-hide");
}
});
$('body').kendoDropTarget({
drop: function (e) {
var pos = $(".ob-clone").offset();
$(e.draggable.currentTarget)
.removeClass("ob-hide")
.offset(pos);
}
})
.draggable {
position: absolute;
background: red;
width: 100px;
height: 100px;
vertical-align: middle;
}
.ob-hide {
display: none;
}
.ob-clone {
background: #cccccc;
}
<link href="http://cdn.kendostatic.com/2013.1.319/styles/kendo.common.min.css" rel="stylesheet"/>
<link href="http://cdn.kendostatic.com/2013.1.319/styles/kendo.default.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdn.kendostatic.com/2013.1.319/js/kendo.all.min.js"></script>
<div id="drop" style="position: absolute; width: 100%; height: 100%; border: 2px solid #000000">
<div class="draggable">
Drag 1
</div>
<div class="draggable">
Drag 2
</div>
</div>
jsFiddle: http://jsfiddle.net/Wayou/fjrcw/