Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 54 additions & 2 deletions examples/browser/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
<link rel="stylesheet" href="https://cdn.jsdelivr.net/foundation/5.5.3/css/foundation.min.css" />
<!-- Font Awesome icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.0.3/css/font-awesome.css" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/>
<link rel="stylesheet" href="styles.css" />

<!-- defer to not block rendering -->
<script src="https://cdn.jsdelivr.net/npm/@json-editor/json-editor@latest/dist/jsoneditor.min.js"></script>
Expand All @@ -27,8 +32,55 @@
<div id="topbar" class="row">
<div class="medium-12 columns">
<h1>Browsified node-wot</h1>
<input id="td_addr" type="url" value="http://plugfest.thingweb.io:8083/testthing" />
<button id="fetch" type="button">Consume</button>
<!-- Tabs for TD selection -->
<ul class="tabs" data-tab id="td-tabs">
<li class="tab-title active"><a href="#tab-custom" id="tab-link-custom">Custom</a></li>
<li class="tab-title"><a href="#tab-counter" id="tab-link-counter">Counter</a></li>
<li class="tab-title"><a href="#tab-testthing" id="tab-link-testthing">Test Thing</a></li>
<li class="tab-title">
<a href="#tab-smartcoffee" id="tab-link-smartcoffee">Smart Coffee Machine</a>
</li>
</ul>
<div class="tabs-content">
<div class="content active" id="tab-custom">
<div class="row">
<div class="medium-8 columns">
<input
id="td_addr"
type="url"
placeholder="Paste the TD URL to start consuming it"
style="width: 100%"
/>
</div>
<div class="medium-4 columns">
<select id="exampleUrls" class="expanded">
<option value="">Select an example...</option>
<option value="http://plugfest.thingweb.io/counter">Counter</option>
<option value="http://plugfest.thingweb.io/http-advanced-coffee-machine">
Smart Coffee Machine
</option>
<option value="http://plugfest.thingweb.io/http-data-schema-thing">
Test Thing
</option>
</select>
</div>
</div>
<div class="row">
<div class="medium-12 columns" style="margin-top: 10px">
<button id="fetch" type="button" class="button">Consume</button>
</div>
</div>
</div>
<div class="content" id="tab-counter">
<p>Counter TD will be loaded and consumed automatically.</p>
</div>
<div class="content" id="tab-testthing">
<p>Test Thing TD will be loaded and consumed automatically.</p>
</div>
<div class="content" id="tab-smartcoffee">
<p>Smart Coffee Machine TD will be loaded and consumed automatically.</p>
</div>
</div>
</div>
</div>
<div id="interactions" class="row" style="display: none">
Expand Down
131 changes: 117 additions & 14 deletions examples/browser/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,38 @@
**/

function get_td(addr) {
servient.start().then((thingFactory) => {
helpers
.fetch(addr)
.then((td) => {
thingFactory.consume(td).then((thing) => {
removeInteractions();
showInteractions(thing);
// Clear all loaded content before loading new TD
const interactions = document.getElementById("interactions");
if (interactions) {
interactions.style.display = "none";
}

servient
.start()
.then((thingFactory) => {
helpers
.fetch(addr)
.then((td) => {
thingFactory
.consume(td)
.then((thing) => {
removeInteractions();
showInteractions(thing);
})
.catch((err) => {
window.alert("Failed to consume TD: " + err);
clearAllInteractions();
});
})
.catch((err) => {
window.alert("Failed to fetch TD: " + err);
clearAllInteractions();
});
})
.catch((error) => {
window.alert("Could not fetch TD.\n" + error);
});
});
})
.catch((err) => {
window.alert("Failed to start servient: " + err);
clearAllInteractions();
});
}

function showInteractions(thing) {
Expand Down Expand Up @@ -166,6 +185,90 @@ function removeSchemaEditor() {
var servient = new WoT.Core.Servient();
servient.addClientFactory(new WoT.Http.HttpClientFactory());
var helpers = new WoT.Core.Helpers(servient);
document.getElementById("fetch").onclick = () => {
get_td(document.getElementById("td_addr").value);

// Tab and auto-consume
const TD_URLS = {
counter: "http://plugfest.thingweb.io/counter",
testthing: "http://plugfest.thingweb.io/http-data-schema-thing",
smartcoffee: "http://plugfest.thingweb.io/http-advanced-coffee-machine",
};

document.addEventListener("DOMContentLoaded", function () {
const tabLinks = [
{ id: "tab-link-custom", tab: "tab-custom" },
{ id: "tab-link-counter", tab: "tab-counter" },
{ id: "tab-link-testthing", tab: "tab-testthing" },
{ id: "tab-link-smartcoffee", tab: "tab-smartcoffee" },
];
const tabContents = tabLinks.map((t) => document.getElementById(t.tab));
const tdInput = document.getElementById("td_addr");
const fetchBtn = document.getElementById("fetch");

// Clear all interactions and editor
function clearAllInteractions() {
// Hide interactions section
const interactions = document.getElementById("interactions");
if (interactions) {
interactions.style.display = "none";
}
// Clear properties, actions, and events lists
["properties", "actions", "events"].forEach((id) => {
const element = document.getElementById(id);
if (element) element.innerHTML = "";
});
// Clear the editor
removeSchemaEditor();
}

tabLinks.forEach(({ id, tab }) => {
const link = document.getElementById(id);
if (link) {
link.addEventListener("click", function (e) {
e.preventDefault();
// Clear any existing content first
clearAllInteractions();

// Switch active tab
document.querySelectorAll("#td-tabs .tab-title").forEach((li) => li.classList.remove("active"));
link.parentElement.classList.add("active");
document.querySelectorAll(".tabs-content .content").forEach((c) => c.classList.remove("active"));
document.getElementById(tab).classList.add("active");

// Auto-fill and consume logic
if (tab === "tab-counter") {
tdInput.value = TD_URLS.counter;
get_td(TD_URLS.counter);
} else if (tab === "tab-testthing") {
tdInput.value = TD_URLS.testthing;
get_td(TD_URLS.testthing);
} else if (tab === "tab-smartcoffee") {
tdInput.value = TD_URLS.smartcoffee;
get_td(TD_URLS.smartcoffee);
}
});
}
});

// Dropdown handle
const exampleSelect = document.getElementById("exampleUrls");
if (exampleSelect) {
exampleSelect.addEventListener("change", function () {
if (this.value) {
tdInput.value = this.value;
// Auto-click
if (fetchBtn) fetchBtn.click();
}
});
}

if (fetchBtn) {
fetchBtn.onclick = () => {
if (tdInput.value) {
get_td(tdInput.value);
} else {
window.alert("Please enter a valid URL or select an example.");
}
};
}
document.getElementById("tab-link-custom").click();
});
4 changes: 2 additions & 2 deletions examples/browser/smart-coffee-machine.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ <h1 class="text-center">Smart Coffee Machine</h1>
</p>
<p>
The Thing Description for the coffee machine is available at
<a href="http://plugfest.thingweb.io:8083/smart-coffee-machine" target="_blank"
>http://plugfest.thingweb.io:8083/smart-coffee-machine</a
<a href="http://plugfest.thingweb.io/http-advanced-coffee-machine" target="_blank"
>http://plugfest.thingweb.io/http-advanced-coffee-machine</a
>.
</p>
</div>
Expand Down
98 changes: 98 additions & 0 deletions examples/browser/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/* Base styles */
body {
padding: 20px;
background: #f5f5f5;
font-family: Arial, sans-serif;
}

/* Top bar */
#topbar {
background: white;
padding: 15px;
margin-bottom: 20px;
border: 1px solid #ddd;
}

/* Tabs */
.tabs {
margin: 0 0 10px 0;
padding: 0;
list-style: none;
border-bottom: 1px solid #ddd;
}

.tabs li {
display: inline-block;
margin-right: 5px;
}

.tabs a {
display: block;
padding: 8px 12px;
text-decoration: none;
color: #333;
background: #f0f0f0;
border: 1px solid #ddd;
border-bottom: none;
}

.tabs .active a {
background: white;
border-bottom: 1px solid white;
margin-bottom: -1px;
}

/* Tab content */
.tabs-content {
background: white;
padding: 15px;
border: 1px solid #ddd;
border-top: none;
}

/* Form elements */
#td_addr,
#exampleUrls {
width: 100%;
padding: 8px;
margin-bottom: 10px;
border: 1px solid #ddd;
}

#fetch {
background: #0066cc;
color: white;
border: none;
padding: 8px 16px;
cursor: pointer;
}

/* Interactions */
#interactions {
margin-top: 20px;
background: white;
padding: 15px;
border: 1px solid #ddd;
}

#interactions h4 {
margin-top: 0;
padding-bottom: 8px;
border-bottom: 1px solid #eee;
}

/* Navigation */
.side-nav {
margin: 0;
padding: 0;
list-style: none;
}

.side-nav li {
padding: 8px 0;
border-bottom: 1px solid #f0f0f0;
}

.side-nav li:last-child {
border-bottom: none;
}