I am trying to create a general widget (component) which maybe a one item component, a list component (like tabs) or anything else.
Exp:
<div class="widget-component">
<div class="item">
<div class="widget-component-title">Title 1</div>
<div class="widget-component-description">Description 1</div>
</div>
<div class="item">
<div class="widget-component-title">Title 2</div>
<div class="widget-component-description">Description 2</div>
</div>
</div>
Components are defined outside the widget script and they only need to respect the defined selectors (widget selector, editables selectors).
On a list widget case a title or description editable occurs more than once.
I have been digging a lot for a solution this is what i came across.
http://ckeditor.com/comment/135051#comment-135051
this solution works but it breaks the generality principle and also i have to keep track of index classes on repeated items.
I even tried to extend the "initEditable" function inside widget/plugin.js but because i did not want to modify the file (preventing my self from future updates) and i could'nt extend it by external script ("initEditable" not accessable) i let it go.
The best suggested solution i came across is this here but it does'nt seem to have been implemented yet.
Any bright idea is appreciated
Thanks
Related
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%;
}
I'm trying to refactor the jquery related code to angular code.
I have the following use case. There are four a tags, on click of each a tag, its following event handler called which makes certain div visible. For example one of the a tag event handler looks like this:
$("#fistdiv").css('display','none');
$("#seconddiv").css('display','none');
$("#thriddiv").css('display','none');
$("#fourthdiv").css('display','block');
In this case fourthdiv is made visible. And each div shows particular contents in a table.
I want to refactor this jquery-code to angular-js. How that can be done? Rather than falling into querying dom and binding event handlers, how can be made in angular terms?
Thanks in advance.
Pretty naive approach but it should be something you actually need:
Link 1
Link 2
Link 3
Link 4
<div ng-show="visible == 1">Some content 1</div>
<div ng-show="visible == 2">Some content 2</div>
<div ng-show="visible == 3">Some content 3</div>
<div ng-show="visible == 4">Some content 4</div>
Demo: http://plnkr.co/edit/QyCzUuBwB4yoAbmsgXid?p=preview
You should take a look at this directive.
https://docs.angularjs.org/api/ng/directive/ngShow
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.
I have a specific goal in mind.
Please reference this page: http://cubancomplex.kodingen.com/test/MM/dashboard1.html
On the very bottom right, there is a <div> with two buttons on each side. The <div> currently has one google chart contained inside.
The goal is for a user to be able to use those two buttons to switch between charts for approximately eight cities.
I am not familiar with javascript or jQuery so I would appreciate any assistance! How should I go about achieving this?
Here is the code for that section:
<div id="footer">
<div class="markerNavLeft" title="Prev" id="prevMarker">‹</div>
<div id="markers">
<div id="chart">
<div id="auckland_chart_div"></div>
</div>
</div>
<div class="markerNavRight" title="Next" id="nextMarker">›</div>
</div>
Based on my experience, there's 2 option that you can use..
you can place your charts in your div id="chart". The first one add a class to mark it as a selected one (e.g. selected), of course the other is hidden… Please add a same class for all of the chart(e.g. chart-detail). Then, you can use
var temp = $(".selected").next(".chart-detail"); $(".selected").removeClass("selected"); temp.addClass("selected");
for the previous button, you can use .previous function.
You can use ajax ( .ajax function or .load function). Mark each chart with an ID so, you know what's the next or previous chart (within php).
I've got a website set up with well structured pages, eg. <h1> for the website name, <h2> for the page name and <h3> for the different sections on the page.
Anyway, I was looking to set a bunch of the really long pages (an FAQ page for example) up with an "accordion" effect, with the <h3> elements being the toggle and the content directly following being toggled. But the collapsible content needs to be in it's own <div class="draw"> (or similar) and this isn't how the content is set up currently. I was hoping this was possible without touching the existing HTML and just somehow changing the DOM with JS (with jQuery assistance?) to accommodate.
I thought maybe wrapping content between the <h3> elements in a classed <div> might work but wouldn't know how to get this done. Help?
Here's one way to do it that doesn't rely on traversable DOM elements between the h3 tags. I'm not sure how efficient it is to swap out the entire contents of the body tag like this on every load though...
$(document).ready(function(){
var content = $('body').html();
content = content.replace(/(<\/h3>)((.|\n|\r)*?)(<h\d>|$)/gi, "$1<div class=\"draw\">$2</div>$4");
$('body').html(content);
});
I tested this out on content formatted like so:
<body>
<h1>Title</h1>
<h2>Sub-Title</h2>
<h3>Section Title</h3>
this is some content
<h1>Title</h1>
<h2>Sub-Title</h2>
<h3>Section Title</h3>
this is some content
...
</body>
The jQuery documentation on the accordion widget is very easy to use. http://docs.jquery.com/UI/Accordion. But using the jQuery method only works if you have the structure they describe in the docs. In other words (as far as I know) it is impossible to use the jQuery accordion widget without touching your HTML. This is the structure:
<div id="accordion">
<h3>Tab 1</h3>
<div>
First tab content
</div>
<h3>Tab 2</h3>
<div>
Tab two content
</div>
<h3>Tab 3</h3>
<div>
Tab three content
</div>
</div>
Then you would create the widget using the line of javascript:
$("#accordion").accordion();
If you wanted to use jQuery to format your HTML for you, you still need a way to select and parse your HTML. Each tab's content needs to be selectable some how. If your HTML already has the tabs separated somehow, then you need to take a look at this page http://docs.jquery.com/Manipulation. It should be pretty straightforward.
If you're willing to consider non-JS alternatives, Stu Nicholls has some interesting html/css (no js) options on his CSS Play website:
http://www.cssplay.co.uk/menu/gallery3l
http://www.cssplay.co.uk/menus/tabmenu.html
(Among others)
I suppose it looks like this:
<html>
<h1>site name</h1>
<h2>page name</h2>
<h3>section</h3>
<p>some stuff</p>
<p>different paragraph</p>
<ul><li>a list</li></ul>
<h3>next section</h3>
<p>different stuff</p>
...
</html>
you could iterate over all direct children of html. At first h3 you start collection all subsequent items until the next h3. if a next h3 comes or page end you create a div, and add it after the starting h3 all collected elements should be removed from their parent (the html) and added as children of the div.
looking at http://docs.jquery.com/Traversing this should be easy. I'm not an expert on jquery, but it should be doable.
Dave Ward of Encosia has great 10 minute tutorial on jQuery, Firebug and selectors that builds exactly what you looking for.