Remove Object from Json Object - angularjs

I was looking for solutions from Google and from this site. But I did not find the right answer for me. I have a json object:
$scope.jsonObject = {
"Card":{
"type":"menu",
"options":["option1","option2"],
"name":"With card",
"next":{
"operations":{
"type":"menu",
"options":["option1","option2"],
"name":"Card Operations",
"next":{
"balance":{
"type":"transaction",
"options":["option1","option2"],
"name":"Get Balance",
"next":null
},
"history":{
"type":"transaction",
"options":["option1","option2"],
"name":"History Card",
"next":null
}
}
}
}
}
}
This is a template menu, From this menu I need create new menu with angular foreach:
$scope.sortMenu = {};
function sortObject(menu){
angular.foreach(menu, function(key,value){
if(key == "card"){
$scope.sortMenu = menu;
}
if(key == "history"){
// I need delete object "history" from $scope.sortMenu
}
sortObject(value.next);
});
}
sortObject($scope.jsonObject);
How to write for delete "history" object from new menu?
Thanks, for all answers. Now, I change the question a bit. This is the $scope.jsonObject in the browser:
This is a menu creator:
function showDefaultMenu(menu,iterator){
angular.forEach(menu, function(value, key){
console.log(key);
$('#myTree').append(
"<div class='col-md-12 col-xs-12'>" +
"<input type='checkbox' id='"+key+"' value='"+key+"' style='position: inherit;margin-left:"+iterator+"px'>"+key+
"</div>"
);
if(value.next !== undefined){
showDefaultMenu(value.next,iterator+20);
}
});
}
showDefaultMenu($scope.jsonObject,20);
This is a code in html:
<div id="myTree" class="col-md-12 col-xs-12" style="margin-top: 50px;border:1px solid black;">
</div>
<div class="col-md-12 col-xs-12" style="margin-top: 10px;" >
<input type="button" ng-click="constructNewMenu()" class="button btn-xs btn-info" value="Create Menu" />
</div>
This is a constructNewMenu() used instead of sortObject():
function constructNewMenu(){
assistantConstructMenu($scope.jsonObject);
}
function assistantConstructMenu(menu){
angular.forEach(menu, function(value, key){
if ($('#' + key).is(':checked')) {
if (key === "card") {
$scope.sortMenu.push(menu);
}
}else{
// I need delete object "no checked" from $scope.sortMenu
}
if(value.next !== undefined){
assistantConstructMenu(value.next);
}
});
}
How to delete "no checked" menu, not knowing his level in the hierarchy of an object?

You could either do
delete $scope.sortMenu.Card.next.operations.next.history;
or just assign it to an empty json object
$scope.sortMenu.Card.next.operations.next.history = {};
P.S. Your Json Object looks complicated. The above code has possibilities of can't get object of undefined errors. May be you could get away by doing null/undefined checks.

if(key == "history"){
delete $scope.sortMenu.Card.next.operations.next[key];
}

use delete of msdn
if(key == "history"){
// I need delete object "history" from $scope.sortMenu
delete $scope.sortMenu.Card.next.operations.next.history;
}
for more information read msdn delete

Use delete method :
if(key == "history"){
delete $scope.sortMenu.Card.next.operations.next.history;
}
for more information read msdn delete

Related

Show and Hide a <div> inside an ng-repeat with 'dirPagination' (AngularJS)

In this very site I've seen this question many times, but none of them works for me because of two things: I need the div to toggle when clicking the "options" button, but also to hide when clicking outside of the div; and I need it to work with dirPagination.
I saw this answer, it works fine but with one problem I just can't solve: it shows ALL the hidden divs at the same time, instead of only showing the one I clicked.
Here's my code:
<body ng-controller="MainCtrl">
<!-- pagination -->
<dir-pagination-controls
max-size="7"
direction-links="true"
boundary-links="true">
</dir-pagination-controls>
<ul>
<li dir-paginate="report in reports | itemsPerPage:4">
Options
<h3>{{report.Title}}</h3>
<div class="options" ng-show="dp">
<p>These are some options</p>
</div>
</li>
</ul>
</body>
And the JS to show the options:
//options div
$scope.showOptions = function(event){
if($scope.dp === false || $scope.dp === undefined) {
$scope.dp = true;
event.stopPropagation();
} else {
$scope.dp = false;
}
};
window.onclick = function(){
if($scope.dp){
$scope.dp = false;
$scope.$apply();
}
};
I've made a Plunker in case you wanna se it in action: my Plunker link
Can somebody help me with this issue? :(
Add a new boolean property on your reports array , for example show
var reports = [
{
"ID":1,
"Title":"Report 1",
"Show":false
},
{
"ID":2,
"Title":"Report 2",
"Show":false
}
]
Apply the property in to ng-show and also pass the current report scope object in to showOptions method to write the logic for hide and show.
<li dir-paginate="report in reports | itemsPerPage:4">
Options
<h3>{{report.Title}}</h3>
<div class="options" ng-show="report.Show">
<p>These are some options</p>
</div>
</li>
$scope.showOptions = function(event,report){
report.Show=!report.Show;
/*you can iterate through each reports and change show to false if the clicked report id not equal to report id , Angular JS will automatically update the scope in to the view*/
reports.forEach(function(item, index) {
if (item.ID !== report.ID) {
item.Show = false;
}
});
if($scope.dp === false || $scope.dp === undefined) {
$scope.dp = true;
event.stopPropagation();
} else {
$scope.dp = false;
}
};
https://next.plnkr.co/edit/hnhWMrgR3GMtVcES
You need to use a separate variable for each div you want to show. You could add the dp attribute to the report. There is no need to loop over the reports to hide them. You can just keep track of the currently visible report and hide it when another one is toggled.
Here is the relevant HTML:
<li dir-paginate="report in reports | itemsPerPage:4">
Options
<h3>{{report.Title}}</h3>
<div class="options" ng-show="report.dp">
<p>These are some options</p>
</div>
</li>
and JavaScript
var visibleReport;
$scope.showOptions = function(event, report){
if (report == visibleReport) {
report.dp = !report.dp;
}
else {
if (visibleReport) visibleReport.dp = false;
report.dp = true;
}
visibleReport = report
event.stopPropagation();
};
window.onclick = function(){
if (visibleReport) visibleReport.dp = false;
visibleReport = null;
$scope.$apply();
};
Here is a working plunker https://next.plnkr.co/edit/sWLxBGlF8D22nvYp?preview

Protractor - Drop down Element Not Visible(auto complete drop down)

I have been facing different diff kind of element not visible issues in my application. kindly help me for solution on this.
below or the html code
For Drop Down
<span class="btn btn-default form-control ui-select-toggle" style="outline: 0;" ng-click="$select.activate()" ng-disabled="$select.disabled" aria-label="Select box activate" tabindex="-1">
To Type text in the Auto Complete Drop down.
<span class="ui-select-placeholder text-muted ng-binding" ng-show="$select.isEmpty()">Select Reseller...</span>
I was able to click on the drop down and enter the text. but after that it fails with element not visible error
If u can click on the Auto complete drop down then try to select the drop down by text value.
by.linkText('Text to be selected'));
or
try using the below function (this will select the value by text)
this.SelectRowByCellValue = function (Elem, Texts)
{
Elem.filter(function (element) {
return element.getText().then(function (text) {
if (text == Texts && text != null)
{
element.click();
return false;
}
else
{
}
});
}).then(function (filteredElements) {
});
};

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

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/

Clear button in AutoComplete of Angular Material blocks all the DOM elements

Yes, this is very rare situation but somehow, if i use the autocomplete as follows, i get all the dom elements blocked and i cant interact anymore with an element from my page.
This is the html-part:
<md-autocomplete style="background-color:white; height:10px;"
md-selected-item="selectedItem"
md-search-text-change="searchTextChange(searchText)"
md-search-text="searchText"
md-selected-item-change="selectedItemChange(item)"
md-items="item in querySearch(searchText) | orderBy:'text'"
md-item-text="item.text"
md-min-length="0"
placeholder="Filteren op tag"
md-menu-class="autocomplete-custom-template">
<md-item-template style="background-color:white;">
<span class="select-title">
<!--<md-icon md-svg-icon="selectboxIcon.svg"></md-icon>-->
<span class="item-tags"> {{item.text}} </span>
</span>
</md-item-template>
</md-autocomplete>
and this is the corresponding parts from my controller:
$scope.querySearch = function (query) {
var results = query ? $scope.allTags.filter($scope.createFilterFor(query)) : $scope.allTags;
return results;
}
$scope.createFilterFor = function (query) {
var lowercaseQuery = angular.lowercase(query);
return function filterFn(item) {
console.log(item);
var itemName = angular.lowercase(angular.lowercase(item.text));
return (itemName.indexOf(lowercaseQuery) === 0);
};
}
$scope.searchTextChange = function searchTextChange(text) {
$log.info('Text changed to ' + text);
}
$scope.selectedItemChange = function selectedItemChange(item) {
console.log("selected");
console.log(item);
}
ps: every functionality works fine and without error. Just clicking the clear button - as shown in the following image- causes this problem -tested in last versions of chrome and mozilla-.
There is an issue posted on github regarding this.
You can check it out here.
It is resolved in the update 0.10.1-rc4.
Update your angular-material to master.
Temporary Workaround:
CSS:
.md-scroll-mask{
position: initial
}

AngularJS ng-repeat filter, function over object property

I am looking for a way to check for each movie if the movie has the category which is selected. Movies is an array which contains objects, those objects have some properties, like you can see in the code below. The categories property is a array of categories where the movie is in. Now there is a variable selectedCategories where the current selected category is stored in.
I don't want to use custom filters, because I think it has te be possible with this one, I just can't quite get it. In the javascript function there can't be changed too much either.
If the return of hasSelectedCategory is true, then it has to execute the block, if false not.
Thanks in advance.
//in the javascript file
scope.hasSelectedCategory = function(categories){
var hasCategory = false;
if (categories.indexOf(scope.selectedCategory) !== -1){
hasCategory = true;
}
return hasCategory;
};
//in the html file
<div class="movieListItem {{listItemView}}" ng-repeat="movie in movies | filter:{hasSelectedCategory(categories): true}">
<h4>{{movie.title}}</h4>
<a href="http://www.youtube.com/embed/{{movie.youtubeId}}?rel=0&autoplay=1">
<img ng-src="{{findPosterSource(movie)}}" class="poster"> </a>
<p ng-hide="listItemView === 'grid'">
{{movie.description}}
</p>
<div class="categories" >
<span ng-repeat="category in movie.categories"> <a ng-href="#">{{category}}</a> </span>
</div>
</div>
You have to use the filter like this:
ng-repeat="movie in movies | filter:hasSelectedCategory"
The hasSelectedCategory function will be invoked for each movie in the movies list. In order to filter by selected categories you can use a function like this:
$scope.hasSelectedCategory = function(movie) {
var hasCategory = false;
angular.forEach($scope.selectedCategories, function(selectedCategory) {
if (!hasCategory && movie.categories.indexOf(selectedCategory) !== -1) {
hasCategory = true;
}
});
return hasCategory;
};
Demo (plunker)

Resources