How To Hide Specific Category from WooCommerce Front-end - javascript

I am using WooCommerce 3.5.7 , and WordPress 5.0.4.
I have a number of products attached to multiple categories:
e.g.
Product 1, attached to categories A,B, C
Product 2, attached to categories A,Y, C
etc...
I want to hide category C from the site so that it is not visible when the categories are displayed in the site category menu navigation on the front-end.
I have tried numerous approaches but none seem to work,
First Approach:
Hiding via CSS.
The structure of the navigation menu is as follows:
<li class="cat-item ">
<span class="icon-toggle"></span>
category-text
</li>
I attempted to hide the element using the below CSS:
a[href="https://siteurl.com/product-category/category-url/"]
{
display: none!important;
}
The problem with this is it removed the hyperlink and text but the category still 'took up space' on the page. This was because this only hides the anchor element and not the entire <li class="cat-item "> that is the parent of that element.
I was unable to find any way to target the parent of a child element in CSS.
Second Approach: Using pre_get_posts:
https://wordpress.stackexchange.com/questions/90923/pre-get-posts-for-exclude-category
$catid = "-1031";
$excludeCategory = function ($catid)
{
return function ($query)
{
if (
$query->is_home()
&& $query->is_main_query()
) {
$query->set('cat', $catid);
}
};
};
add_action('pre_get_posts', $excludeCategory($catid));
In the above example, the category ID I want to hide is '1031'. But this did not work.
Any suggestions, how I can remove this product category so that it does not display in the front end, but is preserved in the backend?

You could try adding onclick="hide()" to the link, then add the following javascript:
function hide() {
document.getElementsByClassName("cat-item ").style.display = "none!important";
}

Related

Hide list item using data attribute when specific text is present on the page with JS

This is trying to hide a checkout payment option from appearing when specific items are in cart (shown on the same page). If the text "BULK" appears in the cart/page to hide a list option based on its data attribute? I've tried learning js and the last 2 hours of watching a course, I understand more but this still seems more advanced than what I can do right now. Would a boolean argument using string.search and insert div.style.display "none"?
Cart example to search for text:
<h4 class="product-title optimizedCheckout-contentPrimary" data-test="cart-item-product-title">BULK Powder 50 lbs.</h4>
Payment option:
<li class="form-checklist-item optimizedCheckout-form-checklist-item" data-test="accordion-item_paypalcommerce">
Once you have a reference to the item (or items - same idea only in a loop) - read the text of the element. Using indexOf sounds reasonable to find a string inside another. And if all is well then just set display:none to the right payment option.
The javascript is basic, but you should also learn some about css selectors should you want to "select" the target elements using a different strategy.
var elem = document.querySelector(".product-title");
var bool = elem.innerText.indexOf('BULK')>=0
if (bool) {
var li = document.querySelector("li[data-test='accordion-item_paypalcommerce']");
li.style.display = 'none'
}
<h4 class="product-title optimizedCheckout-contentPrimary" data-test="cart-item-product-title">BULK Powder 50 lbs.</h4>
Payment options:
<li class="form-checklist-item optimizedCheckout-form-checklist-item" data-test="accordion-item_paypalcommerce">Cash</li>
<li class="form-checklist-item" data-test="accordion-item_paypalcommerce">Credit</li>

Dropdown with key input search of elements

I need your valuable suggestions and guidance to help me get out of this tricky situation.
I have a scenario, where I need to build a Dropdown like the below one.
<ul class="dropdown">
<li>America</li>
<li>Brazil</li>
<li>China</li>
<li>Denmark</li>
<li>Egypt</li>
</ul>
The desired functionality is that I should be able to use keyboard input to scroll through the items, lets say i press key "E" on my keyboard it should hover/focus on Egypt.
I realize this functionality cant be achieved using UL>Li, However we can use Select tag to implement this functionality.
<select class="dropdown">
<option>America</li>
<option>Brazil</li>
<option>China</li>
<option>Denmark</li>
<option>Egypt</li>
<select>
But when we use select tags, we cannot style the dropdown, Especially like CSS padding doesnt work on select tag dropdowns on most broswers.
All I wanna ask Is, How can I build a drop-down with these 3 functionalities :
1.Open on Tab key press
2.Browse listed items using key input.
3.Style the dropdown for cross broswer compatibility.
I did spend ample time in finding a solution for this online, I dint find any perfect solution apart from this plugin
https://silviomoreto.github.io/bootstrap-select/
I'd regret to say that I'm not allowed to use any external plugins at work.To achieve this only tools I'm allowed to use is Bootstrap, jQuery, Javascript ,CSS ,HTML and cant use angular.
Can anyone help me with this.
Unfortunately, it’s not possible to style a <select> dropdown consistently across all browsers. Bootstrap Select and other similar plugins (e.g. Chosen) use JS and custom markup to create a faux <select>, which is bad for accessibility (see https://vimeo.com/84970341#t=614s).
Personally, I would use a <select> element and live with the default browser styling.
You can style the <select> toggle itself, though, without hurting accessibility. Just not the dropdown. Here are some examples:
http://adam.co/lab/jquery/customselect/
http://www.456bereastreet.com/lab/custom-select/
Another option could be to code the countries as a list of links and make it expandable with JS. Just be sure to add the appropriate aria roles.
http://edenspiekermann.github.io/a11y-toggle/
http://heydonworks.com/practical_aria_examples/
1.Open on Tab key press
Open on Tab key press of ul is a very bad solution because Tab key does various functions in the window as well. The dropdown toggle will become buggy as the focus has to be on the window. If you are using an input element like select then that's completely fine.
Still I have created a small mock-up using ONLY javascript as you are not allowed to use any external libraries. Created using ul.
Have a look at this fiddle : JS Fiddle
HTML :
<div>
<ul id="dropdown">
<li class='highlight' data-key='A'>America</li>
<li data-key='B'>Brazil</li>
<li data-key='C'>China</li>
<li data-key='D'>Denmark</li>
<li data-key='E'>Egypt</li>
</ul>
</div>
CSS :
ul {
list-style: none;
display: none;
}
ul li.highlight {
background: yellow;
}
Javascript :
document.addEventListener("keydown", keyDownListener, false);
function keyDownListener(e) {
var keyCode = e.keyCode;
var dropdwn = document.getElementById('dropdown');
if (keyCode == 9) {
dropdwn.style.display = (dropdwn.style.display != 'none' ? 'none' : 'block');
} else if (dropdwn.style.display != 'none') {
var items = dropdwn.getElementsByTagName("li");
items[0].classList.remove("highlight");
for (var i = 0; i < items.length; ++i) {
var aKey = items[i].dataset.key;
if (String.fromCharCode(e.keyCode) === aKey) {
for (var j = 0; j < items.length; ++j) {
items[j].classList.remove("highlight");
}
items[i].classList.add("highlight");
}
}
}
}
Explanation :
Add a keydown event listener on your document.
On press of Tab key show/ hide the dropdown.
On press of any other key, if the dropdown is visible check the data-key of each li and match it with the key pressed. If matches, highlight the respective list item.
And again a reminder, toggle of ul dropdown on Tab key press hurts accessibility. If it is a select dropdown then it's fine.

Use jQuery to copy text from one location, to replace text elsewhere

I've been struggling with this for hours so hope someone can please help.
I have a dropdown menu (.category-navbar) which filters images shown below it. Whichever item is selected in the list is given the class '.select' - what I want is to have a label above that which displays the text of the selected list item.
<div class="dropdown-menu-portfolio">
<label>All</label> // This is the text I want to update
<ul class="category-navbar">
<li class="select">
<a>All</a>
</li>
<li>
<a>Item2</a>
</li>
<li>
<a>Item3</a>
</li>
<li>
<a>Item4</a>
</li>
</ul>
</div>
The label will initially show the text 'All' (as that is the default list item), but I want that to change when one of the other menu items are selected ie. 'Item2', 'Item3' etc.
Below is the code showing what I think I need, I've tried variations of this but nothing has worked - I've put 'copy' and 'replace' to show want I want to happen.
$(".category-navbar li a").click(function() {
$(this)
.copy(".select a").text()
.replace(".dropdown-menu-portfolio label").text();
});
Whilst trying to get anything to work, I found the code below does work, but obviously isn't right as it adds the newly selected item after the label, also it adds the text as a link, whereas I only want plain text.
$(".category-navbar li a").click(function() {
$(this)
.clone(".select a")
.appendTo(".dropdown-menu-portfolio label");
});
Any help would be much appreciated, thanks.
A simple solution would be:
$(".category-navbar li a").click(function() {
// Modifying the label
$('div.dropdown-menu-portfolio label').text($(this).text());
// Removing the class 'select' to the item previously selected
$('li.select').removeClass('select');
// Giving the class 'select' to the item currently selected
$(this).parent().addClass('select');
});
You're overthinking this. Just try
$(".dropdown-menu-portfolio label").text($(this).text());
Your syntax was wrong aside from this better solution.

JQuery - Perform matching based on text inside <A> Tags

I have had a look at;
Jquery Extract URL from Text and
jquery match() variable interpolation - complex regexes
but I'm still a bit lost.
The problem;
I have a page that contains a drop down menu along the top, inside the drop down is the name of an item which I can click on to view that item. The URL of the item is unrelated to the name, it is a unique ID.
Example code of dropdown;
<div class="innerMenuWrapper">
<li class="hasSubMenu sfhover">
Items
<span class="splIcon splIcon-triangle-4-e dropDown">Submenu</span>
<div class="outerMenuWrapper splShadow" style="left: 160px; display: none; ">
<ul>
<div class="innerMenuWrapper">
<li class="">
<a href="/en-US/app/Items/itemahdwhidwbow" tabindex="-1"
class="menuItemLink">item.one</a>
</li>
<li class="">
<a href="/en-US/app/Items/itemfhfaogsgs" tabindex="-1"
class="menuItemLink">item.two</a>
</li></div></ul></div></li></div>
This is all generated externally and managed by the actual web service itself. On the page itself is a table generated from a dataset. I have generated the data with no problem and presentation is fine as-well.
What I want to do is to pull the URL from the HREF above and to wrap the same item in the table on the main page.
E.g. I have a table of 3 columns, Items, Item contents, Item price etc. I want to wrap each Item with its associated URL from the above.
So to take item.one as an example, that is the name it has in the drop down and has the URL, /en-US/app/Items/itemahdwhidwbow. Inside the data itself I have this code to select each first cell of the table and wrap the contents with a link (part of a larger code-set);
if (tr.find("td:nth-child(1)")) {
tr.find("td:nth-child(1)").wrapInner(function() {
var link = $('<a/>');
link.attr('href', 'US/app/Items/itemahdwhidwbow');
link.text($(this));
return link;
});
}
Obviously at the moment the URL is static. What I really need is a way to pull the URL from the associated link in the drop down on the same page. The name in the first table cell will always match the name in the drop down list, is there a simple way for me to do this?
What I have read so far points towards regex use but in this case I am looking for the contents of one part of the code to match something further down the page.
EDIT:
So for example, item.one has the text "item.one". "item.one" is also in the table, I want the "item.one" in the table to have the same link as in the drop down. If I could get to the text inside the anchor then I could just do a match against the text in the table
I'm not clearly understand your table layout structure but i can give you a general idea:
$('a.menuItemLink').each(function(index, linkEl){ //Iterate over dropdown links
var $link=$(linkEl);
tr.find("td:nth-child("+ index +")") //Lets say here we get required cell by index
.wrapInner(
$('<a/>').attr('href', $link.attr('href'))
);
});

Javascript syntax for objects in jquery

I am trying to enhance my page with a jquery right mouse menu, but am having trouble building the correct structures to populate it easily.
Currently my page contains (among other things) a list of items for the user to review. (an html table) Based on the users role, and the current state and context of the row, the user may take one of various actions on each row of data. (approve, reject, refer it to someone else, ect.) My ASP.Net page handles this by setting the visibility of an imagebutton within the row to true, if the option is available. I can control the Cssclass of each button, and am setting the class of for example the "approve" button to “approvebtn”.
Now I want to enhance my site with a right menu.
I am extending my site with Cory S.N. LaViska’s jQuery Context Menu Plugin -
http://abeautifulsite.net/notebook/80
This plugin allows the default right mouse behavior for any elelement to be overridden with a user controlled context menu. The menu is inserted into your page as an unordered list and becomes visible when it is needed.
<ul id="rightMenu" class="contextMenu">
<li class="details">Details </li>
<li class="addnote">AddNote </li>
<li class="listnote">ShowNotes </li>
<li class="approve">Approve </li>
<li class="reject">Reject </li>
<li class="release">Release </li>
<li class="takeover">Takeover </li>
</ul>
Your app gets a callback when something on the right menu is clicked, and you can interrogate the action (the bogus href element) to see which item it was.
I really like this menu because it is simple to use and is completely CSS styled.
However, I need to do something that this plugin does not nativly seem to support. I need to change which items are available on the menu from row to row. Basically if an Imagebutton (for say approve) is avaiable in the row, then its corrisponding menu item should exist as well.
I was able to gain access to the menu just before it is displayed by altering the plugin slightly, to call my function right before the menu is displayed.
This works, but the logic I had to write seems so brute force, that there must be a better way….
In my callback:
function jimsbuggeredfunction(menu,el)
"el" is the element that was right clicked on (usually a table cell), and "menu" is the menu that this right click is bound to. (so I should be using that name and not hardcoding to #rightMenu')
So, the “if” line finds out if the table row containing the element that was “right clicked” contains a specific button (by its class name) if it does the menu item is enabled, otherwise it is disabled. This process continues for every menu item that I want to be flexable row-to-row.
function jimsbuggeredfunction(menu,el) {
if($(el).parents("tr:eq(0)").find('.approvebtn').length > 0)
$('#rightMenu').enableContextMenuItems('#approve');
else
$('#rightMenu').disableContextMenuItems('#approve');
if($(el).parents("tr:eq(0)").find('.rejectbtn').length > 0)
$('#rightMenu').enableContextMenuItems('#reject');
else
$('#rightMenu').disableContextMenuItems('#reject');
if($(el).parents("tr:eq(0)").find('.releasebtn').length > 0)
$('#rightMenu').enableContextMenuItems('#release');
else
$('#rightMenu').disableContextMenuItems('#release');
if($(el).parents("tr:eq(0)").find('.takeoverbtn').length > 0)
$('#rightMenu').enableContextMenuItems('#takeover');
else
$('#rightMenu').disableContextMenuItems('#takeover');
if($(el).parents("tr:eq(0)").find('.revertbtn').length > 0)
$('#rightMenu').enableContextMenuItems('#revert');
else
$('#rightMenu').disableContextMenuItems('#revert');
if($(el).parents("tr:eq(0)").find('.removebtn').length > 0)
$('#rightMenu').enableContextMenuItems('#remove');
else
$('#rightMenu').disableContextMenuItems('#remove');
if($(el).parents("tr:eq(0)").find('.addnotebtn').length > 0)
$('#rightMenu').enableContextMenuItems('#addnote');
else
$('#rightMenu').disableContextMenuItems('#addnote');
if($(el).parents("tr:eq(0)").find('.listnotebtn').length > 0)
$('#rightMenu').enableContextMenuItems('#listnote');
else
$('#rightMenu').disableContextMenuItems('#listnote');
};
There must be a better way to set this up, so that it also just ignores menu items that I want to display all of the time) but it is escaping me at the moment. Is there a better way to accomplish this?
Thanks,
Jim
I would find some way to create a mapping between the two IDs and some more systematic way of finding the relevant button. For example, if the button always belongs inside a certain cell that has a class, let's say "buttonclass", then something like this should work:
var mapping = {
takeoverbtn: '#takeover',
listnotebtn: '#listnote'
// ...
};
function jimsbuggeredfunction(menu,el) {
var buttontype = $(el).parents("tr:eq(0)").find('.buttonclass').children().attr("class");
$('#rightMenu').disableContextMenuItems(mapping[buttontype]);
}
My jQuery is a little rusty, there's probably a cleaner way of retrieving the buttontype, but that general idea ought to work.

Categories

Resources