ngModel checkbox not shown as selected - angularjs

I'm having some trouble getting a checkbox to display the correct state (checked/unchecked) of my model. I have the following in my controller:
app.controller('PhotosCtrl', ['$scope', function($scope) {
$scope.form = {};
$scope.editPhotos = {
token: $scope.token,
idArray: $scope.idArray
};
}]);
My form looks like this:
<form accept-charset="UTF-8" name="editPhotosForm" ng-submit="submit(editPhotos);" multipart="true" novalidate>
<input name="utf8" type="hidden" value="✓">
<input name="authenticity_token" type="hidden" ng-model="editPhotos.token" ng-init="editPhotos.token='<%= form_authenticity_token %>'">
<div class="results-label"><b>{{total_count}}</b> <span ng-if="total_count == 1">Photo</span><span ng-if="total_count != 1">Photos</span> Found</div>
<div>
<div class="col">
<a ng-repeat="r in results" class="card result-link">
<div class="content result">
<div class="caption">
<input type="checkbox" ng-model="idArray[r.id]">
</div>
<div class="image-container" ng-style="{'background-image': 'url(' + r.image_url + ')'}">
</div>
</div>
</a>
</div>
</div>
</form>
On my repeater element, I call ng-init="idArray[r.id] = 'false'" to initialize a key r.id = 'false' for each item in r. I don't know if I need to do this or not. I've tried the code without it and it makes no difference. I've also tried using ng-value-true and ng-value-false but those don't seem to be working for me.
Most of the other posts I've seen on this issue deal with simple variables (e.g. $scope.someVar = true rather than more complex structures like a hash.
Here is the structure of idArray:
$scope.idArray = {1290: "false", 1291: "true", 1292: "true", 1293: "false", 1294: "false", 1414: "false"};
This is generated by the ng-init in my repeater, since the ids of the photos can't be known beforehand.
Here is what results looks like:
{
id: 1290,
company_id: null,
image_url: "http://s3.amazonaws.com/mybucket/photos/images/000/001/290/original/214.JPG?1432217895"
}

Doing the following
ng-init="idArray[r.id] = 'false'"
You're assigning the string value 'false' into your object.
Can't you deal with that inside your controller?
$scope.idArray = {};
for (var i = 0; i < $scope.results.length; ++i){
$scope.idArray[$scope.results[i].id] = (i%2 == 0);
}
And removing the ng-init="" (which is, according to Angular doc, a bad practice https://docs.angularjs.org/api/ng/directive/ngInit ).
Another thing was the anchor element that was wrapping the checkbox element. This lead to the click event that was not triggered on the checkbox, but only on the anchor.
<div class="col">
<div ng-repeat="r in results" class="card result-link">
<div class="content result">
<div class="caption">
<input type="checkbox" ng-model="idArray[r.id]">
</div>
<div class="image-container" ng-style="{'background-image': 'url(' + r.image_url + ')'}">
</div>
</div>
</div>
</div>
fiddle :
http://jsfiddle.net/patxy/wak7pwwp/

Related

Nested ng-repeat issue with api call

I'm having an issue not seeing the second ng-repeat fields. The first ng-repeat fires no problem and the console log of $scope.fields is getting back the correct data, but the input boxes don't seem to be populating on the page.
I seem to be able to get the data correctly, I just don't seem to be able to get the hang of the nested ng-repeat section.
Here is my HTML
<div class="col-lg-6">
<div id="categories_inputs" ng-repeat="category in categories">
<h2>{{category.name + ' - ' + category.templateCategoryId}}</h2><br>
<div id="field_inputs" ng-repeat="field in fields">
Field: <input ng-value="field.field" />
Label: <input ng-value="field.label" />
</div>
</div>
</div>
Here is js
api.getCategories({templateId: template}, function(categories){
$scope.categories = categories;
angular.forEach(categories, function(value, key){
api.getTemplateFields({templateCategoryId: value.templateCategoryId}, function(fields) {
$scope.fields = fields;
});
});
});
Solved it with changing the js to:
$scope.categoryLoaded = function(category){
api.getTemplateFields({templateCategoryId: category.templateCategoryId}, function(fields) {
alert(category.templateCategoryId);
category.fields = fields;
});
};
and the html is now
<div ng-repeat="category in categories" ng-init="categoryLoaded(category)">
<h2>{{category.name + ' - ' + category.templateCategoryId}}</h2><br>
<div ng-repeat="field in category.fields">
Field: <input ng-value="field.field" />
Label: <input ng-value="field.label" />
</div>
</div>

how to remove the value of an input field using angularjs

<div class="info-block" ng-app="">
<div ng-controller="Note">
<div class="checkbox">
<label>
<p><b>Primary Publication: </b>
{{ form_widget(form.input_ppubs, { 'attr': {'class': 'valOption'}}) }}
</p>
</label>
</div>
<div ng-repeat="item in items">
<input type="text" placeholder="new input" ng-model="item.primaryPub">
</div>
<button type="button" ng-click="add()">New Item</button>
</div>
I am trying to retrieve the value of the html input field and remove it from input upon a button click
I am able to get the code, but I don't know how to remove the code.
var Note = function($scope){
$scope.items = [];
$scope.add = function () {
//angular way of implementing document.getElementByID();
pub1 = angular.element('#form_input_ppubs').val();
$scope.items.push({
primaryPub: pub1
});
};
}
You don't have to retrieve your items like this. It's ugly and not the angular way. angular.element('#form_input_ppubs').val();
Instead, simply reference it in your input using ngModel.
Declare it in your scope.
$scope.inputItem = null;
HTML
<input ng-model="inputItem " />
Use it in your function:
$scope.addItem = function(item) {
$scope.items.push(item);
//reset the model
$scope.inputItem = null;
}
Call it using ng-click
<button type="button" ng-click="addItem(inputItem)">Add Item</button>
If you do:
console.log($scope.items);
You should see an entry for primaryPub, the model for your input. Then you can target it by nulling the model, so:
$scope.items.primaryPub = null;
However you're using this inside an ng-repeat:
<div ng-repeat="(i, item) in items">
<input type="text" placeholder="new input" ng-model="items[i].primaryPub">
</div>
So your console.log (if you have more than one item in 'items') should show an array-like structure for primaryPub.

resetting scope data in ng-repeat error

I'm having trouble resetting a scope model. I am sure I am making an obvious mistake that isn't so obvious to me.
<div class="" ng-repeat="comment in comments">
<div class="feed-entry">
<div class="user-image-round" ng-style="{'background-image':'url({{ comment.comment_user_image }})'}"></div>
<div class="right-text-section">
<div class="commentor-name">{{comment.comment_user}}</div>
<p class="comment-text">{{ comment.comment_text }}</p>
<div class="divider"></div>
<div class="" ng-repeat="entry in comment.comment_response_entries">
<div class="comment-entry">
<div class="commenter-image-round" ng-style="{'background-image':'url({{ entry.user_image }})'}">
</div>
<div class="right-text-section">
<div class="commentor-name">{{entry.user_name}}</div>
<p class="comment-text">{{ entry.response_entry }}</p>
</div>
</div>
</div>
</div>
<div class="comment-post">
<form ng-submit="addComment($index, sub_comment)">
<textarea class="text-area" placeholder="Write a comment" ng-model="sub_comment" required></textarea>
<button class="post-button">Post</button>
</form>
</div>
</div>
</div>
angular.module('App')
.controller('CampaignCtrl', function ($scope){
$scope.addComment = function(index, subcomment){
$scope.comments[index].comment_response_entries.push({
user_name : 'Daniel Tawfik',
user_image : '/images/crowdcitizen/daniel-tawfik.jpg',
response_date : 'October 1xt, 2015',
response_entry : subcomment,
response_entry_likes : 0,
response_entry_liked : false,
});
$scope.sub_comment = '';
}
}
I have an ng-repeat on comments. On each comment entry the user should be able to post a response to the comment. ng-sumbmit calls addComment which takes the comment index pushes a comment_reponse_entry object the array. This works fine.
The problem I am having is that when I reset scope model with $scope.sub_comment = '' the textarea value doesn't update. It seems like the scope has changed, but I can't seem to access it again.

Convert user input into a label using angular.js

What I'am trying to do is convert every user input into a label using angular. I believe that I'am doing the right thing, but is not working. I will appreciate if somebody take a look at this code. Thank you
here is a plunker
<div class="row" ng-controller="tagForm">
<div ng-click="addEntry()">
<div class="col-xs-12 col-sm-12 col-md-10 ">
<input type="text" placeholder="What are your area of expertise" ng-model="newEntry.name" class="form-control border" />
</div>
<div class="col-xs-12 col-md-2 center form-button">
<input type="button" value="Add" class="btn btn-orange btn-add" />
</div>
<div class="col-md-8 col-sm-offset-2" id="up">
<br />
<span class="label label-primary" ng-repeat="entry in entries">{{entry.name}}</span>
</div>
</div>
</div>
app.controller('tagForm', ['$scope', function($scope) {
return $scope.addEntry = function() {
$scope.entries.push($scope.newEntry);
return $scope.newEntry = {};
};
}]);
You have a few things wrong in your Plunk, but here's some stuff to start with:
You need to wire up a click event on your Add button. Right now, its not doing anything when you click it
Bind to an ng-model on the scope just using 'newEntry'. All you're typing is a name so thats all you need to save on the scope.
Loop over entries, printing out just 'entry' instead of 'entry.name'
And your controller should look like this (no need for the returns)
app.controller('tagForm', ['$scope', function($scope) {
$scope.entries = [];
$scope.addEntry = function() {
$scope.entries.push($scope.newEntry);
};
}]);
See this fiddle:
http://jsfiddle.net/smaye81/anrv2qms/1/

AngularJS (jsFiddle included): Scope variable not updated before sent to filter

Here's the jsFiddle: http://jsfiddle.net/VSph2/274/
I'm trying to make a filter with checkboxes.
When the user clicks the checkbox, it adds the id to an array called color_ids. I know that's working because I print the array in the console.
However, when I try to combine that with a filter, it doesn't work. I try to pass the $scope.color_ids array, but it is always passing an empty array and not passing the array with values in them.
app.controller('IndexCtrl', ['$scope', "Product", "Color", function($scope, Product, Color) {
...
// this method is triggered by a checkbox
$scope.toggleColorFilter = function(color_id) {
var index = $scope.color_ids.indexOf(color_id);
if (index > -1) {
$scope.color_ids.splice(index, 1);
} else {
$scope.color_ids.push(color_id);
}
console.log($scope.color_ids); //<-- prints the array properly with the new values.
};
}]);
and a filter that isn't working:
app.filter('productFilter', function(){
return function(input, color_ids) {
console.log(color_ids); //<-- prints an empty array all the time [ ]
return input;
}
})
This is my HTML
<h2>Products</h2>
<div class="filters col-two" ng-controller="IndexCtrl">
<h3>Color</h3>
<div ng-repeat="color in colors">
{{color.name}} <input type="checkbox" ng-model="color_ids" ng-change="toggleColorFilter(color.id)">
</div>
<h3>Shape</h3>
<h3>Material</h3>
</div>
<div class="products col-ten" ng-controller="IndexCtrl">
<div class="product" ng-repeat="product in products | productFilter:color_ids">
<h3>
{{ product.name }}
</h3>
<div class="product-thumbs">
<div class="image-wrapper" ng-repeat="product_color in product.products_colors">
<img src="{{ product_color.color.image.url }}" width="75" height="40">
</div>
</div>
</div>
</div>
I want the filter to eventually only show products with a color_id that exist in the color_ids array.
You have three divs with ng-controller="IndexCtrl" in your JSFiddle example. This is the problem. Each time the Angular compiler finds ng-controller in the HTML, a new scope is created.
<div class="filters col-two" ng-controller="IndexCtrl">
<h3>Color</h3>
<div ng-repeat="color in colors">{{color.name}}
<input type="checkbox" ng-model="color_ids" ng-change="toggleColorFilter(color.id)">
</div>
</div>
<div class="products col-ten" ng-controller="IndexCtrl">
<div class="product" ng-repeat="product in products | productFilter:color_ids">
{{ product.name }}
</div>
</div>
Simpliest way is to place this code in one controller and it will print 2 similiar arrays in your console:
<div ng-controller="IndexCtrl">
<div class="filters col-two">
<h3>Color</h3>
<div ng-repeat="color in colors">{{color.name}}
<input type="checkbox" ng-model="color_ids" ng-change="toggleColorFilter(color.id)">
</div>
</div>
<div class="products col-ten">
<div class="product" ng-repeat="product in products | productFilter:color_ids">
{{ product.name }}
</div>
</div>
</div>
JSFiddle
The filter is applied before the color_ids is updated, you should apply the filter in the controller inside the toggle function:
$filter('productFilter')($scope.products, $scope.color_ids);
Here is the working findle (at least I think): http://jsfiddle.net/VSph2/276/
Don't forget to inject the $filter in your controller.

Resources