Angular Xeditable drop down e-ng-change is not working - angularjs

I'm using Angular Xeditable api.I need to change the text field's value according to the value of the drop down.But it's not working.Could you tell me why ? Thanks.
Html
<td>
<span editable-select="user.status" e-form="tableform" e-ng-options="s.value as s.text for s in statuses" e-ng-change="setName($data,user)">
{{ showStatus(user) }}
</span>
</td>
js
$scope.setName = function (id, user) {
var selected = [];
if (id) {
selected = $filter('filter')($scope.statuses, { value: id });
}
if (selected.length) {
user.name = selected[0].text;
}
};
Generated html : you can see that it has been changed text of the name filed as expected (status3).But it doesn't update the text box properly. In other words it doesn't show on the text box.Why ?
<td>
<!-- editable username (text with validation) -->
<span editable-text="user.name" e-form="tableform" onbeforesave="checkName($data, user.id)" class="ng-scope ng-binding editable editable-hide">
status3
</span><span class="editable-wrap editable-text ng-scope"><div class="editable-controls form-group" ng-class="{'has-error': $error}"><input type="text" class="editable-input form-control ng-pristine ng-valid" ng-model="$data"><div class="editable-error help-block ng-binding" ng-show="$error" ng-bind="$error" style="display: none;"></div></div></span>
</td>
UPDATE :
I have tried like this.But then it changes all the rows values.So how can I detect only the changed row ?
$scope.setName = function (id, user,form) {
var selected = [];
if (id) {
selected = $filter('filter')($scope.statuses, { value: id });
}
if (selected.length) {
for (var i = 0; i < form.$editables.length; i++) {
if (form.$editables[i].name === 'user.name') {
form.$editables[i].scope.$data ="sampath"
}
}
}
};
Here is the JsFiddle

I try with your old source code and it's works for me:
if (selected.length) {
user.name = selected[0].text;
}
May be i miss understand your problem.
http://jsfiddle.net/NfPcH/14573/

If I understand it right, you just want to update the text on the textbox (which is bound to the user's name) depending on the status change, right?
If so, then your UPDATED code is too complicated. Just update the property directly on the user object passed to the setName function (like in your first example). It is already bound to the textbox, so you don't have to go all the way around and update the textbox directly. That's the whole point of using angular. You update the models on the scope and the rest happens automatically.
$scope.setName = function (id, user) {
if (!id || !user) {
// Do something to handle this...
return;
}
var selected = $filter('filter')($scope.statuses, { value: id });
selected = selected.length ? selected[0] : null;
user.name = 'sampath (' + selected.text + ')';
};
Here is an udpated fiddle:
http://jsfiddle.net/NfPcH/14765/

Related

Angularjs how to user ng-default with ng-repeat

I am having below data as input json,
"values":[
{"_attributes":{"name":"data.domain"},"_text":"${url}"},
{"_attributes":{"name":"data.port"}},
{"_attributes":{"name":"data.comments"},"_text":"Defaults Comments"},
{"_attributes":{"name":"data.concurrent"},"_text":4}]
]
I am showing comments in my html page using this directive,
<b style="padding-top:5px;"> Comments:</b>
<span class="input">
<input class="inputtxt" type="text" ng-repeat="x in ValueArr" ng-if="x._attributes.name == 'data.comments'" ng-model="x._text">
</span>
which is working fine and showing as expected. But the problem is that sometimes, the comments node
{"_attributes":{"name":"data.comments"},"_text":"Defaults Comments"},
may not be present in array. like this,
"values":[
{"_attributes":{"name":"data.domain"},"_text":"${url}"},
{"_attributes":{"name":"data.port"}},
{"_attributes":{"name":"data.concurrent"},"_text":4}]
]
In that case it shows only "Comments:" and blank screen after that. It does not show input box. In this case, I want to show empty input box. I tried ng-default and and ng-init but that didn't work. How to display input box for absence of matching condition ?
jsfiddle
Not getting any idea, how to achieve that. Please suggest something.
Thanks
The solution works with ng-init.
Just put it on the input like this:
<span class="input" ng-init="initValues()">
<input class="inputtxt" type="text" ng-repeat="x in values" ng-show="x._attributes.name == 'data.comments'" ng-model="x._text" ng-init="initInput(x)">
</span>
And add the function in the Controller:
$scope.initInputComments = function(x) {
if (!x._text || x._text == "") {
x._text = "Defaults Comments"
}
}
Note that you need to test that x._text exists/is defined.
$scope.initValues = function() {
var containsComment = false;
for (var i = 0; i < $scope.values.length; ++i) {
if ($scope.values[i]._attributes.name == 'data.comments') {
containsComment = true;
}
}
if (!containsComment) {
$scope.values.push({
"_attributes": {
"name": "data.comments"
}
});
}
}
Check the working fiddle

Remove empty option in the select using ng-model

I am new to angular js. In my code user changes the value of radio buttons. And depending on the value of the selected radio button, a piece of code is loaded from the ng-switch
HTML:
<body ng-app="">
<div ng-repeat="button in modes">
<label>
<input type="radio" ng-model="data.mode" value="{{button.value}}" ng-click="clearObjectIdModal()" name="e_modes">
{button.label}}
</label>
</div>
<div ng-switch on="data.mode">
<div ng-switch-when="client">
<label for="e_selected_object_item_id">Select Client name: </label>
<select id="e_selected_object_item_id" name="e_selected_object_item_id" ng-model="currentDataItem.object_id" required>
<option ng-repeat="item in customersListArr" value="{{ item.id }}">{{ item.Name }}</option>
</select>
</div>
<div ng-switch-when="agent">
// This part is similar to the previous one
</div>
</div>
</body>
Controller part:
$scope.data = {};
$scope.setFile = function () {
if ($scope.data.mode == 'client')
return 'client';
else if ($scope.data.mode == 'agent')
return 'agent';
$scope.modes = [{
value: 'client',
label: 'Client'
},{
value: 'agent',
label: 'Agent'
}];
$scope.currentDataItem = data; // data is preloaded from inputs in form
There is also a ng-click="clearObjectIdModal()" that clears the model when switching radio buttons:
$scope.clearObjectIdModal = function() {
$scope.currentDataItem = "";
}
The problem is that every time when the radio button is switched to the select value, which dynamically changes, the value of the first option in it becomes equal to undefined. Because in the array from where these options are built there is no such object_id (This is the id that is not there, so an empty field is drawn).
That is, there are all works. But the first option in the select(after switching to another radio button) is rendered as an empty string.
There are thoughts, how it can be fixed?
I'm not sure if I understand you problem correctly but I would suggest a few improvements.
change your setFile function to as follows
$scope.setFile = function (){return $scope.data.mode;}
I also do not see the closing brackets for your function in your code. Besides if your function will only return the data.mode then why need the function?
I would suggest initialize your data object properly like:
$scope.data = {mode:'client'};
Change your clearObjectIdModal function as:
$scope.clearObjectIdModal = function(mode)
{
$scope.currentDataItem = "";
$scope.data.mode=mode;
}
and in your HTML use it as ng-click="clearObjectIdModal(button.mode)"
So in function clearObjectIdModal() I wrote:
$scope.clearObjectIdModal = function() {
if ($scope.e_data["mode"] == 'client') {
if ($scope.customersListArr.length > 0) {
$scope.currentDataItem.object_id = $scope.customersListArr[0]['id'];
}
}
else if ($scope.e_data["mode"] == 'agent') {
if ($scope.agentsListArr.length > 0) {
$scope.currentDataItem.object_id = $scope.agentsListArr[0]['id'];
}
}
}
And after this when I change radio buttons the first option in current select(which every time is changed) will be not empty.
Also the problem with an additional empty option is possible to solve when you add a title as the first item in the list:
<option value="" disabled>Select</option>

Trying to validate that at least one checkbox is checked angularJS

Trying to figure out the best way to stay on the same page alerting the user if they have failed to check at least one checkbox.
HTML:
<div class="col3">
<input type="checkbox" ng-model="$parent.value5" ng-true-value="'Togetherness'" ng-false-value="">
<span class="checkboxtext">
Togetherness
</span><br>
<!--<p>We value our people and recognize that <strong>Together</strong> we achieve superior results.</p><br>-->
<div class="col3">
<a ui-sref="form.submit">
<button name="button" ng-click="SaveValue()">Continue</button>
</a>
Back-end angularJS to check if one of the boxes was checked-
$scope.SaveValue = function () {
var valueStatus = [];
if ($scope.value1 === "Methodical")
{
valueStatus.push($scope.value1);
}
if ($scope.value2 === "Relentless")
{
valueStatus.push($scope.value2);
}
if ($scope.value3 === "Togetherness")
{
valueStatus.push($scope.value3)
}
if ($scope.value4 === "Excellent") {
valueStatus.push($scope.value4)
}
if ($scope.value5 === "Ingenious") {
valueStatus.push($scope.value5)
}
return valueStatus
};
Basically I'm wanting to make an array of these values and then return it. However, I want the user to check at least one box. I've tried redirecting back to the page if valueStatus[0] == null. However, I don't think this is the best way to validate and it does not work completely how I think it ought to.
The way I solve this is putting validation on the length of array (valueStatus in your case) with hidden number input. The input will have min validation on. So, if user fails to check at least one, the form is not submitted;
<input type="number" name="valueStatus" ng-model="valueStatus.length" min="1" style="display: none">
Then, you can use normal validation on valueStatus that is available on the form model
myFormName.valueStatus.$valid
This way, most of the logic is put into the template, which is called angularjs way ;)
UPDATE
Forgot to mention:
You need to update the list of checked values on on-change checkbox event
<input type="checkbox" ng-model="checkboxValue1" on-change="updateValueStatus(checkboxValue1)">
<input type="checkbox" ng-model="checkboxValue2" on-change="updateValueStatus(checkboxValue2)">
and in controller
$scope.updateValueStatus = function(value){
var indexOf = $scope.valueStatus.indexOf(value);
if(indexOf < 0) {
$scope.valueStatus.push(value);
} else {
$scope.valueStatus.splice(indexOf, 1);
}
}
Hope it will help people with the same issue
simply just check the valueStatus length is equal to 0 or not
$scope.SaveValue = function () {
var valueStatus = [];
if ($scope.value1 === "Methodical")
{
valueStatus.push($scope.value1);
}
if ($scope.value2 === "Relentless")
{
valueStatus.push($scope.value2);
}
if ($scope.value3 === "Togetherness")
{
valueStatus.push($scope.value3)
}
if ($scope.value4 === "Excellent") {
valueStatus.push($scope.value4)
}
if ($scope.value5 === "Ingenious") {
valueStatus.push($scope.value5)
}
if (valueStatus.length === 0 ) {
console.log('please select atleast one select box')
}
return valueStatus
};
Edited
remove the ui-sref tag and change the state inside your click function
<button name="button" ng-click="SaveValue()">Continue</button>
in the saveValue function add this
if (valueStatus.length === 0 ) {
console.log('please select atleast one select box')
}else{
$state.go('form.submit') // if atleast one selected then the page will change
}

TR element triggers checkbox via ng-click, but ng-change on checkbox will not fire

I have successfully created functionality to check a hidden checkbox on the ng-click of the row that the checkbox exists in that is generated with an ng-repeat. However, I also have functionality that adds that item to a separate array when the checkbox is checked using the ng-change directive.
My code works perfectly if I un-hide the element and check the checkbox directly, but if I use the ng-click directive on the TR, the checkbox gets checked (visibly) but the array isn't updated. If I then click on it again, it remains checked and the item is added to the new array.
This isn't an issue where the ng-click is taking two clicks to fire. Here is my markup:
<tr ng-cloak ng-repeat="item in mostRecent | orderBy:sortType:sortReverse | filter: query" class="hovered" ng-class="{'hide':showReports && item.status == 'Not Started' || showReports && item.status == 'inProgress','rep-checked': bool}" ng-click="bool = !bool">
<td class="hidden"><div class="checkbox">
<label class="checkbox">
<input type="checkbox" ng-change="sync(bool, item)" ng-model="bool" ng-checked="isChecked(item)">
</label>
</div></td>
and the js:
$scope.isChecked = function(id) {
var match = false;
for(var i=0 ; i < $scope.selectionData.length; i++) {
if($scope.selectionData[i].id == id){
match = true;
}
}
return match;
};
// Create a new array from the selected data
$scope.selectionData = [];
var selectionData = $scope.selectionData;
var result = selectionData.filter(function(e){ return e.id == id; });
$scope.sync = function(bool, item){
if ($scope.selectionData) {
$scope.selectionData.push(item);
}
else {
$scope.selectionData.splice(item);
}
console.log('check' + $scope.selectionData);
};
After some deeper research, I found that the ng-click function on the input isn't registering because the ng-click function of the tr element isn't actually emulating a click event on the input. I added a dynamic ID and replaced the ng-click function with a javascript function of
getElementById('checkboxID').click();
And it worked as expected.

Knockout.js Checkbox checked and click event

We're trying to implement a checkbox and list with the following functionality:
Clicking the checkbox will either clear the array if there are items in there, or add a new item if not.
Remove an item from the array when clicking the Remove button, once the last item is removed the checkbox automatically unchecks itself.
The problem I am having is that if you click to remove each array item, then click the checkbox to add a blank entry, I'm expecting the checkbox to be checked again (as per the checked observable), however it is not?
I have the following code:
http://jsfiddle.net/UBsW5/3/
<div>
<input type="checkbox" data-bind="checked: PreviousSurnames().length > 0, click: $root.PreviousSurnames_Click" />Previous Surname(s)?
</div>
<div data-bind="foreach: PreviousSurnames">
<div>
<input type="text" data-bind="value: $data">
<span data-bind="click: $root.removePreviousSurname">Remove</span>
</div>
</div>
var myViewModelExample = function () {
var self = this;
self.PreviousSurnames = ko.observableArray(['SURNAME1', 'SURNAME2', 'SURNAME3']);
self.removePreviousSurname = function (surname) {
self.PreviousSurnames.remove(surname);
};
self.PreviousSurnames_Click = function () {
if (self.PreviousSurnames().length === 0) {
self.PreviousSurnames.push('');
}
else {
self.PreviousSurnames.removeAll();
}
alet(2)
}
}
ko.applyBindings(new myViewModelExample());
If you are using together the click and the checked then you need to return true from your click handler to allow the browser default click action which is in this case checking the checkbox:
self.PreviousSurnames_Click = function () {
if (self.PreviousSurnames().length === 0) {
self.PreviousSurnames.push('');
}
else {
self.PreviousSurnames.removeAll();
}
return true;
}
Demo JSFiddle.
You need to use a computed to monitor the length of the observable array. This way when the length reaches zero you can react to it automatically.
self.surnames = ko.computed(function() {
var checked = true;
if (self.PreviousSurnames().length === 0) {
self.PreviousSurnames.push('');
checked = false;
}
return checked;
});
Now you will have the blank text box when all of the names are cleared. If you update your binding on the checkbox it will function properly as well.
<input type="checkbox" data-bind="checked: surnames, click: PreviousSurnames_Click" />Previous Surname(s)?
FIDDLE

Resources