Editing function inside ng repeat - javascript

I have an edit control inside of an ng-repeat that is correctly changing boolean values onclick, however, the elements that are hooked to these values via ng-show are not showing/hiding. What is going wrong?
Controller:
$scope.editedAnswers = {};
$scope.toggleEditAnswer = function(answer) {
$scope.editedAnswers[answer._id] = !$scope.editedAnswers[answer._id];
console.log($scope.editedAnswers[answer._id]);
};
$scope.updateAnswer = function(answer) {
answer.$update(function() {
$location.path('answers/' + answer._id);
});
$scope.toggleEditAnswer(answer);
};
HTML:
<div class="answers" ng-show="showAnswers">
<div ng-repeat="answer in answers">
<div class="answer-info">
<a ng-show="!editedAnswer[answer._id]" ng-click="toggleEditAnswer(answer)">edit</a>
<a ng-show="editedAnswer[answer._id]" ng-click="updateAnswer()">save</a>
</div>
<div ng-hide="editedAnswer[answer._id]"></div>
<textarea ng-show="editedAnswer[answer._id]">
{{answer.content}}
</textarea>
</div>
</div>

May be the problem is that in controller you define editedAnswers property, but in HTML you refer to the editedAnswer property (without -s)

try changing this:
<div class="answers" ng-show="showAnswers">
<div ng-repeat="answer in answers">
<div class="answer-info">
<a ng-show="!editedAnswer[answer._id]" ng-click="toggleEditAnswer(answer)">edit</a>
<a ng-show="editedAnswer[answer._id]" ng-click="updateAnswer()">save</a>
</div>
<div ng-hide="editedAnswer[answer._id]"></div>
<textarea ng-show="editedAnswer[answer._id]">
{{answer.content}}
</textarea>
</div>
</div>
to this:
<div class="answers" ng-show="showAnswers">
<div ng-repeat="answer in answers">
<div class="answer-info">
<a ng-show="answer._id != editedAnswer[answer._id]" ng-click="toggleEditAnswer(answer)">edit</a>
<a ng-show="answer._id == editedAnswer[answer._id]" ng-click="updateAnswer()">save</a>
</div>
<div ng-hide="answer._id == editedAnswer[answer._id]"></div>
<textarea ng-show="answer._id == editedAnswer[answer._id]">
{{answer.content}}
</textarea>
</div>
</div>
In your version you're simply showing if editedAnswer[answer._id] exists.
In my edit (which may not be evaluating what you actually want - you may need to change != and == around) I am checking if the current answer equals (or not) then editedAnswer[answer._id] - I.E answer._id == editedAnswer[answer._id]

Related

Get all href values from a string which is filled with HTML code from a textarea

Solved :)
var test = $('textarea[name=extract]').val();
var hh = $.parseHTML(test) ;
$.each($(test).find('.tile__link'),function(i,b){
var reff = $(this).attr('href');
$('.links').append("link/" +reff + "<br><br>");
})
I have HTML code copied from an website. And I want all href values with the class .tile_link in a String.
I did not find an solution, how I can get the value of href with the class .tile_link without the divs and text just the link?
Here's an example:
var test = $('textarea[name=extract]').val();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea name="extract">
<span class="txt-raise">8min</span>
</div></div>
<div class="js-hunq-badge fit-tr pr-- pt--"></div>
<div class="tile__footprint">
</div>
</a>
</div><div class="tile grid-tile tile--bordered"> <a href="#/profile//grid" class="tile__link">
<div role="image" aria-label="HSHBerl" style="background-image:url()" class="tile__image"></div>
<div class="bg-raise tile__info">
<div class="info info--middle txt-raise">
<div class="txt-truncate layout-item--consume">
<div class="typo-small lh-heading txt-truncate">
8 km <span class="icon icon-small icon-gps-needle icon-badge"></span>
</div>
<div class="lh-heading txt-truncate">
<div class="info__main-data">
<div class="info__username">
</div>
<div class="js-romeo-badge"></div>
<div class="info__icon-set">
</div>
</div>
</div>
</div>
</div>
</div>
<div class="tile__onlinestate js-online-state"><div>
<span class="icon icon-online-status ui-status--online icon-raise" title="Online"></span>
</textarea>
But I don't know how to extract it to get only the values of href.
You can do someting like this:
$(".tile_link").attr('href');
If you have more than one element with that class, you can do forEach or map.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
Example:
$('.tile_link').map(function (element) { return $(this).attr('href'); });

auto complete on editable divs angular js

I am not able to perform the auto suggestion functionality on divs with contenteditable attribute. Also when I write mass-autocomplete to divs, it is showing an error message like "mass-autocomplete not allowed on element div".
The following is code I have written. Could you please give the solution for this?
$scope.getClients = {
suggest: suggest_Client
};
<div class="row">
<div class="col-xs-12">
<div class="marginTB15" mass-autocomplete>
<div class="reach_box" contenteditable="true" ng-model="user.communities" mass-autocomplete-item="getNetworks">
<span class="form-control-feedback form-control-feedback_left_textbox"><img src="images/icon7.png" ></span>
<div class="reach"></div>
</div>
</div>
</div>
</div>
Seems that you using the mass-autocomplete directive incorrectly, it need so have an <input> tag as a element. Consider just having 2 blocks inside your div - one is a normal autocomplete:
<div mass-autocomplete>
<input ng-model="user.communities" mass-autocomplete-item="getNetworks">
</div>
while another one is a static end result of the autocompletion - say <div>{{user.communities}}</div>. And those two will be toggled by click for example. By this you wont' need content-editable at all.
So full code may look like this:
//controller
$scope.stateEdit = false;
$scope.toggleWidgetState = function(){
$scope.stateEdit = !$scope.stateEdit;
}
$scope.getClients = {
suggest: suggest_Client,
on_select:toggleWidgetState //here we put our widget back to read-only state
};
//other logic to handle mass-autocomplete
//template
<div class="row">
<div class="col-xs-12">
<div mass-autocomplete ng-show="stateEdit">
<input ng-model="user.communities" mass-autocomplete-item="getNetworks">
<ul> <li>Cardiologist Connect<button type="button">X</button></li></ul>
</div>
<div ng-show="!stateEdit" ng-click="toggleWidgetState()">
{{getNetworks}}
<span class="form-control-feedback form-control-feedback_left_textbox"><img src="images/icon7.png" ></span>
<div class="reach"></div>
</div>
</div>
</div>

Cleaning up Angular Partials

I am making a menu that has a few different types of buttons with AngularJS. Based on the type of button, the html needs to have different characteristics. Also, the currently selected menu item needs to have a different color than the available buttons. Currently, I am using this mess of code:
<div id="navbar" ng-show="navbar.show" ng-mouseenter="navbar.keep()" ng-mouseleave="navbar.release()">
<div ng-repeat="navSection in navbar.navSections" ng-init="sectionIndex = $index" class="navblock">
<div ng-repeat="navItem in navSection.navigationItems">
<div ng-switch on="navItem.function">
<div ng-switch-when='CategoryNav', ng-click='navbar.navClick(sectionIndex, $index)'>
<div info="navItem", ng-if='sectionIndex == navbar.section && $index == navbar.item', id="selected">
<a ui-sref="{{navItem.function}}" ng-href="{{navItem.function}}">
<div class="navbutton">{{navItem.label}}</div>
</a>
</div>
<div info="navItem", ng-if='sectionIndex != navbar.section || $index != navbar.item', id="notselected">
<a ui-sref="{{navItem.function}}" ng-href="{{navItem.function}}">
<div class="navbutton">{{navItem.label}}</div>
</a>
</div>
</div>
<div ng-switch-when='StorefrontNav', ng-click='navbar.changeStorefront(navItem.type)'>
<div info="navItem", id="notselected">
<a ui-sref="{{navItem.function}}" ng-href="{{navItem.function}}">
<div class="navbutton">{{navItem.label}}</div>
</a>
</div>
</div>
<div ng-switch-default>
<div info="navItem", ng-if='sectionIndex == navbar.section && $index == navbar.item', id="selected">
<a ui-sref="{{navItem.function}}" ng-href="{{navItem.function}}">
<div class="navbutton">{{navItem.label}}</div>
</a>
</div>
<div info="navItem", ng-if='sectionIndex != navbar.section || $index != navbar.item', id="notselected">
<a ui-sref="{{navItem.function}}" ng-href="{{navItem.function}}">
<div class="navbutton">{{navItem.label}}</div>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
It works fine but I want to clean it up a little bit. I have thought about making a directive and passing in the functions the different links need to work (for example, the navbar.changeStoreFront()) but that seems like a lot of extra code just to clean the format up a bit. Does anyone know any better ways of cleaning this up?
I noticed that the simplest way to make the code more readable is to put the attributes on separate lines. Take this for example:
<ui-gmap-google-map center='{expression}'
control='{Object}'
zoom='{expression}'
dragging='{expression}'
refresh='{expression}'
options='{expression}'
events='{expression}'
bounds='{expression}'
pan='{string or boolean}'
>
<!-- other ui-gmap-directives here -->
</ui-gmap-google-map>

angularjs how to set text inside element based on textbox input

My code is:
<div ng-controller="myCtrl">
<div class="row">
<div class="col-md-4 col-sm-3">
<checked-input ng-scope="$eventID"></checked-input>
</div>
<div class="col-md-4 col-sm-3">
<output ng-scope="$postbackOutput">***This is where I want the text typed in the textbox to go***</output>
</div>
<div class="col-md-3 col-sm-3">
<a ng-click="generateURL($eventID)" class="btn-plus">
<span class="glyphicon glyphicon-plus"></span>
</a>
</div>
</div>
</div>
So what I'm trying to do is get that $eventID that's inside the first column div, then pass it as an argument to the function call generateURL() when the link in the <a> tag is clicked in the third column. Inside the controller I have:
app.controller('postbackCtrl', function($scope) {
$scope.generateURL = function(eventID) {
$scope.postbackOutput = eventID;
}
});
But it doesn't seem to be setting the text in the <output> correctly. Could anyone help? I've just started out with angular so it's a bit confusing.
You can just bind the var to the view with handlebar brackets:
<output ng-scope="$postbackOutput">
{{ postbackOutput }}
</output>
Here is a working plunkr

Why is a dynamic input value not showing a change with Angularjs?

I have a input with ng-model="articleTitle" and a div with {{articleTitle. When someone types in the input the div is updated.
However, I have a box that lists all the articles with <div class="element">...</div> around them. When a person clicks a list div I want the input to update then in turn the div that shows the title.
Everything works if I type in the input box. However, selecting an article does update the input box but not the div. If I add anything into the input box the div does update.
How, can I tell Angularjs that the input changed without interacting direction with the input?
----- edit -----
per request I've added some relevant code. This also include suggestions by mohamedrias :
html:
<html xmlns="http://www.w3.org/1999/xhtml" class="wp-toolbar ng-scope" lang="en-US" ng-app="coverEditor">
...
<div class="feature box" ng-controller="featureBox">
<div class="item">
<div class="edit">
<img src="/edit-image" />
<div class="form-elements">
<p class="title">Feature Settings</p>
<div class="element">
<p class="select-trigger">Article</p>
<div class="select-box" id="set-article">
<p class="title">Select Article</p>
<div class="element current" data-value="11">Test Article</div>
</div>
</div>
<div class="element">
<input type="text" name="feature" id="feature" ng-model="article.featureTitle" class="article-title" placeholder="Title" />
</div>
...
</div>
</div>
<div class="item-content featureBackColor">
<h1>{{article.featureTitle}}</h1>
</div>
</div>
</div>
angular-scripts.js (loads in header)
var coverEditor = angular.module("coverEditor",['ngRoute']);
coverEditor.controller('featureBox',function($scope){
$scope.article = {};
});
admin.js (jquery that loads in the footer)
$('#set-article .element').click(function(){
var articleElement = $(this);
var articleTitle = articleElement.text();
$('#theme-layout .element').removeClass('current');
articleElement.addClass('current');
articleElement.closest('.form-elements').find('.article-title').val(articleTitle);
});
The purpose of the jquery is to get values/text from the selected article and place it in the input changing the value and hopefully updating the title via angular.
----- edit -----
code update
html:
<html xmlns="http://www.w3.org/1999/xhtml" class="wp-toolbar ng-scope" lang="en-US" ng-app="coverEditor">
...
<div class="feature box" id="featureBox" ng-controller="featureBox">
<div class="item">
<div class="edit">
<img src="/edit-image" />
<div class="form-elements">
<p class="title">Feature Settings</p>
<div class="element">
<p class="select-trigger">Article</p>
<div class="select-box" id="set-article">
<p class="title">Select Article</p>
<div class="element current" data-value="11">Test Article</div>
</div>
</div>
<div class="element">
<input type="text" name="feature" id="feature" ng-model="article.featureTitle" class="article-title" placeholder="Title" />
</div>
...
</div>
</div>
<div class="item-content featureBackColor">
<h1>{{article.featureTitle}}</h1>
</div>
</div>
</div>
angular-script.js:
var coverEditor = angular.module("coverEditor",['ngRoute']);
coverEditor.controller('featureBox',function($scope){
$scope.article = {};
//set artcle
jQuery('#set-article .element').click(function(){
var articleElement = jQuery(this);
var articleTitle = articleElement.text();
var scope = angular.element("#featureBox").scope();
jQuery('#theme-layout .element').removeClass('current');
articleElement.addClass('current');
articleElement.closest('.form-elements').find('.article-title').val(articleTitle);
scope.$apply();
});
});
Updated based on comment
As you're out of angular scope and changing the value in Jquery.
You must use $scope.$apply() after the jquery statement which sets the value.
$('#set-article .element').click(function(){
var articleElement = $(this);
var articleTitle = articleElement.text();
$('#theme-layout .element').removeClass('current');
articleElement.addClass('current');
articleElement.closest('.form-elements').find('.article-title').val(articleTitle);
$scope.$apply();
});
Assuming you're doing it in link function of directive or inside the controller.
If you're completely out of angular scope, then use
var scope = angular.element(document.querySelector(".feature.box")).scope();
scope.$apply();
// change the selector based on your controller
So your code will be:
$('#set-article .element').click(function(){
var articleElement = $(this);
var articleTitle = articleElement.text();
$('#theme-layout .element').removeClass('current');
articleElement.addClass('current');
articleElement.closest('.form-elements').find('.article-title').val(articleTitle);
var scope = angular.element(document.querySelector(".feature.box")).scope();
scope.$apply();
});

Categories