Angular: Differing HTML templates within an ng-repeat - javascript

I want to use a different template within a repeated block based on the type of data that I am repeating. In my example, the array could contain data or it could contain tweet objects from Twitter. Currently my code looks like this...
<ul data-ng-hide="sourceIsTwitter()" collapse="!showStrings">
<li data-ng-repeat="matchedString in matches">{{matchedString}}</li>
</ul>
<ul data-ng-show="sourceIsTwitter()" collapse="!showStrings">
<li data-ng-repeat="tweet in matches">
{{ tweet.text }}
<i>{{ tweet.user.name }}</i>
{{ formatDateFromTwitter(tweet.created_at) }}
</li>
</ul>
... and throws lots of errors when the content source isn't Twitter. How should I restructure this to use the right template based on the type of the object? Assume that matches is an array of objects and each object has a property type that I can check.

You would probably be best served by the ngSwitch directive:
<li data-ng-repeat="obj in matches" data-ng-switch="obj.type">
<span data-ng-switch-when="twitter"><!-- Do Twitter Rendering --></span>
<span data-ng-switch-when="facebook"><!-- Do Facebook Rendering --></span>
<span data-ng-switch-when="foo"><!-- Do Foo Rendering --></span>
</li>

I had this situation with lots of possible templates - which made ng-switch a bit clunky looking. I put each template in it's own html file and used ng-include with a scope function to retrieve the correct template name:
<ul>
<li data-ng-repeat="match in matches">
<div ng-include="getTemplate(match)"></div>
</li>
</ul>

Related

Prevent merge of elements when they are unique

I'm using TinyMCE 6 and I've created a custom block insert using a <ul>, and for the most part this is working great. However, if I have several and position the cursor in front of one of the blocks and hit backspace, it then merges all the contained <li> into a single <ul>. I've tried using attributes like data-id, id, name etc but Tiny simply discards this data from one of the elements and does the merge anyway. If I use a random number as a class name, they do not merge so this is a workaround.
For reference, the blocks are set as noneditable (I have a double-click handler configured for a custom function), so I don't see why it would try and merge them anyway.
Any ideas?
Here's a snippet of HTML as it should be:
<ul id="123" class="leaders mceNonEditable">
<li class="item-en text_gold"><span>Mmm Cookies</span><span>$MONEY$$$$$$</span></li>
<li class="item-ja"><span>SOMEJATEXT</span></li>
</ul>
<ul id="234" class="leaders mceNonEditable">
<li class="item-en"><span>Mmm Cookies</span><span>$495</span></li>
<li class="item-ja"><span>SOMEJATEXT</span></li>
</ul>
And some that ended up:
<ul id="123" class="leaders mceNonEditable">
<li class="item-en text_gold"><span>Mmm Cookies</span><span>$MONEY$$$$$$</span></li>
<li class="item-ja"><span>SOMEJATEXT</span></li>
<li class="item-en"><span>Mmm Cookies</span><span>$495</span></li>
<li class="item-ja"><span>SOMEJATEXT</span></li>
</ul>

Link from another page element to a specific data-filter

I have a HTML portfolio page that has filtering attribute
<ul class="portfolio-filters list-inline">
<li class="filter active" data-filter="all">All</li>
<li class="filter" data-filter="webdesign">Web Design</li>
<li class="filter" data-filter="responsive">Responsive</li>
<li class="filter" data-filter="wordpress">Wordpress</li>
</ul>
And I have another HTML page that has some services. example of one of my codes in the other page:
<div>
<i></i>
<div>
<h4>Web Design</h4>
</div>
</div>
What I want is when user click on this service icon for example, it will redirect the user to the webdesign filter of the portfolio page.
I tried many ways like adding link portfolio.html?filter=webdesign to the a href of the service icon but it didn't work.
I think you should follow a few tutorials on HTML5, CSS 3 and Javascript.
I made a basic version in this codepen. Please note I'm using the URLSearchParams API which is not supported in IE and other older browser. Also, I'm using Ecmascript 6.
What does the algorithm do?
Check the URL, is there a filter parameter (as in http://.../somewhere?filter=wordpress)
If not, do nothing and show everything, otherwise,
get all the content that has a filter class
display the content that match
hide the rest.
The crux of the algorithm lies in the getting of the query parameters, then it's a matter of looping over a collection and changing the style's display attribute (see the documentation for the display attribute)
// 1. get URL query param (does not work on IE, AFAIK)
const url = new URL(window.location.href)
const currentFilter = url.searchParams.get('filter')
// we only filter stuff if a filter is provided
if (currentFilter != null) {
// 2. collect all filters
const collection = document.getElementsByClassName('filter')
// 3. traverse the collection, hide what's not of interest, show the rest
for (let item of collection) {
if (item.classList.contains(currentFilter)) {
item.style.display = 'block'
break
}
item.style.display = 'none'
}
}
Maybe this works for you. Give your li tags specific id's:
<ul class="portfolio-filters list-inline">
<li class="filter active" data-filter="all" id="all-filter">All</li>
<li class="filter" data-filter="webdesign" id="webdesign-filter">Web Design</li>
<li class="filter" data-filter="responsive" id="responsive-filter">Responsive</li>
<li class="filter" data-filter="wordpress" id="wordpress-filter">Wordpress</li>
</ul>
Then you can just link to the specific id:
<div>
<i></i>
<div>
<h4>Web Design</h4>
</div>
</div>
Else you would have to use javascript I guess.

How can I manipulate an element's data attributes from an external page link?

I'm looking for the absolute simplest way to pass a data attribute along to a new page (non AJAX loading).
I've been messing around with a Wordpress theme all night trying to customize the gallery category filters. I want to do as little coding as possible in making my adjustments to a pre-existing layout, but the complicating factor here is that I have a single page which already has data attributes assigned to elements that can be filtered from links on the same page and I need to be able to load the page with data attributes already set for filtering from external links.
I'll try to make a visual for the scenario that might help (or not ?):
First page is already functioning:
<!---main-gallery_page.php--->
<header class="category-filters">
<ul class="list">
<li> Category Filter 1 </li>
<li> Category Filter 2 </li>
<li> Category Filter 3 </li>
</ul>
</header>
<div class="gallery-thumbs">
<!--- thumbnails with example-id data attributes are filtered, respectively: "generic-X" --->
</div>
Second page needs to manipulate the page above after loading it ^
<!---second-example_page.php--->
<div class="alternate-category-filters">
<ul class="list">
<li> Category Filter 1 </li>
<li> Category Filter 2 </li>
<li> Category Filter 3 </li>
</ul>
</div>
Obviously the second example is not going to function because the new page doesn't receive any instructions to filter the thumbnails, so it'll just load as-is.
Just want to be able to operate the category filter on page load as specified from an external (non-ajax) page. Any ideas on a simple method? I've been trying to see what I can do with php echoes and even stuffing the info into the hyperlink href value, but I couldn't get that to work. It would be ideal if I could do something like this:
<!---second-example_page.php--->
<div class="alternate-category-filters">
<ul class="list">
<li> Category Filter 1 </li>
<li> Category Filter 2 </li>
<li> Category Filter 3 </li>
</ul>
</div>
Help would be greatly appreciated, I've exhausted myself jumping around millions of topics that always seem to just miss explaining this particular scenario's solution.
You could poll a value in localStorage. Make the main page poll localStorage.category. (Using setTimeout for example). Then, once the second page loads and changes the value, the main page could see the change and act accordingly.

Angularjs json ng-repeat displays items properties only with manual iterator

Im getting json from some web service and displaying it with ng-repeat but i can't seem to display item properties.
<ul>
<li data-ng-repeat="item in itemList">
<p>{{item}}</p>
</li>
</ul>
This works and will display all json
<ul>
<li data-ng-repeat="item in itemList">
<p>{{item.name}}</p>
</li>
</ul>
This doesnt work.
<ul>
<li data-ng-repeat="item in itemList">
<p>{{item[0].name}}</p>
</li>
</ul>
This works but will only display 1 item.
I just started working with angular and i feel im missing something becouse of it, if needed ill try to post a jfiddle of a sample.
UPDATE
im tring to get twitch.tv stream info
https://github.com/justintv/Twitch-API/blob/master/v2_resources/streams.md#get-streams
raw json from 2 streams, what i get from the first example
http://pastebin.com/bQLqu9BR
UPDATE 2
my code
http://plnkr.co/edit/3eOZ598zt2hkrJcsOLhP
Hmmm... I seem to be able to work with the sample data you provided.
See the following:
http://plnkr.co/edit/M3TQ4qI1DJPtgv6jCQLy?p=preview
Snippet:
<ul>
<li ng-repeat="item in srcData">
<p ng-bind="item.game"></p>
<p ng-bind="item.channel.display_name"></p>
<p ng-bind="item.channel.url"></p>
</li>
</ul>
You don't need to include an index for each item to display its properties, every item knows its index number and you can access it using the $index variable.
Check this out:
http://plnkr.co/edit/ECyyFYVupVG7mKqwsGaB
<ul>
<li ng-repeat="item in itemList">
{{$index}}
<p>
Game: {{item.game}}
</p>
<p>
Channel Name: {{item.channel.name}}
</p>
</li>
</ul>

AngularJS : Appending the same structure on the click of each item

My index.html page is like following:
<div id="sidepanel" ng-controller="myCtrl">
<ul class="drop-down">
<li ng-repeat="item in items">
{{item.name}}
</li>
</ul>
</div>
<div id="mainpanel" ng-controller="listCtrl">
<div ng-view></div>
</div>
For this ng-view I have record-list.html to show all the records which is like following:
<div class="container">
<ul class="design">
<li id="{{record.name}}" ng-repeat="record in records">
<div>......</div>
</li>
</ul>
</div>
Now i want to add the same structure (as like each record) append on the click of each item of the side panel.
what is the logic for that ?
My recent UI Looks like this & i want to add the same structure on each click which should be append the existing structure.
Please Help.Thanks.
It sounds like perhaps each "record" has a set of children "records." If this is the case, I would recommend using angular's ng-switch directive to conditionally display the correct (or no) set of sub-records on the side.

Categories

Resources