KnockoutJS- Show message when foreach has no result - data-binding

One of the web pages is showing products using databind:foreach
Here is the piece of code
<div class="product-list">
<ul data-bind="foreach: products">
<li>
<div class="product-summary">
<div class="photo">
<a data-bind="attr:{href: Link}">
<img data-bind="attr:{src: SummaryImageUrl, title: DisplayName}" alt="product image" />
</a>
</div>
<div class="product-info">
<h4 class="product-title" data-bind="attr:{title: DisplayName}">
<a data-bind="attr:{href: Link}, text: DisplayName"></a>
</h4>
<!-- ko if: Brand-->
<div data-bind="html: Brand" class="product-brand"></div>
<!-- /ko-->
<!-- ko ifnot: Brand-->
<div class="product-brand"> </div>
<!-- /ko -->
I want to show a message if there is no product.Hence, added a line as below:
<div data-bind="visible:products().length==0">
No product(s) found.
</div>
<div class="product-list">
<ul data-bind="foreach: products">
<li>
Now when page is loading, it shows No products found and then hides it and renders whole products
Could you please help?

The problem is when the data for the products is loaded compared to when it gets rendered on to the screen. I imagine what is happening is that there is a process to retrieve the products from the server, while that is happening the screen is rendered and bound to the view model, resulting in the No Products Found being displayed. then at some unspecified time later the products get loaded and the screen gets updated with the new data. I think what you probably need is a flag to indicate when a search is being performed, and when its finished. this will allow you to show and hide the rendering of the results when the results are known.
<div data-bind="visible: showResults">
<div data-bind="visible:products().length==0">
No product(s) found.
</div>
<div class="product-list">
<ul data-bind="foreach: products">
<li></li>
</ul>
</div>
</div>

I would created an observable flag to notify if data is loaded and then wrap your html in ko virtual binding as shown in following code snippet.
function viewModel() {
var self = this;
self.products = ko.observableArray([]);
self.isDataLoaded = ko.observable(false);
self.loadData = function(){
setTimeout(function(){
self.products.push({name:"A"});
self.products.push({name:"B"});
self.products.push({name:"C"});
self.products.push({name:"D"});
self.isDataLoaded(true);
}, 2000);
}
}
var vm = new viewModel();
vm.loadData();
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--ko if:isDataLoaded-->
<div class="product-list">
<ul data-bind="foreach: products">
<li data-bind="text:name"></li>
</ul>
</div>
<div data-bind="visible:products().length==0">
No product(s) found.
</div>
<!-- /ko -->

Related

How to add forward back and refresh buttons for webviews in Electronjs?

I am displaying multiple webview contents using Electron Js.
part of index.html
<div class="contentArea">
<div id="mySidebar" class="leftMenu">
<ul id="myTab" class="nav nav-tabs">
<li class="nav-item">
Tab1
</li>
<li class="nav-item">
Tab2
</li>
<li class="nav-item">
Tab3
</li>
</ul>
</div>
<div class="contentPages tab-content">
<div class="tab-pane show active" id="webview1">
<webview src="link1" style="width:100%; height:100%" disablewebsecurity allowpopups></webview>
</div>
<div class="tab-pane" id="webview2">
<webview src="link2" style="width:100%; height:100%" disablewebsecurity allowpopups></webview>
</div>
<div class="tab-pane" id="webview3">
<webview src="link3" style="width:100%; height:100%" disablewebsecurity allowpopups></webview>
</div>
<script>
$(document).ready(function () {
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var activeTab = $(e.target).text(); // Get the name of active tab
var previousTab = $(e.relatedTarget).text(); // Get the name of previous tab
$(".active-tab span").html(activeTab);
$(".previous-tab span").html(previousTab);
});
});
</script>
</div>
</div>
I used bootstrap and jquery for design.
Navigation between webviews works very nicely with jquery.
I'm trying to do. Creating forward, backward and refresh buttons for each webview.
It's like an internet browser.
I didn't manage to use the codes properly in ElectronJS.
Can anyone who knows about this please help?
It's Work.
$(document).on( 'click', '#back-button-id', function(){
if(webview-id.canGoToOffset(-1)){
webview-id.goBack();
} });
$(document).on( 'click', '#next-button-id', function(){
if(webview-id.canGoToOffset(+1)){
webview-id.goForward();
} });

Where I can find some of this data bind in Ghost using handlebars?

I know my question seems weird but since I'm new when using ghost with handlebars language, I'm quite confused as to where I can find some of this data bind such as title, #site.logo, etc. I try to find it inside casper template but I still not find it, this is the example of the code image inside casper theme
if you ask why I try to find it, I want to try add some of the content inside it or at least I want to take a look what kind of data bind that casper have or provided.
for example in this post.hbs you can see that there is a lot of data bind in here, but I just can't find what else the data bind they provided,
{{!< default}}
{{!-- The tag above means: insert everything in this file
into the {body} of the default.hbs template --}}
<header class="site-header">
{{> site-header}}
</header>
{{!-- Everything inside the #post tags pulls data from the post --}}
{{#post}}
<main id="site-main" class="site-main outer">
<div class="inner">
<article class="post-full {{post_class}} {{#unless feature_image}}no-image{{/unless}}">
<header class="post-full-header">
{{#if primary_tag}}
<section class="post-full-tags">
{{#primary_tag}}
{{name}}
{{/primary_tag}}
</section>
{{/if}}
<h1 class="post-full-title">{{title}}</h1>
{{#if custom_excerpt}}
<p class="post-full-custom-excerpt">{{custom_excerpt}}</p>
{{/if}}
<div class="post-full-byline">
<section class="post-full-byline-content">
<ul class="author-list">
{{#foreach authors}}
<li class="author-list-item">
<div class="author-card">
{{#if profile_image}}
<img class="author-profile-image" src="{{img_url profile_image size="xs"}}" alt="{{name}}" />
{{else}}
<div class="author-profile-image">{{> "icons/avatar"}}</div>
{{/if}}
<div class="author-info">
{{#if bio}}
<div class="bio">
<h2>{{name}}</h2>
<p>{{bio}}</p>
<p>More posts by {{name}}.</p>
</div>
{{else}}
<h2>{{name}}</h2>
<p>Read more posts by this author.</p>
{{/if}}
</div>
</div>
{{#if profile_image}}
<a href="{{url}}" class="author-avatar">
<img class="author-profile-image" src="{{img_url profile_image size="xs"}}" alt="{{name}}" />
</a>
{{else}}
{{> "icons/avatar"}}
{{/if}}
</li>
{{/foreach}}
</ul>
<section class="post-full-byline-meta">
<h4 class="author-name">{{authors}}</h4>
<div class="byline-meta-content">
<time class="byline-meta-date" datetime="{{date format="YYYY-MM-DD"}}">{{date format="D MMM YYYY"}}</time>
<span class="byline-reading-time"><span class="bull">•</span> {{reading_time}}</span>
</div>
</section>
</section>
</div>
</header>
{{#if feature_image}}
<figure class="post-full-image">
{{!-- This is a responsive image, it loads different sizes depending on device
https://medium.freecodecamp.org/a-guide-to-responsive-images-with-ready-to-use-templates-c400bd65c433 --}}
<img
srcset="{{img_url feature_image size="s"}} 300w,
{{img_url feature_image size="m"}} 600w,
{{img_url feature_image size="l"}} 1000w,
{{img_url feature_image size="xl"}} 2000w"
sizes="(max-width: 800px) 400px,
(max-width: 1170px) 1170px,
2000px"
src="{{img_url feature_image size="xl"}}"
alt="{{title}}"
/>
</figure>
{{/if}}
<section class="post-full-content">
<div class="post-content">
{{content}}
</div>
</section>
{{!-- Email subscribe form at the bottom of the page --}}
{{#if #labs.members}}
{{> subscribe-form}}
{{/if}}
{{!--
<section class="post-full-comments">
If you want to embed comments, this is a good place to do it!
</section>
--}}
</article>
</div>
</main>
{{!-- Links to Previous/Next posts --}}
<aside class="read-next outer">
<div class="inner">
<div class="read-next-feed">
{{#if primary_tag}}
{{#get "posts" filter="tags:{{primary_tag.slug}}+id:-{{id}}" limit="3" as |related_posts|}}
{{#if related_posts}}
<article class="read-next-card">
<header class="read-next-card-header">
{{#../primary_tag}}
<h3><span>More in</span> {{name}}</h3>
{{/../primary_tag}}
</header>
<div class="read-next-card-content">
<ul>
{{#foreach related_posts}}
<li>
<h4>{{title}}</h4>
<div class="read-next-card-meta">
<p><time datetime="{{date format="YYYY-MM-DD"}}">{{date format="D MMM YYYY"}}</time> –
{{reading_time}}</p>
</div>
</li>
{{/foreach}}
</ul>
</div>
<footer class="read-next-card-footer">
<a href="{{#../primary_tag}}{{url}}{{/../primary_tag}}">{{plural meta.pagination.total empty='No posts' singular='% post' plural='See all % posts'}}
→</a>
</footer>
</article>
{{/if}}
{{/get}}
{{/if}}
{{!-- If there's a next post, display it using the same markup included from - partials/post-card.hbs --}}
{{#next_post}}
{{> "post-card"}}
{{/next_post}}
{{!-- If there's a previous post, display it using the same markup included from - partials/post-card.hbs --}}
{{#prev_post}}
{{> "post-card"}}
{{/prev_post}}
</div>
</div>
</aside>
{{/post}}
{{!-- The #contentFor helper here will send everything inside it up to the matching #block helper found in default.hbs --}}
{{#contentFor "scripts"}}
<script>
$(document).ready(function () {
// FitVids - start
var $postContent = $(".post-full-content");
$postContent.fitVids();
// FitVids - end
// Replace nav with title on scroll - start
Casper.stickyNavTitle({
navSelector: '.site-nav-main',
titleSelector: '.post-full-title',
activeClass: 'nav-post-title-active'
});
// Replace nav with title on scroll - end
// Hover on avatar
var hoverTimeout;
$('.author-list-item').hover(function () {
var $this = $(this);
clearTimeout(hoverTimeout);
$('.author-card').removeClass('hovered');
$(this).children('.author-card').addClass('hovered');
}, function () {
var $this = $(this);
hoverTimeout = setTimeout(function () {
$this.children('.author-card').removeClass('hovered');
}, 800);
});
});
</script>
{{/contentFor}}
can someone help me to point it out where I can find a list of data bind they provided? I'm quite confused to understand it
they call that Helpers and you can find the full list here:
Themes documentation
There is several categories: Functionnal, Data, Utility, Extra... And you find several inside with a description for each.
Regards
Are you looking for a particular piece of data that you've put into Ghost admin? {{#site.logo}} and {{#site.title}} is how you out put those data values 😊

Meteor swiper slider taking time to load images and videos?

I am using swiper slider in meteor but it's taking too much time to load images and videos in slider on the home page. On my home page posts are coming and each posts videos and images are coming in the slider. But after taking too much time to load it crash the page. This is code to show posts videos and images in swiper slider.
{{#if imagesArguments}}
<div class="argu-scroller" id="argumentImages" style="border:1px solid #d4d6d8; margin-top:10px;" data-userProfile="{{getImage plaintiff._id}}">
<div class="swiper-wrapper">
{{#if meta.thumbnail_url}}
<div class="swiper-slide swiper-card">
<div class="evidencecard">
<div class="evidencecard-inside">
<header>
<a href="{{plaintiff_bitlyurl.url}}" target="_blank">
<img src="{{meta.thumbnail_url}}" />
<div class="text-wrap">
<h2>{{meta.title}}</h2>
</div>
</a>
</header>
<main>
<div class="info-wrap">
<h5>{{plaintiff_bitlyurl.url}}</h5>
<!--<p>{{evidenceFull plaintiff_evidence}}</p>-->
<p>{{meta.description}}</p>
</div>
</main>
</div>
</div>
</div>
{{/if}}
{{#each imagesArguments}}
<div class="swiper-slide swiper-image">
<div class="argumentimageshome argument2 tem-miniargument">
<a data-toggle="modal" data-target="#imageZoomview" class="imgZoom" data-id="{{this}}" >
<img class="img-thumbnail" src="{{this}}" />
</a>
</div>
</div>
{{/each}}
{{#each videoArguments}}
<div class="swiper-slide swiper-video">
<div class="argumentvideoshome">
<div class="video">
<video height="150" controls>
<source src="{{this}}" type="video/mp4">
</video>
</div>
</div>
</div>
{{/each}}
</div>
</div>
{{/if}}
code to call slider in js file
Template.miniArgument.onRendered(function(){
var swiper = new Swiper('.argu-scroller', {
slidesPerView: 3,
spaceBetween: 30,
slidesPerGroup: 3,
loop: true,
loopFillGroupWithBlank: true,
pagination: {
el: '.swiper-pagination',
clickable: true,
},
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
});
});
I think this is not related to Meteor. Did you try to use the virtualization component in the Swiper? You would need to lazy-load extra slides. If not too many, you can preload all of them with the ones in view being prioritized. If you have many, you need to make use of the lazy load. Check this discussion: https://github.com/nolimits4web/swiper/issues/1279 . In your Network tab in Chrome developer tools, do you see a lot of MBs being downloaded? If you have huge assets ... it will indeed take time.

initial mobile screen doesn't scroll

The template i'm using doesn't allow scrolling on load. You can only touch scroll after you have selected a collapsed menu item. Once you scroll back to the top it "locks" again (so-to-speak).
The main area that seems to be unscrollable is a slider. Can anyone tell me what I need to do to make this site be scrollable on load?
Any information is greatly appreciated.
The site is here... http://www.slicemfg.com
<div id="home">
<div class="tp-banner-container">
<div class="tp-banner" >
<ul>
<!-- THE FIRST SLIDE -->
<li data-transition="zoomout" data-slotamount="4" data-masterspeed="700">
<img src="images/1.jpg" alt="" /> }
<!-- THE CAPTIONS IN THIS SLIDE -->
<div class="caption big-text lft"
data-x="center"
data-y="350"
width="10px"
data-speed="700"
data-start="700"
data-easing="easeOutExpo">
<div class="big-text"><span4>YOUR IDEAS REALIZED</span4></br><div><a class="button3 scroll" href="#contact">CONTACT US</a></div></div>
</div>
</li>
<li data-transition="zoomout" data-slotamount="1" data-masterspeed="700">
<img src="images/14.jpg" alt="" />
<div class="just_pattern"></div>
<div class="caption big-text lft"
data-x="center"
data-y="center"
data-speed="700"
data-start="700"
data-easing="easeOutExpo"><div class="big-text"><span4>YOUR IDEAS REALIZED</span4></br><div><a class="button3 scroll" href="#contact">CONTACT US</a></div></div>
</div>
</li>
<li data-transition="zoomout" data-slotamount="1" data-masterspeed="700">
<img src="images/07.jpg" alt="" />
<div class="just_pattern"></div>
<div class="caption big-text lft"
data-x="center"
data-y="center"
data-speed="700"
data-start="700"
data-easing="easeOutExpo"><div class="big-text"><span4>YOUR IDEAS REALIZED</span4></br><div><a class="button3 scroll" href="#contact">CONTACT US</a></div></div>
</div>
</li>
<li data-transition="zoomout" data-slotamount="1" data-masterspeed="700">
<img src="images/04.jpg" alt="" />
<div class="just_pattern"></div>
<div class="caption big-text lft"
data-x="center"
data-y="center"
data-speed="500"
data-start="500"
data-easing="easeOutExpo"><div class="big-text"><span4>YOUR IDEAS REALIZED</span4></br><div><a class="button3 scroll" href="#contact">CONTACT US</a></div></div>
</div>
</li>
</ul>
</div>
</div>
</div>
To fix this issue, you need to add touchenabled:"off", to your revolution config.
Your config should now look like this:
(function($) { "use strict";
var revapi;
jQuery(document).ready(function() {
revapi = jQuery('.tp-banner').revolution(
{
delay:5000,
startwidth:2000,
startheight:500,
soloArrowRightVOffset:50,
soloArrowLeftVOffset:50,
hideThumbs:0,
onHoverStop:"off",
navigationType: "none",
fullWidth:"off",
fullScreen:"on",
fullScreenOffsetContainer: "",
touchenabled:"off" //Disable touch events.
});
}); //ready
})(jQuery);

Display SignIn Modal in topbar menu with zurb foundation 5 and meteor

I am working on a project with Meteor JS (version 1.2) using the accounts-password package for user sign up / sign in.
I am using - or at least try to use - Zurb Foundation 5 (version 5.3) for my projekt. I tested the ewall:foundation package and the juliancwirko:zf5 package and both works well.
For accounts i added the useraccounts:foundation package.
Using the {{> atForm}} tamplate on a page works also well. The SignIn/SignUp Form displays correctly.
But using it in a fixed top NavBar does not work. It displays it not correctly. (See pictures and source below.)
I am getting NO errors in the console that something is not loading correctly.
I assume the useraccounts:foundation package to display a button/link in the navbar and then show a modal/popup with the login form.
My Question: Is any of the packages broken or am I using them wrong in any way?
Or is my assumption, that the useraccounts:foundation package should display the signin form in a nav bar with a modal, just wrong? If so, what do I need to do to get that desired behavior in my app?
The App displays the signin form in the page correctly, but in the navbar wrong.
In the mobile view ...
... it displays also not correctly.
I made a simple projekt without any router etc to test just the above packages, here is the source:
project/client/main.html
<head>
<title>ZF5 Demo</title>
</head>
<body>
{{> header}}
{{> content}}
</body>
project/client/header.html
<template name="header">
<nav class="top-bar" data-topbar="">
<ul class="title-area">
<li class="name">
<h1>ZF5 Demo</h1>
</li>
<li class="toggle-topbar menu-icon"><span>menu</span></li>
</ul>
<section style="left: 0%;" class="top-bar-section">
<ul class="right">
<li>Home</li>
<li>{{> atForm}}</li>
</ul>
</section>
</nav>
</template>
project/client/header.js
Template.header.rendered = function () {
$(document).foundation('reflow');
}
project/client/content.js
<template name="content">
<section class="row">
<div class="large-12 columns">
<div class="panel">
<h1>Content</h1>
{{> atForm}}
</div>
</div>
</section>
</template>
The rendered HTML looks like that (only the navbar part).
<body>
<nav data-topbar="" class="top-bar">
<ul class="title-area">
<li class="name">
<h1>ZF5 Demo</h1>
</li>
<li class="toggle-topbar menu-icon"><span>menu</span></li>
</ul>
<section class="top-bar-section" style="left: 0%;">
<ul class="right">
<li>Home</li>
<li>
<div class="at-form">
<div class="at-title">
<h3>Sign In</h3>
</div>
<div class="at-pwd-form">
<form method="POST" action="#" novalidate="" id="at-pwd-form" role="form">
<div class="at-input row">
<div class="large-12 columns">
<label for="at-field-email">
Email
</label>
<input aria-label="Email " placeholder="Email" name="at-field-email" id="at-field-email" type="email">
</div>
</div>
<div class="at-input row">
<div class="large-12 columns">
<label for="at-field-password">
Password
</label>
<input aria-label="Password " placeholder="Password" name="at-field-password" id="at-field-password" type="password">
</div>
</div>
<button id="at-btn" class="at-btn button" type="submit">
Sign In
</button>
</form>
</div>
<div class="at-signup-link">
<p>
Don't have an account?
<a class="at-link at-signup" id="at-signUp" href="#">Register</a>
</p>
</div>
</div>
</li>
</ul>
</section></nav>
[...content...]</body>
EDIT
I tried to wrap the {{> atForm}} template into a dropdown in project/client/header.html:
<template name="header">
<nav class="top-bar" data-topbar="">
<ul class="title-area">
<li class="name">
<h1>ZF5 Demo</h1>
</li>
<li class="toggle-topbar menu-icon"><span>menu</span></li>
</ul>
<section style="left: 0%;" class="top-bar-section">
<ul class="right">
<li>Home</li>
<li>
<a data-dropdown="signin-dropdown" aria-controls="signin-dropdown" aria-expanded="false">Sign In</a>
<div id="signin-dropdown" data-dropdown-content class="f-dropdown content" aria-hidden="true">
<div>
{{> atForm}}
</div>
</div>
</li>
</ul>
</section>
</nav>
</template>
The result looks like this:
Now the Menu Button looks better, ...
... but the LogIn Form is rendered incorrect.
I also tried out several other things and nothing worked out.
I think this is a problem only with the way I use foundation, because I am new to that framework and don't understand every detail.
So I will stick with the SignIn Modal Form like shown in that example.

Resources