感谢你们所有人过去帮助过我们。现在我们遇到了一个新问题。这是显示租赁属性条目的dApp的代码。输入表单正确接受和处理文本字段,但"可用" element,设置为布尔值,格式化为复选框,仅显示值" True"无论是否选中此框。我们尝试过在线查找的每种代码组合,但似乎没有任何效果。请帮忙!并提前致谢。
合同代码:
pragma solidity ^0.4.18;
import "./Ownable.sol";
contract RentalContract is Ownable {
struct Article{
uint id;
address seller;
address buyer;
string propaddress;
uint256 rental_price;
string description;
bool available;
string contact;
}
mapping(uint => Article) public articles;
uint articleCounter;
event LogSellArticle(
uint indexed _id,
address indexed _seller,
string _propaddress,
uint256 _rental_price,
string _description,
bool _available,
string _contact
);
event LogBuyArticle(
uint indexed _id,
address indexed _seller,
address indexed _buyer,
string _propaddress,
uint256 _rental_price,
string _description,
bool _available,
string _contact
);
function kill() public onlyOwner {
selfdestruct(owner);
}
function sellArticle(string _propaddress, uint256 _rental_price, string _description, bool _available, string _contact) public {
articleCounter++;
articles[articleCounter] = Article(
articleCounter,
msg.sender,
0x0,
_propaddress,
_rental_price,
_description,
_available,
_contact
);
LogSellArticle(articleCounter, msg.sender, _propaddress, _rental_price, _description, _available, _contact);
}
function getNumberOfArticles() public view returns (uint){
return articleCounter;
}
function getArticlesForSale() public view returns (uint[]){
uint[] memory articleIds = new uint[](articleCounter);
uint numberOfArticlesForSale = 0;
for(uint i = 1; i <= articleCounter; i++){
if(articles[i].buyer == 0x0){
articleIds[numberOfArticlesForSale] = articles[i].id;
numberOfArticlesForSale++;
}
}
uint[] memory forSale = new uint[](numberOfArticlesForSale);
for(uint j = 0; j < numberOfArticlesForSale; j++){
forSale[j] = articleIds[j];
}
return forSale;
}
function buyArticle(uint _id) payable public {
require(articleCounter > 0);
require(_id > 0 && _id <= articleCounter);
Article storage article = articles[_id];
require(article.buyer == 0x0);
require(msg.sender != article.seller);
require(msg.value == article.rental_price);
article.buyer = msg.sender;
article.seller.transfer(msg.value);
LogBuyArticle(_id, article.seller, article.buyer, article.propaddress, article.rental_price, article.description, article.available, article.contact);
}
}
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Rent My Place</title>
<!-- Title will appear as a tab in browser on webpage -->
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
<!-- Application -->
<link href="css/app.css" rel="stylesheet">
</head>
<body>
<div class="container">
<!-- container that contains title panel-->
<div class="jumbotron text-center">
<p style="font-size:80px;padding: 1em;padding-top: 10px;padding-bottom: 10px; border:10px;border-style:solid;border-color:#c3c3c3;">
<font color = "#880015" >Rent My Place</font></p>
</div>
<div class="col-md-12" id="article-list">
<div class="row">
<div class="col-lg-12">
<p id="account" class="welcome pull-right"></p>
<p id="accountBalance" class="welcome pull-left"></p>
</div>
</div>
<div class="row panel panel-default">
<div class="panel-heading clearfix">
<div class="panel-title">
<p style="font-size:24px;padding: 1em;padding-top: 10px;padding-bottom: 10px; border:5px;border-style:solid;border-color:#c3c3c3;">
<font color = "#880015">Renter's Tip: </font><font color = "#000000">Inspect the property before you send money.</font><br><font color = "#880015">Landlord's Tip: </font><font color = "#000000">Meet prospective tenants in person.</font></p>
<!-- Button that opens second window to a form to fill out-->
<button class="btn btn-info btn-lg pull-right" data-toggle="modal" data-target="#sellArticle">Post a Rental</button>
</div>
</div>
<!-- when the event button gets click, it will show the list-->
<ul id="events" class="collapse list-group"></ul>
</div>
<div id="articlesRow" class="row">
<!-- ARTICLES with pertinent item information LOAD HERE -->
</div>
</div>
</div>
<!--Result that is displayed after input-->
<div id="articleTemplate" style="display: none;">
<div class="row-lg-12">
<div class="panel panel-default panel-article">
<div class="panel-heading">
<h3 class="panel-title"></h3>
</div>
<div class="panel-body">
<strong>Baths</strong>: <span class="baths"></span><br/>-->
<strong>Address</strong>: <span class="propaddress"></span><br/>
<strong>Rental Price</strong>: <span class="rental_price"></span><br/>
<strong>Description</strong>: <span class="description"></span><br/>
<strong>Property is available for showing</strong>: <span class="available"></span><br/>
<strong>Contact Email</strong>: <span class="contact"></span><br/>
</div>
<div class="panel-footer">
<button type="button" class= "btn btn-primary btn-success btn-buy" onclick="App.buyArticle(); return false;">Buy</button>
</div>
</div>
</div>
</div>
<!-- Modal form to sell an article -->
<div class="modal fade" id="sellArticle" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Rent Your Place</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-lg-12">
<form>
<div class="form-group">
<label for="propaddress">Address</label>
<input type="text" class="form-control" id="propaddress" placeholder="Enter the address">
</div>
<div class="form-group">
<label for="rental_price">Rent (in USD) </label>
<input type="text" class="form-control" id="rental_price" placeholder="$" pattern="[0-9]+([\.,][0-9]+)?">
</div>
<div class="form-group">
<label for="description">Description</label>
<textarea type="text" class="form-control vresize" id="description" placeholder="Describe your property" maxlength="255"></textarea>
</div>
<div class="form-group">
<label for="available"></label>
<input type="checkbox" id="available"> Property is available for showing
</div>
<div class="form-group">
<label for="contact">Contact Email</label>
<input type="text" class="form-control" id="contact" placeholder="Enter your contact email" >
</div>
</form>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-success" data-dismiss="modal" onclick="App.sellArticle(); return false;">Submit</button>
<button type="button" class="btn" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<div id="footer" class="container">
<nav class="navbar navbar-default navbar-fixed-bottom">
<div class="navbar-inner navbar-content-center text-center">
<p class="text-muted" credit><a href="http://www.axbean.com">AXbean</a> - © 2018</a></p>
</div>
</nav>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/RentalApp.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/web3.min.js"></script>
<script src="js/truffle-contract.js"></script>
</body>
</html>
Javascript:
App = {
web3Provider: null,
contracts: {},
account: 0x0,
loading: false,
init: function() {
return App.initWeb3();
},
initWeb3: function() {
// initialize web3
if(typeof web3 !== 'undefined') {
//reuse the provider of the Web3 object injected by Metamask
App.web3Provider = web3.currentProvider;
} else {
//create a new provider and plug it directly into our local node
App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
}
web3 = new Web3(App.web3Provider);
App.displayAccountInfo();
return App.initContract();
},
displayAccountInfo: function() {
web3.eth.getCoinbase(function(err, account) {
if(err === null) {
App.account = account;
$('#account').text(account);
web3.eth.getBalance(account, function(err, balance) {
if(err === null) {
$('#accountBalance').text(web3.fromWei(balance, "ether") + " ETH");
}
})
}
});
},
initContract: function() {
$.getJSON('RentalContract.json', function(chainListArtifact) {
// get the contract artifact file and use it to instantiate a truffle contract abstraction
App.contracts.RentalContract = TruffleContract(chainListArtifact);
// set the provider for our contracts
App.contracts.RentalContract.setProvider(App.web3Provider);
// listen to events
App.listenToEvents();
// retrieve the article from the contract
return App.reloadArticles();
});
},
reloadArticles: function() {
//avoid reentry bugs
if(App.loading){
return;
}
App.loading = true;
// refresh account information because the balance might have changed
App.displayAccountInfo();
var chainListInstance;
App.contracts.RentalContract.deployed().then(function(instance) {
chainListInstance = instance;
return chainListInstance.getArticlesForSale();
}).then(function(articlesIds) {
// retrieve the article placeholder and clear it
$('#articlesRow').empty();
for(var i = 0; i < articlesIds.length; i++){
var articleId = articlesIds[i];
chainListInstance.articles(articleId.toNumber()).then(function(article){
App.displayArticle(article[0], article[1], article[3], article[4], article[5], article[6], article[7]);
});
}
App.loading = false;
}).catch(function(err) {
console.error(err.message);
App.loading = false;
});
},
displayArticle: function(id, seller, propaddress, rental_price, description, available, contact) {
var articlesRow = $('#articlesRow');
var articleTemplate = $("#articleTemplate");
articleTemplate.find('.propaddress').text(propaddress);
articleTemplate.find('.rental_price').text('$' + rental_price);
articleTemplate.find('.description').text(description);
articleTemplate.find('.available').text(available);
articleTemplate.find('.contact').text(contact);
articleTemplate.find('.btn-buy').attr('data-id', id);
//seller
if(seller == App.account){
articleTemplate.find('.article-seller').text("You");
articleTemplate.find('.btn-buy').hide();
}else{
articleTemplate.find('.article-seller').text(seller);
articleTemplate.find('.btn-buy').show();
}
//add this new article
articlesRow.append(articleTemplate.html());
},
sellArticle: function() {
// retrieve the detail of the article
var _description = $('#description').val();
var _propaddress = $('#propaddress').val();
var _rental_price = $('#rental_price').val();
var _available = $('#available').val();
var _contact = $('#contact').val();
App.contracts.RentalContract.deployed().then(function(instance) {
//return instance.sellArticle(_description, _beds, _baths, _propaddress, _rental_price, _property_type, _available, _contact_email, {
return instance.sellArticle(_propaddress, _rental_price, _description, _available, _contact,{
from: App.account,
gas: 500000
});
}).then(function(result) {
}).catch(function(err) {
console.error(err);
});
},
// listen to events triggered by the contract
listenToEvents: function() {
App.contracts.RentalContract.deployed().then(function(instance) {
instance.LogSellArticle({}, {}).watch(function(error, event) {
if (!error) {
$("#events").append('<li class="list-group-item">' + event.args._propaddress + ' is now for sale</li>');
} else {
console.error(error);
}
App.reloadArticles();
});
instance.LogBuyArticle({}, {}).watch(function(error, event) {
if (!error) {
$("#events").append('<li class="list-group-item">' + event.args._buyer + ' bought ' + event.args._propaddress + '</li>');
} else {
console.error(error);
}
App.reloadArticles();
});
});
},
buyArticle: function() {
event.preventDefault();
// retrieve the article price and data
var _articleId = $(event.target).data('id');
var _price = parseFloat($(event.target).data('value'));
App.contracts.RentalContract.deployed().then(function(instance){
return instance.buyArticle(_articleId, {
from: App.account,
value: web3.toWei(_price, "ether"),
gas: 500000
});
}).catch(function(error) {
console.error(error);
});
}
};
$(function() {
$(window).load(function() {
App.init();
});
});