Trouble in looping - javascript

I came to an error in my loop code, so basically my code should also find the table in Results 1, 2, 3, 4 so on.. I need it to be like, whenever i press the add button it triggers to add another table rows. I also need a code that will trigger the find button and show a result span in my code whenever I click the add button, it will duplicate new set of code for my find button.
Here is the screenshot.
And here is my code for the find button that will appear whenever i click find.
if (e.target.dataset.op === 'finding') {
$(document).ready(function () {
$('.button1').click(function () {
const input = $('#randomizer').val()
const closest = findClosest(input)
// const html = `Inches of Mercury Row: ${closest.inches}, Value: ${closest.value}`
const html = `TEST INCHES OF MERCURY TO ROW ${closest.inches} ${closest.value} L/MIN`
$('#results1').html(html)
})
})
And here is my html for that.
<tbody>
<tr>
<td>
<label></label>
<input id="randomizer" type="text6" value="0" class="randomColor" />
<label> L/MIN # </label>
<button data-op="del" title="delete row"> ✖ </button>
<button data-op="finding" class="button1">FIND</button>
</td>
</tr>
</tbody>
</table>
<!-- <p id="piduk" style="display:none;">Result: <span id="results"></span></p> -->
<p id="piduk" style="display:none; "><span id="results" class="spanColor" style="background-color:red; font-weight: bold;"></span></p>
<p id="piduk1" style="display:none;">Result: <span id="results1"></span></p>
</div>
Here is my fiddle for the whole code.
Fiddle Link here

Related

Functions crashes after first successful iteration (element is not attached to the page document)

Would like to ask what is wrong with the functions bellow, the first iteration works without any problem but, after the grid is refreshed, when protractor tries to move to the next cell, it gives me this error message:
Failed: stale element reference: element is not attached to the page document
The idea of this is to read the 5th column (or 4th if you consider stating from 0), check each row that contains the value "true", if contains true then do the operation of editing the row, clicking in a checkbox and saving (everything is performed at the line)
Each element has a unique ID related to status code so that why I am "not using rows" in the function (only to get the text from the line and then pass as string to complete the ID of the element)
**Every time that the value is changed and saved, the table gets a refresh
function resetGoodItemStatus(siteToResetValues){
var cellsConform = element.all(by.css('#datatableDir tr td:nth-of-type(5)'));
var conformCounter = 0;
selectValueDropDown(siteToResetValues)
cellsConform.each((eachCell) => {
eachCell.getText().then((cellText) => {
switch (cellText)
{
case 'true':
element(by.id(conformCounter+'-1')).getText().then(function(value){
element(by.id('btnEdit-US.'+value)).click();
element(by.xpath("//*[#editable-checkbox=\"scopeValue.getConformMapping(scopeValue.getDataRow("+'\'US.'+value+"\')).conform\"]/../span/span/input")).click();
element(by.id('btnSubmit-US.'+value)).click();
})
default:
browser.sleep(100)
}
conformCounter += 1
});
});
}
HTML before editing the line:
<tr role="row" class="odd">
<td id="0-0" class="ng-scope">
<form editable-form="" name="scopeValue.rowforms['US.DAM']" onaftersave="scopeValue.saveData('US.DAM',0)" ng-show="scopeValue.rowforms['US.DAM'].$visible" class="form-buttons form-inline ng-pristine ng-valid ng-hide" style="">
<button type="button" class="btn btn-xs btn-trans kni kni-check-circle text-info" id="btnSubmit-US.DAM" ng-disabled="scopeValue.rowforms['US.DAM'].$waiting" ng-click="scopeValue.rowforms['US.DAM'].$submit()">
</button>
<button type="button" class="btn btn-link kni kni-x-circle-slim" ng-disabled="scopeValue.rowforms['US.DAM'].$waiting" id="btnCancel-US.DAM" ng-click="scopeValue.cancelData('US.DAM',0)">
</button>
</form>
<div class="buttons" ng-show="!scopeValue.rowforms['US.DAM'].$visible">
<button type="button" class="btn btn-xs btn-trans kni kni-edit-circle text-info" ng-click="scopeValue.rowforms['US.DAM'].$show()" id="btnEdit-US.DAM">
</button>
</div></td>
<td id="0-1" class="ng-scope sorting_1">DAM</td>
<td id="0-2" class="ng-scope">US.DAM</td>
<td id="0-3" class="ng-scope">Generic Damaged Code</td>
<td id="0-4" class="ng-scope">
<span editable-checkbox="scopeValue.getConformMapping(scopeValue.getDataRow('US.DAM')).conform" e-name="conform" e-form="scopeValue.rowforms['US.DAM']" e-required="" class="ng-scope ng-binding editable">false</span>
</td></tr>
HTML after clicking at the Edit button:
<td id="0-4" class="ng-scope">
<span editable-checkbox="scopeValue.getConformMapping(scopeValue.getDataRow('US.DAM')).conform" e-name="conform" e-form="scopeValue.rowforms['US.DAM']" e-required="" class="ng-scope ng-binding editable editable-hide">false</span>
<span class="editable-wrap editable-checkbox ng-scope">
<span class="editable-controls"><input type="checkbox" name="conform" required="required" class="editable-input ng-pristine ng-empty ng-invalid ng-invalid-required ng-touched" ng-model="$data" style="">
<div class="editable-error ng-binding ng-hide" ng-show="$error" ng-bind="$error" style=""></div>
</span>
</span>
</td>
Thank you for your time!
One simple way is to get text of all cells in the 5th column into text array, then iterate the text array, the array index is equivalent to the table row index.
Once cell text is equal true, use row index to find the table row. The rest elements can be found within the table row.
Because in each iteration, below code will find all table rows from page again, should not happen Stale Exception
function resetGoodItemStatus(siteToResetValues){
var cellsConform = element.all(by.css('#datatableDir tr td:nth-of-type(5)'));
selectValueDropDown(siteToResetValues);
cellsConform.getText().then(function(conforms) {
// conforms is a string Array, each one is the text of one cell of 5th column
conforms.forEach(function(conform, rowIndex) {
if(conform === 'true') {
var row = element.all(by.css('#datatableDir tr').get(rowIndex);
row.element(by.css('button[id^="btnEdit-US"]')).click();
row.element(by.css('input[type="checkbox"]')).click();
row.element(by.css('button[id^="btnSubmit-US"]')).click();
browser.sleep(3000)
}
});
});
}

GTM - Table - Click on a button, and get the text of another selector

I am not a developer but I am trying to get hand in hand with Google Tag Manager.
I am working for some people that they want to track a button click on a search result.
So, you'd get the 10 products, with the name, description and a Sample button.
I can track the button on GTM (that's the easy bit), but I need to assign the button click to each product name.
This is the bit of HTML that I want to work on:
<tr>
<td>
<p class="category">
Product
</p>
<a href="/sector/product/123456789"><img class="search_image" src="https://example.com/medium/123456789.jpg" alt="Name of the Product" onerror="this.src='system/images/company_logo_block.jpg'" />
</a>
</td>
<td>
<h3>Name of the product</h3>
<p>Benefits of the product explained</p>
<p>Material <b>Plastic</b></p>
<div class="button_container">
<div class="action_container">
<div class="action_trigger">
<input type="hidden" id="code_123456789" name="code" value="123456789" />
<label class="visible" for="quantity_123456789">Quantity</label><br />
<input class="search_result_quantity numeric_only" id="quantity_123456789" name="quantity" type="number" value="1"
onkeydown="return isValidInput(this, 5, event);"/>
<label for="add_to_basket_123456789">Add to basket</label>
<input class="add_sample search_result_action" id="add_to_basket_123456789" name="add_to_basket" type="submit" value="Add to basket" />
</div>
<div class="action_response">
<img src="/sector/system/images/loading.gif" alt="Loading" />
</div>
<div class="action_result">
<img src="/sector/system/images/tick.jpg" alt="Success" /><span>Added.</span>View basket
</div>
<label for="get_sample">Get a Sample</label><input class="add_sample search_result_action" name="Sample_product" type="button" value="Sample Product" onclick="window.location='http://www.samplepage.com/123456789';"/>
<div class="clearer"></div>
</div>
</div>
<br/>
<p123456789</p>
<p>
Online
| 24/09/2015
</p>
<p><strong>Price: £26.99 +VAT</strong></p>
</td>
</tr>
So, when a user clicks on the button "Sample Product", I would like to grab the name of the product, which sits on the top <tr> with the tag h3.
For each product, there is a <tr> where all the information sits
On the console, I can get the "nodes" with document.querySelectorAll ("tr td h3)[0] - or [1] or [2] according to the name of the product I want.
I now can't get a function that, onClick a Button, will return me the <h3> text of that <tr> selector. Is this even possible?
Thanks so much for your help.
George
Ok. After long hours of trial and error, I came up with a solution that works.
I'll leave it here in case it might help someone.
function() {
var els = document.querySelectorAll('[value="Sample Product"]');
for (var i = 0; i < els.length; i += 1) {
if (els[i] === {{Click Element}}) {
var elsname = document.querySelectorAll('tr td h3')[i].innerText
return elsname; }
}
return elsname;
}

On Button Click, how do I change row with span to input and focus each input using angularjs

I have a table, with 2 labels/inputs (i use a ng-show/ng-hide which works with the edit button), and 2 buttons (1 button is edit, and 1 button is delete). What i want to do is when the user clicks the edit button, it should hide the spans and shows the inputs(textboxes) and focus on the first input. If the user clicks outside of either inputs, (in my opinion, loses focus which mean using blur method), then the inputs should turn back to span with the updated values. Here is what I have created, but I can't figure out the rest. New to angular so any help will be appreciated and voted.
This is the html code:
<table class="tableGV">
<tbody>
<tr>
<td class="DisplayRowData">
<span class="LabelText" data-ng-hide="data1">{{data1}}</span>
<input class="DataText" type="text"data-ng-show="showEditMode" maxLength="1" data-ng-model="editData1" ng-change="cs.ClassCode"/>
</td>
<td class="DisplayRowData">
<span class="LabelText" data-ng-hide="data2">{{data2}}</span>
<input class="DataText" type="text" data-ng-show="data2" maxlength="50" data-ng-model="data2" />
</td>
<td align="right">
<button type="button" id = "btnEditClassService{{$index}}" data-ng-click="edit(cs, $index)" class="editButton"></button>
<button type="button" id = "btnDeleteClassService{{$index}}" data-ng-click="delete(cs, $index)" class="deleteButton"></button>
</tr>
</tbody>
</table>
after this, i am not sure where to go. Thanks for anyone to help me.
you can check this plnkr. The solution is not elegant but I think it sastify your requirement.
function onEdit(){
vm.isEdit = true;
executeAfterDOMRender(function(){
document.getElementById('txt1').focus()
});
}
function onBlur(){
executeAfterDOMRender(function(){
var txtIds = ['txt1', 'txt2'];
var activeElementId = document.activeElement.id;
if(~txtIds.indexOf(activeElementId)){
//txt boxes is focued, do nothing here
} else {
vm.isEdit = false;
}
});
}
function executeAfterDOMRender(callback){
$timeout(callback);
}

What jQuery function would access the next Table and the next Input[type=submit] button in this markup?

I have a page with where mp3 products are being sold. Each page represents an album entity.
At a minimum each page contains an album product and at least one or more mp3’s available for purchase as a separate products.
Each album and mp3 product has it’s on form with an input[type=submit] button that functions as an ‘add to cart’ button.
Some mp3’s have been designated as album only. This is done w/ markup via a span tag.
<span class=“album-only-tag”>True</span>
Based on that markup, I’m trying to write some javascript that will do 3 things:
• remove the table containing the price
• disable the submit button, so user’s cannot add to cart (they instead have to purchase the album).
•change the value of the input[type=“submit”] to read as ‘album only’.
Also, after code runs as per mp3 it needs to stop, and leave the other price table & ’add to cart’ buttons intact.
My jQuery code here is not working. My use of the next() function is incorrect i guess.
What jQuery function should i use to access the next table and the next form input[type=“submit”] button in this markup?
btw - the markup here has been abbreviated.
<div class="views-row views-row-1 views-row-odd views-row-first">
<div class="ds- 1col node node--ltv-track-ii node-teaser node-product-type node--ltv-track-ii node-product-type-teaser node-ltv-track-ii-teaser view-mode-teaser node--teaser node--ltv-track-ii--teaser clearfix">
<span class="album-only-tag">True</span>
<table class="commerce-price-rrp-your-price">
<tr class="odd">
<td class="webprice-title">Price</td>
<td class="webprice-total">$5.95</td> </tr>
</table>
<div class="field field-name-field-product">
<form class="commerce-add-to-cart commerce-cart-add-to-cart-form-1909 commerce-cart-add-to-cart-form-1909" action="/ltvalbums/wah/lokaha" method="post" id="commerce-cart-add-to-cart-form-1909" accept-charset="UTF-8">
<div><input type="hidden" name="product_id" value="1909" />
<input type="hidden" name="form_build_id" value="form-qbskkxq4JIW0IEzmvAgwqow7QylhhgdtnfmqbHrdMe0" />
<input type="hidden" name="form_id" value="commerce_cart_add_to_cart_form_1909" />
<div id="edit-line-item-fields--2" class="form-wrapper"></div> <input type="submit" id="edit-submit--2" name="op" value="Add to cart" class="form-submit" />
</div>
</form>
</div>
Huge thanks for any help on this!
Here is you go,
$('.album-only-tag').each(function () {
var table = $(this).next('table');
var submitBtn = table.next('div').find('input[type="submit"]');
// disable the add to cart button
submitBtn.prop('disabled', true);
// change the text to "Album only"
submitBtn.val("album only");
// remove the table
table.remove();
});

How to get next input element id by using class in jquery?

I have to get next textbox id on change event of the first textbox using jquery.
How can i get that. I have used next() for that but its not working as i wanted.
Here is my code,
<table>
<tbody>
<tr>
<td>
<p>PF Value</p><br>
</td>
<td>
<span id="ctl00_ctl00_bcr_bcr_TextBox1" class="txtfill" style="display: inline-block;">
<input name="ctl00$ctl00$bcr$bcr$TextBox1$textbox1" class="txtSec80CCD" value="0" id="ctl00_ctl00_bcr_bcr_TextBox1_textbox1" onblur="calcDedSecCCD(this)" style="width: 70px;" type="text">
<span id="ctl00_ctl00_bcr_bcr_TextBox1_valCustom" style="color: Red; display: none;">*</span>
<div id="ctl00_ctl00_bcr_bcr_TextBox1_ErrorDiv" class="ValidatorErrorDiv" style="display:none">
<span id="ctl00_ctl00_bcr_bcr_TextBox1_Label1">You must enter a <br>number</span>
</div>
</span>
</td>
<td>
<span id="ctl00_ctl00_bcr_bcr_TextBox2" class="txtfill" style="display: inline-block;">
<input name="ctl00$ctl00$bcr$bcr$TextBox2$textbox1" class="txtSec80CCD" value="0" id="ctl00_ctl00_bcr_bcr_TextBox2_textbox1" style="width: 70px;" type="text">
<span id="ctl00_ctl00_bcr_bcr_TextBox2_valCustom" style="color: Red; display: none;">*</span>
<div id="ctl00_ctl00_bcr_bcr_TextBox2_ErrorDiv" class="ValidatorErrorDiv" style="display:none">
<span id="ctl00_ctl00_bcr_bcr_TextBox2_Label1">You must enter a <br>number</span>
</div>
</span>
</td>
</tr>
<tr>
<td>
<p>Life Insurance Premium</p><br>
</td>
<td>
<span id="ctl00_ctl00_bcr_bcr_TextBox3" class="txtfill" style="display: inline-block;">
<input name="ctl00$ctl00$bcr$bcr$TextBox3$textbox1" class="txtSec80CCD" value="0" id="ctl00_ctl00_bcr_bcr_TextBox3_textbox1" onblur="calcDedSecCCD(this)" style="width: 70px;" type="text">
<span id="ctl00_ctl00_bcr_bcr_TextBox3_valCustom" style="color: Red; display: none;">*</span>
<div id="ctl00_ctl00_bcr_bcr_TextBox3_ErrorDiv" class="ValidatorErrorDiv" style="display:none">
<span id="ctl00_ctl00_bcr_bcr_TextBox3_Label1">You must enter a <br>number</span>
</div>
</span>
</td>
<td>
<span id="ctl00_ctl00_bcr_bcr_TextBox4" class="txtfill" style="display: inline-block;">
<input name="ctl00$ctl00$bcr$bcr$TextBox4$textbox1" class="txtSec80CCD" value="0" id="ctl00_ctl00_bcr_bcr_TextBox4_textbox1" style="width: 70px;" type="text">
<span id="ctl00_ctl00_bcr_bcr_TextBox4_valCustom" style="color: Red; display: none;">*</span>
<div id="ctl00_ctl00_bcr_bcr_TextBox4_ErrorDiv" class="ValidatorErrorDiv" style="display:none">
<span id="ctl00_ctl00_bcr_bcr_TextBox4_Label1">You must enter a <br>number</span>
</div>
</span>
</td>
</tr>
......
......
......
</tbody>
</table>
I have written my script like this,
function calcDedSecCCD(id) {
var eid = $(id).attr('id');
//var elementVal = $('#' + eid).val();
//var nxtEid = $(eid).next(':input .txtSec80CCD').attr('id');
var nextele = $(this + ':input .txtSec80CCD').next();
//alert(nextele);
var nextId = $(nextele).attr('id');
alert("First Element: "+eid);
alert("First Element: " + nextId);
}
I want textbox id : ctl00$ctl00$bcr$bcr$TextBox2$textbox1 on change event of textbox1.
How can i get the id of text input using class.
Or any other way to get id of next textbox on change of first one.
You've written your markup so that it is too hard to read. In time you will you come to appreciate short ID's, names etc. as there is no need to use 40 characters in every selector, it just makes it hard to write javascript and css, and even harder to read and understand the code later.
You've also managed to create an elaborate system of nested elements that are almost certainly unnecessary, and hard to traverse with javascript, keeping it more simple is usually a good idea.
First of, you should probably not pass "id" as a variable to your function, as "id" actually does something in javascript (it gets the elements id, see below script).
If it's only within each "td" you are looking for the next input element, the below will work, but it will not work for the last input in a "td" to find the next input that is within the next "tr" etc.
function calcDedSecCCD(elm) {
var eid = elm.id;
var nextId = $(elm).parents('td').next().find('input')[0].id;
alert("First Element: "+eid);
alert("Next Element: "+nextId);
}
Here's a FIDDLE
You might use the jquery index function
var $spans = $("td>span.txtfill");
// Your next function
function get_next_span(elem){
var $span = $(elem).closest('td>span.txtfill'),
index = $spans.index($span);
return $spans.eq(index+1);
}
So if you had a text field you would use the helper function like this:
var $current = $("#ctl00_ctl00_bcr_bcr_TextBox2_textbox1"),
$next = get_next_span($current).find('input[type=text]');
Or in a change event:
$("input[type=text]").change(function(){
get_next_span(this).find('input[type=text]').show();
});

Categories