I'm trying to implement model-view-control in a web app. I'm importing all the js in the bottom of the html but I'm getting this error:
Uncaught ReferenceError: SideController is not defined
at HTMLDocument.<anonymous> (app.js:9)
I've posted my relevant code below. How can SideController not be found? It is imported in the exact same way as SideBarView, which seems to import successfully.
<!DOCTYPE html>
<html lang="en">
<body>
<div class="col-lg-3 col-md-3 col-sm-3 col-xs-12 sidebar collapse" id="sidebar">
<div class="noofpeople">
<div class="row noofpeople-wrapper">
<h4>My Dinner</h4>
<label>People <input id="numberOfGuests" type="number" class="form-control"></label><button type="button" id="plusButton"><span class="glyphicon glyphicon-plus"></span></button><button type="button" id="minusButton"><span class="glyphicon glyphicon-minus"></span></button>
</div>
</div>
</div>
<!-- jQuery -->
<script src="https://code.jquery.com/jquery.js"></script>
<!-- The application JavaScript code -->
<script src="js/app.js"></script>
<script src="js/model/dinnerModel.js"></script>
<script src="js/view/sidebarView.js"></script>
<script src="js/controllers/sidebarController.js"</script>
</body>
</html>
js/app.js:
$(function() {
//We instantiate our model
var model = new DinnerModel();
// And create the instance of ExampleView
var sidebar = $("#sidebar");
if(sidebar[0] != undefined){
var sidebarView = new SideBarView(sidebar, model);
var sidebarController = new SideController(sidebar, model);
}
var dishreel = $("#dishreel");
if(dishreel[0] != undefined){
var dishReelView = new DishReelView(dishreel, model);
}
});
js/controllers/sidebarController.js:
var SideController = function(container, model){
var plusButton = container.find("#plusButton");
var minusButton = container.find("#minusButton");
plusButton.onclick = function(){
model.incrNumberOfGuests();
};
minusButton.onclick = function(){
model.decrNumberOfGuests();
};
};
I missed a > on the last import.
Related
I'm trying to developp a Forge Autodesk Viewer for a webapp, this tutorial. I have an issue while trying to load extensions, indeed they never load on the viewer.
I've already developped the viewer of the tutorial, and the extensions worked correctly.
The main difference between my viewer and the tutorial's viewer is the use of a viewerApp in the tutorial while I had to use directly a GUIViewer3D (For the aggregation of several models).
I've already tried to load the viewer and the extensions in a different order, but it didn't change worked either. I assumed the code of the extension is correct, since it works in the tutorial, but I'm not sure about how I linked it to my viewer.
The code to load the viewer :
Autodesk.Viewing.Initializer(options, function onInitialized() {
// Initialisation du Viewer
var viewerDiv = document.getElementById('MyViewerDiv');
var config = {
extensions: ['DockingPanelExtension']
};
viewer = new Autodesk.Viewing.Private.GuiViewer3D(viewerDiv, config);
viewer.initialize();
});
The code of the index
<head>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=no" />
<meta charset="utf-8">
<!-- The Viewer CSS -->
<link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/6.*/style.min.css"
type="text/css">
<!-- Developer CSS -->
<link rel="stylesheet" href="/static/style.css" type="text/css">
<!-- Common packages: jQuery, Bootstrap, jsTree -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jstree/3.3.7/jstree.min.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jstree/3.3.7/themes/default/style.min.css" />
</head>
<body>
<!-- Fixed navbar by Bootstrap: https://getbootstrap.com/examples/navbar-fixed-top/ -->
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<ul class="nav navbar-nav left">
<li>
<a href="http://developer.autodesk.com" target="_blank">
<img alt="IM-Pact" src="static/img/IMPact.png"
height="20">
</a>
</li>
<li>
<button type="button" class="btn btn-default navbar-btn" onClick="callNew()">Add next model</button>
</li>
</ul>
</div>
</nav>
<!-- End of navbar -->
<div class="container-fluid fill">
<div class="row fill">
<div class="col-sm-4 fill">
<div class="panel panel-default fill">
<div class="panel-heading" data-toggle="tooltip">
Buckets & Objects
<span id="refreshBuckets" class="glyphicon glyphicon-refresh" style="cursor: pointer"></span>
<button class="btn btn-xs btn-info" style="float: right" id="showFormCreateBucket"
data-toggle="modal" data-target="#createBucketModal">
<span class="glyphicon glyphicon-folder-close"></span> New bucket
</button>
</div>
<div id="appBuckets">
tree here
</div>
</div>
</div>
<div class="col-sm-8 fill">
<div id="MyViewerDiv"></div>
</div>
</div>
</div>
<form id="uploadFile" method='post' enctype="multipart/form-data">
<input id="hiddenUploadField" type="file" name="theFile" style="visibility:hidden" />
</form>
<!-- Modal Create Bucket -->
<div class="modal fade" id="createBucketModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Cancel">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="myModalLabel">Create new bucket</h4>
</div>
<div class="modal-body">
<input type="text" id="newBucketKey" class="form-control"> For demonstration purposes, objects
(files) are
NOT automatically translated. After you upload, right click on
the object and select "Translate". Bucket keys must be of the form [-_.a-z0-9]{3,128}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="createNewBucket">Go ahead, create the
bucket</button>
</div>
</div>
</div>
</div>
<!-- <button id="MyNextButton" onClick="callNext()">Next!</button> -->
<!-- The Viewer JS -->
<script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/viewer3D.min.js?v=v6.6"></script>
<!-- Developer JS -->
<script src="static/js/docLoad.js"></script>
<script src="static/js/modelLoad.js"></script>
<script src="static/js/extensions/dockingpannelextension.js"></script>
<script src="static/js/viewer.js"></script>
<script src="static/js/tree.js"></script>
</body>
The code of the extension
// *******************************************
// Model Summary Extension
// *******************************************
var propsToList = [];
function addToList(item) {
if (propsToList.includes(item)) {
var index = propsToList.indexOf(item);
propsToList.splice(index, 1);
} else {
propsToList.push(item)
}
console.log(propsToList)
}
function ModelSummaryExtension(viewer, options) {
Autodesk.Viewing.Extension.call(this, viewer, options);
this.panel = null; // create the panel variable
}
ModelSummaryExtension.prototype = Object.create(Autodesk.Viewing.Extension.prototype);
ModelSummaryExtension.prototype.constructor = ModelSummaryExtension;
ModelSummaryExtension.prototype.load = function () {
if (this.viewer.toolbar) {
// Toolbar is already available, create the UI
this.createUI();
} else {
// Toolbar hasn't been created yet, wait until we get notification of its creation
this.onToolbarCreatedBinded = this.onToolbarCreated.bind(this);
this.viewer.addEventListener(Autodesk.Viewing.TOOLBAR_CREATED_EVENT, this.onToolbarCreatedBinded);
}
return true;
};
ModelSummaryExtension.prototype.onToolbarCreated = function () {
this.viewer.removeEventListener(Autodesk.Viewing.TOOLBAR_CREATED_EVENT, this.onToolbarCreatedBinded);
this.onToolbarCreatedBinded = null;
this.createUI();
};
ModelSummaryExtension.prototype.createUI = function () {
var _this = this;
// prepare to execute the button action
var modelSummaryToolbarButton = new Autodesk.Viewing.UI.Button('runModelSummaryCode');
modelSummaryToolbarButton.onClick = function (e) {
// check if the panel is created or not
if (_this.panel == null) {
_this.panel = new ModelSummaryPanel(_this.viewer, _this.viewer.container, 'modelSummaryPanel', 'Model Summary');
}
// show/hide docking panel
_this.panel.setVisible(!_this.panel.isVisible());
// if panel is NOT visible, exit the function
if (!_this.panel.isVisible()) return;
// ok, it's visible, let's get the summary!
// first, the Viewer contains all elements on the model, including
// categories (e.g. families or part definition), so we need to enumerate
// the leaf nodes, meaning actual instances of the model. The following
// getAllLeafComponents function is defined at the bottom
_this.getAllLeafComponents(function (dbIds) {
// now for leaf components, let's get some properties
// and count occurrences of each value.
// get only the properties we need for the leaf dbIds
_this.viewer.model.getBulkProperties(dbIds, propsToList, function (dbIdsProps) {
// iterate through the elements we found
dbIdsProps.forEach(function (item) {
// and iterate through each property
item.properties.forEach(function (itemProp) {
// now use the propsToList to store the count as a subarray
if (propsToList[itemProp.displayName] === undefined)
propsToList[itemProp.displayName] = {};
// now start counting: if first time finding it, set as 1, else +1
if (propsToList[itemProp.displayName][itemProp.displayValue] === undefined)
propsToList[itemProp.displayName][itemProp.displayValue] = 1;
else
propsToList[itemProp.displayName][itemProp.displayValue] += 1;
});
});
// now ready to show!
// the Viewer PropertyPanel has the .addProperty that receives the name, value
// and category, that simple! So just iterate through the list and add them
propsToList.forEach(function (propName) {
if (propsToList[propName] === undefined) return;
Object.keys(propsToList[propName]).forEach(function (propValue) {
_this.panel.addProperty(
/*name*/
propValue,
/*value*/
propsToList[propName][propValue],
/*category*/
propName);
});
});
})
})
};
// modelSummaryToolbarButton CSS class should be defined on your .css file
// you may include icons, below is a sample class:
modelSummaryToolbarButton.addClass('modelSummaryToolbarButton');
modelSummaryToolbarButton.setToolTip('Model Summary');
// SubToolbar
this.subToolbar = (this.viewer.toolbar.getControl("MyAppToolbar") ?
this.viewer.toolbar.getControl("MyAppToolbar") :
new Autodesk.Viewing.UI.ControlGroup('MyAppToolbar'));
this.subToolbar.addControl(modelSummaryToolbarButton);
this.viewer.toolbar.addControl(this.subToolbar);
};
ModelSummaryExtension.prototype.unload = function () {
this.viewer.toolbar.removeControl(this.subToolbar);
return true;
};
ModelSummaryExtension.prototype.getAllLeafComponents = function (callback) {
var cbCount = 0; // count pending callbacks
var components = []; // store the results
var tree; // the instance tree
function getLeafComponentsRec(parent) {
cbCount++;
if (tree.getChildCount(parent) != 0) {
tree.enumNodeChildren(parent, function (children) {
getLeafComponentsRec(children);
}, false);
} else {
components.push(parent);
}
if (--cbCount == 0) callback(components);
}
this.viewer.getObjectTree(function (objectTree) {
tree = objectTree;
var allLeafComponents = getLeafComponentsRec(tree.getRootId());
});
};
// *******************************************
// Model Summary Panel
// *******************************************
function ModelSummaryPanel(viewer, container, id, title, options) {
this.viewer = viewer;
Autodesk.Viewing.UI.PropertyPanel.call(this, container, id, title, options);
}
ModelSummaryPanel.prototype = Object.create(Autodesk.Viewing.UI.PropertyPanel.prototype);
ModelSummaryPanel.prototype.constructor = ModelSummaryPanel;
Autodesk.Viewing.theExtensionManager.registerExtension('ModelSummaryExtension', ModelSummaryExtension);
Thanks in advance !
In the extension JavaScript file, you're registering the extension under the name ModelSummaryExtension, but in the viewer initialization code you're passing the config object with extensions: ['DockingPanelExtension']. That's likely why the extension isn't loaded. Try initializing the GuiViewer3D class with the following config instead:
let config = {
extensions: ['ModelSummaryExtension']
};
EDIT (after the extension naming has been fixed):
When initializing the GuiViewer3D, call its start() method instead of initialize(). It will internally call initialize() (for initializing internal structures, event handlers, etc.), setUp(); (for configuring the viewer based on your config object), and finally it will call loadModel() if there's a URN or a filepath argument passed to the function.
I want to loop through a JavaScript object and repeat an html script as many times as the object length.
Here, I have the following in a script tag
<script>
var obj;
ipcRenderer.on('requests-results', (event, hosSchema) => {
obj = hosSchema
})
</script>
obj is an array retrieved from Mongo database as the picture below shows:
and I have the following inside <body> tag:
<div class="row">
<div class="col-md-4 col-sm-4">
<div class="card">
<div class="card-content">
<span class="card-title">.1.</span>
<p>.2.</p>
</div>
<div class="card-action">
.3.
.4.
</div>
</div>
</div>
</div>
How can I loop through obj to repeat the code between <div> tag as many times as obj.length?
I would suggest you to use Handlebars as #Amit mentioned.
first move out the code inside <div id="page-inner"> as below:
<div id="page-inner">
</div>
<script id= "requests-template" type="text/x-handlebars-template">
<div class="row">
{{#each requests}}
<div class="col-md-4 col-sm-4">
<div class="card">
<div class="card-content">
<span class="card-title">{{this.fieldName}}</span>
<p>{{this.fieldName}}</p>
</div>
<div class="card-action">
{{this.fieldName}}
{{this.fieldName}}
</div>
</div>
</div>
{{/each}}
</div>
</script>
Then inside another script page of type text/javascript you create the requests and assigned obj/hosSchema to it as below:
<script type="text/javascript">
var requestInfo = document.getElementById('requests-template').innerHTML;
var template = Handlebars.compile(requestInfo);
var requestData = template({
requests: obj
})
$('#page-inner').html(requestData);
</script>
NOTE: you need handlebars package installed (npm install handlebars --save)
Use templating script like Handlebars.js, Mustache.js or underscore.js.
Check below link for more description.
http://www.creativebloq.com/web-design/templating-engines-9134396
Try this:
var divlist = document.getElementsByTagName['div'];
var duplicate = null;
var rowIndex = -1;
var found = false;
for(var i = 0;i<obj.length;i++)
{
if(!found)
for(var p = 0;p<divlist.length;p++)
{
if(rowIndex != -1 && duplicate != null)
{
//set a Boolean to true and break
found = true;
break;
}
if(divlist[p].className == "col-md-4 col-sm-4")
{
//copy the element
duplicate = divlist[p];
}
else if(divlist[p].className == "row")
{
//identify the row's index
rowIndex = p;
}
}
//append the duplicate
divlist[rowIndex].appendChild(duplicate);
}
I have my own knockout's component:
ko.components.register("library-link-form",
{
viewmodel: LibraryLinkViewModel,
template: { controller: "PartialViews", action: "LibraryLinkPartial" }
//This is custom template loader, which loads asp.net partial view from controller via ajax request.
});
My LibraryLinkViewModel.js:
function LibraryLinkViewModel() {
var self = this;
self.OtherLibrary = ko.observable("");
self.Type = ko.observable("");
}
Partial view _LibraryLinkForm:
#{
var libraryDropdownId = $"dropdown-{Guid.NewGuid().ToString().Substring(0, 8)}";
var typeDropdownId = $"dropdown-{Guid.NewGuid().ToString().Substring(0, 8)}";
var scriptId = $"script-{Guid.NewGuid().ToString().Substring(0, 8)}";
var contextId = $"context-{Guid.NewGuid().ToString().Substring(0, 8)}";
var librariesList = //some list with predefined libraries
var typeList = // some list with predefined library's types
}
<!-- ko template: { afterRender: function()
{
eval($('##scriptId').html());
}
}
-->
<!-- /ko -->
<div id ="#contextId">
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-body">
<div class="col-md-12">
<div class="row">
<form class="form-horizontal">
<div class="form-group">
<div class="col-md-6">
#(Html.Kendo().DropDownList()
.Name(libraryDropdownId)
.DataValueField("Value").DataTextField("Text")
.HtmlAttributes(new
{
style = "width: 100%",
data_bind = "value: OtherLibrary"
}).BindTo(librariesList).Deferred()
)
</div>
<div class="col-md-4">
#(Html.Kendo().DropDownList()
.Name(typeDropdownId)
.DataValueField("Value").DataTextField("Text")
.HtmlAttributes(new
{
style = "width: 100%",
data_bind = "value: Type"
}).BindTo(typeList).Deferred()
)
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<deferred-script class="hidden" id="#scriptId">
#(Html.Kendo().DeferredScripts(false))
</deferred-script>
</div>
And finally, how I combine it all:
<button type="button" data-bind="click: addLibraryLink"></button>
<ul class="list-unstyled" data-bind="foreach: LibraryLinks">
<li><library-link-form></library-link-form></li>
</ul>
<script type="text/javascript">
function LibraryViewModel() {
var self = this;
self.LibraryLinks = ko.observableArray();
self.addLibraryLink = function () {
ko.components.clearCachedDefinition();
self.LibraryLinks.push(new LibraryLinkViewModel());
};
}
ko.applyBindings(new LibraryViewModel());
</script>
I'm using Knockout v.3.4, Asp.Net Core v.1.0.0.
So, the problem is that when I'm trying to add new library link to list, knockout bindings simply don't work, maybe because of error:
Uncaught ReferenceError: Unable to process binding "value: function
(){return OtherLibrary }" Message: OtherLibrary is not defined
What should I do with this error? How can I properly add my knockout's component to the list?
The answer is simple. Let's look at the example, and check contexts in it:
<div data-bind="foreach: LibraryLinks"> // here we have LibraryViewModel context
<library-link-form> // here we have LibraryLinkViewModel context
//inside component we have THIRD context, which is empty!
</library-link-form>
</div>
So, the problem is, that OtherLibrary in data_bind = "value: OtherLibrary" refers to the third context, which is empty and nowhere defined.
Simply calling parent's context solves the problem.
For example: data_bind = "value: $parent.OtherLibrary"
I am trying to create an onclick event which will show/hide elements of an array however I am struggling with the showSubTabGroup() function below.
Sidenote: Eventually I would like to make this onmouseenter and onmouseleave, rather than 'click' as you see below.
I would like to be able to click on a div and show subsequent div's below as you might expect from a navigation feature.
The console is not returning any errors, however the 'click' function seems alert("CLICKED") properly.
Any help would be greatly appreciated.
Problem:
Tab.prototype.showSubTabGroup = function (tabIndex, subTabIndex) {
this.tab[tabIndex].addEventListener('click', function () {
alert("CLICKED");//Testing 'click' call
for (var i = subTabIndex; i < this.subTabGroup; i++) {
this.subTab[i].style.display = "";
}
});
}
function Tab (subTabGroup) {
this.tab = document.getElementsByClassName("tab");
this.subTab = document.getElementsByClassName("sub-tab");
this.subTabGroup = subTabGroup;
}
Tab.prototype.hideSubTabs = function () {
for (var i = 0; i < this.subTab.length; i++) {
this.subTab[i].style.display = "none";
}
}
Tab.prototype.showSubTabGroup = function (tabIndex, subTabIndex) {
this.tab[tabIndex].addEventListener('click', function () {
for (var i = subTabIndex; i < this.subTabGroup; i++) {
this.subTab[i].style.display = "";
}
});
}
var tab = new Tab(3);
tab.hideSubTabs();
tab.showSubTabGroup(0,0);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Responsive Nav</title>
</head>
<body>
<!-- JQuery CDN -->
<script src="http://code.jquery.com/jquery-3.1.0.js"></script>
<div class="container">
<div class="tab">
<p>TAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
</div>
<div class="container">
<div class="tab">
<p>TAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
</div>
<div class="container">
<div class="tab">
<p>TAB</p>
</div>
<div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
<div class="sub-tab">
<p>SUBTAB</p>
</div>
</div>
</div>
<script type="text/javascript" src="tab.js"></script>
<script type="text/javascript" src="tabEvents.js"></script>
</body>
</html>
The problem of what is this inside the click. It is not your tab code, it is the reference to the element that you clicked on. You need to change that by using bind
Tab.prototype.showSubTabGroup = function (tabIndex, subTabIndex) {
this.tab[tabIndex].addEventListener('click', (function () {
for (var i = subTabIndex; i < this.subTabGroup; i++) {
this.subTab[i].style.display = "";
}
}).bind(this));
}
As I read your post, I assume hideSubTabs() is working properly. In that case I will suggest to use in showSubTabGroup():
this.subTab[i].style.display = "initial";
instead of
this.subTab[i].style.display = "";
"initial" will set to its default e.g. as "block" for div and "inline" for span
I see that you also have included jQuery. If I may ask why don't jQuery functions which will do the same with less code:
$('.tab').on('click',function() {
$(this).closest('.container').find('.sub-tab').toggle()
})
$('.tab').click();
$('.tab')[0].click();
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I created a script to display the weather on my site, my problem when I execute it displays nothing.
this is my script :
<!DOCTYPE html>
<html>
<head>
<title>Weather API Test</title>
</head>
<body>
<script type="text/html" id="weather_tmpl">
<div class="weather_wrapper">
<div class="top_wrapper top_wrapper_e">
{{=day0}}
<div class="bt_control" id="meteo_controller">
<a href="javascript://">
<img src="arrow_open.png" id="meteo_trigger_img" width="27" height="17" alt="Arrow" />
</a>
</div>
</div>
<div class="bottom_wrapper" id="meteo_future_days">
<div class="next_days_wrapper">
<div class="day first">
{{=day1}}
<div class="clear"></div>
</div>
<div class="day">
{{=day2}}
<div class="clear"></div>
</div>
<div class="day last">
{{=day3}}
<div class="clear"></div>
</div>
</div>
<div class="bottom"></div>
</div>
</div>
</script>
<script type="text/html" id="detail_tmpl">
<div class="date">{{=date.weekday}},
<br />{{=date.day}} {{=monthname_short}}.</div>
<div class="temp">{{=high.celsius}}</div>
<div class="icon">
<img src="{{=icon_url}}" width="34" height="34" alt="icone" />
</div>
</script>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="t.min.js"></script>
<script type='text/javascript'>
(function(){
var mainTpl = new t($('#weather_tmpl').html()),
detailTpl = new t($('#detail_tmpl').html());
$.getJSON('http://api.wunderground.com/api/2ea138a9dd52eabe/forecast/q/CA/San_Francisco.json')
.done(function(data){
var tplData = {};
$.each(data.forecast.simpleforecast.forecastday, function(index, day){
tplData['day'+index] = detailTpl.render(day);
});
$('body').append(mainTpl.render(tplData));
});
})();
</script>
<script>
var meteostatus = 0; // closed
$('#meteo_controller').click(function() {
if (meteostatus == 0) {
meteostatus = 1;
$('#meteo_future_days').fadeIn('slow');
$('#meteo_trigger_img').attr('src', $('#meteo_trigger_img').attr('src').replace('open', 'close'));
} else {
meteostatus = 0;
$('#meteo_future_days').fadeOut('slow');
$('#meteo_trigger_img').attr('src', $('#meteo_trigger_img').attr('src').replace('close', 'open'));
}
});
</script>
</body>
</html>
PS:
The data for the current day, and the forecast for the next 3 are in the array data.forecast.simpleforecast.forecastday.
I've used a templating library called t.js which you can find here
have a nice day
Replace the two of your scripts (the one with the id of library and the one with t.min.js) with:
<script src="https://github.com/jasonmoo/t.js/blob/master/t.min.js" />
<script type="https://github.com/jasonmoo/t.js/blob/master/template" id="test">
(function(){
var mainTpl = new t($('#weather_tmpl').html()),
detailTpl = new t($('#detail_tmpl').html());
$.getJSON('http://api.wunderground.com/api/2ea138a9dd52eabe/forecast/q/CA/San_Francisco.json')
.done(function(data){
var tplData = {};
$.each(data.forecast.simpleforecast.forecastday, function(index, day){
tplData['day'+index] = detailTpl.render(day);
});
$('body').append(mainTpl.render(tplData));
});
})();
var meteostatus = 0; // closed
$('#meteo_controller').click(function() {
if (meteostatus === 0) {
meteostatus = 1;
$('#meteo_future_days').fadeIn('slow');
$('#meteo_trigger_img').attr('src', $('#meteo_trigger_img').attr('src').replace('open', 'close'));
} else {
meteostatus = 0;
$('#meteo_future_days').fadeOut('slow');
$('#meteo_trigger_img').attr('src', $('#meteo_trigger_img').attr('src').replace('close', 'open'));
}
});
</script>
You tried to put a script src as a local path on your server, where the file is being hosted on github.
Also, there is a script error.