thebiglebowski11
thebiglebowski11

Reputation: 1461

angularjs not able to update input fields

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

Answers (5)

Stewie
Stewie

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.

WORKING PLUNKER

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

j.wittwer
j.wittwer

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

Anton Bessonov
Anton Bessonov

Reputation: 9813

Code look forme fine too. What should you do:

  1. Remove ALL script- and link-meta-tags (also js and css) from html file. Are field enabled now?
  2. Add script-meta-tags one after one and check if fields still enabled: angular.min.js, jquery.min.js
  3. Add edit_property.js and remove dependency to angular-file-upload (replace ['angularFileUpload'] with [])
  4. Still populated and enabled? Add another scripts. Enabled? Add css's. Enabled? Restore dependency to ['angularFileUpload'].

P.S. Do you check console output? P.P.S. Your angular version is very old...

Upvotes: 0

Priya Ranjan Singh
Priya Ranjan Singh

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

Alex Choroshin
Alex Choroshin

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

Related Questions