Reputation: 1461
I know there has been several questions on this already, but most recommend to use dot syntax which I am already doing. I have an input field which is linked to a scope variable:
<!doctype html>
<html>
<head>
<title>Test - Home</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="/css/style.css">
<script src="/file-upload/angular-file-upload-shim.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
<script src="/file-upload/angular-file-upload.min.js"></script>
<script type="text/javascript" src="/edit_property.js"></script>
<script src="/xml2json.js"></script>
<script>var myProp = "<%= property_id %>";</script>
<style>
body { padding-top:80px; word-wrap:break-word; }
</style>
</head>
<body ng-app="editProp">
<%- include partials/navbar.ejs %>
<div class="container">
<div ng-controller="editPropController">
<div class="row">
<h3 class="form-fonts" ><span class="glyphicon glyphicon-pencil"></span> Edit Property - {{ my_property.name }} </h3>
<button class="btn btn-warning btn-sm" ng-click="changeShowDetails()" ng-show="!showDetails">Edit Details</button>
<button class="btn btn-warning btn-sm" ng-click="changeShowImages()" ng-show="showDetails">Edit Images</button>
<div class="input-text-form" style="padding-top:10px;" ng-show="showDetails">
<div class="col-md-6 form-group">
<label class="form-fonts" for="name">Name</label>
<input class="form-control" id="name" type="text" ng-model="my_property.name"/>
</div>
<div class="col-md-6 form-group">
<label class="form-fonts" for="price">Price ($)</label>
<input class="form-control" id="price" type="text" ng-model="my_property.price"/>
</div>
<div class="col-md-6 form-group">
<label class="form-fonts" for="city">City</label>
<input class="form-control" id="city" type="text" ng-model="my_property.city" placeholder="e.g. Chicago" required/>
</div>
<div class="col-md-6 form-group">
<label class="form-fonts" for="state">State</label>
<input class="form-control" id="state" type="text" ng-model="my_property.state" required placeholder="e.g. IL" ng-minlength="2" ng-maxlength="2"/>
</div>
<div class="col-md-6 form-group">
<label class="form-fonts control-label">Apt, Suite, Bldg. (optional)</label>
<input name="suite" class="form-control" type="text" placeholder="e.g. Apt #7" ng-model="my_property.suite" />
</div>
<div class="col-md-6 form-group">
<label class="form-fonts" for="zip">Zip</label>
<input class="form-control" id="zip" type="text" ng-model="my_property.zip"/>
</div>
<div class="col-md-6 form-group">
<label class="form-fonts" for="bedrooms">Bedrooms</label>
<input class="form-control" id="bedrooms" type="text" ng-model="my_property.num_beds"/>
</div>
<div class="col-md-6 form-group">
<label class="form-fonts" for="bedrooms">Bathrooms</label>
<input class="form-control" id="bedrooms" type="text" ng-model="my_property.num_beds"/>
</div>
<div class="col-md-6 form-group">
<label class="form-fonts" for="is_rented">Is Rented?</label>
<input class="form-control" id="is_rented" type="text" ng-model="my_property.is_rented"/>
</div>
<div class="col-md-12 form-group">
<label class="form-fonts" for="description">Description</label>
<textarea class="form-control" id="description" name="description" ng-model="my_property.description" srows="3"></textarea>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
The input field gets populated with the correct value, but I am not able to edit it. Even more bizarre is that the textarea can be edited... Here is the controller:
'use strict'
var editProp = angular.module('editProp', ['angularFileUpload'])
.run(function ($rootScope, $location, $http) {
$http.get('/api/config').success(function(config) {
$rootScope.config = config;
});
});
function editPropController($scope, $http, $window, $upload, $rootScope, $route) {
$scope.prop_id = myProp;
$scope.my_property;
$scope.showDetails = true;
$scope.newImageUploads = [];
$scope.selected_images = [];
$http.get('/api/propertyById/' + $scope.prop_id)
.success(function(properties) {
$scope.my_property = properties[0];
})
.error(function(err) {
alert('We got an error: ' + err);
});
$scope.saveEdits = function() {
$http.put('/api/updateProperty', $scope.my_property)
.success(function(property) {
var myImages = {};
myImages['imageArr'] = $scope.newImageUploads;
$http.put('/api/updatePropertyImages/' + $scope.prop_id, myImages)
.success(function(data){
console.log('success');
$window.location.href = '/profile';
})
.error(function(data) {
alert('There was an uploading the images. Please contact [email protected] for assistance');
})
})
.error(function(err) {
alert('we got an error: ' + JSON.stringify(err));
})
};
$scope.select_image = function(image) {
var image_index = $scope.selected_images.indexOf(image)
if(image_index != -1) {
$scope.selected_images.splice(image_index, 1);
} else {
$scope.selected_images.push(image);
}
}
$scope.delete_selected_images = function() {
console.log('selected images: ' + JSON.stringify($scope.selected_images));
}
$scope.changeShowDetails = function() {
$scope.showDetails = true;
};
$scope.changeShowImages = function() {
$scope.showDetails = false;
};
$scope.cancel = function() {
$window.location.href = '/profile';
};
}
Here is the $scope.my_property object:
{"__v":0,"_id":"53655b63d81f2e3eaf000001","city":"test","description":"this is a test property","is_rented":false,"landlord_id":"53504b0230d09f1c4a000001","latitude":"41.8902901","longitude":"-87.6384679","name":"test","num_baths":1,"num_beds":1,"price":1800,"street":"test","zip":"60654","imageURLs":["https://test.s3.amazonaws.com/shimmy-assets%2F3320%24hottub.jpg"]}
And finally the api call to get the property:
exports.propertyById = function(req, res) {
console.log('getting property by id: ' + req.params.property_id);
Property.find({'_id': req.params.property_id }, function(err, property) {
if(err) res.send(err);
res.send(property);
});
};
Again, the form does get populated with values it's just they cannot be edited. I added all my code because previous answers have not been able to find the solution.
Upvotes: 2
Views: 1666
Reputation: 60416
You have a CSS problem. Not Angular.
Your input fields are wrapped in divs with col-md-6
class. Bootstrap grid classes (except the col-xx-12
class) are floated. This means the box (non-floating) element that comes after them will be rendered over them, thus making them inaccessible to mouse click.
This is why your last form control (textarea) is editable; it is overflowing all other fields.
Twitter Bootstrap grid columns (elements with col-nn-[1-11]
class) are supposed to be wrapped in row
class, in order to "contain" the floating. In your HTML you did not wrap your input pairs in row
class.
To fix, simply wrap each input pair in <div class="row">
element.
Solution excerpt:
<div class="row">
<div class="col-md-6 form-group">
<label class="form-fonts" for="name">Name</label>
<input class="form-control" id="name" type="text" ng-model="my_property.name" />
</div>
<div class="col-md-6 form-group">
<label class="form-fonts" for="price">Price ($)</label>
<input class="form-control" id="price" type="text" ng-model="my_property.price" />
</div>
</div>
<div class="row">
<div class="col-md-6 form-group">
<label class="form-fonts" for="city">City</label>
<input class="form-control" id="city" type="text" ng-model="my_property.city" placeholder="e.g. Chicago" required/>
</div>
<div class="col-md-6 form-group">
<label class="form-fonts" for="state">State</label>
<input class="form-control" id="state" type="text" ng-model="my_property.state" required placeholder="e.g. IL" ng-minlength="2" ng-maxlength="2" />
</div>
</div>
... and so on
Upvotes: 0
Reputation: 9497
I was able to reproduce this on my computer, but not on plunker. The fix was to upgrade bootstrap to at least version 3.0.3
.
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css"/>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
At a glance, I don't see a specific mention of this bug in the list of bug fixes and changes for the release. But 3.0.2
was the last version I could reproduce the error in. Upgrading to 3.0.3
eliminated the problem.
Update
The bug can be reproduced in plunker using the embedded view: http://embed.plnkr.co/7cmvSLFMlek40R6igKba/preview
And here is a demonstration of the fix, upgraded to bootstrap version 3.0.3
:
http://embed.plnkr.co/IBfNRzR63wzE2EFwRRm0/preview
Upvotes: 4
Reputation: 9813
Code look forme fine too. What should you do:
P.S. Do you check console output? P.P.S. Your angular version is very old...
Upvotes: 0
Reputation: 1567
ng-model supports two way data binding which means if you can see the value populated and can edit it in textbox, it changes in background at the same time, in your case $scope.property.name
Upvotes: 0
Reputation: 6187
There seems to be no problem with your code, i created a fiddle and successfully populated the input field and updated it.
Example:
js:
app.controller('MyCtrl', function($scope, $http) {
$scope.property = {};
$http.get('data.json')
.success(function(data) {
$scope.property = data[0];
})
});
html:
<body ng-controller="MyCtrl">
<label class="form-fonts" for="name">Name</label>
<input class="form-control" id="name" type="text" ng-model="property.name"/>
{{property}}
</body>
Live example: http://plnkr.co/edit/gka74k4dn9hs0AHJ4TZi?p=preview
Upvotes: 0