Show button if two values are equal - angularjs

I'm finishing up an app of mine, which is a forum, and I need users to be able to delete their own topics.
So, In my "Topics List" template, I have successfully rendered the following code:
<body ng-app>
[...]
<button ng-show="estudante == 'admin'"></button>
[...]
From:
<button ng-show="{{ request.user.username }}=='{{ topic.creator }}'">Remover Tópico</button>
This button should not be displayed if the values of topic.creator and request.user.username are not equal. However, ng-if, ng-hide and ng-show properly configured don't seem to have any effect.
Is there a way to get this to work? Am I missing something on the scopes topic? :)
Thanks in advance!
UPDATE:
Using '' in both values or none is the same. The button is displayed if the value mismatches:
Forum

Normally you dont need the curly brackets around the variable like {{xxx}} in this case. And also the '' can be removed, maybe it works after removing them.
<button ng-show="request.user.username == topic.creator">Remover Tópico</button>

Try this:
<button ng-show="request.user.username == topic.creator">Remover Tópico</button>
In your controller you should have the values you wish to compare assigned to $scope something like this:
$scope.request.user.username = "some name";
$scope.topic.creator = "some name";

<button ng-show="reqeust.user.role === 'admin' && user.username === topic.crator">Remover Tópico</button>
i think this solve this problemn, but verify your code.

Related

AngularJS - Validate a part of a form

I'm using Angular 1.5.9
I have a big form, which I scattered through different Bootstrap Accordion.
When there is an error in the form, I want to be able to change the class of my accordions to show in which accordions the error is located.
To check for errors in a whole form, I can check
myFormName.$error
And to check errors for an element, I can simply do
myFormName.myInputName.$error
But I don't know if there is a way to do this for multiple element at once, without having to check each element individually.
My first thought was to change the name of my inputs like so:
<input name="accordion1.fieldName">
But this didn't give me the expected result: I don't have myFormName.accordion1.$error, actually, I don't even have myFormName.accordion1.fieldName, since my data is actually stored in myFormName['accordion1.fieldName'] which is pretty much useless.
Has anyone found an answer to this problem? I think I'll have to check each field, which is kinda ugly, and a mess to maintain whenever we add / remove fields...
Maybe there is a directive out there that could do that for me, but as a non-native English speaker, I can't find which key words to use for my search in this situation.
One approach is to nest with the ng-form directive:
<form name=form1>
<div ng-form=set1>
<input name=input1 />
<input name=input2 />
</div>
</form>
{{form1.set1.$error}}
You could name the fields with a prefix such as 'accordion1_' then add a controller function that will filter your fields.
ctrl.fieldGroup = function(form, fieldPrefix) {
var fieldGroup = {};
angular.forEach(form, function(value, key) {
if (key.indexOf(prefix) === 0) {
fieldGroup[key] = value;
}
});
return fieldGroup;
}
Then ctrl.fieldGroup('accordion1') will return an object with the appriopriate fields on it. You could extend the function further to add an aggregate $error property to the resulting fieldGroup object.

Show directive as result of a click

I want to show content that comes from a directive when the user clicks on a link.
<li>Show popup</li>
Obviously I'm new to angularjs. I know the approach above doesn't make sense really but I was also trying to imagine how this might be done with ng-if but not coming up with anything. Any ideas? Thanks!
Edit 1: The directive that I want to use is:
<ng-pop-up></ng-pop-up>
That's part of ngPopup.
Edit 2: This is now resolved. It turns out that in the case of ngPopup, you put the directive somewhere, then you open the dialog using the open method, so I really didn't take advantage of the solutions given here. Giving Martin credit because his solution solves problem originally stated. Thanks all.
Not exactly sure what you are looking for.
When you say, content from a directive, is this an existing directive, or do you think the content should come from a directive?
In your example where you have show popup, do you mean you would like to have a dialog displayed when you click the link?
Or do you just want something like the following example?
angular.module('app', []);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app=app>
<a href="#" ng-click='showMessage = true'>Click Here</a>
<div ng-show="showMessage">Your Message Here</div>
</div>
Try looking at using ng-if (AngularJS docs). You can use a boolean in your scope to that is toggled by the ng-click.

AngularJS: how put correct model to repeated radio buttons

I think I have some sort of special code here as all I could google was "too simple" for my problem and it also didn't helped to come to a solution by myself, sadly.
I got a radio button group of 2 radios. I am iterating over "type" data from the backend to create the radio buttons.
My problem is the data binding: When I want to edit an object its "type" is set correctly, but not registered by the view so it doesn't select the desired option.
Follwing my situation:
Backend providing me this as "typeList":
[
{"text":"cool option","enumm":"COOL"},
{"text":"option maximus","enumm":"MAX"}
]
HTML Code:
<span ng-repeat="type in typeList track by type.enumm">
<input
type="radio"
name="type" required
ng-model="myCtrl.object.type"
ng-value="type">
{{type.text}}
</span>
Some Explanation
I don't want to use "naked" texts, I want to use some sort of identifier - in this case it is an enum. The chosen value shall be the entire "type", not only "type.text" as the backend expects type, and not a simple String.
So all I do with this is always a package thingy, the type.text is for like formatted/internationlized text etc.
A Pre-Selection works by setting this in the controller: this.object.type = typeList[0];
The first radio button is already selected, wonderful.
But why isn't it selected when editing the object. I made a "log" within the HTML with {{myCtrl.object.type}} and the result is {"text":"cool option","enumm":"COOL"}. The very same like when pre selecting. I already work with the same "technique" using select inputs, and it works fine. I also found some google results saying "use $parent because of parent/child scope". But 1) I didn't get that straight and 2) think it is not the problem here, as I use a controllers scope and not the $scope, or is this thinking wrong?
It might be explained badly, sorry if so, but I hope someone 1) get's what I want and 2) knows a solution for it.
Thank you!
If you're trying to bind to elements from an array, I believe you need to assign the actual elements from the array to your model property.
So this creates a new obj and sets it to $scope.selectedType (not what you want):
$scope.selectedType = {"text":"cool option","enumm":"COOL"};
whereas this assigns the first element of the array (which is what you want)
$scope.selectedType = $scope.typeList[0];
So to change the model, you can lookup the entry from the array and assign it to your model with something like this
$scope.selectedType = $scope.typeList.filter(...)
Here's a quick example of this approach http://plnkr.co/edit/wvq8yH7WIj7rH2SBI8qF

Angularjs including partials based on location

I want to include different headers in my index.html, one for when the user is logged in, and one for when he's not. This is my idea:
<script>console.log(location.hash === '#/')</script>
<div ng-if="location.hash === '#/' " id="header" ng-include="'partials/homeHeader.html'"></div>
The console prints true, but the part in ng-if doesn't work well. How can I solve this, or is there a better solution?
Thanks!
Inside your controller, create a scope item based on the location hash:
$scope.currentHash = location.hash;
And then use the scope item in your view:
<div ng-if="currentHash === '#/'" ... >

How can I disable a button in AngularJS if there are elements in an array?

I have an object: model.data
How can I disable a button if this object has an array of questions and if that array has more than one element?
I did try:
data-ng-disabled="model.questions.length > 0"
But this does not seem to work at all.
EDIT: Modifying answer in response to posts and comments
What about:
data-ng-disabled="checkQuestions()"
And then in your controller:
$scope.checkQuestions = function() {
if (model.questions.length > 1) { // your question said "more than one element"
return true;
}
else {
return false;
}
};
What it really comes down to is that there are multiple ways to accomplish this task; an expression, a function, a bound variable (as demonstrated by the various responses here). If none of them are working, the problem might lie in your model instead. If you could clear up some inconsistencies (see my comments about asking for the structure of your model... also, are you interested in it disabling if there's anything in the array, or only if there is more than one thing in the array?), it will help figure this out.
Here's a fiddle that shows all three approaches; you'll see that they all work. Compare your controller to the fiddle and see if it comes together.
http://jsfiddle.net/jlmcdonald/P8qjR/3/
You definitely can use an expression instead of a function. But you may check if the array is undefined.
<button ng-disabled="model.questions != undefined && model.questions.length > 0"></button>
I couldn't get #zsong answer to work and I didn't want to create a function just to return an array length, so I got it working by creating another scope variable which returned the array.length.
$scope.modelQuestionsLength = $scope.model.questions.length;
I could then do
<button ng-disabled="modelQuestionsLength > 0"></button>
Create a model then set its default value to false. Then change its value to true, if your array length is not empty. Followed with binding the model to the button's ng-disabled attribute.
I couldn't get the undefined way to work, so if anyone else is having trouble, this worked for me:
<input ng-disabled="fieldsPermittedForEdit.indexOf('postDate') < 0">
In this example, I am disabling the field unless postDate exists in the fieldsPermittedForEdit array.

Resources