I use a 3rd party shopping module for this site and hence i cannot tinker with the sourcecode of this module.
Everthing works fine but here is my issue.
On the checkout option the summary contains field which are redundant and i want to hide this fields.
Discount: GBP £0.00
Sub total: GBP £90.00
Shipping: GBP £10.00
Handling: GBP £0.00
Total: GBP £100.00
As you see above only 3 fields have values. I want to use Javascript and hide the fields which do not have any values like "Discount", "Shipping" and "Handling".
Here is a Fiddle to my code
Here is my code
<div class="CartTotalAmountContainer">
<div class=" TotalSalesOrderDetailDiscountAmount">
<div>
<label> <span>Discount:</span>
</label>
</div> <span>GBP £0.00</span>
</div>
<div class="SubTotalAmount">
<div>
<label> <span>Sub total:</span>
</label>
</div> <span>GBP £90.00</span>
</div>
<div class="TotalShippingAmount">
<div>
<label> <span>Shipping:</span>
</label>
</div> <span>GBP £10.00</span>
</div>
<div class="TotalHandlingAmount">
<div>
<label> <span>Handling:</span>
</label>
</div> <span>GBP £0.00</span>
</div>
<div class="TotalAmount">
<div class="dnnLabel">
<label> <span>Total:</span>
</label>
</div> <span>GBP £100.00</span>
</div>
</div>
No my logic is i can access the topcontainer of the elements by using
var X= document.getElementsByClassName("CartTotalAmountContainer");
but how do i access the data inside the individual spans and make the style="display:none" for their parent divs.
Try .querySelector:
var x = document.querySelectorAll(".CartTotalAmountContainer > div > span");
for(var i=0; i<x.length; i++) {
if(x[i].innerHTML == "GBP £0.00") {
x[i].style.display = "none";
}
}
Demo!
And here's some reading for ya: https://developer.mozilla.org/en-US/docs/Web/API/Document.querySelectorAll
Here is a complete native JS solution which works in IE8 and below: jsFiddle: http://jsfiddle.net/giri_jeedigunta/46QyE/
var outerDiv = document.getElementsByTagName('div'),
cartContainer, i,
j,
cartInnerContent;
// Since getElementsByclassName doesnt work in IE8:
for(i = 0; i < outerDiv.length; i++) {
if(outerDiv[i].className === 'CartTotalAmountContainer') {
cartContainer = outerDiv[i];
cartInnerContent = cartContainer.getElementsByTagName('div');
break;
}
}
// Queryselector have limitations in IE8 and below
for(j = 0; j < cartInnerContent.length; j++) {
if(typeof cartInnerContent[j].getElementsByTagName('span')[1] !== 'undefined') {
var spanContent = cartInnerContent[j].getElementsByTagName('span')[1].innerHTML,
priceSplit = spanContent.split('£')[1].split('.')[0];
console.log(priceSplit);
if(parseInt(priceSplit) === 0) {
cartInnerContent[j].style.display = 'none';
}
}
}
Related
I came up with a very strange (for me) error today when it comes to html checkboxes.
So, I have a table list with a checkbox in the end and a script to read the whole row for each selected checkbox. It is working fine, but I decided to add a "Select All" feature, and here is where things get weird. When I use the Select all, I receive an error and my object is empty.
Here is the code I am using for the select all:
c.transacoes = function() {
$('input[type=checkbox]:checked').each(function() {
var row = $(this).parent().parent();
var rowcells = row.find('td');
var chkdTransac = [];
var obj = (g_form.getValue('u_transactions').length != 0) ? JSON.parse(g_form.getValue('u_transactions')) : [];;
var i;
for (i = 0; i < 5; i++) {
chkdTransac[i] = rowcells[i].innerText;
}
obj.push({
descricao_transacao: chkdTransac[1],
valor_transacao: chkdTransac[2].replace(/-/g, ''),
data: chkdTransac[3],
ref_essence: chkdTransac[4],
narrative: chkdTransac[5]
});
g_form.setValue('u_transactions', JSON.stringify(obj));
c.modalInstance.close();
});
};
toggle = function(source) {
checkboxes = document.getElementsByName('cb1');
for (var i = 0, n = checkboxes.length; i < n; i++) {
checkboxes[i].checked = source.checked;
}
};
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">${Transactions}
<button type="button" class="close" data-dismiss="modal" aria-label="Close" ng-click="c.closeModal()"> <span aria-hidden="true">×</span>
</button></h4>
</div>
<div paging page="1" page-size="10" total="1000">
<table id="table1" class="table table-bordered table-striped">
<thead>
<tr>
<th>${Select}<input type="checkbox" onClick="toggle(this)" /></th>
<th>${description}</th>
<th>${Amount}</th>
<th>${date}</th>
<th>${reference}</th>
<th>${Narrative}</th>
<!--<th>${Select All}<input type="checkbox" onClick="toggle(this)" /></th> -->
</tr>
</thead>
<tbody>
<tr ng-repeat="transac in c.transactions">
<td><input type="checkbox" name="cb1"></td>
<td>{{transac.transaction.description}}</td>
<td>{{transac.transaction.amount}}</td>
<td>{{transac.transaction.date}}</td>
<td>{{transac.transaction.reference}}</td>
<td>{{transac.transaction.narrative}}</td>
</tr>
</tbody>
</table>
</div>
<div class="panel-body">
<div class="col-sm-4"></div>
<div class="col-sm-4" style="align-items:center;">
<div style="margin-bottom: 8px;">
</div>
<div>
<button type="button" class="btn btn-primary btn-block" ng-click="c.transacoes()">${Use selected transactions}</button>
</div>
</div>
<div class="col-sm-4"></div>
</div>
</div>
The idea here is that a table with a list is generated dynamically with a checkbox that I later verify if it is checked and fill a multirow variable set (in ServiceNow) with the information.
If I select manually the boxes, the code works perfectly, but if I use the select all, the following error message is trown:
"TypeError: Cannot read property 'innerText' of undefined"
You guys have any idea why this is happening and how to solve this?
Thanks in advance.
I assume you meant to create multiple checkboxes and add a feature that will select all the checkboxes at once.
If my assumption is correct, you will need to create more checkboxes and modify your function as follows:
function toggle(source) {
// store all the checkboxes that named 'cb1[]' in an array
var checkboxes = document.getElementsByName('cb1[]');;
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i] != source)
// set true to the checked property of the rest of the checkboxes
checkboxes[i].checked = source.checked;
}
}
<input type="checkbox" on onclick="toggle(this);" />Select all!<br />
<input type="checkbox" name='cb1[]' />checkbox 1<br />
<input type="checkbox" name='cb1[]' />checkbox 2<br />
<input type="checkbox" name='cb1[]' />checkbox 3<br />
<input type="checkbox" name='cb1[]' />checkbox 4<br />
Remember to "attach square brackets to the end of the name in order for server-side code to treat checked checkboxes as an array. Otherwise only the last checked item in the group would be available upon submission" (source: dyn-web.com).
Original code is from the following response where querySelectorAll is used instead of getElementsByName: How to implement “select all” check box in HTML?
Ok, so I figured out that where some "trash" before my rows when I used the "select all" checkbox, so I made a small change in the c.transacoes function to ignore those undefined and it is working.
Here is the final function:
c.transacoes = function() {
$('input[type=checkbox]:checked').each(function() {
var row = $(this).parent().parent();
var rowcells = row.find('td');
var chkdTransac = [];
var obj = (g_form.getValue('u_transactions').length != 0) ? JSON.parse(g_form.getValue('u_transactions')) : [];;
var i;
for (i = 0; i < 6; i++) {
if (rowcells[i] == undefined) {
return;
} else {
chkdTransac[i] = rowcells[i].innerText;
}
}
var date = chkdTransac[3].split("T");
obj.push({
descricao_transacao: chkdTransac[1],
valor_transacao: chkdTransac[2].replace(/-/g, ''),
data: date[0],
ref_essence: chkdTransac[4],
narrative: chkdTransac[5]
});
g_form.setValue('u_transactions', JSON.stringify(obj));
c.modalInstance.close();
});
};
sorry i do not speak english well, i want to create a tool that allows to duplicate a div thanks to an "input number" and a button and then I also want to clone this tool by reinitializing it to be able to use the tool again , Here is a piece of code:
$(function() {
$('#btn_dupliquate').on('click', function() {
var numDuplication = $('#num-duplication').val();
if (numDuplication > -1) {
var div = $('.common_preview');
$('.result').html('');
for (var i = 0; i < numDuplication; i++) {
$('.result').append(div.clone());
}
}
});
});
$(function() {
$(".heading").keyup(function() {
var heading=$(this).val();
$(".common_preview").html("<div class='bloc'><p class='model'>"+heading+"</p></div>");
return false;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="toNumDuplicate">
<input type="text" class="heading" />
<br/>
<br/>
<input id="num-duplication" type="number" >
<br/>
<br/>
<button id="btn_dupliquate"> dupliquate </button>
</div>
<div id="toDuplicate">
<div class="common_preview" >
<div class="bloc">
<p class="model">test</p>
</div>
</div>
</div>
<div class="result"></div>
<button id="btn_clone">clone</button>
You could abstract your function to take dynamic selector strings for the duplicate button, duplicate number input, preview div and result div.
(Hope this question hasn't been asked yet : I didn't find it via a keyword search)
I'd like to detect, using jQuery, which element (div, span, anything) contains all the other XKindOfElement.
Meaning, for example, if I have multiple checkboxes in my screen, I want to know which div contains all those checkboxes.
<div id="block1">
<div id="underblock1">
<input type="checkbox" name="thing[]" value="1" />
<div id="underunderblock1">
<input type="checkbox" name="thing[]" value="2" />
</div>
</div>
<div id="underblock2">
<input type="checkbox" name="thing[]" value="3" />
</div>
</div>
In this example, it will return the div#block1 because only it contains all the input[type="checkbox"] of the page.
Hope you'll understand and could help me !
UPDATE
Thinking of something... What do you think about this process :
Check if our element exists in the page
If so, count how many of this element exists and save it (let's say count)
Check if the parent of the first element find contains all the count elements
If not, check if the parent of the parent contains all the count elements,
etc
When the checked parent does contain all the count elements: it is our "smallest global parent" !
Would it be ok or too slow, too "expansive"... ?
I'm not very familiar with all the jQuery helper methods, but this approach might work for you:
Collect all the elements you want to be included
Collect their parents arrays and reverse them: all these arrays now start with: html > body and continue all the way to the actual element
loop through a parent array and check if the other parent arrays have the same element at the current index
the first element that doesn't match marks the index of the last shared parent
Note: you might want to refactor the code a bit to make sure you don't run into any errors for edge cases.
var required = $("input[type=checkbox]");
var getClosestParent = function(elements) {
var maxLength = 0;
var allParents = [];
elements.each(function(i, el) {
var parents = $(el).parents().toArray().reverse();
maxLength = Math.max(maxLength, parents.length);
allParents.push(parents);
});
var ref = allParents[0];
var others = allParents.slice(1);
for (var i = 0; i < maxLength; i += 1) {
for (var j = 0; j < others.length; j += 1) {
if (ref[i] !== others[j][i]) {
return ref[i - 1];
}
}
}
return null;
}
console.log(getClosestParent(required).id);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="block1">
<div id="underblock1">
<input type="checkbox" name="thing[]" value="1" />
<div id="underunderblock1">
<input type="checkbox" name="thing[]" value="2" />
</div>
</div>
<div id="underblock2">
<input type="checkbox" name="thing[]" value="3" />
</div>
</div>
Get an array of arrays for each of the parents, then loop over them until you find a miss-match:-
var parents = new Array();
var minDepth = (Math.pow(2, 53) - 1);
$('[type=checkbox]').each(function(i, e) {
parents.push($(e).parents().get().reverse());
if (minDepth > parents[i].length)
minDepth = parents[i].length;
});
var topParent, testParent;
finished:
for (var i = 0; i < minDepth; i++) {
testParent = parents[0][i];
for (var j = 0; j < parents.length; j++) {
if (parents[j][i] != testParent)
break finished;
}
topParent = parents[0][i];
}
console.log(topParent);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="block1">
<div id="underblock1">
<input type="checkbox" name="thing[]" value="1" />
<div id="underunderblock1">
<input type="checkbox" name="thing[]" value="2" />
</div>
</div>
<div id="underblock2">
<input type="checkbox" name="thing[]" value="3" />
</div>
</div>
Ok so, I'm answering to myself thx to you guys. I thought about #user3297291 said, however I still think starting from the element itself is faster than starting from html > body > etc.
So I make this, what do you think ?
var required = jQuery("input[type=checkbox]");
var getClosestGlobalParent = function(elements) {
var count = elements.length,
result = null;
if(count) {
if(count > 1) {
jQuery(elements[0]).parents().each(function(i, el) {
if(jQuery(this).find(elements).length == count) {
result = jQuery(this); // We also can return "this"
return false; // If the parent is found, we stop the .each loop
}
});
} else {
result = jQuery(elements[0]).parent(); // If there's only one element, his closest parent IS his .parent()
}
}
return result;
}
console.log(getClosestGlobalParent(required).attr('id'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div id="under_container">
<div id="block1">
<div id="underblock1">
<input type="checkbox" name="thing[]" value="1" /> Val1
<div id="underunderblock1">
<input type="checkbox" name="thing[]" value="2" /> Val2
</div>
</div>
<div id="underblock2">
<input type="checkbox" name="thing[]" value="3" /> Val3
<br /><input type="checkbox" name="thing[]" value="4" /> Val4
</div>
</div>
</div>
</div>
$.fn.sharedParents = function(){
if (this.length == 0)
return this;
var parents = $(this.get(0)).parents();
for (var i=0; i<parents.length; i++)
for (var j=1; j<this.length; j++)
if (!$.contains(parents[i], this[j]))
{
delete parents[i];
break;
}
return parents;
}
For given set of elements - get all the parents of the first element. Then for all the other elements check if given parents contain those elements. The result is a list of all parents containing all elements, and, as such, the deepest parent will be the first entry of that list.
https://jsfiddle.net/hwte8n3w/
I have a set of number fields with the class product-quantity. When I add a number to the input field a div class name-number-field should appear after the class name-number-header. When a number is taken away from the field, the last name-number-field should be removed.
when val= 8 and size= 0 8 div's should be added
when val= 8 and size= 3 5 div's should be added
this what I came up with, but I am stuck
$(document).ready(function() {
$('.product-quantity').on('change',function(){
selector = "#product-"+$(this).attr('data-product-id')+
"[data-size-field='"+$(this).attr('data-size') +"']";
if ($(this).val > $(selector).size) {
for (var i = 0; i < (val-size); i++){
$('.size-field').insertAfter($(".name-number-header"));
}
}
if ($(this).val < $(selector).size) {
for (var i = 0; i < (size-val); i++){
$('.size-field :last').remove();
}
}
});
});
http://s24.postimg.org/x4njd7r44/Screen_Shot_2013_12_12_at_6_03_47_PM.jpg
here is a link to a screen shot of the html inspection ^^^^^^^^^^^^^^^^^
html:
<div class="size-column">
<div class="size-field">
<div id="size-label"></div>
<div class="number-input">
<input id="XSmall" class="product-quantity" type="number" name="XSmall" min="0"
max="9999" data-size="XSmall" data-product-id="1"></input>
</div>
</div>
<div class="size-field">
<div id="size-label"></div>
<div class="number-input">
<input id="Small" class="product-quantity" type="number" name="Small" min="0"
max="9999" data-size="Small" data-product-id="1"></input>
</div>
</div>
<div class="size-field">
<div id="size-label"></div>
<div class="number-input">
<input id="Medium" class="product-quantity" type="number" name="Medium" min="0"
max="9999" data-size="Medium" data-product-id="1"></input>
</div>
</div>
....up to 5xl
<div class="name-number-form" data-switch="1" style="display: none;">
<div class="name-number-header"></div>
<div id="number-field-set">
<div class="name-number-field" data-size="XSmall">
</div>
<div class="name-number-field" data-size="Small">
</div>
<div class="name-number-field" data-size="Medium">
</div>
...up to 5xl
Edited code:
$(document).ready(function() {
$('.product-quantity').on('change',function(){
selector = "#product-"+$(this).attr('data-product-id')+
" [data-size-field='"+$(this).attr('data-size') +"']";
var val = $(this).val();
var size = $(selector).size();
if (val > size) {
for (var i = 0; i < (val-size); i++){
$('hi').insertAfter($(".name-number-header"));
}
}
if (val < size) {
for (var i = 0; i < (size-val); i++){
$('.name-number-field :last').remove();
}
}
});
});
I created a fiddle that simulates something like what I am trying to do. What I dont want is the second input to effect the adding and removing of the div in the first column.
http://jsfiddle.net/7PhJZ/19/
$('.size-field').insertAfter($(".name-number-header"));
searches for elements with the class size-field.
If i understood your question correctly you want to create new size-field divs and append them.
If so, try it like that:
$('<div/>',{'class':'size-field'}).insertAfter($(".name-number-header"));
This will create a new div with class size-field and adds it after .name-number-header.
jQuery script which opens selected box in new window one by one for specific time. But it runs all boxes on click button whether i check anything or not I am so Confused.
My jQuery code:
function bon()
{
var field = document.getElementsByName('list');
var len = field.length;
var j=0;
for (i = 0; i < field.length; i++)
{
lk[j] = document.getElementById('addlink_'+i).value;
j++;
}
win = window.open("","myWindow","height=500,width=500,menubar=no,status=no");
process();
var interval = document.getElementById('interval').value;
window.setInterval(function(){ process();}, interval);
}
function process()
{
if(oldval<lk.length)
{
var ln =lk[oldval];
win.location.href =ln;
//$.post("updateclick.php",{dbid:recordid},function(data) { document.getElementById(countid).innerHTML = data; });
oldval =oldval+1;
}
else
{
window.location.href=location.href;
}
}
function process1(a,b)
{
if(document.getElementById('chkbox_'+a).checked==true)
{
}
else
{
thisimg(a,b);
}
}
And my HTML code is:
<div class='posts'>
<input style='float:left; height:85px;' type='checkbox' name='list' value='chck_".$counter."' id='chkbox_".$counter."'/>
<div class='title box' onclick='process1(".$counter.",".$row['id'].")'>
<div style='float:left;' onclick='thisimg(".$counter.",".$row['idDiv1'].")'>
<img src='".$imgpath."' height='50' width='50' />
</div>
<div class='click' style='float:right;'>
<b>Clicks <br/>
<div id='count_".$counter."'> ".$click." </div>
<input type='hidden' id='addlink_".$counter."' value='".$app_link."' rel='nofollow'/></b>
</div>
<div style='float:left; width:100px; overflow:hidden; white-space: pre;'>
<b> ".$title."</b>
<br/>".$beforetime."
</div>
</div>
</div>
This is my button code:
<select id="interval">
<option value="5000"> 5 Seconds</option>
<option value="10000"> 10 Seconds</option>
</select>
<input class="butn" type="button" value="Collect" onclick="bon()" />
Working: the user has to select the check boxes which they want to open in new window one by one for specific time( provided in my option box). But whether i check any one or not it executes one by one all like it selects all check boxes.
Ok here is the actual HTML that prints
<div class=posts>
<input style='float:left; height:85px;' type=checkbox name=list value=chck_0 id=chkbox_0 />
<div class='title box' onclick='process1(0,190757)'>
<div style='float:left;' onclick='thisimg(0,190757)'>
<img src='/images/3c59e768eefb1d5d4a0bfdf0ae23cf5a.png' height=50 width=50 />
</div>
<div class=click style='float:right;'><b>Clicks <br/>
<div id=count_0> 0
</div>
<input type=hidden id=addlink_0 value='/link/zqdba3' rel=nofollow></b>
</div>
<div style='float:left; width:100px; overflow:hidden; white-space: pre;'> <b> Title</b><br/>2 Hs 31 Ms ago
</div>
</div>
</div>
Please help I am very confused.
You are iterating over all of your addlink_ inputs without looking at the checkbox. If the ith checkbox is checked, then push the corresponding input element's value onto the array.
var field = document.getElementsByName('list');
var len = field.length;
lk = [];
for (i = 0; i < len; i++) {
if(field[i].checked) {
lk.push(document.getElementById('addlink_'+i).value);
}
}