i need hide an element when an especific text is showing - javascript

I want to hide the check-out button when the text "No shipping options found for" is visible. I'm selecting by query all to get some elements, after this I select the button and I apply the style display none, but it is still showing. I don't know what i'm doing wrong.
function hidenv() {
var txt = document.querySelectorAll(".shipping td")[0].innerText;
if (txt >= "No shipping options found for") {
document.querySelectorAll(".proceed-to-checkout").forEach((element) => element.style.display = "none");
}
}
<tr class="shipping">
<th>Shipment</th>
<td data-title="Shipment">
No shipping options found for <strong>xxxx, xxx, 0000</strong>.
</td>
</tr>
<div class="proceed-to-checkout">
<a href="https://nextstep.nxt/" class="checkout-button">
Proceed payment</a>
</div>

It is because no event is defined to execute function . Here hidenv() at bottom works as automatic execution on load .
Also add the word you want to match in separate container so that it can be easily retrieved and matched properly .
function hidenv() {
var txt = document.querySelectorAll(".notFound")[0].innerText;
if (txt == "No shipping options found for") {
document.querySelector(".proceed-to-checkout").style.display = "none";
}
}
hidenv();
<tr class="shipping">
<th>Shipment</th>
<td data-title="Shipment">
<span class="notFound">No shipping options found for</span><strong> xxxx, xxx, 0000</strong>.
</td>
</tr>
<div class="proceed-to-checkout">
<a href="https://nextstep.nxt/" class="checkout-button">
Proceed payment</a>
</div>

#Rana have been share a good answer but the text showing don't have any html tag. So i did this.
First select the text inside another and and later aply the display none
function hidenv() {
var txt = document.querySelector(".shipping").querySelectorAll("td")[0].innerText;
if (txt === "No shipping options found for") {
document.querySelector(".proceed-to-checkout").style.display = "none";
}
}
hidenv();
<tr class="shipping">
<th>Shipment</th>
<td data-title="Shipment">
No shipping options found for <strong>xxxx, xxx, 0000</strong>.
</td>
</tr>
<div class="proceed-to-checkout">
<a href="https://nextstep.nxt/" class="checkout-button">
Proceed payment</a>
</div>

I think depending on text inside an element is not a god idea! but if you really want to do it, this is the way!
It's better to have div inside and make it show and hide. Hiding a is not the best idea.
let theShipmentElement = $("td[data-title='Shipment']");
if(theShipmentElement.html().indexOf('No shipping options found for') > -1){
theShipmentElement.hide();
}

Related

How to Write a Function that Lists Products in a Table Side-by-Side

I have a script that allows users on my e-commerce site to select 3 products and it highlights the products as they select.
How can I grab the $pro_image, title, desc, etc. of the 3 products selected and put them into a table for side-by-side view?
I am assuming we will somehow need to check for the $pro_id that is selected to identify each product separately?
<div class="col-md-10">
<h4>Not sure which product to choose? <br> Select up to 3 and compare side-by-side.</h4>
<div class="col-md-2">
<button type="compare" class="btn btn-success" name="submit-compare">Compare</button>
</div>
<div class="col-md-12">
<?php getpcatpro();
$get_products = "SELECT * FROM products ORDER BY RAND() LIMIT 0,9";
$run_products = mysqli_query($con,$get_products);
while($row_products=mysqli_fetch_array($run_products)){
$pro_id = $row_products['product_id'];
$pro_title = $row_products['product_title'];
$pro_img1 = $row_products['product_img1'];
$pro_link = $row_products['product_link'];
echo "
<div class='col-md-4 col-sm-6'>
<div class='product' onclick='highlight(this)'>
<center>
<img class='img-responsive' src='admin_area/product_images/$pro_img1'>
</center>
<div class='text'>
<center>
<a href='$pro_link'> $pro_title </a>
</center>
</div>
</div>
</div> ";
}
?>
<script>
var selected_items = 0;
function highlight(target) {
if(target.style.border == ""){
if(selected_items < 3){
target.style.border = "1px solid red";
selected_items += 1;
}
} else{
target.style.border = "";
selected_items -= 1;
}
}
</script>
</div>
</div>
Firstly, there's no button type called 'compare', please stick to standards, you shouldn't put random things into these attributes, you can create your own if need be (which I do not think you need to). See here for the three types you are allowed: https://www.w3schools.com/tags/att_button_type.asp (you should just use 'button')
Second, do not add styles through JS, you will cause an entire repaint every time you change a pixel. Instead, toggle class names on the class attribute of an element, let CSS do the work of styling, and JS do the work of interaction.
Thirdly, move all 'PHP' to the top of your script (such as defining your SQL statement and fetching the result of it) rather than having these things interspersed within HTML (just use PHP later in the document to build HTML from the PHP variables at the top of the script), such as looping through your result set to build out the HTML, not to perform important tasks such fetching the data itself, this will help you track whats doing what where so you don't tie yourself up in IF statements etc.
OK, Create a function, bound to your compare button, that toggles the state of an element. Instead of 'highlighting' using styles, toggle a class 'compare' on the product parent container:
<style>
.product.compare{
border: 1px solid red;
}
</style>
<script>
$('.btn.compare').click(function(){
$(this).closest('.product').toggleClass('compare');
});
</script>
<div class='products'>
<div class='product' data-id='1'>
<h2>A Product</h2>
<button class='btn compare'>compare</button>
</div>
<div class='product' data-id='2'>
<h2>Another Product</h2>
<button class='btn compare'>compare</button>
</div>
</div>
This will basically, when the button is clicked, find the parent element with class '.product' then toggle the class '.compare' on it, so you should have .product.compare
You'll need to design your table to have fixed rows with class names, like so:
<table class='comparison'>
<thead>
<tr class='product-title'></tr>
</thead>
<tbody>
<tr class='product-price'></tr>
</tbody>
</table>
Once you have products with a toggled state (a class has been added which both highlights the row with CSS visibly, but also flags it for comparison to jQuery, create a new button and method for it to call to build the comparison table
<button class='btn goCompare'>Go Compare</button>
$(function(){
$(".btn.goCompare").on('click', function(e){
e.preventDefault();
buildComparisonTable();
});
});
function buildComparisonTable(){
var comparisonTableBody = $('table.comparison tbody');
var comparisonTableBodyProductTitleCol = $('table.comparison thead tr.product-title');
var comparisonTableBodyProductPriceCol = $('table.comparison tbody tr.product-price');
comparisonTableBody.find('.product-col').remove();
$('.product.compare').each(function(){
var id = $(this).attr('data-id');
var title = $(this).attr('data-title');
var price = $(this).attr('data-price');
comparisonTableBodyProductTitleCol.append('<th class="product-col">'+title+'</th>');
comparisonTableBodyProductPriceCol.append('<td class="product-col">'+price+'</td>');
});
}
The choice is yours, but think about how you can cleverly and correctly mark up your pages to be easily read by your scripts. You can either stuff all of the product data into attributes on a parent element:
<div class='product' data-id='1' data-title='A Product' data-price='$10.00' data-primary-category='Homeware'>
<h2>A Product</h2>
<button class='btn compare'>compare</button>
</div>
Or you can add a class to each element that has the data you intend to gleam:
<div class='product' data-id='1'>
<h2 class='product-title'>A Product</h2>
<span class='product-price'>$10.00</span>
<span class='product-category'>Homeware</span>
<img class='product-img' src='/images/product-1.jpg' />
</div>
Now you can target what you want easily and get information from it using proper class names, a considered layout, correct use of technologies and a simple approach. This code-pen illustrates: https://codepen.io/anon/pen/voBKgV

Add bin number for accessory product onto the packing slip - Bigcommerce

I have exhausted all the resources I could think of, between their community forum and their support staff, I can't get a hint.
The Scenario: A person chooses a product to buy. When they click 'add to cart', they are presented with a list of options, containing other products that they can choose from to bundle with the original product. The product they choose becomes sort of like an accessory to the main product.
When I go to print the packing slip, all the information for the main product is visible, but only a small description for the attached product can be seen. In this example I bought a Bottle, and added a Journal as my accessory:
The attached product, just like the main product, IS an actual product that you can buy separately on its own, but in this case, it is added on as an accessory. In the image you can see the quantity, SKU, and bin# for the main product, but there isn't a bin for the accessory product.
The following snippet displays the product information onto the packing slip. (this is the original snippet)
<tr>
<td class="ProductBinNumber">%%GLOBAL_ProductBinNumber%%</td>
<td class="ProductSku">%%GLOBAL_ProductSku%%</td>
<td class="ProductDetails">
%%GLOBAL_ProductName%%
<div class="ProductAttributes" style="%%GLOBAL_HideAttributes%%">
%%GLOBAL_ProductAttributes%%
</div>
<div class="ProductVariationOptions" style="%%GLOBAL_HideVariationOptions%%">
%%GLOBAL_ProductOptions%%
</div>
<div class="ProductConfigurableFields" style="%%GLOBAL_HideConfigurableFields%%">
%%GLOBAL_ProductConfigurableFields%%
</div>
<div class="ProductGiftWrapping" style="%%GLOBAL_HideGiftWrapping%%">
%%GLOBAL_ProductGiftWrapping%%
</div>
<div class="ProductEventDate" style="%%GLOBAL_HideEventDate%%">
%%GLOBAL_ProductEventDate%%
</div>
</td>
<td class="ProductQuantity">%%GLOBAL_ProductQuantity%%</td>
</tr>
I have tried adding different store-wide variables to different positions within this table, but no matter what I do, the information that gets returned is the information for the main product - my only goal here is to get the bin# for the accessory product to display on this sheet.
I should mention that I did the same thing with product thumbnails, displaying them only for certain products, but the only way I figured out how to do it, was searching through text to find matches, and appending hardcoded image url's to a div within the rows that had the matching text....not ideal especially when your dealing with a lot of products - here is my revised HTML, followed by the JS that adds the logo to the appropriate product (definitely iteration one of test code):
<span id="prod-tab-results">%%GLOBAL_ProductsTable%%</span>
<!--using JS to grab the text from this variable-->
<tr>
<td class="ProductBinNumber" style="width: 25px;">%%GLOBAL_ProductBinNumber%%
</td>
<td class="ProductBinNumber2">
<img id="logo-src-img-tag" src="" style="width: 55px; border: 1px solid black;"/>
<!--This is where the JS will append the img path to src-->
</td>
<td class="ProductSku">%%GLOBAL_ProductSku%%</td>
<td class="ProductDetails">
%%GLOBAL_ProductName%%
<div class="ProductAttributes" style="%%GLOBAL_HideAttributes%%">
%%GLOBAL_ProductAttributes%%
</div>
<div class="ProductVariationOptions" style="%%GLOBAL_HideVariationOptions%%">
%%GLOBAL_ProductOptions%%
</div>
<div class="ProductConfigurableFields" style="%%GLOBAL_HideConfigurableFields%%">
%%GLOBAL_ProductConfigurableFields%%
</div>
<div class="ProductGiftWrapping" style="%%GLOBAL_HideGiftWrapping%%">
%%GLOBAL_ProductGiftWrapping%%
</div>
<div class="ProductEventDate" style="%%GLOBAL_HideEventDate%%">
%%GLOBAL_ProductEventDate%%
</div>
</td>
<td class="ProductQuantity">
%%GLOBAL_ProductQuantity%%
</td>
</tr>
And the JS simplified for your understanding:
var itemsInThisOrder = $.trim($('span#prod-tab-results').text());
var logoSrcArray = ["http://PATH1",
"http://PATH2",
"http://PATH3",
"http://PATH4",
"http://PATH5"];
var logoTextArray = ["[Sample]ProductText1",
"[Sample]ProductText2",
"[Sample]ProductText3",
"[Sample]ProductText4",
"[Sample]ProductText5"];
if ( itemsInThisOrder.indexOf("[Sample]") >= 0 ) {
console.log("there is an accesory product that needs a logo and bin#");
for (var i=0; i < 10; i++) {
var theProductText = $.trim($('.ProductSku').eq(i).text());
for (var z=0; z < logoTextArray.length; z++) {
if ( theProductText === logoTextArray[z] ) {
$('.ProductBinNumber2').eq(i-1).children('img').attr("src", logoSrcArray[i]);
}
}
}
}
I'm thinking that there MUST be a way to accomplish this (bin #'s, not pictures) using Bigcommerce's variables, but I have exhausted my resources within their forum and support. As you can see, this might be okay for a 5 product demo, but it's pretty much one of the worst ways I can think of to go about doing this, unfortunately, it's the only way I can think of.
I appreciate any time and help, thank you.

How can I change table navbar with CSS in an extension?

I am currently developing a Chrome extension for my university and I have done most of the things I want to do but I am having difficulty with one thing is that whenever I try to select the first <table> tag which is the navbar in this link I can't seem to hide it and then add my custom navbar using CSS.
Here is my code (I have included random createtextnode that I want to add to give a sense for what I want do or I am trying to do):
CSS
table:nth-child(1)
{
display:none;
}
JavaScript
var note = document.getElementsByName('stud_login')[0];
var par = document.createElement("div");
var tag = document.createElement("a");
var t1 = document.createTextNode(" Hello! Please try to refresh page again if the verification is not filled properly.");
var t2 = document.createTextNode("Click here");
var t3 = document.createTextNode(" Any suggestions? ");
var br = document.createElement("br");
par.setAttribute("class", "info-msg");
par.appendChild(t1);
tag.setAttribute("href", "http://goo.gl/forms/QI8gPMfKML");
tag.setAttribute("target", "_blank");
tag.setAttribute("id", "rahultag");
par.appendChild(t3);
tag.appendChild(t2);
par.appendChild(tag);
note.parentElement.appendChild(par);
Here is the HTML code i want to target and is the first table that occurs:
<table width="100%" height="15%" border="0" align="center" cellpadding="0" cellspacing="0" background="images/banner_bg3.jpg">
<tr>
<td width="25%" align=left>
<img src="images/vit_logo6.jpg" height="76" width="297">
</td>
<td align=center>
<br>
<font size=5 color=#FFFFFF face="Comic Sans MS">
<b>V-TOP</b><br>Student Login
</font>
</td>
</tr>
</table>
To target the first table, then this would likely give you the desired result
var note = document.getElementsByTagName('table')[0];
If the table is not the first element in its parent, you need to use insertBefore instead of appendChild
note.parentElement.insertBefore(par, note);
Side note:
If the table:nth-child(1) { display: none; } won't work, you could use replaceChild to replace the table with your new element
note.parentElement.replaceChild(par, note);
or simply remove it
note.parentElement.removeChild(note);
Note though, that if you are to remove it, do that after you inserted the new, or else there will be no reference where to insert the new.
If you still need to remove before add, read more here how to get the element to be removed's next sibling: https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore

JQuery: Replacing <br /> with a delimiter when grabbing .text()

I'm trying to grab some text from an HTML element that is formed like this:
<td>
<br>
48 main Ave
<br>
Virginia, VA 23000
<br>
(800) 789-7898
</td>
The problem is keeping the format, or some sort of separation between the lines (it can be any sort of delimiter, but something to show the break). I can't simply use .text():
$('td').text()
// 48 main AveVirginia, VA 23000(800) 789-7898
Nor can I use .html() because there is actually a bunch of other junk in the .
Is there any other creative way I may be able to either keep the line break in OR place some sort of delimiter where the tag is?
Thanks!
EDIT: First off, you guys are awesome! Thanks for taking the time to respond, all of you.
I think using replace is the way to go. But I find once I've done that, I'm not able to grab the text any more. Here is my full code:
detailsArray = [];
$("tr[id*=Row]").each(function(index){
type = $(this).attr("type");
id = $(this).attr("idtag");
if (id){
$("div[detail*="+id+"] tr td").each(function(index){
var content = $(this).html();
content = content.replace(/<br>/g,'|');
$(this).replaceWith(content);
detailsArray
.push(type+', '+ $(this)
.text()
);
})
}
});
The problem is, the $(this).text() doesn't capture the change. So I tried breaking it out into two different portions, like so:
detailsArray = [];
$("tr[id*=Row]").each(function(index){
type = $(this).attr("type");
id = $(this).attr("idtag");
if (id){
//First we change it around
$("div[detail*="+id+"] tr td").each(function(index){
var content = $(this).html();
content = content.replace(/<br>/g,'|');
$(this).replaceWith(content);
}
//Then we grab it
$("div[detail*="+id+"] tr td").each(function(index){
detailsArray
.push(type+', '+ $(this)
.text()
);
})
}
});
I see the change happen on the page, but now the grab portion comes up empty. detailsArray = [].
So how can I use this? Thanks!
EDIT** Thought a better look at the html would help:
<div detail="27fdgd68_4_B_">
<table border="0" cellpadding="10" cellspacing="0" width="100%" class="size2">
<tbody>
<tr bgcolor="#FFF5CC">
<td>
<b>
<a target="_blank" href="" onclick="script()">Big Properties</a>
</b>
<a target="_blank" href="http://www.bigproperties.com"></a>
<br>
48 main Ave
<br>
Virginia, VA 23000
<br>
(800) 789-7898
</td>
</tr>
</tbody>
</table>
</div>
Again, the goal is to get the following text (assuming a '|' delimiter):
48 main Ave|Virginia, VA 23000|(800) 789-7898
Use replace()
Example of using it:
var content = $('myElement').html();
content = content.replace(/<br>/g,',');
To update html code use jQuery function replaceWith()
$(".yourDivClass").replaceWith(content);
var content = $("div").html();
content = content.replace(/<br>/g,',');
$("div").replaceWith(content);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<br/>
4884 Travertine Ave
<br/>
Virginia Beach, VA 23462
<br/>
(757) 605-5234
</div>
I think the separation is there but you cannot see it in the browser, otherwise this alert here would not show on separate lines.
alert($('td').text())
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table><tr>
<td>
<br>
4884 Travertine Ave
<br>
Virginia Beach, VA 23462
<br>
(757) 605-5234
</td>
</tr>
</table>
You could do $('td').html.replace(/\<br>/g, '|')) to replace all the <br> tags with a pipe symbol (or any other delimiter you like).
Depending on how you plan to use the grabbed data, there can be more elegant solutions.

How to handle ASP.NET forms where javascript plugin is generating alternative input?

I have a ASP.NET MVC webpage that submits a form with ajax like this :
function ValidateFormAndAjaxSubmit(formId, callingElement) {
if (IsNotDblClick(callingElement.id)) {
var _form = $("#" + formId);
var validator = _form.validate();
var anyError = false;
anyError = !_form.valid();
if (anyError) {
window.latestClick = '';
return false; // exit if any error found
}
$.post(_form.attr("action"), _form.serialize(), function (data) {
if (data.success && data.redirectUrl.length > 0) {
window.location.href = data.redirectUrl;
}
else {
var isValid = validateResponse(_form, data);
window.latestClick = '';
}
})
}
}
All control in the form is generated with helpers like Html.TextBoxFor and so on and this works great.
The problem is that a jquery plugin(Select2) will turn a regular textbox into a list like this :
<div class="floatLeft">
<label class="controlTitleContainer" for="Url">Taggar</label>
<br style="clear:both;">
<div class="select2-container select2-container-multi bigdrop" id="s2id_txtTagBox" style="width: 408px"> <ul class="select2-choices" style=""> <li class="select2-search-choice"> <div>Film </div> </li><li class="select2-search-choice"> <div>Hund </div> </li><li class="select2-search-field"> <input type="text" autocomplete="off" class="select2-input valid" tabindex="0" style="width: 10px;"> </li></ul></div><input style="width: 408px; display: none;" class="bigdrop" id="txtTagBox" name="Tags" type="text" value="">
</div>
You can here see that the textbox is set to display none while the added tags is shown like a ul list. In this case I have added Film and Hund to the list.
I need these values to be sent to the service(with the above ajax call), the question is how?
From what I can tell from the documentation, select2 is designed work with select lists, not textboxes. Try generating a select list instead of a textbox.
Look at the source for "Multi Valued Select Boxes" in the examples, the underlying markup is a select box, but the plugin generates a div to make it look like a textbox.

Categories

Resources