I'm extremely new to ReactJS and am trying to use it to make a simple fitness web app. Currently, if I was to do this using JQuery, I would end up with a thousand lines in a single file, which isn't what I want, so I'm trying to get as much externalisation in as possible while keeping one html file. The premise is that when the user hits the page, the "Main" class will be rendered to the screen. When they press one of the video images, the DOM will unrender the main and replace it with the specific page linked to the video. As thing stand, I'm trying to create large classes full of html to render each time, and it's throwing a simple error that I don't understand enough to fix. Could you explain to me what I'm doing wrong.
Index.html
<!DOCTYPE html>
<html>
<head>
<title> Get Fit </title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href='https://fonts.googleapis.com/css?family=Montserrat:400,700' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Roboto:400,100,300,500' rel='stylesheet' type='text/css'>
<link href = "css/styles.css" rel = "stylesheet">
<script type = "text/javascript" src = "js/male.js"></script>
<script>
$(document).ready(function(){
$("button").click(function(){
$("button").removeClass("active");
$(this).addClass("active");
});
});
</script>
</head>
<body>
</body>
</html>
Male.js
var Main = React.createClass({
render: function() {
return (
<div class = "header">
<img class = "img-responsive" src = "assets/header.png" alt = "header" />
</div>
<div class = "content">
<div class = "genderSelection">
<h1 class = "title"> YOUR WORKOUT PLAN </h1>
<button id = "male"> Male </button>
<button id = "female"> Female </button>
</div>
<div class = "dayContainer">
<h2 class = "workoutDay"> Monday </h2>
<img class = "video img-responsive" src = "assets/back.png" alt = "monday-1" />
<img class = "video img-responsive" src = "assets/back.png" alt = "monday-2" />
<img class = "video img-responsive" src = "assets/back.png" alt = "monday-3" />
<img class = "video img-responsive" src = "assets/back.png" alt = "monday-4" />
<img class = "video img-responsive" src = "assets/back.png" alt = "monday-5" />
<img class = "video img-responsive" src = "assets/back.png" alt = "monday-6" />
</div>
</div>
<div class = "footer">
</div>
);
}
});
var MaleMonday1 = React.createClass({
render: function() {
return (
);
}
});
ReactDOM.render(
<Main />
);
Any links to helpful documentation is also much appreciated, the documentation I followed for this has seemed to lead me in to trouble so far.
Your current problem is two fold, first off standard HTML attributes aren't always used in React. For example, class is className, for is htmlFor. See here which attributes are supported.
Secondly, React needs to return a single DOM node which is why you're not seeing anything on screen and getting the error: Adjacent XJS elements must be wrapped in an enclosing tag.
If you wrap your entire HTML that you currently have in your render function within a div tag you'll have much more luck!
render: function() {
return (
<div>
<div className = "header">
</div>
<div className="content">
<div className= "genderSelection">
</div>
<div className = "dayContainer">
</div>
</div>
<div className="footer">
</div>
</div>
);
}
In addition to #limelights answer:
Thirdly, your <body> is empty. Try adding something like:
<body>
<div id="react-container"></div>
</body>
Fourth, your ReactDOM.render() needs a destination in the DOM to put your component. (documentation here) E.g:
ReactDOM.render(
<Main />,
document.getElementByID("react-container")
);
As for your question about general documentation, react's own tutorials (here) are a good place to start.
Related
I have a container holding four divs. After I click on one div, the remaining three neeed to be appended to another div. How can I achieve this?
<!DOCTYPE html>
<html lang="en">
<head>
<title>Week 4 Game</title>
<link rel = "stylesheet" type = "text/css" href = "assets/css/reset.css">
<link rel="stylesheet" type="text/css" href="assets/css/style.css">
<!-- Added link to the jQuery Library -->
<script src="https://code.jquery.com/jquery-2.2.3.js" integrity="sha256-laXWtGydpwqJ8JA+X9x2miwmaiKhn8tVmOVEigRNtP4=" crossorigin="anonymous"></script>
<script type="text/javascript" src = "assets/javascript/game.js"> </script>
</head>
<body>
<div class = "characters">
<div class="charContainer darth">
<h2 id="c1"></h2>
<img class="vade" src="assets/images/vader.jpg">
<p id="c1hp" data-hp = "120"></p>
</div>
<div class="charContainer luke">
<h2 id="c2"></h2>
<img class="skywalker" src="assets/images/luke.jpg">
<p id="c2hp" data-hp = "100"></p>
</div>
<div class="charContainer won">
<h2 id="c3"></h2>
<img class="obi" src="assets/images/obiwan.jpg">
<p id="c3hp" data-hp = "150"></p>
</div>
<div class="charContainer maul">
<h2 id="c4"></h2>
<img class="dmaul" src="assets/images/maul.png">
<p id="c4hp" data-hp = "180"></p>
</div>
</div>
<div id="your">
<h2>Your Character</h2>
<!-- <img class="dmaul" src="assets/images/maul.png"> -->
</div>
<div id="enemies">
<h2>Enemies</h2>
<!-- <img class="dmaul" src="assets/images/maul.png"> -->
</div>
</body>
</html>
JQuery
$(document).ready(function(){
var yourCharacter;
var enemy1;
var enemy2;
var enemy3;
$('#c1').text("Darth Vader");
$('#c2').text("Luke Skywalker");
$('#c3').text("Obi Won");
$('#c4').text("Darth Maul");
var health = $('#c1hp').data('hp');
$('#c1hp').html(health);
var health = $('#c2hp').data('hp');
$('#c2hp').html(health);
var health = $('#c3hp').data('hp');
$('#c3hp').html(health);
var health = $('#c4hp').data('hp');
$('#c4hp').html(health);
$('.charContainer').on('click', function(){
yourCharacter = $(this);
$('#your').append(yourCharacter);
enemy1 = $('.vader');
$('#enemies').append(enemy1);
})
});
I need to append the remaind charContainers that were not clicked to the enemies container div
This works for me. You may want to add a check for equality, since the chosen div will be initially appended to enemies, then moved:
$('.charContainer').on('click', function(){
$('.charContainer').each(function() {
$('#enemies').append($(this));
})
yourCharacter = $(this);
$('#your').append(yourCharacter);
})
Since "your character" has already been moved by the time the rest of the characters need to be moved, the selector '.characters>.charContainer' (all the "charContainer" children of "characters") will not select your character (since it's already moved) - just the remaining characters
$('.charContainer').on('click', function() {
$('#your').append($(this));
$('.characters>.charContainer').each(function() {
$('#enemies').append($(this));
});
})
Alternate version using arrow function:
$('.charContainer').on('click', function() {
$('#your').append($(this));
$('.characters>.charContainer').each( (undefined, char) => { $('#enemies').append($(char)) } );
})
Or borrowing Tekebo's use of appendTo:
$('.charContainer').on('click', function() {
$(this).appendTo('#your');
$('.characters>.charContainer').appendTo('#enemies');
})
Note: the main advantage of using the children selector as opposed to the siblings of the clicked div or all divs of the 'charContainer' class is that it doesn't matter which order it's done in - the result will be the same. (However, moving the clicked div last will cause more work to be done)
You could simply use siblings(), like this:
$(document).ready(function(){
$(".charContainer").on("click",function(){
$(this).siblings().appendTo("#enemies");
$(this).appendTo("#your");
});
});
*I updated the plunkr and the code to better represent my localhost version. The Angularjs version was not the problem despite fixing the previous plunkr. *
First, let me say I am really struggling with Angularjs but I'm determined to learn it. I'm a designer, not a brick-layer (forgive the Star Trek reference).
I'm building a prototype where clicking on a small thumbnail to the left loads a larger version to the right. I'm using ng-click on the image to pass the unique "current" ID. Clicking doesn't affect the large image ng-src. I tried various permutations and don't see what I could be doing wrong.
*New info: I am using ng-repeat to iterate through a list of images. I try to pass each image url through ng-click but that seems to be where it gets lost. *
http://plnkr.co/edit/vYiykI7dfMKd34ZmS13N?p=preview
The app/controller:
<script>
var app = angular.module('pageApp', []);
app.controller('imgCtrl', function($scope) {
$scope.current = '7078/7250439172_72562c8e45_k';
});
</script>
The html wth thumbnail and large image:
<div class="container">
<div class="row" ng-app="pageApp" ng-controller="imgCtrl">
<div class="col-xs-3">
<ul class="list-group sm-img">
<li class="list-group-item text-center" ng-repeat="n in ['7078/7250439172_72562c8e45_k', '7087/7250440014_a32980508e_k', '7225/7250440766_8db45aa277_h']">
<img class="img-responsive" src="https://farm8.staticflickr.com/{{n}}.jpg" ng-click="current='{{n}}'" /><span>{{current}}</span>
</li>
</ul>
</div>
<div class="col-xs-9">
<img class="img-responsive" ng-src="https://farm8.staticflickr.com/{{ current }}.jpg" />
</div>
</div>
</div>
Try to create function in controller an execute it from ng-click
$scope.changeImg = function (c) {
$scope.current=c;
}
Your problem quite funny: you are loading Angular2 version however using Angular1.x syntax and code. Load correct library version, for example 1.4.8, and everything will start working properly:
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
Demo: http://plnkr.co/edit/0efkCT9wwEaWfK0nR6su?p=info
It is working now. http://plnkr.co/edit/nmqDqcmtyTq479wZWsuR?p=preview
you are using angular 2 which has much more different than angular 1 (1.4)
<!DOCTYPE html>
<html ng-app="pageApp">
<head>
<link data-require="bootstrap#3.3.5" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" />
<link data-require="bootstrap#3.3.5" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootswatch/3.3.5/cosmo/bootstrap.min.css" />
<link data-require="bootstrap#3.3.5" data-semver="3.3.5" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css" />
<script data-require="bootstrap#3.3.5" data-semver="3.3.5" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://code.angularjs.org/1.4.0/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
<script>
var app = angular.module('pageApp', []);
app.controller('imgCtrl', function($scope) {
$scope.current = '7078/7250439172_72562c8e45_k';
});
</script>
</head>
<body>
<div class="container">
<div class="row" ng-controller="imgCtrl">
<div class="col-xs-3">
<img class="img-responsive" src="https://farm8.staticflickr.com/7078/7250439172_72562c8e45_k.jpg" ng-click="current='7078/7250439172_72562c8e45_k'" />
<img class="img-responsive" src="https://farm8.staticflickr.com/7087/7250440014_a32980508e_k.jpg" ng-click="current='7087/7250440014_a32980508e_k'" />
<img class="img-responsive" src="https://farm8.staticflickr.com/7225/7250440766_8db45aa277_h.jpg" ng-click="current='7225/7250440766_8db45aa277_h'"/>
</div>
<div class="col-xs-9">
<img class="img-responsive" ng-src="https://farm8.staticflickr.com/{{ current }}.jpg" />
</div>
</div>
</div>
</body>
</html>
I am practicing Windows Phone development using WinJS and I have the following code which parses JSON received from a particular URL. And using the images to be bound to a list view in an HTML page,
JavaScript code:
WinJS.xhr({ url: urlToBeUsed }).then(
function (sportsResponse) {
var sportsJSON = JSON.parse(sportsResponse.responseText);
var listItems = sportsJSON.Videos.Data;
for (var i = 0; i < listItems.length; i++) {
var imageList = listItems[i].Items;
var count = imageList.length;
if (count > 0) {
listItems[i].Items[0].Images.forEach(imageIteration);
function imageIteration(value, index, array) {
var picture = value.Url;
var name = value.title;
sportsImageList.push({
title: name,
picture: picture
});
}
}
}
imageList.itemDataSource = sportsImageList.dataSource;
})
}
HTML Code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<!-- WinJS references -->
<script src="//Microsoft.Phone.WinJS.2.1/js/base.js"></script>
<script src="//Microsoft.Phone.WinJS.2.1/js/ui.js"></script>
<script src="/js/navigator.js"></script>
<link href="/css/default.css" rel="stylesheet" />
<link href="/pages/home/home.css" rel="stylesheet" />
<script src="/pages/sports/sports.js"></script>
</head>
<body>
<!-- The content that will be loaded and displayed. -->
<div class="fragment homepage" style="width:100%;height:100%;padding:10px">
<div class="myTemplate" data-win-control="WinJS.Binding.Template">
<div class="myItem">
<img data-win-bind="src:picture" style="width:100px;height:100px" />
</div>
</div>
<div id="imageList" data-win-control="WinJS.UI.ListView" data-win-bind="winControl.itemDataSource:sportsImageList.dataSource" data-win-options="{itemTemplate:select('.myTemplate')}"></div>
</div>
</body>
</html>
I have tried many ways to bind the URL to the Image, but on the screen I can only see the links but not the actual images.
Where am I wrong?
All help and suggestions appreciated.
Thank you!
I believe your error is in your assignment line, remember that itemDataSource is a property of the ListView control. As it is in your code you're assigning that property to the imageList element.
Change it to this:
imageList.winControl.itemDataSource = sportsImageList.dataSource;
I tried to use jQuery so I can make the cursor a pointer but it doesn't work. Basically jQuery doesn't work and I don't know what to do because I really tried everything and checked twice.
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="ShowMeHowMainPageCSS.css"/>
</head>
<body>
<div class = "Parts" id = "part1">News Feed</div>
<div class = "Parts" id = "part2">Blog</div>
<div class = "Parts" id = "part3">Video</div>
<div class = "Parts" id = "part4">My Profile</div>
<div id = "menu">
<div id = "newsFeedMenu" class = "circle"></div>
<div id = "BlogMenu" class = "circle"></div>
<div id = "videoToturialsMenu" class = "circle"></div>
<div id = "MyProfileMenu" class = "circle"></div>
</div>
<script>
$(document).ready(function(){
$('.circle').hover(function(){
$(this).css('cursor','pointer');
$('#menu').css('opacity','1');
});
});
</script>
<script type ="text/javascript" src = "jQueryF.js"></script>
<script type ="text/javascript" src = "showMeHowJQUERY.js"></script>
</body>
</html>
you need to load the javascript file first before you define anything using them
put this as the top of your code inside the head tag
<script type ="text/javascript" src = "jQueryF.js"></script>
<script type ="text/javascript" src = "showMeHowJQUERY.js"></script>
So, as you can see I amusing javascript to show/hide elements, however when you click the .png it shows the text but does not hide the other element's text. I have been going over and over this script and Google searching the hell out of it and I cannot come up with an answer. I think I need another pair of eyes, so if anyone takes a look at this let me know if there are errors or if I'm missing some code.
<html>
<head>
<meta name = "viewport" content = "initial-scale = 1.0, user-scalable = no" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<script type="text/javascript" src="NKit.js"></script>
<link rel="stylesheet" type="text/css" href="style.css" />
<script type="text/javascript">
function showStuff(id) {
document.getElementById(id).style.display = 'block';
}
function hideStuff(id) {
document.getElementById(id).style.display = 'none';
}
</script>
</head>
<body>
<div class="content">
<section class="left">
<p>
<img src="character1.png" id="char1" />
</p>
<p>
<img src="character2.png" id="char2" />
</p>
</section>
<section class="right">
<span id="character1" style="display: none;">Show character1 information</span>
<span id="character2" style="display: none;">Character 2 information</span>
</section>
</div>
</body>
</html>
<a href="#" onclick="showStuff('character1');" onclick="hideStuff('character2');">
On this line, you first set the property onclick to showStuff('character1'), then you reassign it to hideStuff('character2').
So, you should wrap these two function calls into one function and then assign that function to onclick.
onclick="function() { showStuff('character1'); hideStuff('character2'); }