Angular: Get ng-model by ng-attr-id? - javascript

Is there a way to get ng-model value by ng-attr-id ?
I'm making a Comment/Reply box and I would like to get the value of the current reply.
Here is my html--
<div class="comments-list" ng-show="CommentsLoaded">
<ul>
<li ng-repeat="comment in comments">
<div>
{{comment.content}}
</div>
<div ng-click="showReply(comment.id)">
Reply
</div>
<div ng-class="hideReply" ng-attr-id="{{'reply-'+comment.id}}">
<textarea ng-model="replytxt" ng-attr-id="{{'replytxt-'comment.id}}"></textarea>
<div class="form-group">
<button type="button" ng-click="sendReply(comment.id)">
Publier
</button>
</div>
</div>
</li>
</ul>
</div>
Here is the angularjs--
$scope.sendReply = function(commentId){
var elm = document.getElementById('replytxt-'+commentId);
console.log(elm);
}
The above function show this in console:
<textarea ng-model="replytxt" ng-attr-id="{{'replytxt-'+comment.id}}" class="ng-pristine ng-valid ng-touched" id="replytxt-31"></textarea>

You don't need to retrieve element value by its selector. Do pass replytxt value inside sendReply function itself on click.
ng-click="sendReply(comment.id, replytxt)"
$scope.sendReply = function(commentId, replytxt){
Suggestion: rather than having replytxt there independently as ng-model, you can put it on comment level property like comment.replytxt, so that you don't need to take care of passing replytxt value separately to server.
ng-click="sendReply(comment)"
Code
$scope.sendReply = function(comment){
console.log(comment.id, comment.replytxt);
}

Related

ngModel is reflecting to all textareas

I have multiple textareas (looping with ngFor and adding new divs with textareas inside). What i need is for every textarea to have separate ngModel and i don't want to directly bind this to property from object in dataArray - for example:
[(ngModel)]='data.note' or [(ngModel)]='data.feedback' .
This works but I don't have feedback property in dataArray so it won't for work for second textarea.
For example with my current implementation change in one textarea is reflecting in all other textareas. I tried with index approach but getting error:
ERROR TypeError: Cannot read property '1' of undefined
<div *ngFor="let data of dataArray; let index=index;trackBy:trackByIndex;">
<div class="card-body">
<form class="form">
<div class="form-body">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<textarea name="note" [(ngModel)]='selectedNote' class="form-control"
rows="2"></textarea>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<textarea name="feedback" [(ngModel)]='selectedFeedback' class="form-control" rows="4"></textarea>
</div>
</div>
</div>
</div>
</form>
</div>
With current code if i add some text in first textarea with name 'note' that change is reflected for all textareas with name 'note'. As mentioned tried with adding
[(ngModel)]='selectedFeedback[index]' but i am getting error.
Also tried with giving different names to textareas:
<textarea name="note{{index}}" [(ngModel)]='dataArray[index]' rows="2"></textarea> OR
<textarea name="note{{index}}" [(ngModel)]='selectedNote' rows="2"></textarea>
but change is reflecting for each textarea again.
You can try it with any array, I am using data(n) function to return an Array of length n. In this example it's just for iteration
<div *ngFor="let item of data(8); let i = index">
<textarea [(ngModel)]='values[i]'></textarea>
</div>
// To reflect changes
<div *ngFor="let item of data(8); let i = index">
<div>{{ values[i] }}</div>
</div>
With TS
export class AppComponent {
values = [];
data(n) {
return Array(n);
}
}
Working example in Stackblitz.com
ngModel binds with the name property. So if you want to use multiple textarea try using different name attribute. You can iterate over like -
<ng-container *ngIf="let data of dataArray; index as i">
<textarea name="feedback_{{i}}" [(ngModel)]='selectedFeedback' class="form-control" rows="4"></textarea>
</ng-container>

jquery selecting child elements

The setup.
I am using MVC 5, and I have created a view with data sent in the form of a viewmodel.
With in this view I have rendered a List object as stacked div's, as seen below.
As you will see, I am displaying hidden fields, so that the viewModel send back the data to the controller on submit.
<div class="row item-row">
<div class="small-4 columns">
objType
</div>
<div class="small-6 columns">
<input id="object_0__Id" name="object[0].Id" type="hidden" value="999999">
<input id="object_0__Reference" name="object[0].Reference" type="hidden" value="myRef">myRef
<input id="object_0__RecordChanged" name="object[0].RecordChanged" type="hidden" value="NoChange">
</div>
<div class="small-2 columns remove-item">
<button class="button tiny expand centre button-gray" onclick="javascript: RemoveItem(999999);">Remove</button>
</div>
</div>
<div class="row item-row">
<div class="small-4 columns">
objType
</div>
<div class="small-6 columns">
<input id="object_1__Id" name="object[1].Id" type="hidden" value="000001">
<input id="object_1__Reference" name="object[1].Reference" type="hidden" value="myRef">myRef
<input id="object_1__RecordChanged" name="object[1].RecordChanged" type="hidden" value="NoChange">
</div>
<div class="small-2 columns remove-item">
<button class="button tiny expand centre button-gray" onclick="javascript: RemoveItem(000001);">Remove</button>
</div>
</div>
Ok, so the javascript function RemoveItem is:
function RemoveItem(id)
{
event.preventDefault();
var element = $(event.target).closest('.item-row');
$(element).closest('DeedReference_0__RecordChanged').val('Deleted'); ***** This is what I am trying to do.
$(element).hide();
}
From the above, when I click on say RemoveItem(00001), the variable element contains the following:
<div class="small-4 columns">
objType
</div>
<div class="small-6 columns">
<input id="object_0__Id" name="object[0].Id" type="hidden" value="000001">
<input id="object_0__Reference" name="object[0].Reference" type="hidden" value="myRef">myRef
<input id="object_0__RecordChanged" name="object[0].RecordChanged" type="hidden" value="NoChange">
</div>
<div class="small-2 columns remove-item">
<button class="button tiny expand centre button-gray" onclick="javascript: RemoveItem(000001);">Remove</button>
</div>
The value I need to update is object[0].RecordChanged, but at this moment in time, I do not know the index value. So I was planning on using the ends with selector, but am not able to get it to work.
I have got as far as:
$(event.target).closest('.item-row').children()[1]
But this gives me the div, since I have tried:
$(event.target).closest('.item-row').children()[1].Find('Id*"__RecordChanged"')
$(event.target).closest('.item-row [id*="RecordChanged"]')
$(event.target).closest('.item-row:[id*="RecordChanged"])
And using the variable
$(element [id*="RecordChanged"])
$(element [id$="RecordChanged"])
UPDATE
Fixed bug in code that was suggesting that I was looking at the wrong index.
Also, If I click the remove button for RemoveItem(000001), I am trying to update the value object_0__RecordChanged.
Changed view model to have an index property. Then changed placed the HTML.EditorFor within a foreach loop enabling me to populate the index property before it is rendered out.
Then the code was changed from:
function RemoveItem(id)
{
event.preventDefault();
var element = $(event.target).closest('.item-row');
$(element).closest('DeedReference_0__RecordChanged').val('Deleted'); ***** This is what I am trying to do.
$(element).hide();
}
to:
function RemoveItem(id)
{
event.preventDefault();
var recordChanged = '#object_' + id + '__RecordChanged';
$(recordChanged).val('Deleted');
var element = $(event.target).closest('.item-row');
$(element).hide();
}
Much simpler!

Onclick set value to input

I want to change the value form input onclick. I've tried it but the input value don't change. Can't find the error. For example when I click on the choice-label the input should get the value 5.
$('.training-niveau .choice-label').click(function() {
$('#train-niveau').val(this);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="field training-niveau-icon training-niveau">
<input id="train-niveau" class="train-niveau" name="train-niveau" value="1" type="radio" aria-required="true" autocomplete="off">
<li class="choice-line thirst-line">
<div class="choice-wrapper">
<div class="choice-label">4</div>
<div class="choice-line"></div>
<div class="choice-container">
<div class="choice-inset"></div>
<div class="choice-bg"></div>
<div class="choice-bd"></div>
<div class="choice-overlay"></div>
</div>
</div>
</li>
</div>
$('#train-niveau').val(this);
is setting the value of the input to the jquery object of the label.
use $('#train-niveau').val($(this).text());
Just calling this only pulls in the document object.
$('.training-niveau').on('click', '.choice-label', function() {
console.log($('#train-niveau').val()); //before
$('#train-niveau').val($(this).text());
console.log($('#train-niveau').val()); //after
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="field training-niveau-icon training-niveau">
<input id="train-niveau" class="train-niveau" name="train-niveau" value="1" type="radio" aria-required="true" autocomplete="off">
<li class="choice-line thirst-line">
<div class="choice-wrapper">
<div class="choice-label">4</div>
<div class="choice-line"></div>
<div class="choice-container">
<div class="choice-inset"></div>
<div class="choice-bg"></div>
<div class="choice-bd"></div>
<div class="choice-overlay"></div>
</div>
</div>
</li>
</div>
this doesn't contain the value, but rather a whole set of functions and values (to verify, do console.log(this); If you want the value of this, use this instead:
$('#train-niveau').val(this.val()); < Which only applies if a value is set to your choice label.
Inside the click function this is the normal javascript DOM element, it is not a jQuery object. If you want to use .val() you need to convert this to a javascript variable
$('.training-niveau .choice-label').click(function(){
var $this = $(this);
$('#train-niveau').val($this.val());
});

is there any way to bind ng-model to multiple input fields uniquely inside a directive?

In my Project i Got a Issue like.I need to bind the user hobbies in the text field.if the user comes with a single hobby he can directly enter the hobby that he has. but when he had multiple then he had to click add multiple hobbies button.that working fine when i am displaying input fields dynamically using directives.but the issue is the value that coming from ng-model for that input field is binding to all input fields.
Here is my code.
Thanks in advance!
these are the images
this is how i am getting
this is what i need
In HTML
<div>
<div id="showHobbyfield"></div>
<input type="number" class="form-control" placeholder="ADD HOBBIES"
ng-click="addHoby()">
</div>
In controller
$scope.addHoby= function(){
var compiledeHTML = $compile("<div my-hobby></div>")($scope);
$("#showHobbyfield").append(compiledeHTML);
};
$scope.addUser = function(){
$scope.Users= [];
var obj = {
userhobby : $scope.user.morehobies
};
$scope.Users.push(obj);
menuStorage.put($scope.Users);
//menustorage is service to store user in localStorage.
In directive
'use strict';
angular.module('myApp')
.directive('myHobby', function() {
return {
scope : false,
templateUrl: 'views/my-hobby.html'
};
});
this is template: my-hobby.html
<div class="input-group">
<input type="text" ng-model="user.morehobies" class="form-control" placeceholder="type your hobbies here">
<div class="close-icon">
<span class="glyphicon glyphicon-remove" style="padding-left: 6px;"> </span>
</div>
</div>
For this i would suggest some other way if its ok with you.
If your hobbies is coming in array, like
user.morehobies = ['Reading', 'Writing']
or create array for storing hobbies.
then inside directive you can pass that object in directive.
I will use ng-repeat inside directive.
<div class="input-group" ng-repeat="h in hobies">
<input type="text" ng-model="h" class="form-control" placeceholder="type your hobbies here">
<div class="close-icon">
<span class="glyphicon glyphicon-remove" style="padding-left: 6px;"> </span>
</div>
</div>
so whenever user clicks on "Add hobbies" then we can add empty string in hobbies object in directive.
and whenever user clicks on remove you can remove that item from array.

How to close element when click outside the element using AngularJs Only?

This is my code
$scope.searchHide = function() {
$scope.selectMenuSetting = "SearchPanel";
$scope.secondPanelShow = !$scope.secondPanelShow;
$scope.secondColumn = false;
};
$scope.showSearchPopUp = function() {
$scope.selectMenuSetting = "SearchPopUp";
$scope.secondColumn = !$scope.secondColumn;
$scope.secondPanelShow = false;
};
<div class="tab-panel">
<i class="nc-icon-mini ui-1_zoom" ng-class="{'active': selectMenuSetting === 'SearchPanel'}"></i>
<i class="nc-icon-mini ui-3_select" ng-class="{'active': selectMenuSetting === 'SearchPopUp'}"></i>
</div>
<div class="second-search-hide-panel padt5" ng-if="secondPanelShow">
<div class="second-search-input ">
<input type="text" placeholder="text" ng-model="searchText" ng-change="refreshData(searchText)"><i class="nc-icon-mini ui-1_zoom active"></i>
</div>
</div>
<div class="second-search-hide-panel" ng-if="secondColumn">
<div class="second-search-input" ng-if="showObjectTypes">
<div class="second-search-input">
<label class="control-label">Type</label>
<select class="form-control" ng-model="objectType" ng-change="callingGetData(objectType)">
<option value="major">Major Objects</option>
<option value="support">Supporting Objects</option>
<option value="lookup">LookUp Objects</option>
</select>
</div>
</div>
</div>
In the above code contains two anchor tags. When I click first anchor tag display search text field and when click second anchor tag show dropdown. But, when I click outside the element I want to hide the anchor tags using AngularJS without using jQuery.
This needs the ng-blur directive on the element, although i'm not sure why you want to use nothing but Angular...

Categories