ng-if expression not evaluating correctly - javascript

I am a very confused as to why my ng-if expression is not evaluating like I think it should be. I am taking the ID of the button from the previous page, and trying to match that ID with a new ID on the next page with an ng-if expression.
My index.html page produces the amount of buttons based off my JSON object data, then when one gets clicked, it should go in my getButtonClicked scope with the correct ID of the button clicked. In the scope, I store this correct ID in a sessionStorage.
index.html
<div ng-controller="AppCtrl">
<button ng-repeat="x in data" id="{{x.id}}" ng-click="getButtonClicked(x.id)" onclick="window.location='secondPage.html';" >{{x.id}} {{x.userFirstName}} {{x.userLastName}}</button>
</div>
retrieveData.js
// creates a module
var myApp = angular.module("myModule",[]);
myApp.controller('AppCtrl' , function($scope, $http){
$http.get("thisurlworksjustreplacingip")
.success(function(response) {$scope.data = response;});
$scope.getButtonClicked = function(buttonNumber){
sessionStorage.setItem("school", buttonNumber);
}
});
function returnSchool(){
return (sessionStorage.getItem("school"));
}
Then on my secondPage.html I try to match up the sessionStorage variable, which I return in returnSchool() to the ID of a button in ng-if. So if you clicked the second button on the first page, it should show a button on the second page with that same data. Eventually I will change the data that is displayed on the button, I just want get the ID's matched properly before I do so.
secondPage.html
<div ng-controller="AppCtrl">
<button ng-repeat="x in data" id="{{x.id}}" ng-if="x.id == returnSchool()">X ID: {{x.id}} Get Value: {{returnSchool()}} {{x.userFirstName}} {{x.userLastName}}</button>
</div>
<script>console.log(returnSchool());</script>
The thing I do not understand is, when I try to print it out on the button using angular, returnSchool() will not print anything. When I print out returnSchool() in the console below, it prints out the correct ID of the button I clicked on the last page (1,2,3,4). If I change ng-if="x.id == returnSchool()", which displays no buttons, to ng-if="x.id != returnSchool()", it prints all the buttons, leaving me to believe that maybe returnSchool() does not equal the button id pressed on the previous page? I think something is just not evaluating properly in my ng-if.

Related

ng-disabled on inputs from ng-repeat loop

I'm displaying inputs basing on array like this
<div data-ng-repeat="n in langInput.values">
<input type="text"
id="auction_name_{{n.selected}}"
class="form-control"
name="auction_name_{{$index}}"
data-ng-model="inputs.auction_name[$index + 1]"
data-ng-minlength="5"
data-ng-maxlength="60"
required />
<span data-ng-show="sellItem['auction_name_'+$index].$error.required">Wymagane!</span>
It also give's me ability of angularjs validation. Next after <form> is closed I want to create "next" button but I also want to do validation there so if user don't fullfill required inputs he will not be able to click it.
Array which I'm ng-repeating on is:
$scope.langInput = {
count: 3,
values: [
{
id: "1",
selected: "pl"
},
{
id: "2",
selected: "eng"
}
],
add: function () {
if (this.count < 7) {
this.values.push({id: this.count, selected: "eng"});
this.count += 1;
console.log(this.values);
}
},
remove: function () {
if (this.count > 2) {
this.values.pop();
this.count -= 1;
console.log(this.count);
}
}
};
I know I can use this ng-disabled directive however I don't know how I can check this inputs which are displayed in loop because its name is changing depending on $index of loop.
I've created plunker
My situation is that I know that I can disable button when some of element is invalid by ng-disabled="sellItem.$error" but in my form in real project I have this form much bigger and I have many ways of acomplishing form so in the end when user finish fullfilling form user still got some of inputs which are not even shown invalid.
So I can't use ng-disabled="sellItem.$error" because after user complete form he still got invalid inputs in background.
I also can not split form to many little forms because it will call 1 endpoint on submit.
What I did in real project is inject 3 different buttons and show them on correct step. Every of this button need to have ng-disabled to not let user to go to next step without completing step' inputs.
So intead of ng-disabled="sellItem.$error" I need to specify all inputs in ng-disabled of one step ( which is about 5 inputs ).
So it would look something like this:
ng-disabled="sellItem.first_input.$error &&
sellItem.second_input.$error && ..."
And I would do this but then I come to problem that I can't "loop" inside of ng-disabled and I want to "loop" inside it because names of inputs are generated by JS
name="auction_name_{{n.id}}"
they and not constant they change, user can add more inputs and delete them
at page start I have two inputs which after JS run are name="auction_name_1" and name="auction_name_2" (due to binding interpolated value) and then user can and third one name="auction_name_3"so I can't also hardcode them within ng-disabled.
I don't know how I can check this inputs which are displayed in loop because its name is changing depending on $index of loop.
Generally one stores the input as a property of the object in the array so that it stays with the object as its position in the array changes.
Also use the id property of the object:
<form name="sellItem" ng-submit="submit()">
<div data-ng-repeat="n in langInput.values">
<input type="text"
id="auction_name_{{n.selected}}"
class="form-control"
̶n̶a̶m̶e̶=̶"̶a̶u̶c̶t̶i̶o̶n̶_̶n̶a̶m̶e̶_̶{̶{̶$̶i̶n̶d̶e̶x̶}̶}̶"̶
name="auction_name_{{n.id}}"
̶d̶a̶t̶a̶-̶n̶g̶-̶m̶o̶d̶e̶l̶=̶"̶i̶n̶p̶u̶t̶s̶.̶a̶u̶c̶t̶i̶o̶n̶_̶n̶a̶m̶e̶[̶$̶i̶n̶d̶e̶x̶ ̶+̶ ̶1̶]̶"̶
data-ng-model="n.input"
data-ng-minlength="5"
data-ng-maxlength="60"
required />
<span data-ng-show="sellItem['auction_name_'+n.id].$error.required">Wymagane!</span>
<span data-ng-show="sellItem['auction_name_'+n.id].$error.minlength">Za krótkie!</span>
<span data-ng-show="sellItem['auction_name_'+n.id].$error.maxlength">Za długie!</span>
</div>
<button type="submit" ng-disabled="sellItem.$error">
{{Submit}}
</button>
</form>
Be sure to generate unique values for the id property.
Update
Added Submit button.
For more information, see
AngularJS Developer Guide - forms
AngularJS <form> Directive API Reference
AngularJS ng-submit Directive API Reference

Meteor: Creating a single CMS form

So I am having difficulty creating a single form that, when updated, updates HTML text.
For example, on page 1 of my site, there is a form with the words TITLE written in it. Now on page 2 the only words on the page are TITLE. Now I want to be able to update that form to now say TITLE 2 and have is update page 2 instantly.
I want to make lots of these forms so what is the way to do this with the least amount of code?
If your form and the element showing your text are in different template, you have to use Session.
In your first template (page 1): Attach an event to your input so when you type text you update the Session variable.
In your second template (page 2): Use a simple helper returning the value of the Session variable
Here's the code:
<template name="page1">
<input type="text" class="js-change-text">
</template>
Template.page1.events({
"keyup .js-change-text"(event, instance) {
let inputValue = event.target.value);
Session.set('inputValue', inputValue);
},
});
<template name="page2">
<h1>{{getInputValue}}</h1>
</template>
Template.page2.helpers({
getInputValue() {
return Session.get('inputValue');
},
});

How do I dynamically set the value of a input when I load the html after a click?

So I have a bunch of p elements that call the redo function on click.
As you can see, I load the quest[q] template onto the .form div when it gets clicked. Each of these templates that can be loaded were previously submitted forms that sent the value to an object.
When the P element gets clicked, the idea is to rerender the form that gives the user the ability to modify the value in the object.
Right now I am just hard coding examples as you can see by setting the value of income id (which is the id of the input on template that I am rendering onto the .form div).
However this isnt working, so when the template is rerender, the value in the input blank.
Can anyone help me figure out so as to how I can get the value of the input to show the previously submitted value?
function redo(q,elem){
q=Number(q);
console.log(q);
if(q+1 != iterator){
$('.form').load(quest[q]);
iterator=q+1;
}
var income = document.getElementById('income');
income.value=1; (this will be objectname.property);
}
Here you go with an example solution https://jsfiddle.net/1nxv2qhr/1/
$('p').click(function(){
$("#income").text("This is a test message");
$('#div1').html("This is a test message");
$('#textbox1').val("This is a test message");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Click Me!!!</p>
<p id="income"></p>
<div id="div1"></div>
<input type="text" id="textbox1" />
For, setting the value to an element like (paragraph, div), please use .html or .text and for input textbox use .val
Hope this will help you to achieve solution.

Showing URL in the button title

So, I have 4 categories, 2 subcategories and two button as shown below.
https://jsfiddle.net/mboz45fv/15/
So, here is what I am trying to achieve.
There are two buttons and 4 category buttons, 2 sub category buttons.
By default, it will say Button 1 and Button 2.
When cat_B button is clicked (Image-A), the user will be directed to .com/cat_B page (Image-B). I want to show the cat_B in the title of the button 1 as shown in the picture.
Each categories will have two sub-categories.
When sub_cat_B is clicked, the user will be redirected to .com/cat_b/sub_cat_b. I would like the title of the button 2 to be sub_cat_B when they are in that page.
How can I achieve this?
Thanks!
Personally I would build each page with seperate buttons already showing the host page URl, precisely as you describe, i presume there is a reason why not. if you do want to set a buttons text with jquery you could use:
$("#cat_b").html('.com/cat_b');
If reduced code is what youre after then assuming you are using buttons not inputs and have structured your button something like:
<button id="cat_b" class="butt" onclick="location.href='.com/cat_b'">button</button>
You could use #rkho's approach but grab the url directly from the buttons own onclick attribute, also triggering this by class should reduce the amount of code:
$('.butt').click(function(){
var link=$(this).attr('onclick');
var buttonText = link.substr(link.lastIndexOf('/') + 1);
$("#cat_b").html(buttonText)
})
We're going to get the URL in the window first. Let's store it in a variable called id:
var id = window.location.href
Then, let's grab everything to the right of that last slash:
var buttonText = id.substr(id.lastIndexOf('/') + 1);
Now, you can set your specific button (let's assume you've labeled it with a class 'button'):
$(".button").text(buttonText);

Accessing dynamic element id's in AngularJS

I am working with an app that has an ng-repeat that populates a navigation sidebar with a list of items from a Mongo DB. The ng-repeat also populates a series of option buttons for each item. A couple of these option buttons share a dynamic id for each iteration in the ng-repeat. What should be happening here is when I click on one of these buttons, it would change the button 'text' and display some additional options under the menu item and toggle back when clicked again.
Here is my code for these buttons:
<span>
<button ng-hide="highlightItem()" ng-click="showTopic()" ng-attr-id="{{ 'category' + subject._id }}" class="add-button"><i class="fa fa-chevron-down"></i></button>
<button ng-click="hideTopic()" ng-show="highlightItem()" ng-attr-id="{{ 'category' + subject._id }}" class="add-button"><i class="fa fa-chevron-up"></i></button>
</span>
The issue that I am having is that I cannot seem to figure out how to access that dynamic id in my controller. I have code in place that will change the button between the ng-show and ng-hide, but it does it for all iterations of ng-repeat.
This is currently how I am attempting to access the dynamic id. I am not getting any errors, but when I try to use this in my function it doesn't work.
$scope.subjectList = subjects.get({});
var topicButton = document.getElementById('topic' + $scope.subjectList._id);
I have also tried
var topicButton = document.getElementById('topic' + $scope.subject._id);
What is the best way to access the dynamic id in Angular/Javascript? I do not want to use jQuery with this if at all possible.
First and foremost, never manipulate the DOM within an angular controller! It is bad practice. Also, it is bad practice to evaluate methods in ngShow/ngHide.
If I understand you correctly, you're trying to get the subject_id for some reason when the button is clicked. Why can't you just pass back either the id or the entire subject to your method? Then your html would look something like this:
<span>
<button ngClick="toggleTopic(subject)" class="add-button">
<i class="fa" ng-class="{'fa-caret-down': subject.hidden, 'fa-caret-up': !subject.hidden}"></i>
</button>
</span>
Then in your controller you could write something like this:
$scope.toggleTopic = function(subject) {
subject.hidden = !subject.hidden;
};
Using the hidden attribute of your subjects, you can now show or hide elements of your dropdown with ngShow/ngHide like so:
<p ng-bind="subject.descripton" ng-hide="subject.hidden"></p>
This way, you don't have to search the DOM for elements at all.

Categories

Resources