loading on specific div in loop vuejs - javascript

This is my first question in this forum. I had been using jquery for a while but now I recently shifted to vuejs and found it's awesome.
Here is a little hitch I am having. The problem is I have to set v-loading on buttons in a loop and when I click I need it to be true (i.e starts showing). This is how I have done it but I don't know how to trigger it.
<div class="col-sm-12" style="padding:0;" v-for="follow_request in follow_requests" v-loading.body="true">
<div class="col-sm-4">
<img class="img-circle" :src="follow_request.user.image | appendBaseUrl"
style="height:60px;"/>
</div>
</div>
v-loading.body="true"
I need to make it true and false on click, but only this specific div.

I typically suggest adding a property to the object that you are iterating over that represents the state. For each of the follow_request objects in your follow_requests array, add the property, loading.
Then you can use it in your template.
<div class="col-sm-12"
style="padding:0;"
v-for="follow_request in follow_requests"
v-loading.body="follow_request.loading"
#click="follow_request.loading = !follow_request.loading>

Related

Flex, AngularJS + Masonry, akoenig/angular-deckgrid and more [duplicate]

This question already has answers here:
How to Create Grid/Tile View? [duplicate]
(8 answers)
Closed 6 years ago.
I've been sending this emails:
I'm about to release an application for web application security which requires the use of a grid like Masonry. I've tried all, and every single angular module, directives, and different approaches, including CSS based techniques, pure Vanilla JS, and your solution is, one of the best options available online. I found, however a main issue, that affects not only your approach, but every single Angular module or addon.
Issue #1:
Your solution, as any other solution, is based on an array of information that is already handled by angular. In your example case, it would be source="photos". Now, the problem comes when there's 2 different groups of elements. Let's assume, that I have a group of elements that where previously defined in the DOM. In other words:
<div angular-grid>
<p class="angular-grid-elem">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
<div class="angular-grid-elem" style="height:500px">Same happens with this content.</div>
<!-- and here comes more content, which is loaded from an array of information -->
<div class="angular-grid-elem" ng-repeat="data in data_array">
<p>{{data.header}}</p>
<p>{{data.details}}</p>
</div>
</div>
Now, as you can see in the example, the content inside the main div, , should be all, affected by the masonry layout. Of course, this is pseudo code and I'm aware that the sintaxis of your approach is different. However what I'm trying to represent here, is that your module, would be way better, if you would be able to apply the masonry like grid, including elements which are already present in the DOM/HTML in first place, with elements that are coming from an array.
Issue #2:
There's a second issue I found in multiple angular modules and approaches. What happens if I have 2, 3 or let's say even 16 divs which all of them, present the same masonry like behaviour? I have to admit, I didn't try it with your module, as I couldn't solve the initial problem, that requires the proper handling of the combination of elements that are (1) pre-defined in the HTML, and (2) coming from and ng-repeat function.
A possible approach:
In order to solve the second problem and the first one, at the same time, I have thought that the best approach might be to make use of element classes and elements ids to handle the situation? Why? Because it can easily applied into elements that are already there in the DOM in first place, as well, to elements that are joining or leaving dynamically by the use of a ng-repeat or any other of the angular functions.
Here's an example of what I'm saying:
<div class="angular-grid-dad-one" ng-grid="{'dad': 'angular-grid-dad-one', 'childs': 'angular-grid-elem'}" >
<p class="angular-grid-elem">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
<div class="angular-grid-elem" style="height:500px">Same happens with this content.</div>
<!-- and here comes more content, which is loaded from an array of information -->
<div class="angular-grid-elem" ng-repeat="data in data_array">
<p>{{data.header}}</p>
<p>{{data.details}}</p>
</div>
</div>
In this case, the main div defines itself as id="angular-grid-dad-one",
And also tells the Angular module, that the element angular-grid-dad-one is a container div of a masonry like structure,
And that it's childs are marked as angular-grid-elem.
As we could see on this line.
ng-grid="{'dad': 'angular-grid-dad-one', 'childs': 'angular-grid-elem'}"
This way, it allow us to make use of the Angular module in multiple instances. For example.
<div class="seccion_01" ng-grid="{'dad': 'seccion_01', 'childs': 'seccion_01_child'}" ng-show="seccion == '1'">
<p class="seccion_01_child">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
<div class="seccion_01_child" style="height:500px">Same happens with this content.</div>
<!-- and here comes more content, which is loaded from an array of information -->
<div class="seccion_01_child" ng-repeat="data in data_array">
<p>{{data.header}}</p>
<p>{{data.details}}</p>
</div>
</div>
<div class="another_container" ng-grid="{'dad': 'another_container', 'childs': 'child_of_container'}" ng-show="seccion == '2'">
<p class="child_of_container">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
<div class="child_of_container" style="height:500px">Same happens with this content.</div>
<!-- and here comes more content, which is loaded from an array of information -->
<div class="child_of_container" ng-repeat="data in data_array">
<p>{{data.header}}</p>
<p>{{data.details}}</p>
</div>
</div>
<div class="redundant_example" ng-grid="{'dad': 'redundant_example', 'childs': 'childs_of_redundancy'}" ng-show="seccion == '3'">
<p class="childs_of_redundancy">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
<div class="childs_of_redundancy" style="height:500px">Same happens with this content.</div>
<!-- and here comes more content, which is loaded from an array of information -->
<div class="childs_of_redundancy" ng-repeat="data in data_array">
<p>{{data.header}}</p>
<p>{{data.details}}</p>
</div>
</div>
I have used a Json styled instruction in the ng-grid value in order to explain my point, but it doesn't really have to be Json. It even could be 2 different paramenters:
<div class="dad" ng-grid-dad="dad" ng-grid-childs="childs" ng-show="seccion == '3'">
<p class="childs">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
<div class="childs" style="height:500px">Same happens with this content.</div>
<!-- and here comes more content, which is loaded from an array of information -->
<div class="childs" ng-repeat="data in data_array">
<p>{{data.header}}</p>
<p>{{data.details}}</p>
</div>
</div>
As well, regarding the infinite scroll that you have created, you would be able to load more elements, triggering the infinite scroll, and loading only elements from one specific array, of course.
Please let me know if I can help further, I would like to integrate your module into my application.
And let's hope that by the next implementation of HTML and CSS we have this situation fully under control by the next generation of browsers, I'm aware of the work it takes to make this grids in Javascript.
Actually, I am gonna go out on a limb and say that flex-wrap: wrap will fix the issue.
.holder {
flex-wrap: wrap
-moz-columns: 2 auto;
box-sizing: border-box;
display: flex;
padding: 0 40px;
width: 100%;
}

Using ng-model (or other solution) without breaking MVC paradigm

I recently asked a question on Stack where I was trying to obtain a DOM element's ID via AngularJS' ng-click. Essentially the answer which was given (with an important caveat was):
Use event.currentTarget vs event.target to get the element to which the binding was registered, BUT this is an atypical way to do it because it ties the controller to the DOM when ideally the controller should know nothing about the DOM.
I'm starting to get a better idea of this now, but would like some further help / clarification.
Using ng-repeat I dynamically render a number of tiles being pulled from a database and present them to the user for selection. When a user clicks on a given tile I want to be able to 'know' that element's ID (or some unique identifier key) so that I can pass it into my javascript / java and then retrieve the details for said key where they are rendered in a different, more detailed view.
I've started to research ng-model which supports the two-way MVC idea, but I'm stuck. You can see below that I'm dynamically rendering each tile with a different ng-model value which equals the tile's database key. Is this the solution I want? If so, how can I reference the ng-model value in javascript? Or if I do that, am I breaking the MVC again? If that's the case, what would be a solution which preserves the model?
Cheers
HTML:
<div ng-repeat="tile in tileResult">
<div ng-model={{tile.id}} ng-click="handleThisElement($event); changeView('panel3')" class="container-fluid btn-default tile">
<div class="row">
<div class="col-xs-9">
<div class="row">
...
</div>
</div>
<div class="col-xs-3 tile-stats">
<div class="row text-center">
...
</div>
</div>
</div>
</div>
</div>
Tie the ng-model to an object, best if it's something in the repeater. Also, ng-model is generally used with an input... not on a div, so I'm not sure what you're trying to achieve here.
You may want to initialize the value to the index (or some other default) if the value doesn't exist, this will avoid null pointers when you want to change the value later.
<div ng-repeat="tile in tileResult">
<div ng-model="tile.someDataValue" ng-init="tile.someDataValue = $index" ng-click="handleThisElement($event); changeView('panel3')" class="container-fluid btn-default tile">
...
</div>
</div>
To later reference the value, you can just access your tileResult object at the appropriate value/index
Ex:
console.log($scope.tileResult[0].someDataValue);
Or you can access the entire 'tile' on click by passing the 'tile' into a function. Ex:
<div ng-model="tile.someDataValue" ng-init="tile.someDataValue = $index" ng-click="someFunction(tile); handleThisElement($event); changeView('panel3')" class="container-fluid btn-default tile">
$scope.someFunction = function(someTile){
console.log(someTile.id, someTile); // log the id, then the entire object
}
If I understand you correctly, you want to be able to access the unique identifier for each tile.
This can easily be done without Ng-Model! One easy fix would be to set the id of each element with the unique identifier:
<div ng-repeat="tile in tileResult">
<div id="{{tile.id}}" ng-click="handleThisElement($event); changeView('panel3')" class="container-fluid btn-default tile">
<div class="row">
This way, when you pass $event to your handleThisElement function, you are able to access the id in the same way you have before.

Ajax content sortable jQuery portlets, order by 'sortOrder' variable after loading

I have a conumdrum and am looking for advice as to the best way to proceed. I have a tabbed portlet interface set up. Tabs are generated dynamically from a JSON response, and then portlets for each tab are loaded from another web service JSON response on first tab activation. The portlets need to be ordered by a pre-determined variable returned from the JSON (currently they are loaded in the order the ajax requests return).
I am looking for the simplest way to do this. My initial thinking is to append the variable to a class on portlet creation to end up with HTML mark-up similar to:
<div class="tabBody">
<div class="portlet sortOrder1">Content</div>
<div class="portlet sortOrder4">Content</div>
<div class="portlet sortOrder2">Content</div>
<div class="portlet sortOrder5">Content</div>
<div class="portlet sortOrder3">Content</div>
</div>
And then sort them after all portlets have been loaded using javascript with something similar to:
tab.find('sortOrder2').insertAfter(tab.find('.sortOrder1'));
As a quick example (with tab being a variable). The actual implementation would be a bit more complex, as I'll likely loop through all portlets, wildcard the sortOrder selector and parse out the int as the number of portlets per tab is not static.
Am I missing something and there's a painfully simple way of achieving this?
Thanks in advance.
UPDATE:
I have implemented the answer given below by #André Snede Hansen and it's working perfectly. Sort Order is achieved through the data attribute method (rather than using classes as I was originally intending) dynamically adding the integers returned from each response and then sorting at the end of my portletify (adding ui classes sortable etc) tab method.
Testing in IE back to 7 with no issues.
This is a quick way to solve what you are looking for
HTML:
<div class="tabBody">
<div class="portlet" data-order="1">Content1</div>
<div class="portlet" data-order="4">Content4</div>
<div class="portlet" data-order="2">Content2</div>
<div class="portlet" data-order="5">Content5</div>
<div class="portlet" data-order="3">Content3</div>
</div>
Javascript:
$(".tabBody .portlet").sort(function(x, y){
var orderX = parseInt($(x).attr("data-order"),10) || 0;
var orderY = parseInt($(y).attr("data-order"),10) || 0;
return orderX - orderY;
}).appendTo($(".tabBody"));
I have made a JSFiddle for the above code
$(".tabBody .portlet") returns an array of elemets, and arrays have a sort method.
The sort method is described further here: Array.prototype.sort()

angular-ui > ui-utils > ui-scroll does not work (v. 0.1.0)

I am using this: http://angular-ui.github.io/ui-utils/ and to be more specific this:https://github.com/angular-ui/ui-utils/blob/master/modules/scroll/README.md
however it does not seem to work. Here is an example:
<div ng-scroll-viewport style="height:240px;" class="chat-messages">
<div class="chat-message" ng-scroll="chat in chats">
<div ng-class="$index % 2 == 0? 'sender pull-right' : 'sender pull-left'">
<div class="icon">
<img src="{{chat.img}}" class="img-circle" alt="">
</div>
<div class="time">
{{chat.time}}
</div>
</div>
<div ng-class="$index % 2 == 0? 'chat-message-body on-left' : 'chat-message-body'">
<span class="arrow"></span>
<div class="sender">{{chat.name}}</div>
<div class="text">
{{chat.msg}}
</div>
</div>
</div>
</div>
But All I get in HTML is this :
<div class="chat">
<div class="chat-messages" style="height:240px;" ng-scroll-viewport="">
<!--
ngScroll: chat in chats
-->
</div>
If I replace ng-scroll with ng-repeat, it works perfectly. But chats need scroll bars, so... How can I get one? :)
The documentation of ngScroll directive had also tricked me into simply replacing ng-repeat by ng-scroll. Unfortunately, it turned out not as simple as that, see also the small, working example at http://plnkr.co/edit/fWhe4vBL6pevcuLutGC4 .
Note that
"datasource" (or whatever object you want to iterate over for the contents of the scroll list) must implement a method "get(index,count,success)" that calls success(results), see hXXps://github.com/angular-ui/ui-utils/blob/master/modules/scroll/README.md#data-source
The array must have exactly count elements. Otherwise, no scroll window/bar will ever show, which can be very irritating!
Although UI.Utils says it has no external dependencies, ui.scroll has actually a dependency on either ui.scroll.jqlite, or jQuery. So make sure to list both ui.scroll and ui.scroll.jqlite in your module definition which contains the controller with datasource object (and load their .js files, or load ui-utils.js which contains both), see https://github.com/angular-ui/ui-utils/blob/master/modules/scroll/README.md#dependencies
Be careful when your server is sending some Content Security Policies (CSP). Maybe turn them off while trying to get ng-scroll to work first, then re-apply CSP and tune the policies accordingly for ui.scroll to work.
One way of getting a scroll is to use CSS, set overflow-y to scroll and you will get scroll bar.
If you need to scroll to the bottom, play with anchorScroll
http://docs.angularjs.org/api/ng.$anchorScroll.

Is there a simple Javascript command that targets another object?

I have a page with two divs in it, one inside the other like so:
<div id='one'>
<div id='two'></div>
</div>
I want div one to change class when it is clicked on, then change back when div two is selected.
I'm completely new to javascript, but I've managed to find a simple command that makes div one change when I click it.
<div id='one' class='a' onclick="this.className='b';">
<div id='two'></div>
</div>
Now I just need an equally simple way to change div one back when number two is clicked.
I've tried changing "this.className" to "one.classname," and for some reason that worked when I was working with images, but it doesn't work at all with divs
<div id='one' class='a' onclick="this.className='b';">
<div id='two' onclick="one.className='a';">
This does not work.
</div>
</div>
Essentially I'm wondering if there is a substitute for the javascript "this" that I can use to target other elements.
I've found several scripts that will perform the action I'm looking for, but I don't want to have to use a huge, long, complicated script if there is another simple one like the first I found.
You can use document.getElementById
<div id='two' onclick="document.getElementById('one').className='a'; return false;">
This does not work.
</div>
This would work:
document.getElementById('one').className = 'a';
you could get the element by id with:
document.getElementById("one")

Categories

Resources