jQuery: Comparing strings in if statement not working as expected - javascript

I have this code that isn't working for some reason. I've narrowed down the issue to the variable itself, but I'm not sure why the variable doesn't work...
var style = $('.user-profiles .custom-field-profileboxstyle td:last-of-type').text();
if (style === 'Sandwich') {
$('.user-profiles').append("I am a sandwich.");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="user-profiles">
<table>
<tr class="custom-field-profileboxstyle">
<td>Profile Box Style:</td>
<td>Sandwich</td>
</tr>
</table>
</div>
It seems to work when I set the variable like this:
var style = 'Sandwich';
However, I need to use the jQuery text selector.

Your above code works but the main reason your style comparison in if is not working could be the trailing and leading whitespaces in td so you can use trim() in style so that the whitespaces are removed and compared to string without spaces like below. It is always safe approach to use trim() on string comparison so that you get the desired output as expected.
var style = $('.user-profiles .custom-field-profileboxstyle td:last-of-type').text();
if (style.trim() === 'Sandwich') {
$('.user-profiles').append("I am a sandwich.");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="user-profiles">
<table>
<tr class="custom-field-profileboxstyle">
<td>Profile Box Style:</td>
<td> Sandwich </td>
</tr>
</table>
</div>

It should work. You are probably trying to execute the script when the elements are not loaded. Try to execute it when the document is ready.
https://learn.jquery.com/using-jquery-core/document-ready/
var style = $('.user-profiles .custom-field-profileboxstyle td:last-of-type').text();
console.log(style);
if (style === 'Sandwich') {
$('.user-profiles').append("I am a sandwich.");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="user-profiles">
<table>
<tr class="custom-field-profileboxstyle">
<td>Profile Box Style:</td>
<td>Sandwich</td>
</tr>
</table>
</div>

You must append a TD?? because it works but you are not appending a td but you are appending out of the table try this...
var style = $('.user-profiles .custom-field-profileboxstyle td:last-of-type').text();
if (style === 'Sandwich') {
string = 'I am a sandwich.';
$('.custom-field-profileboxstyle').append("<td>"+string+"</td>");
}

Related

How to remove <br> and everything after that?

If I do the following is fine:
<div id="results">
<p>Hello<br>there</p>
</div>
$($("#results p").children('br').get(0).nextSibling).remove();
I get: hello
But if I do:
<th class="infobox">Head</th>
<td>Hello<br>there</td>
var newLineRemove = $(".infobox td").children('br').get(0).nextSibling();
$wikiDOM.find(newLineRemove).remove();
Gives me
Uncaught TypeError: Cannot read property 'nextSibling' of undefined
That is because .get(...) returns a DOM element not a jQuery object.
In the first example you're using $(...) to convert that DOM element to a jQuery object but you're not doing that in the second example.
This will convert the DOM element to a jQuery element and get rid of the error
var newLineRemove = $($(".infobox td").children('br').get(0).nextSibling);
But it won't do what you want it to do because as #Forty3 said "the <td> isn't inside the ..infobox"
This seems to work but I've probably made things more complicated then they have to be:
$(function(){
var td = $(".infobox").next();
if(td.find("br").length){
$(td.contents().get().reverse()).each(function(){
$(this).remove();
if(this.tagName == "BR"){
return false;
}
});
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<th class="infobox"></th>
<td>Hello<br>there</td>
</table>
I've simplest solution for this, try this one:
$('td').each(function() {
$(this).html($(this).html().split('<br>')[0]);
});
li {
margin-bottom: 10px;
}
#usp-custom-3 {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table>
<tr>
<th class="infobox"></th>
</tr>
<tr>
<td>Hell
<br>there</td>
</tr>
<tr>
<td>Hello
<br>there<br>there</td>
</tr>
</table>
Your code doesn't work because the ".infobox td" selector is looking for a td element inside an .infobox element, but in your HTML the td immediately follows the .infobox.
If you want something that is very similar to your existing JS but working with that HTML (noting that td and th elements need to be inside a tr in a table) you can do this:
$($(".infobox").next().children("br")[0].nextSibling).remove()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table>
<tr>
<th class="infobox"></th>
<td>Hello<br>there</td>
</tr>
</table>
That is, use .next() to get the element following the .infobox, get that element's child br elements, take the first one's .nextSibling, then wrap it in a jQuery object so that you can call .remove().
EDIT: Note that if there were multiple rows with similar elements the above code would only do the removal on the first one. If it were my code I would probably select all of the relevant elements and then update their HTML something more like this:
$(".infobox").next("td").html(function(i, h) { return h.split('<br>')[0] })

Javascript remove specific css value

I am trying to remove the word "Quantity" from below and I think I am close but obviously something is off since it's not working.
<div class="DetailRow" style="display: ;">
<div class="Label">
<label>Quantity</label>
With:
<script type="text/javascript">
$(document).ready(function(){
$('#text_qty_').parent().parent().remove();
$('#qty_').parent().parent().remove();
$('.QuantityInput').remove();
$('label[for="Quantity"]').css('display', 'none').remove();
});
</script>
Try doing it with pure js after adding an id.
<div class="DetailRow" style="display: ;">
<div class="Label">
<label id ="text">Quantity</label>
<script type="text/javascript">
$(document).ready(function(){
document.getElementById("text").innerHTML = "";
});
</script>
Your label needs an id. In this example, I'll use "quantity" as the id.
$('label[id="quantity"]').hide();
This will work but this will apply the style to all labels.
$('label')
Using Pure JavaScript is best though.
Try this $('label').html('');.
$('label[for="Quantity"]') will not retrieve <label>Quantity</label> since it doesn't have the attribute for. Just use $('label') or $('.Label label') and it will work.
Try this if you want to remove the label element itself:
var labels = $('label');
if( labels.text() == 'Quantity' ){
labels.remove();
}
To just remove the word Quantity without removing the label element:
labels.text('');
If you want to remove its parent:
labels.parent().remove();
Also to remove the parent's parent, the <div class="DetailRow"> use this:
labels.parent().parent().remove();
JSFiddle
You can use plain javascript and existing markup with querySelector:
var el = document.querySelector('.DetailRow .Label label');
if (el) {
// do stuff
}
If you want to remove the content, then:
el.textContent = '';
If you want to remove the element, then:
el.parentNode.removeChild(el);
and so on…
I think you can check the label value, and remove the label if the value equals to "Quantity"
Try this:
<div class="DetailRow">
<div class="Label">
<label>Quantity</label>
</div>
</div>
And the script:
$(document).ready(function(){
$(".DetailRow label:contains('Quantity')").hide();
});
http://codepen.io/Himechi90/pen/rOJYjX
Thank you Griffith! This worked perfectly. Full code for anyone trying to remove the quantity and quantity box from only some of your products on bigcommerce. Note that you need to create a separate product template and add this below %%Panel.Header%%
<script type="text/javascript">
$(document).ready(function(){
$('#text_qty_').parent().parent().remove();
$('#qty_').parent().parent().remove();
$('.QuantityInput').remove();
$('label').filter(function() { return $(this).text() === "Quantity"; }).remove();
});
</script>
Note also that your values for #text_qty_ etc may change depending on your template.
Thank you all for taking the time to help me!

Using each() for checking which class is clicked

So here's my problem, I'm new to jQuery. What I am trying to do here is check for user to click on a certain table cell/row and it would then display a div named popup of an index the same as the table cell votes. Without having to make separate functions of all the rows in my table.
Using some numerical value will display all the dialogs from a click of the cell of the same value the first time and from the second time only the correct one.
I bet there's some other way to do it and maybe there's just a stupid error.
Using the index value in the click and dialog function won't work.
I am open to suggestions on improvement also.
The scripts:
<script type='text/javascript'>
$(document).ready( function() {
$('.votes').each(function(index) {
$('.votes:eq(index)').click(function() {
$('.popup:eq(index)').dialog();
});
});
});
</script>
HTML for the table part, only a snippet
<td class='votes'>5</td>
<td class='votes'>15</td>
<td class='votes'>25</td>
HTML for the div part, only a snippet of the div:
<div class='popup'>
<ul>
<li>John Johnsson</li>
<li>John Doe</li>
</ul>
</div>
<div class='popup'>
<ul>
<li>Matt Theman</li>
<li>Peter Watley</li>
</ul>
</div>
jsFiddle Demo
You don't have to iterate using each for .click, that will happen internally. You can use .index() to get the index of the element clicked with reference to its parent.
$('.votes').click(function() {
$('.popup').eq($(this).index()).dialog();
});
Initially, the main problem is that you are not using string concatenation to apply the index to the selector (demo):
$('.votes:eq(index)')
// the Sizzle selector engine doesn't know what the string "index" is.
instead of
$('.votes:eq(' + index + ')')
// using concatenation calls the .toString() method of index to apply "0" (or "1", "2", etc.)
// so that the parsed string becomes '.votes:eq(0)' which the Sizzle selector engine understands
Once the Sizzle selector engine understands which elements to target (demo), the second problem is how jQueryUI changes the DOM with the .dialog method.
Inital markup:
<table>
<tbody>
<tr>
<td class="votes">5</td>
<td class="votes">15</td>
<td class="votes">25</td>
</tr>
</tbody>
</table>
<div class="popup">
<ul>
<li>John Johnsson</li>
<li>John Doe</li>
</ul>
</div>
<div class="popup">
<ul>
<li>Matt Theman</li>
<li>Peter Watley</li>
</ul>
</div>
Once the first click event is handled, one of the div.popup elements is transformed into a jQueryUI Dialog and is appended to the body, removing it from its initial position, like so:
<table>
<tbody>
<tr>
<td class="votes">5</td>
<td class="votes">15</td>
<td class="votes">25</td>
</tr>
</tbody>
</table>
<div class="popup">
<ul>
<li>Matt Theman</li>
<li>Peter Watley</li>
</ul>
</div>
<div class="ui-dialog ui-widget ..."> ... </div>
So your initial indexes no longer apply. Fortunately, there are several solutions to both problems (a few of which I've listed below).
Solutions to Problem 1:
Use string concatenation as described above.
Use the .eq method instead, which will accept the index variable as-is
Use a delegate handler instead and grab the index from within the handler:
Example of 2:
$('.votes').eq(index);
Example of 3:
$('table').on('click', '.votes', function (e) {
var vote = $(this),
index = vote.parent().index(vote);
});
Solutions to Problem 2:
Create all of the dialogs initially and open them as needed.
Create the dialogs using a deep clone of the div element. (Not recommended)
Remove the td element to match the removed and re-appended div element. (Not recommended)
Example of 1:
var popups = [];
$('.popup').each(function (i, elem) {
var popup = $(elem).data('index', i).dialog({
"autoOpen": false
});
popups.push(popup)
});
$('table').on('click', '.votes', function (e) {
var vote = $(this),
index = vote.index();
popups[index].dialog('open');
});
I'm sure there are other solutions as well, but these are the ones I thought of of the top of my head.
Functional demo: http://jsfiddle.net/2ChvX/2/
UPDATE:
With your chosen table structure, you're actually looking for the index of the parent tr element as that is what corresponds with the div.popup element. To get the index of the parent tr element, change the line that gets the index from:
index = vote.index();
to:
index = vote.parent().index();
Updated fiddle: http://jsfiddle.net/AZpUQ/1/
Updated
FWIW, here's an example using the jQueryUI dialog (which I presume you are using?) and javascript sectionRowIndex and cellIndex.
Reusable code allowing you to identify the cell the user clicked in and perform appropriate action.
http://jsfiddle.net/KbgcL/1/
HTML:
<table id="myTable">
<tr>
<th>Label:</th>
<th>Washington</th>
<th>Idaho</th>
<th>California</th>
</tr>
<tr>
<td class='label'>Votes</td>
<td class='votes'>5</td>
<td class='votes'>15</td>
<td class='votes'>25</td>
</tr>
<tr>
<td class='label'>Voters</td>
<td class='voters'>5,000</td>
<td class='voters'>15,000</td>
<td class='voters'>25,000</td>
</tr>
</table>
<div id="msg"></div>
jQuery/javascript:
var myTr;
$('#msg').dialog({
autoOpen:false,
title: 'Report:'
});
$('#myTable tr td').click(function() {
myTr = $(this).closest('td').parent()[0].sectionRowIndex;
myCell = this.cellIndex;
myState = $('#myTable').find('tr:eq(0)').find('th:eq(' +myCell+ ')').html();
myVoters = $('#myTable').find('tr:eq(' +myTr+ ')').find('td:eq(' +myCell+ ')').html();
if (myTr==2 && myCell==3){
//California
$('#msg').html('There are ' +myVoters+ ' voters in ' +myState);
$('#msg').dialog('open');
}else if(myTr==1 && myCell==1){
$('#msg').html('There were ' +myVoters+ ' votes made in ' +myState);
$('#msg').dialog('open');
}
});

Jquery Get last row of table within last element in a series

I have a series of slides based off of sections:
<div id="slides">
<section id="first">
<section>
<table>
<thead>
</thead>
<tbody>
<tr id="somethingUnique">
...
</tr>
</tbody>
</table>
</section>
<section>
<table>
<thead>
</thead>
<tbody>
<tr id="somethingUnique">
...
</tr>
</tbody>
</table>
</section>
...
</section>
</div>
I need to select grab the ID of the last row from the table in the last section of #first section.
I'm using the following Jquery, getting "undefined" back...any ideas?
var lastListItem = $('#first:last-child table>tbody>tr:last').attr("id");
alert(lastListItem);
$('#first table:last tr:last')
or:
$('#first tr:last')
http://jsfiddle.net/hunter/QMzHH/
var lastListItem = $("#first").find("section").last().find("tr").last().attr("id");
I prefer using [0].id instead of .attr("id") since its one less method call; however, if you're not positive that you'll always have a table in that DOM position, attr is safer.
var lastListItem = $('#first section:last table tr:last').attr("id");
.find():
Get the descendants of each element in the current set of matched
elements, filtered by a selector, jQuery object, or element.
​$("#first")​.find("tr:last").attr("id")
or more simply in this case:
$("#first tr:last").attr("id")
EXAMPLE
The other answers work but the problem with your attempt is the fact that
:last-child has to be applied to the child element (section), not the parent (#first). The following should work
$('#first section:last-child table>tbody>tr:last').attr("id");
And could be simplified to
$('#first section:last-child tr:last-child').attr("id");
http://jsfiddle.net/e7mUD/1

Problem with appending HTML and JSTL code in a DIV object using jQuery

What's supposed to happen:
Every time I click an item in a list (single selection), information in that object is displayed on a separate div.
The problem:
I can't get the information to display on the separate div.
Table containing the list and the preview area is supposed to display:
<table id="preview" style="width: 100%;" class="border">
<tr>
<td style="width: 25%;">
<!-- List here -->
</td>
<td style="width: 75%;">
<div id="template_preview" style="overflow:auto">
</div>
</td>
</tr>
</table>
On load, this will be called:
<script type="text/javascript" language="javascript">
$(document).ready(function(){
changePreview();
});
</script>
The changePreview() function:
function changePreview()
{
var selectedValueFromListId = $('#listId').val();
$('#template_preview').html('<c:forEach var="some_var" items="${model.someList}">');
$('#template_preview').append('<input type="hidden" id="someTemplateId" value="${some_var.someListId}" />');
var someTemplateId = $('#someTemplateId').val();
if (selectedValueFromListId == someTemplateId)
{
$('#template_preview').append('test');
$('#template_preview').append('<c:if test="${some_var.objectOne.objectTwo.objectTwoId == valueOfSomething}">');
$('#template_preview').append('some text here - <c:out value="${some_var.label}" />');
$('#template_preview').append('</c:if>');
}
$('#template_preview').append('</c:forEach>');
}
I haven't tested out jQuery's .html() or .append() functions before so I'm not sure if I'm using them right or if what I'm trying to do is possible.
I hope I've explained my problem in enough detail. I've tried researching it in search sites but so far I haven't found a solution.
Thanks in advance.
JavaScript and jQuery gets executed client side, and JSTL gets compiled server side, BEFORE javascript even reach the client and get executed... So you can not expect to print some 'JSTL like' string with jQuery and expect it to work.
The solution for you, is to control the javascript you write to the page with JSTL, and not the contrary:
<script type="text/javascript">
function changePreview() {
var selectedValueFromListId = $('#listId').val();
<c:forEach var="some_var" items="${model.someList}">
$('#template_preview').append('<input type="hidden" id="someTemplateId" value="${some_var.someListId}" />');
var someTemplateId = $('#someTemplateId').val();
if (selectedValueFromListId == someTemplateId) {
$('#template_preview').append('test');
<c:if test="${some_var.objectOne.objectTwo.objectTwoId == valueOfSomething}">
$('#template_preview').append('some text here - ${some_var.label}');
</c:if>
}
</c:forEach>
}
</script>
ps. I'm assuming that everything else is ok, i don't know your model so i can not test it...

Categories

Resources