I'm using the this Jquery code to select multiple rows at once. As you see I tried changing the background color with the code "lastChecked.style.background = "yellow";" but it's not working. How do I do this?
var lastChecked = null;
$(document).ready(function() {
$('.chkbox').click(function(event) {
if(!lastChecked) {
lastChecked = this;
return;
}
if(event.shiftKey) {
var start = $('.chkbox').index(this);
var end = $('.chkbox').index(lastChecked);
for(i=Math.min(start,end);i<=Math.max(start,end);i++) {
$('.chkbox')[i].checked = lastChecked.checked;
lastChecked.style.background = "yellow";
}
}
lastChecked = this;
});
});
Here's all of the code used:
{% extends "base.html" %}
{% block title %}Most Common Calls | CPRS Help{% endblock %}
{% block script %}
<script type="text/javascript">
/*<![CDATA[*/
function highlight_row(row_id,checkbox)
{
var row = document.getElementById(row_id);
row.style.background = checkbox.checked ? "yellow" : "";
}
function unhighlight_row(row_id)
{
var row = document.getElementById(row_id);
row.style.background = "white"; // background yellow
}
/*]]>*/
</script>
{% endblock %}
{% block content %}
<h2>Most Common Calls</h2>
<form action="/mark_as_uninteresting/" method="post">
{% csrf_token %}
<table class="calls">
<tr><th style="width:30px">N</th><th>Word</th><th style="width:150px;"><input class="searchbutton" type="submit" value="Mark as Uninteresting" /></th></tr>
{% for word in word_frequencies %}
<tr id="row_{{ forloop.counter }}"><td>{{ word.n }}</td><td style="padding:0;">{{ word.word }}</td><td style="text-align:center"><input type="checkbox" name="checkbox_{{ word.id }}" onclick="highlight_row('row_{{ forloop.counter }}',this)" id="id_chk{{ forloop.counter }}" class="chkbox" /></td></tr>
{% endfor %}
</table>
</form>
<script type="text/javascript" src="/media/js/jquery-1.5.2.min.js"></script>
<script type="text/javascript">
var lastChecked = null;
$(document).ready(function() {
$('.chkbox').click(function(event) {
if(!lastChecked) {
lastChecked = this;
return;
}
if(event.shiftKey) {
var start = $('.chkbox').index(this);
var end = $('.chkbox').index(lastChecked);
for(i=Math.min(start,end);i<=Math.max(start,end);i++) {
$('.chkbox')[i].checked = lastChecked.checked;
}
}
lastChecked = this;
});
});
</script>
{% endblock %}
UPDATED SOLUTION:
Ok, now that your issue is more clear, here is the correct solution:
If you want the rows to have a background color when selecting using the shift key, you need to change this line:
lastChecked.style.background = "yellow";
to →
$('.chkbox')[i].parentNode.style.backgroundColor='yellow';
OR
$('.chkbox').eq(i).parents('tr').style.backgroundColor='yellow';
Your version tries to set the background color on the checkbox. This is impossible. You need to select the checkbox's parent Node.
The first version in my solution will target the checkbox's immediate parent. This is ok to use in your case if your <tr>'s only go one level deep. If, however, your <tr>'s can go deeper (i.e. a checkbox might be in a <span> which is then inside the <tr>) you should use the second version, which searches the checkbox's ancestors for a <tr> element, then sets its background.
Related
When I click on a list item 'Add' button, I'm using button.onclick to send that item's text to fill out a table on the same html page. However, I keep getting a "Cannot read property 'style' of null" in the console whenever I click an item. This was working fine until recently. Something changed...somewhere, but I can't figure out why it's returning this error suddenly.
Here's the Javascript
function showPage(page) {
document.querySelectorAll('div').forEach(div => {
div.style.display = 'none';
})
document.querySelector(`#${page}`).style.display = 'block';
}
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('button').forEach(button => {
button.onclick = function() {
showPage(this.dataset.page);
}
});
});
function myFunction(txt) {
var myTxt = txt;
console.log(myTxt)
if (txt.includes('QB')) {
document.getElementById("id_QB").value = myTxt;
}
else if (txt.includes('RB')) {
document.getElementById("id_RB1").value = myTxt;
}
else if (txt.includes('WR')) {
document.getElementById("id_WR").value = myTxt;
}
else if (txt.includes('TE')) {
document.getElementById("id_TE").value = myTxt;
}
else if (txt.includes('K')) {
document.getElementById("id_K").value = myTxt;
}
}
</script>
Here's the html page which is displaying a django template (I've deleted the on-page script tags containing the Javascript above).
{% load static %}
{% block body %}
<form method="POST">
{% csrf_token %}
<table id="playerName">
{{ form.as_table }}
</table>
<input type="submit" value="Submit" >
</form>
<br>
{% for player_data in player_data %}
<li><p>Player ID: {{ player_data.player_id }}: {{ player_data.player_name }}, {{ player_data.team }}, {{ player_data.position }}</p></li> <button onclick="myFunction('{{ player_data.player_name }} {{ player_data.position }}')">Add</button>
{% endfor %}
{% endblock %} ```
This is my views.py
def list_note(request):
note_info = Note.objects.filter(id_teacher__exact=request.user.id).select_related()
actual_date = date.today()
for notes in note_info:
note_date = notes.remind.date()
tmp = actual_date + timedelta(days=3)
note_expired_list = []
if tmp == note_date:
print()
else:
note_expired_list.append(notes)
print(note_expired_list)
note_data = {
"note_details": note_info,
"note_expired_list_details": note_expired_list,
}
return render_to_response('list_note.html', note_data, context_instance=RequestContext(request))
I want use value note_expired_list_details in <scrpit> tag to display this in alert. How do this?
I try use {{ note_expired_list_details}} but in <script> tag not work.
This is a part of my templates (I try finding HTML element by Id in JS)
{% extends "base.html" %}
{% load staticfiles %}
{% block content %}
<div >
{% for details in note_expired_list_details %}
<p>{{ details }}</p>
{% endfor %}
<script>
var x = document.getElementsByTagName("p");
alert("Test\n" + x[1].childNodes.nodeValue + "\n");
</script>
</div>
{% endblock %}
Why not store value of {{ note_expired_list_details }} in a JS variable and then use it however you want?
<script>
var expiredList = '{{ note_expired_list_details }}';
alert(expiredList);
</script>
I've been given a script by my e-commerce provider that will allow me to dynamically change the stock levels based on the product option selected by the user from a simple select element.
While the code seems strait forward, it will not run properly. As I am fairly new to jQuery, I'm assuming this is due to me not properly initializing the script within my html. The code itself is a default code that my e-commerce provider hands out, but does not support it in any way.
Here is the script
<script>
// <![CDATA[
var selectCallback = function(variant, selector) {
if (variant) {
if (variant.available) {
// Selected a valid variant that is available.
$('#add-to-cart').removeClass('disabled').removeAttr('disabled').val('Add to Cart').fadeTo(200,1);
} else {
// Variant is sold out.
$('#add-to-cart').val('Sold Out').addClass('disabled').attr('disabled', 'disabled').fadeTo(200,0.5);
}
// Whether the variant is in stock or not, we can update the price and compare at price.
if ( variant.compare_at_price > variant.price ) {
$('#product_price').html('<span class="product-price on-sale">'+ Shopify.formatMoney(variant.price, "") +'</span>'+' <s class="product-compare-price">'+Shopify.formatMoney(variant.compare_at_price, "")+ '</s>');
} else {
$('#product_price').html('<span class="product-price">'+ Shopify.formatMoney(variant.price, "") + '</span>' );
}
} else {
// variant doesn't exist.
$('#add-to-cart').val('Unavailable').addClass('disabled').attr('disabled', 'disabled').fadeTo(200,0.5);
}
}
// initialize multi selector for product
jQuery(function($) {
new Shopify.OptionSelectors("product-select", { product: , onVariantSelected: selectCallback });
});
// ]]>
</script>
Any ideas on why this might not be working? You can see this script live on my site:
http://www.yandasmusic.com/products/fender-american-standard-stratocaster?variant=1178632565
EDIT:
Upon further inspection, I have found a second piece of code that also calls up the product option selection box. I can tell that this code also serves the function of changing the currently shown product image based on the current option selected:
<script>
var selectCallback = function(variant, selector) {
if (variant && variant.available) {
jQuery('#add-to-cart').removeAttr('disabled').removeClass('disabled'); // remove unavailable class from add-to-cart button, and re-enable button
if(variant.price < variant.compare_at_price){
jQuery('#product_price .price').html('<span class="money">' + Shopify.formatMoney(variant.price, "{{ shop.money_format }}") + '</span><span class="money compare-at-price">' + Shopify.formatMoney(variant.compare_at_price, "{{ shop.money_format }}") + '</span>');
} else {
jQuery('#product_price .price').html('<span class="money">' + Shopify.formatMoney(variant.price, "{{ shop.money_format }}") + '</span>');
}
} else {
jQuery('#add-to-cart').addClass('disabled').attr('disabled', 'disabled'); // set add-to-cart button to unavailable class and disable button
var message = variant ? "Sold Out" : "Unavailable";
jQuery('#product_price .price').text(message);
}
// if (variant && variant.featured_image) {
// var originalImage = $(".zoomWrapper img");
// var newImage = variant.featured_image;
// var element = originalImage[0];
// Shopify.Image.switchImage(newImage, element, function (newImageSizedSrc, newImage, element) {
// $(element).parents('a').attr('href', newImageSizedSrc);
// $(element).attr('src', newImageSizedSrc);
// });
// };
if (variant && variant.featured_image) {
var originalImage = $("#elevatezoom_big");
var newImage = variant.featured_image;
var element = originalImage[0];
Shopify.Image.switchImage(newImage, element, function (newImageSizedSrc, newImage, element) {
$(element).attr('src', newImageSizedSrc);
$("#elevatezoom_gallery a").each(function(){
if ( $(this).attr('data-zoom-image') == newImageSizedSrc ) {
$(this).trigger('click')
};
});
});
};
};
jQuery(document).ready(function($){
new Shopify.OptionSelectors("product-select", { product: {{ product | json }}, onVariantSelected: selectCallback, enableHistoryState: true });
// Add label if only one product option and it isn't 'Title'.
{% if product.options.size == 1 and product.options.first != 'Title' %}
$('.selector-wrapper:eq(0)').prepend('<label>{{ product.options.first }}</label>');
{% endif %}
// Auto-select first available variant on page load.
{% assign found_one_in_stock = false %}
{% for variant in product.variants %}
{% if variant.available and found_one_in_stock == false %}
{% assign found_one_in_stock = true %}
{% for option in product.options %}
$('.single-option-selector:eq({{ forloop.index0 }})').val({{ variant.options[forloop.index0] | json }}).trigger('change');
{% endfor %}
{% endif %}
{% endfor %}
});
</script>
If I run both scripts, the page shows two select boxes for the product options. Is it possible to combine them?
You have a JavaScript error on your page because of this line of code:
new Shopify.OptionSelectors("product-select", { product: , onVariantSelected: selectCallback });
According to this reference document: https://docs.shopify.com/manual/configuration/store-customization/advanced-navigation/linked-product-options, that line of code should actually look like this:
new Shopify.OptionSelectors("product-select", { product: {{ product | json }}, onVariantSelected: selectCallback });
We're looking for a solution to hide the add to cart button if a product is already in cart. So that the user can not order more than 1 of each product.
A Mentor from Codementor wrote a function which hides the Add to Cart button if a selected variant is in the cart:
var updateCartButtons = function () {
if (typeof (window.cartItems) === "undefined") {
window.cartItems = [];
}
var cartItemVariantID, selectedVariantID, selectedVariantName;
selectedVariantName = $('.swatch :radio:checked').val();
selectedVariantID = $('#product-select option').filter(function () {
return $(this).text() === selectedVariantName;
}).val();
$('.buymarginsecond').removeClass('addedToCart');
for (var i = 0, l = cartItems.length; i < l; i++) {
cartItemVariantID = cartItems[i].variant_id;
if (cartItemVariantID == selectedVariantID) {
$('.buymarginsecond').addClass('addedToCart');
break;
}
}
};
We'd like to change this function to the effect that the
button disappears as soon as the main product is in the cart.
So you can only order one of each product and not different variants of the product.
You can use this code in your product.liquid file where add to cart is button is show. It will loop through the titles in the cart and if found set the variable to yes. Then check if variable is no, not in cart and show add to cart.
{% assign in_cart = 'no' %}
{% for item in cart.items %}
{% if item.product.title == product.title %}
{% assign in_cart = 'yes' %}
{% endif %}
{% endfor %}
{% if in_cart == 'no' %}
// SHow Add to Cart
{% endif %}
I want to set up two div entries on a page that are refreshed from a database at different rates.
I'd like to have one div display random entries from the database every second, and below that, every 10 seconds a random entry is selected and has 500 points added to its score.
I can do the second (lottery_Winner):
<div id="lottery_Winner" class = "tableCenter">
{% for entry in lottery_winner %}
<li class = "lot"> <a> {{"WINNER"}}</a> </li>
<li class = "lot"> <span id="entry-text">{{ entry.text }}</span> <span id="score">{{ entry.score }}</span></li>
<script>
$(document).ready(function() {
var currentid = {{entry.id}};
var args = {'lotteryid':currentid};
$.get("/lotteryWinner/", args).done(function(data) {
$("#score").text(data);
});
});
</script>
{% endfor %}
</div>
<script>
setTimeout(function() {
$.ajax({
url: "",
context: document.getElementById("lottery_Winner"),
success: function(data){
$("#lottery_Winner").html(data);
}
});
}, 5000);
</script>
but when I do the first (lottery_Cycle), I get unexpected results - they both refresh the same time (undesired), there is a "ghost" element for one or both of the divs, and the lottery_cycle div entry can get the 500 points, the Winner and Cycle have the same entries and the page refresh cascades until it hangs periodically.
Here's the code I tried:
<div id="lottery_Cycle" class = "tableCenter">
{% for entry in lottery_winner %}
<li class = "lot"> <a> {{"LOTTERY"}}</a> </li>
<li><a href="/entries/{{ entry.id }}/"> <div class = "lot" style = "text-align: left";>{{ entry.text }}
<div style="float: right">{{ entry.score }}</div></a></li>
{% endfor %}
</div>
<div id="lottery_Winner" class = "tableCenter">
{% for entry in lottery_winner %}
<li class = "lot"> <a> {{"*** LOTTERY WINNER ***"}}</a> </li>
<li class = "lot"> <span id="entry-text">{{ entry.text }}</span> <span id="score">{{ entry.score }}</span></li>
<script>
$(document).ready(function() {
var currentid = {{entry.id}};
var args = {'lotteryid':currentid};
$.get("/lotteryWinner/", args).done(function(data) {
$("#score").text(data);
});
});
</script>
{% endfor %}
</div>
<script>
setTimeout(function() {
$.ajax({
url: "",
context: document.getElementById("lottery_Winner"),
success: function(data){
$("#lottery_Winner").html(data);
}
});
}, 5000);
setTimeout(function() {
$.ajax({
url: "",
context: document.getElementById("lottery_Cycle"),
success: function(data){
$("#lottery_Cycle").html(data);
}
});
}, 1000);
</script>
and here is relevant part of views.py;
def lottery(request):
context = {
'lottery_cycle': Entry.objects.random(),
'lottery_winner': Entry.objects.random(),
}
return render(request, 'entries/lottery.html', context);
def lotteryCycle(request):
c = Entry.objects.random()[0]
return HttpResponse("%s,%s,%s" % (c.id, c.text, c.score))
def lotteryWinner(request):
lottery_id = request.GET.get('lotteryid')
if request.method=='GET':
l = Entry.objects.get(pk=lottery_id)
l.score +=500
l.save()
return HttpResponse(l.score)
else:
pass
return HttpResponse('done')
(I tried setInterval as well as setTimeout, same result) Is there any advice on getting the two div refreshes working properly on different timings?