Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
86 changes: 81 additions & 5 deletions examples/browser/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@
<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="styles.css" />

<!-- defer to not block rendering -->
<script src="https://cdn.jsdelivr.net/npm/@json-editor/json-editor@latest/dist/jsoneditor.min.js"></script>
<!-- local vs cdn dependency -->
<script src="../../packages/browser-bundle/dist/wot-bundle.min.js" defer></script>
<!-- <script
<!-- <script src="../../packages/browser-bundle/dist/wot-bundle.min.js" defer></script> -->
<script
src="https://cdn.jsdelivr.net/npm/@node-wot/browser-bundle@latest/dist/wot-bundle.min.js"
defer
></script> -->
></script>
<script src="index.js" defer></script>

<script>
Expand All @@ -27,8 +28,83 @@
<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-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>
<li class="tab-title">
<a href="#tab-counter" id="tab-link-counter">Counter</a>
</li>
<li class="tab-title">
<a href="#tab-custom" id="tab-link-custom">Custom</a>
</li>
</ul>
<div class="tabs-content">
<div class="content active" id="tab-testthing">
<p>Consumed TD at <a href="" target="_blank" class="td-url"></a></p>
<p>
<strong>TD Description:</strong>
<span class="td-description">Loading...</span>
</p>
</div>
<div class="content" id="tab-smartcoffee">
<p>
Consumed TD at
<a href="" target="_blank" class="td-url"></a>
</p>
<p>
<strong>TD Description:</strong>
<span class="td-description">Loading...</span>
</p>
</div>
<div class="content" id="tab-counter">
<p>Consumed TD at <a href="" target="_blank" class="td-url"></a></p>
<p>
<strong>TD Description:</strong>
<span class="td-description">Loading...</span>
</p>
</div>
<div class="content" id="tab-custom">
<div class="row">
<div class="medium-12 columns">
<input
id="td_addr"
type="url"
placeholder="Paste the TD URL to start consuming it"
style="width: 100%"
onkeydown="if(event.key==='Enter') document.getElementById('fetch').click()"
/>
</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 id="custom-td-info" style="margin-top: 10px">
<p>Consumed TD at <a href="" target="_blank" class="td-url"></a></p>
<p>
<strong>TD Description:</strong>
<span class="td-description">Enter a TD URL above to consume it.</span>
</p>
</div>
</div>
</div>

<!-- Error message container -->
<div id="error-container" class="row" style="display: none; margin-top: 10px">
<div class="medium-12 columns">
<div class="alert-box alert" id="error-message">
<span id="error-text"></span>
<a href="#" class="close" id="close-error">&times;</a>
</div>
</div>
</div>
</div>
</div>
<div id="interactions" class="row" style="display: none">
Expand Down
212 changes: 198 additions & 14 deletions examples/browser/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,44 @@
**/

function get_td(addr) {
servient.start().then((thingFactory) => {
helpers
.fetch(addr)
.then((td) => {
thingFactory.consume(td).then((thing) => {
removeInteractions();
showInteractions(thing);
hideError();

// 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);
updateTabDescription(addr, td);
})
.catch((err) => {
showError("Failed to consume TD: " + err);
clearAllInteractions();
updateTabDescription(addr, null, "Failed to consume TD: " + err);
});
})
.catch((err) => {
showError("Failed to fetch TD: " + err);
clearAllInteractions();
updateTabDescription(addr, null, "Failed to fetch TD: " + err);
});
})
.catch((error) => {
window.alert("Could not fetch TD.\n" + error);
});
});
})
.catch((err) => {
showError("Failed to start servient: " + err);
clearAllInteractions();
updateTabDescription(addr, null, "Failed to start servient: " + err);
});
}

function showInteractions(thing) {
Expand Down Expand Up @@ -163,9 +188,168 @@ function removeSchemaEditor() {
}
}

// Error handling functions to show/hide error messages on web page instead of using alert window
function showError(message) {
const errorContainer = document.getElementById("error-container");
const errorText = document.getElementById("error-text");

if (errorContainer && errorText) {
errorText.textContent = message;
errorContainer.style.display = "block";
}
}

function hideError() {
const errorContainer = document.getElementById("error-container");
if (errorContainer) {
errorContainer.style.display = "none";
}
}

function updateTabDescription(url, td, error) {
// Find active tab and update its description
const activeTab = document.querySelector(".tabs-content .content.active");
if (!activeTab) return;

// Update URL link
const urlElement = activeTab.querySelector(".td-url");
if (urlElement && url) {
urlElement.href = url;
urlElement.textContent = url;
}

// Update description
const descriptionElement = activeTab.querySelector(".td-description");
if (!descriptionElement) return;

if (error) {
descriptionElement.textContent = error;
descriptionElement.style.color = "red";
} else if (td && td.description) {
descriptionElement.textContent = td.description;
descriptionElement.style.color = "";
} else {
descriptionElement.textContent = "No description available";
descriptionElement.style.color = "";
}
}

// Clear all interactions and editor
function clearAllInteractions() {
console.log("clearAllInteractions function called");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this leftover.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: @relu91 refers to the console log only...

hideError();
const interactions = document.getElementById("interactions");
if (interactions) {
interactions.style.display = "none";
}
["properties", "actions", "events"].forEach((id) => {
const element = document.getElementById(id);
if (element) element.innerHTML = "";
});
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 configuration
const TD_URLS = {
testthing: "http://plugfest.thingweb.io/http-data-schema-thing",
smartcoffee: "http://plugfest.thingweb.io/http-advanced-coffee-machine",
counter: "http://plugfest.thingweb.io/counter",
};

document.addEventListener("DOMContentLoaded", function () {
// Parse URL parameters to pre-fill the input field
let $_GET = location.search
.substr(1)
.split("&")
.reduce((o, i) => ((u = decodeURIComponent), ([k, v] = i.split("=")), (o[u(k)] = v && u(v)), o), {});

// Tab configuration in correct sequence
const tabLinks = [
{ id: "tab-link-testthing", tab: "tab-testthing" },
{ id: "tab-link-smartcoffee", tab: "tab-smartcoffee" },
{ id: "tab-link-counter", tab: "tab-counter" },
{ id: "tab-link-custom", tab: "tab-custom" },
];

const tdInput = document.getElementById("td_addr");
const fetchBtn = document.getElementById("fetch");
const closeErrorBtn = document.getElementById("close-error");

// Error close button handler
if (closeErrorBtn) {
closeErrorBtn.onclick = (e) => {
e.preventDefault();
hideError();
};
}

// Pre-fill input from URL parameter if provided
if ($_GET["url"]) {
tdInput.value = $_GET["url"];
}

// Tab click handlers
tabLinks.forEach(({ id, tab }) => {
const link = document.getElementById(id);
if (link) {
link.addEventListener("click", function (e) {
e.preventDefault();
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-consume TD based on tab
if (tab === "tab-testthing") {
get_td(TD_URLS.testthing);
} else if (tab === "tab-smartcoffee") {
get_td(TD_URLS.smartcoffee);
} else if (tab === "tab-counter") {
get_td(TD_URLS.counter);
} else if (tab === "tab-custom") {
// Reset custom TD tab
const customDesc = document.querySelector("#tab-custom .td-description");
if (customDesc) {
customDesc.textContent = "Enter a TD URL above to consume it.";
customDesc.style.color = "";
}
const customUrl = document.querySelector("#tab-custom .td-url");
if (customUrl) {
customUrl.href = "";
customUrl.textContent = "";
}
}
});
}
});

// Custom TD fetch button
if (fetchBtn) {
fetchBtn.onclick = () => {
if (tdInput.value) {
get_td(tdInput.value);
} else {
showError("Please enter a valid URL.");
}
};
}

// Auto-load TD if URL parameter was provided
if ($_GET["url"]) {
document.querySelectorAll("#td-tabs .tab-title").forEach((li) => li.classList.remove("active"));
document.getElementById("tab-link-custom").parentElement.classList.add("active");
document.querySelectorAll(".tabs-content .content").forEach((c) => c.classList.remove("active"));
document.getElementById("tab-custom").classList.add("active");
get_td($_GET["url"]);
} else {
// Default to Test Thing tab
document.getElementById("tab-link-testthing").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
Loading