Set different classes on click (in the most AngularJS way) - javascript

I am currently learning AngularJS and already started a little project, which is basically an older project of mine, done in jQuery.
Everythings fine so far, but the last hours I wrapped my head around this area. In jQuery back then 5 minutes, but I have no idea what's the best way in AngularJS)
Here is my jQuery: A calendar view. It opens and closes days on click. Once a day is clicked it gets the class opened. Also there is the state locked, where I disable to open the day at all.
$('.mod-item').on('click', function(){
if ($(this).find('.mod-item-day').not('.locked')) {
if($(this).find('.mod-item-day').hasClass('open')){
$(this).find('.mod-item-day').removeClass('open').addClass('opened');
}else{
$(this).find('.mod-item-day').addClass('open');
}
}
});
Here is the markup:
<ul class="mod">
<li class="mod-item">
<div class="mod-item-day opened"><span>1</span></div>
<div class="mod-item-content">
<img src="../images/present1_late.jpeg" alt="">
</div>
</li>
So my question is - what's the most AngularJS way to do it?

You do this basically the way shown in the To Do example on the Angular website.
On the day's div, specify ng-click="callbackInYourScopeCode()". In the To Do example, it's ng-click="archive()"
On the day's div's class, include a property from your model. In the To Do example, for instance, there's <span class="done-{{todo.done}}">{{todo.text}}</span>. Note the property todo.done.
In your scope code, have the function (callbackInYourScopeCode) change your model's property (done in the To Do example).
Angular will call your scope code in response to a click, and then update the element based on changes to your model.

Related

Avoid menu toggle to close when clicking

I'm using a .fadeToggle menu on my site.
I'm having some buttons that are showing a different div when clicking on them.
Everything's correct and you can be navigating on it but I want to avoid user to be clicking on the same button and close the info (it makes the screen be completely blank).
If I'm using the e.stopPropagation() I'm not able to navigate through it.
Thanks in advance.
HTML:
</div><div id="toggleContainer2">
<p><p>This is not an advertising platform, all selected agencies are more or less a subjective choice. The author reserves the right not to be responsible for the topicality, correctness, completeness or quality of the information provided. Liability claims regarding damage caused by the use of any information provided, including any kind of information which is incomplete or incorrect, will therefore be rejected. </p>
<p>All offers are not-binding and without obligation. Parts of the pages or the complete publication including all offers and information might be extended, changed or partly or completely deleted by the author without separate announcement.</p></p>
</div>
...
<a class="btn" id="trigger2">Disclaimer</a>
JS:
<script>
$(document).ready(function() {
// toggle advanced search
$("#toggleContainer2").hide();
$("#trigger2").click(function() {
$("#toggleContainer2").fadeToggle(1500);
$("#toggleContainer").hide();
});
});
</script>
Edit: I've been re-read your post, your problem is you didn't understand how .fadeToggle works, because what you describe is exactly what it is intented for.
What you need is to read that : fadeIn because it's the function that you need.
Older answer
What you need is to change the way you're tracking the target of the event.
Let say your dropdown as the class .dd and your button class is .menu_b, you will got something like this
$('body').on('click','.menu_b',function(e){
if($(e.target).hasClass('menu_b')) {
$('.dd').fadeToggle();
}
});

Dragula Angular2 update values using observable

I am writing a tree control using Angular2 and ng2-dragula (based on dragula). I am currently using something very similar to the example nested repeat example here. I have no problem loading in my list and getting drag and drop to work as expected. What I need to do is click a button, go back to the http service get fresh data, then update data on page. I know that I can use javascript to find the id and update that way but it doesn't seem like the correcy way to handle it.
Here is my component code - All this does is just over write the view data and completey undo any drags changed etc (im sure that is by design). I have tried a bunch of different different ways to use dragulaModel, but no matter what the whole component is re-rendered no matter what happens. I need to be able just to update the child text
I'm new to angular and want to make sure i follow the correct patterns
item.component.ts
loadItems(){
this._itemsService.getIems();
}
reloadIems(){
this._itemsService.getItems();
}
item.component.html
<div *ngIf="items">
<div class="holder">
<div *ngFor="let item of items | async">
<div (click)="checkCollapsed(item.text)" >
<div *ngIf='item.children' [dragula]='"first-bag"'>
<div *ngFor='let child of item.children' class="item">
<span class="handle">+</span><span id='{{child.id}}' [innerHtml]="child.text"> </span>
</div>
</div>
</div>
</div>
</div>
</div>
Edit
If I add a .subscribe to loadItems() then update this.items manually like this.items[0].children[0].text = "1000" in reloadItems() it works as i would like. Should I be manually updating the whole object this way? Seems like a hack
**Edit 2 **
I managed to get it to work by subscribing in the loadItems() then comparing the 2 objects in reloadItems, then making any necessary changes there. I think due to the subscribe it is autoupdating. Can anyone confirm if im doing it wrong/right (working plnkr here, leaving out the angular dependencies)

Using foundation's dropdowns within angular ng-repeat

I want to display a dropdown within a table shown using ng-repeat. The dropdown is built using Foundation's dropdown.js stuff.
<tr ng-repeat="lead in leads | filter:filterText>
<td>
<input type="text" data-dropdown="dropdown-{[{lead.id}]}"
autocomplete="off"/>
<ul id="dropdown-{[{lead.id}]}" class='f-dropdown' data-dropdown-content>
<li>Dropdown List</li>
</ul>
</td>
</tr>
When I put the input + ul outside of the ng-repeat (minus the added lead.id to define the ID) it works fine, but when it's inside the ng-repeat Foundation throws this error:
Uncaught TypeError: Cannot read property 'is_hover' of undefined
on line 46 when hovering over, line 53 when hover out, and line 31, when clicking of foundation.dropdown.js.
I'm 100% sure this has to do with the fact that Foundation gets initiated before the Angular.js app gets initiated. I'm temporarily working around this by adding data-dropdown-init manually to the dropdown input, but I don't think that's pretty.
Any direction would be welcome.
Here's a plunkr imitating the problem: http://plnkr.co/edit/fyTcPX17Fkbe8hSlUMtb?p=preview
One pretty easy solution is to use Angular-Foundation though it's fairly opinionated about how you implement things.
This error happens since the foundation dropdown function initiates before the angular app initiates. The one workaround to prevent this error is add the HTML attribute after angular app started. Just modify
data-dropdown-content
to
ng-attr-data-dropdown-content="{{$index}}"
I had the same issue and this one solved it

jQuery tabs programmatically call a URL based tab from within code

Situation
As you can see in the screenshot below, I have an area of my site which makes use of tabs to split up the user dashboard. The tab indexes along the top are declared as URLs and as a result jQuery creates the references at runtime. I would like the user to be able to click the "here for free content" link and the system calls the Free content tab. Let's call that URL "testserver/user/free-content" for the moment
Issue
Now, I know how to programmatically deal with this situation when the tabs are declared on page as divs and have static IDs I may assign but, in this case, am not ashamed to say it has me a little stuck before I've even started.
If I set an ID on the link, jQuery will overwrite it so, I can't use that approach.
Start of solution
What I'm thinking of is the following, sorry that for the moment, I don't have a fiddle, as/if I progress, I'll update the question.
User clicks the link and jQuery picks up the event by checking if it hasClass('tab-url-call')
Temporarily save the URL attribute
Loop through the tab index
Check if URL attribute matches the temp stored
If matching call this tab
This bit has me at an end of what to do
Next
Update - Extra information
As requested, here is some HTML to demonstrate the current structure
<div id="user-tabs" class="tabs">
<ul>
<li>
Welcome
</li>
<li>
Free content
</li>
<li>
Learning
</li>
</ul>
<div id="tab-user-home">
<h3>You current have freen content "showing"</h3>
<p>
This is just an information box to highlight that the user has an
option set to show free content and inform them that they can
reach it via the tab controls or click
<a
class="tab-url-call"
href="testserver/user/free-content"
>
here for free content
</a>
</p>
</div>
</div>
Thank you for taking the time to read my question.
In abstract what you are looking for is
//register a click event handler for elements with class tab-url-call
$(document).on('click', '.tab-url-call', function(e){
e.preventDefault();
//you need to place the selector for the tab header element here
//find the anchor element with the same href as the clicked element which is inside the tab header element
$('tabheader').find('a[href="' + $(this).attr('href') + '"]').click();
})

Make a link do 2 actions

Before anything, I don't know if I'm taking the right approach to this so bear with me on this.
My problem is as follows: I'm trying to use an accordion where each tab is a category and when expanded, the accordion shows the artists in that category. So far, so good.
Now, the other part of what I'm trying to achieve is this: Once I click on the tab (which has a "#" link) I need to display the artists list in a div, which I was planning to do with AJAX. I can do this without problems if the link was INSIDE the accordion contents (for example, if I wanted to click on an artist) but can't figure out how to make it work when clicking a tab.
My code is as follows:
<li class="artistlist">
Photo
<ul>
<li>Artist</li>
<li>Artist</li>
<li>Artist</li>
</ul>
</li>
</ul>
<div id="contentbox">
<div id="artistcat">
</div>
</div><!-- /contentbox -->
and what I'm trying to do is the following: replace href=# with something like this:
Abstrakt
thus, when clicking on a category (for example "photo") it expands the accordion (which it does) AND shows the content in the ajax box, which is exactly the same content of the accordion only with thumbnails.
So basically, I need to make that tab link do 2 actions: 1) expand the accordion and 2) show the ajax content.
I'm thinking that perhaps the AJAX solution is the wrong way, either way, any help will be greatly appreciated.
Try to use jQuery, and make a little piece of code that does what you need to.
Like
$('#contentbox').click( function() {
$('#content').ajax( /* do ajax stuff */ );
// animate accordion
});
If you can, use jQuery or some other library.
Use observers to trap click events. This way you seperate your html from your javascript.
use to do the ajax requests => you can do multiple things "on succeed" and
throw clean errors when the ajax requests fail.
your library will also give you the tools to trigger multiple observers "onClick"

Categories

Resources