I am working on a webpage. On this page there is a portfolio grid of downloadable resources that are represented with pictures. Currently if someone tries to change the filter before all of the images load it will break it.
I would like those buttons to not be clickable until all of the images on the screen have loaded, and I would like to do so using JQuery.
How can I accomplish this?
Add a class to the filters container that prevents interaction such as:
.disabled {
pointer-events: none;
}
<div id="filters-container" class="cbp-l-filters-alignCenter disabled">
And then use the initComplete.cbp event from the plugin to remove it.
$("#grid-container").on('initComplete.cbp', function() {
$('#filters-container').removeClass('disabled');
});
Hide all images by default using CSS
img{
display: none;
}
/* disable all buttons using class disabled*/
.disabled{
pointer-events: none;
}
Use Jquery to check if all loaded, then display images and enable buttons
JQuery
$(window).load(function(){
$('img').fadeIn(800); //or $('img').show('slow');
$('.disabled').css('pointer-events', 'auto');
});
Related
I'm new in the php language, I have to create some buttons that have to filter / show some posts of certain categories but without the page being reloaded. So I know it's possible to use a function with php and ajax but I don't understand how to call ajax and what to write.The result should be this
So with php you can only send requests to the server to filter the posts causing a reload of the page. What you want is an instant filter, that gets all the data first and then, for example with javascript, filter this already loaded posts by category / taxonomy.
Doing this with Vue.js is pretty easy. Why use Vue js? You can simply add it with one line of code to your wordpress page.
I assume, you are now in your archive.php inside of the folder of your theme.
Put this code below the get_header() ?> and make vue available on your page:
<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
You can find the production code here: https://v2.vuejs.org/v2/guide/ If you don't need the console warnings for debugging.
I now give you the code and will explain after that. With the follwing code in your archive.php (in the main container of your archive page), you put a link which toggles a div container with the filter buttons. The buttons are all your categories, if you click them, the posts will be filtered:
<div id="filtered_posts">
<span class="filter_button" v-on:click="isHidden = !isHidden">Filter by Category</span>
<div class="filters" v-if="!isHidden">
<span class="filter" :class="{ active: currentFilter === '' }" v-on:click="setFilter('')">All</span>
<span class="filter" :class="{ active: currentFilter === category.id }" v-on:click="setFilter(category.id)" v-for="category in categories">{{ category.name }}</span>
</div>
<transition-group id="archive" class="categories" name="categories" >
<div v-if="currentFilter === post.categories['0'] || currentFilter === ''" v-bind:key="post.title.rendered" v-for="post in posts">
<a v-bind:href="post.link"><img v-bind:src="post._embedded['wp:featuredmedia']['0'].media_details.sizes.medium_large.source_url"></a>
<a v-bind:href="post.link"><h4 v-html="post.name"></h4></a>
<p class="smaller" v-html="post.title.rendered"></p>
</div>
</transition-group>
</div>
<script src="<?php echo get_template_directory_uri(); ?>/js/filter.js"></script>
So what we are doing here is we make an container (#filtered_posts) and put the link to toggle the filter buttons. After that there are the filter buttons inside of the div with the .filters class. The first span is for resetting to all posts, the second span circles through your categories (done by vue js for you) the call the setFilter() function on click.
The transition-group is used for a nice transition animation we add later. Here you check your current set filter in the if and circle through your posts, done by v-for="post in posts", as we did it with the categories before. We output some values by using the wp rest api fields, calling them with a dot followed by the name.
At the end we include a javascript file. And there we get the data to be displayed.
Please now create a folder in your theme folder called "js" and put an empty filter.js file in it.
You get now the code for the filter.js file, which you are getting in the archive.php file with the script tag.
new Vue({
el: '#filtered_posts',
data: {
currentFilter: '',
categories: [],
posts: [],
isHidden: true,
},
mounted() {
fetch("https://yourWordpressURLhere.com/wp-json/wp/v2/categories")
.then(response => response.json())
.then((data) => {
this.categories = data;
})
fetch("https://yourWordpressURLhere.com/wp-json/wp/v2/posts?per_page=20&_embed=wp:term,wp:featuredmedia")
.then(response => response.json())
.then((data => {
this.posts= data;
}))
},
methods: {
setFilter: function (filter) {
this.currentFilter = filter;
}
}
});
We are creating a vue instance and set it to the element with the id "filtered_posts", so its the container wrapping our code from before.
We now create some data objects to save data in it for the categories, the posts, the current filter and an isHidden for the toggle of the filter buttons.
We mount some data via api from wordpress. Please use the URL of your wordpress page. Make sure you have https to make it work. We are saving the recieved data into our "categories" and "posts" objects.
The setFilter function gets the current filter via parameter and sets it for this element.
We only have to set some CSS now, please add to your style.css of your theme:
.categories {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
}
.categories-enter {
-webkit-transform: scale(0.5) translatey(-80px);
transform: scale(0.5) translatey(-80px);
opacity: 0;
}
.categories-leave-to {
-webkit-transform: translatey(30px);
transform: translatey(30px);
opacity: 0;
}
.categories-leave-active {
position: absolute;
z-index: -1;
}
With this CSS code, you have nice transitions when clicking your filter buttons.
You are now all set up, should get your categories in clickable buttons, which filter the output underneath.
There is a lot more to explain about this code, but I think the post is already long enough. If you ask in the comments, I will add more information if needed.
Hope this gives you a smooth and easy starting point for filtering posts with vue js with no reload.
I have a php page which generates links based on results from an "USERS" table, "NAME" row.
I'm using a jQuery tooltip so that a div appears when those links are hovered.
When the hover happens, I am able to get the link's text using $(this).text(), however, I don't seem to be able to parse the result so that it can link with PHP, as I want to display in the 'hidden' div certain info about the HOVERED user (e.g. his e-mail address).
Something like: When "Mike" is hovered, show Mike's e-mail address in the hover div.. and so on.
I've tried with cookies (when mouseover happens, I used something like:
$.post("gophp.php", {"name":$(this).text()}, function(results) {
nada
});
, with gophp.php setting a cookie with data from $_POST['name']) - the div inside the other page is then able to show the cookie, BUT if I hover some other link, the data which is displayed remains the same because the page has to be reloaded.
Please help me, I'm going nuts.
why are you trying to use cookies?
Why dont you use:
$.post("gophp.php", {"name":$(this).text()}, function(results) {
$('div').html(results);
});
and in your gophp.php:
<?php echo 'some_mail#address.com' ?>
(You have to adapt both php and jquery to your situation)
This seems a horrible way around what you're wanting to do. Just have the email address on the page, but initially hidden, and show it on hover.
For example, in your HTML have:
<ul class="people-list">
<li>
<a href="">
<span class="name">Martin Bean</span>
<span class="email">martin#example.com</span>
</a>
...
</li>
</ul>
And then to style it:
.people-list a {
display: block;
width: 100px;
position: relative;
}
.people-list .name, .people-list .email {
display: block;
}
.people-list a .email {
display: none;
}
.people-list a:hover .email {
display: block;
}
Should do the trick in a primitive fashion. You can then position/style as necessary.
Of course, why you want email addresses public available is a whole different topic of conversation.
I'm having following problem: my PHP page generates navigation menus from db like <ul> menus then with the help of JS shows it like multi-level menu. The problem is, it shows whole loading process. At first user sees something like that:
Then
How to hide whole loading process of page, or is there any other solution for this issue?
hide it in css,
#loading {
display: block;
background: url(loading.gif) no-repeat center center;
}
#container {
display: none;
}
and, in javascript show it again (this code uses jquery)
$(function(){
$('#loading').fadeOut(250, function(){
$('#container').show();
});
});
of course you can do this like anyhow you want, hide and show anything in css,
then on document ready, switch it over to the content. by hiding the loading div, and showing the content.
Set the style on display:none; until your page is completely loaded.
Generally this is done by showing/hiding a div or two over the top of your content. You can get a fancy loading gif from http://www.ajaxload.info/ to get you started. Then you'll want to place a DIV on your page:
<div id="loading">
<p><img src="loading.gif" /> Please Wait</p>
</div>
You'll want this hidden by default, so you'd need to add this CSS:
#loading { display:none; }
You'd also want to setup the display for this too:
#loading { display:none; position:fixed; left:0; top:0; width:100%; height:100%;
background-image:url("transparentbg.png"); }
#loading img {position: absolute; left:50%; top:50%}
The file transparentbg.png would be a 25x25 black PNG set to about 80% opaque. Next you would need a way to show and hide this with jQuery:
function showLoading() {
$("#loading").show();
}
function hideLoading() {
$("#loading").hide();
}
I've been searching for examples of custom on mouse right click menus but i would like to emulate the same options you get when you right click in chrome on a web page Maintaining cut, copy, and paste but also (here is the tricky part) instead of opening a new tab in your browser it opens the same webpage inside an iframe, option.
Thanks
Take a look at this plugin, it might help you
http://plugins.jquery.com/project/jqueryContextMenu
I would suggest hiding the "Window" which will be a div or some HTML element
Once user has right clicked on an element you can access it through jquery selectors and
enable it's visibility.
css:
#hiddenFrame {
display: none;
width: 250px;
height: 250px;
}
javascript:
menu1 = { attributes: "brief_number,brief_id,...",
items: [
{
type:RightContext.TYPE_MENU,
text:"some text",
onclick:function() {$('#hiddenFrame').show();}
}
]
};
I am trying to reproduce the lock function on posts on facebook with jquery and php/mysql.
Below is an image showing the different actions it does when clicked on.
I think you would do somehing like on hover, show a hidden div with a tooltip, on hover off remove it. On click event show another hidden div but somehow has to change the button's colors as well. When the menu div is clicked open it has a menu and if any of these are clicked it needs to send the result to backend script with ajax. After clicking an option or clicking outside of the divs it will hide all the divs, maybe it is just a click anywhere closes it so maybe a toggle can be used?
Can anyone clarify I am going in the right direction. I havent used jquery very much or javascript. Any examples of something like this or help would be greatly appreciated.
fb http://img2.pict.com/ed/9a/3a/2341412/0/screenshot2b166.png
You don't need JavaScript for the hover. Make an element that serves as your tooltip and position it above your dropdown button. Then make a parent <div> for both. Your HTML should look something like this:
<div id="container">
<div id="button">...</div>
<div id="tooltip">...</div>
</div>
Once you've done that, you can use CSS to position the tooltip and show it when necessary.
#container {
/* All child elements should be positioned relative to this one. */
position: relative;
}
#container #tooltip {
/* Hide by default. */
display: none;
/* Place the tooltip 2px above the button. */
position: absolute;
bottom: 2px;
right: 0px;
}
#container #button:hover + #tooltip {
/* Show it when someone's hovering over the button. */
display: block;
}
To show the drop-down box, you probably will need JavaScript. Add another element to the container:
<div id="container">
<div id="button">...</div>
<div id="tooltip">...</div>
<ul id="selection">
<li>Something</li>
<li>Something Else</li>
<li>A Third Thing</li>
</ul>
</div>
Position it as you like using position: absolute and hide it using display: none. Then show it when we click on the button:
$('#button').click(function() {
$('#selection').show();
});
You can then make your sub-items do whatever they like, as long as they also hide #selection.
$('#selection li').click(function() {
// do something
$('#selection').hide();
});
Finally, you want to change the background and text colours upon hover. That's easy enough:
#selection li {
background-color: #ccc;
color: black;
}
#selection li:hover {
background-color: black;
color: white;
}
This won't work perfectly in IE 6 or (I believe) 7 - you'll need to investigate alternative solutions for that. Either use JavaScript or check out IE7.js and IE8.js.
Here is the approach I would take:
For hovering check out jQuery's hover event to change the different image states
For the tooltip there are several jQuery plugins such as qTip that you can achieve something like this
For clicking, jQuery's click event will do the trick
The dropdown will be a little trickier. You will need to use a combination of ajax methods and selector methods to change the page (i.e. the bullet)
Finally you will have to do a request of some sort when the page initially loads to find out which setting is selected, then display the selection. This could be done either with php as the page loads, or an ajax request as mentioned above.