Angular get form elements - javascript

I am trying to get element name and class from a form that is passed on to a function. How can i do that?
Html side.
<form name="test">
<div>
<input type="text" class="test1" name="test2"/>
</div>
<div>
<input type="text" class="test3" name="test4"/>
</div>
</form>
<div>
<input type="button" data-ng-click="save(test)" />
</div>
and Javascript side
$scope.save = function(form){
for(how many elements are there)
(get elements values)
}
how can I do that, can it even be done like that? My purpose is to change class and some other attributes when it's necessary.

You can access the form directly from $scope using its name, i.e. $scope.test, and the elements from the form, e.g. $scope.test.test2.
However, if you want to loop through the elements without having to know their individual names you can do something like:
angular.forEach($scope.test, function (element, name) {
if (!name.startsWith('$')) {
// element is a form element!
}
});

I'm relatively new to AngularJS, but I am going to make a solid attempt to answer to test my knowledge and hopefully help you.
So in your form, on each of your elements you should use a ng-model. For example, here is a form that may collect a users first and last name:
<form name="test">
<div>
<input type="text" class="test1" name="test2" data-ng-model="user.name/>
</div>
<div>
<input type="text" class="test3" name="test4" data-ng-model="user.last/>
</div>
</form>
<div>
<input type="button" data-ng-click="save(test)" />
</div>
This will allow you to access the data in your form through $scope.user.
Now for changing classes and attributes, I'm not sure what rules dictate a class/attribute change on your form, but you could use the ng-dirty class as a "flag" to watch for when the user makes a change. Some more information here as to what exactly you are trying to accomplish would be helpful.

A common piece of advice I've seen for angular.js is that, you should only do DOM manipulation in directives, so you should definitely consider doing it according to Anthony's answer, that is, using ng-model.
Go down below to see a way to do it more properly using directives.
But if you insist on doing it in the controller, here is a jsfidle that shows you how you can approach it:
http://jsfiddle.net/3BBbc/2/
HTML:
<body ng-app="myApp">
<div ng-controller="MyCtrl">
<form id="test">
<div>
<input type="text" class="test1" name="test2" />
</div>
<div>
<input type="text" class="test3" name="test4" />
</div>
</form>
<div>
<input type="button" ng-click="save('test')" value="submit" />
</div>
</div>
</body>
JavaScript:
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.save = function (formId) {
$('#' + formId).find('input').each(function (idx, input) {
// Do your DOM manipulation here
console.log($(input).val());
});
};
}
And here is the jsfiddle showing you how to do it with directives. It's a bit more complicated though...:
http://jsfiddle.net/3BBbc/5/

I am trying to get element name and class from a form that is passed on to a function. How can i do that?
Your pseudocode is on the right track:
$scope.save = function( formName ) {
angular.forEach( $scope[ formName ], function( field, fieldName ) {
// Ignore Angular properties; we only want form fields
if( fieldName[ 0 ] === '$' ) {
return;
}
// "fieldName" contains the name of the field
// Get the value
var fieldValue = field.$viewValue;
} );
}
My purpose is to change class and some other attributes when it's necessary.
To do that, you can get the field elements, with the Angular element wrapper:
// Get the field element, as an Angular element
var fieldElement = angular.element( document.querySelector( '[name="' + fieldName + '"]' ) );
You can then use various jqLite methods on these elements. For instance, to set the element's class (overwriting the existing class), you can use the attr method:
// Replace existing class with "new-class"
fieldElement.attr( 'class', 'new-class' );

Related

How to trigger JS event only for the non-hidden media query class?

I have few input html tags with same class name for mobile and desktop (media query)
Sometimes $(".className").val() is empty since it is taking value from the hidden html tag.
$(".className").val() should only fetch value from the non hidden html tag.
Html -
<div class="mobileDiv">
<input type="text" class="searchItem">
<input type="text" class="searchCategory">
</div>
<div class="desktopDiv">
<input type="text" class="searchItem">
<input type="text" class="searchCategory">
</div>
Javascript -
// Same code is shared for both mobile and desktop
$(document).on('keyup', '.searchItem', function() {
val = $(".searchItem").val()
categoryVal = $(".searchCategory")
// cannot use "this" because other class values are also needed on this event
});
How do i achieve this?
Using $(".searchItem").val() will always return the value of the first one found in the page.
Within the event handler function this is the element the event actually occurred on
$(document).on('keyup', '.searchItem', function() {
let val = $(this).val()
console.log(val)
});
input.mobileDiv{display:none}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" class="searchItem mobileDiv">
<input type="text" class="searchItem desktopDiv">

Show/hide angular element by condition

I built a feature adding "and zombies" to book names of choice, using basic angular.
<input type="text" ng-model="bookname" onclick="zombies()">
<h1> {{bookname}} </h1>
I want the "and zombies" (and the text inserted in the input) to be displayed only when there's text inside the input.
I tries this for starts, just to call the angular using JS and it doesn't work.
<script>
function zombies() {
document.getElementsByTagName("h1").innerHTML = "{{}}" + "and zombies";
};
</script>
How do I display the text when there's text inside the input?
(please go easy on me, I'm studying alone and you all started as juniors)
You Just need to add the condition which checks the value of bookname and display the static content with your name.
Like this -
<input type="text" [(ngModel)]="bookname" (click)="zombies()">
<h1> {{bookname}} <span *ngIf='bookname'>and zombies</span> </h1>
You can use a condition here.
<input type="text" [(ngModel)]="bookname" onclick="zombies()">
<h1 *ngIf="bookname"> {{bookname}} and zombies</h1>
Or if you want to use javascript:
<input type="text" ng-model="bookname" onclick="zombies()">
<h1 id="txtheading"></h1>
function zombies() {
var heading_value = document.getElementById("txtheading").value;
document.getElementById("txtheading").innerHTML = heading_value + " and zombies";
};
Easiest Solution you don't need onclick function ng-model will work itself.
AngularJs:
<input type="text" ng-model="bookname">
<h1>{{(bookname)? bookname+' and zombies' : bookname}}</h1>
Angular 2/4/5/6:
<input type="text" [(ngModel)]="bookname">
<h1>{{(bookname)? bookname+' and zombies' : bookname}}</h1>

javascript add button with two input

I'm trying to write this in javascript without using jquery. It basically has two input field: author and quote, and on click should be added to the page.
I'm also trying to save it on the page in case I leave the page. The added quote disappears when i execute the method:
function radd() {
if((document.getElementById("q").value!="") && (document.getElementById("a").value!="")) {
$("#mid-wraper" ).append("<p class='left-bullet'>"+document.getElementById("q").value+"-<span class='yellow-heading'>"+ document.getElementById("a").value+"</span></p>");
document.getElementById("q").value="";
document.getElementById("a").value="";
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="but" onClick="radd()">Add</button>
<label for="q">Add ur Quote!</label><input id="q" name="q" />
<label for="a">The author name</label><input id="a" name="a" />
Try this
function radd()
{
if((document.getElementById("q").value!="")&& (document.getElementById("a").value!=""))
document.getElementById("mid-wraper").innerHTML += "<p class='left-bullet'>"+document.getElementById("q").value+"-<span class='yellow-heading'>"+ document.getElementById("a").value+"</span></p>";
document.getElementById("q").value="";
document.getElementById("a").value="";
}
function add(){
//create a new elem
var el=document.createElement("p");
//you can assign id, class , etc
el.id="yourcustomid";
el.textContent="yourcontent";
//then add to the wrapper
var wrapper=document.getElementById("mid-wrapper");
wrapper.appendChild(el);
}
This code shows you how to create a new paragraph and add it to your wrapper js...
You could also do something like this; far more easier in my opinion. Simply create both inputs, but set their attributes to hidden. And using javascript, delete the "hidden" attribute.
<button id="but" onClick="radd()">Add</button>
<input id="q" hidden="hidden" >Add ur Quote!</input>
<input id="a" hidden="hidden">The author name</input>
The JS part:
function radd(){
document.getElementById("q").removeAttribute("hidden");
document.getElementById("a").removeAttribute("hidden");
}

How to bind the value of select to an input when it's dinamically created

I have a problem with a Js/Rails code. I have a form that is created dynamically when I click a button(It can create multiple of this forms in the same page), it contains a select that have an ID that is never the same. I need to put some value into an input according to the select value. In the first form It works perfectly but later in the other forms it doesn't work. Like I said, I don't have access to the ID's because those are created in rails.
HTML
<div class="test">
<div>
<div class="divSelect">
<select id="1470190840697_ad_type">
<option>Element1</option>
<option>Element2</option>
<option>Element3</option>
<option>Element4</option>
<option>Element5</option>
<option>Element6</option>
</select>
</div>
<div class="divInput">
<input type="text">
</div>
</div>
<div>
//This is dynamically created
<div class="divSelect">
<select id="1470190846932_ad_type">
<option>Element1</option>
<option>Element2</option>
<option>Element3</option>
<option>Element4</option>
<option>Element5</option>
<option>Element6</option>
</select>
</div>
<div>
<input type="text">
</div>
</div>
Javascript - jQuery
$('.test').on('change',$('.divSelect').children('select'),function(){
updateTime();
});
function updateTime() {
var tipoPauta = { 'Element1':1,
'Element2':2,
'Element3':3,
'Element4':4,
'Element5':5,
'Element6':6
}
var select = $('.divSelect').children('select');
$('.divInput').children('input').val(tipoPauta[select.val()]);
};
JSBIN CODE
Thanks a lot! I'm crazy with this problem.
As #adeneo mentioned, you need to specify a string as a selector as the second argument. Also to update the correct input element, your code should be something like
$('.test').on('change', '.divSelect' ,function(){
var $select = $(this).find('select');
updateTime($(this), $select);
});
function updateTime($divelement, $selectelement) {
var tipoPauta = { 'Element1':1,
'Element2':2,
'Element3':3,
'Element4':4,
'Element5':5,
'Element6':6
}
var $input = $divelement.next().children('input');
$input.val(tipoPauta[$selectelement.val()]);
};

Get auto incremented div id so that it can be used with ajax to return a value back to php

Using mysql_query results to create an html form like below with auto incremented prefixed value for div ids:
<div id="favorite'.$count.'">
<form action="javascript:void(0);" method="post">
<input type="hidden" name="sec" value="'.$ident_inpt.'"/>
<input type="hidden" name="t" id="t'.$count.'" value="mo-'.$usr.'-'.$rmid.'-'.$_SESSION['STORE'].'"/>
<input type="submit" value="'.$lang['590'].'" class="favorites" onclick="upd_favorite();"/>
</form>
</div>
How can I get the ids of favorite### and t### so that I can get the loop going?
I use this but only works with static ids:
$('#favorite').html(ajaxRequest.responseText);
and: var addit = document.getElementById("t").value;
Thanks in advance for any suggestion.
You could use something like the following. demo: http://jsfiddle.net/MCkRk/
$('div[id^=favorite]').each(function() {
console.log('inputval', $(this).find('input[id^=t]').val());
});​
You could also specify a common class across the elements:
<div id="favorite1" class="favs"></div>
<div id="favorite2" class="favs"></div>
And then you can grab them all like:
$('.favs').each(function() {
console.log($(this).id);
}
You could also specify a custom attribute like:
<div id="favorite1" customattr="favorite"></div>
And grab them like:
$('[customattr=favorite]').each(function() { ... };

Categories

Resources