Check if there is a visible character inside an element - javascript

I am curious whether there is an easy way in jquery (or javascript) to check whether there is a visible character inside a div or td element.
Example:
Let's say I have a table with a header and a row below as filters as follows:
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
....
</tr>
<tr>
<th><input id="FirstNameFilter" /></th>
<th>
<select id="LastNameFilter">
<option value="Smith">Smith</option>
<option value="Doe">Doe</option>
<option value="Nelson">Nelson</option>
</select>
</th>
....
</tr>
</thead>
If the user wants to filter according to first name, he/she types something in the respective field, if he/she wants to filter according to last name, he/she selects from the drop down.
This then activates a javascript function which filters the rows of the table.
Now, is there a convenient way to get all those <th>'s where the user has typed or selected something?
.is(':empty') or checking for the visibility would not work obviously, and the only other option I can think of right now is to somehow check whether there is an element inside the th (because there could also be columns without filter), and if it's an input tag or select tag and then either query .val() or .(':selected').val() respectively.
So the question basically is, whether there's a way to check that with 1 function regardless of the type of element inside the <th> - I'm thinking of maybe there is a way to check if there is a visible character (on the DOM) somewhere inside the <th> (including it's sub elements even)?
Thanks
Edit
I'm basically looking for a selector to select:
th's which have an input element AND the input element is not empty
th's which have a select element AND the some option selected (who's value is not empty by the way)
What I don't want to get is:
th's which are empty
th's which have an input element but it is empty
th's which have a select element but no option selected or the selected option's value is null
Hope that's clearer

Perhaps you mean this?
I am not testing the tag does not have a value (for example a span or such) - that needs more coding
const textAndValues = [...document.querySelectorAll('th')]
.flatMap(th => [...th.childNodes]
.map(node => node.nodeType === 1 ? node.value : node.textContent.trim()).filter(val => val)
);
console.log(textAndValues)
<table>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
</tr>
<tr>
<th><input id="FirstNameFilter" /></th>
<th>
<select id="LastNameFilter">
<option value="Smith">Smith</option>
<option value="Doe">Smith</option>
<option value="Nelson">Smith</option>
</select>
</th>
</tr>
</thead>
</table>

Related

Ternary operator for rows without using state

I have a table with a dynamic number of rows. Within each row I have two cells. When the row is in the initial state, only the first cell is showing. When the row is clicked, both cells will show. I know how to do this with a static element and using state, but I am not sure how best to structure this table.
<tbody>
{invAdd.map(add =>
<tr key={add.itemName} className="bckgr-white border-1b add-items disp-flex" onClick={this.handleAddClick}>
<td className="point-none">{add.itemName}</td>
{if parentNode has class "selected"
?
<td>
<input className="addit-input" type="text" />
<select className="select">
<option value="ABC" />
<option value="DEF" />
</select>
</td>
:
null
}
</tr>
)}
</tbody>
I am not sure how to make this comparison without using state. I tried dynamically generating variables but this did not work either.

Problems with Ajax and Trigger in Jquery

I'm working on a Symfony application in which I have a table and each row in that table have a select to select a value and a button to launch an event with Jquery to save the data in the database.
The click event would be the next:
$(document).on('click',"#contenedor_registro_Ngrupos button",function(event){
// Here some checks are made (with ajax request) and if you can not change the value is added to select a class to indicate the error.
});
If I change the value of a select and click-on button, everything is done correctly. the data is saved or error is shown by the added class.
The problem I have to want to make a change at all and save all automatically. To do this I have created a select that to change, change the value to select all of the table, and also a button that should run all the buttons of the table.
I used "Trigger" to simulate click on all buttons of the table as follows:
$(document).on('click',"#button_all",function(event){
$("contenedor_registro_Ngrupos select[class='modified']").each(function(){
$(this).closest("tr").find("button").trigger("click");
});
});
But the problem I have is when running trigger and simulate the click, only adds the error to the last item to be displayed with the error, but the above will not be added. I tried with alert (); within the function to follow the process and standing execution to display alerts if added the wrong class, so I guess that will be problems implementing the Trigger in each, which does not give time for the simulation function is performed the click button.
I would like to know how I can solve this problem or if there is another way to run the click event of the buttons automatically without having to manually clicking on all buttons.
*HTML:
<div id="contenedor_registro_Ngrupos" class="derecha contenedor_registro">
<div>
<div id="cabecera_lista">
<h2>Educación Infantil</h2>
</div>
<div>
<table class="records_list">
<thead>
<tr>
<th></th>
<th>Curso</th>
<th>Nivel</th>
<th>Nº Grupos</th>
<th></th>
</tr>
</thead>
</table>
<div class="inner_table">
<table>
<tbody>
<tr>
<td>
<span class="oculto">*</span>
</td>
<td>3 años</td>
<td>Infantil</td>
<td>
<select id="Ngrupo">
<option value="1" selected="selected">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</td>
<td>
<button>Guardar</button>
</td>
</tr>
<tr>
<tr>
<td>
<span class="oculto">*</span>
</td>
<td>4 años</td>
<td>Infantil</td>
<td>
<select id="Ngrupo">
<option value="1" selected="selected">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</td>
<td>
<button>Guardar</button>
</td>
</tr>
<tr> //The same above code
<tr> //The same above code
<tr> //The same above code
<tr> //The same above code
</tbody>
</table>
</div>
</div>
</div>
*Images:
When selecting (Where you see a "3" should show a "1" to select that value, but inadvertently change before making image capture.And the three values "1" are in orange, previously had another value, and to change them is added the modified class that color.)
When I click Save All("Guardar Todo" Button)
When I click on save each button ("Guardar" Button)
The problem is not in the functions or selectors, the problem I have on how to call automatically to simulate a click on all buttons with the modified class, which is added previously in other functions.
jQuery.ajax():- Perform an asynchronous HTTP (Ajax) request. Ajax settings are A set of key/value pairs that configure the Ajax request.
Ajax setting option -
async (default: true) :
By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option
to false.
Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active.
In your case you're trying to hit multiple request at time through trigger event. And due to this you are getting proper response from server to handle it.

Reusing single HTML select / drop down list for multiple table rows?

I have an HTML table which is typically 10-30 rows long with a column for "item name". The drop down itself has around 75 products to choose from. To make the page size smaller, I wanted to reuse a single drop down list for every row.
That is, when I click a row, jQuery should
Read the item name in the TD
Load the drop down list into the TD
Select the active value as the previous text value
On row exit, reverse the process
The items in the drop down are populated from a database on page load. I'm thinking the best way is to keep the list hidden and only make it appear in that spot as needed. But I'm not sure how to accomplish step 2 and 3
Edit
Not sure what code you're looking for since that's what my question is. But if I had something like below, I need to put that hidden select list into the active row and make it select to the value already in the table cell.
<table>
<tr>
<td>Item Name</td>
<td>Item Value</td>
</tr>
<tr>
<td>Product A</td>
<td>166.22</td>
</tr>
<tr>
<td>Product B</td>
<td>166.22</td>
</tr>
</table>
<select id="itemname" style="display:none;">
<option value="2231A22">Product A</option>
<option value="2231A21">Product B</option>
<option value="2231A20">Product B</option>
</select>
Edit 2- Probable Solution
Based off one of the responses below, I poked around a bit and was able to create this script which works. Not sure if I can make it more efficient, but it does what I was looking for. The function takes "e" as a TD
function addItem(e) {
if ($(e).find('select').length) {
var input = $(e).find('select').eq(0);
$(e).text($(input).val());
$(input).appendTo($('.promotion-header'));
}
else {
var text = $(e).text();
$(e).text('');
$('#itemname').appendTo(e).val(text).show();
};
}
Try copying all elements of the main div to all other div using by setting and getting html from .html() method. Here in the demo, all elements in myDropDownListDiv is copied to anotherDiv.
HTML :
<div id="myDropDownListDiv"><select id="itemname">
<option value="2231A22">Product A</option>
<option value="2231A21">Product B</option>
<option value="2231A20">Product B</option>
</select>
</div>
<div id="anotherDiv">
</div>
jQuery :
$(document).ready(function(){
//copies all contents of myDropDownListDiv into anotherDiv
$("#anotherDiv").html($("#myDropDownListDiv").html());
});
Demo

AngularJS ng-repeat filter based on select option

I am new to AngularJS. I am trying to filter the data set shown based on the option selected with a select box.
<div ng-controller="CurrentTrandetailsController">
<div>
<div class="pull-right">
<label for="show-filter" class="show-label">Show </label>
<select name="show-filter" ng-model="searchText.accruedcard" id="show-filter" ng-options="trandetail.accruedcard as trandetail.accruedcard for trandetail in currentTrandetails.trandetails ">
<option value="">All</option>
</select>
</div>
<h3>Current trandetails</h3>
</div>
<div>
<table class="table table-striped table-hover">
<tbody>
<tr ng-repeat="trandetail in currentTrandetails.trandetails | filter:searchText">
<td>{{trandetail.dateAccrued}}</td>
<td>{{trandetail.accruedcard}}</td>
<td>{{trandetail.placeAccrued}}</td>
<td>{{trandetail.discountcents}}</td>
<td>{{trandetail.shortExpiryDate}}</td>
</tr>
</tbody>
</table>
</div>
</div>
I used the example given in http://docs.angularjs.org/api/ng.filter:filter, which uses an input box to filter. On selecting a given card, it seems to filter fine. However, when I select "All", which has its value set to "", it doesn't display all the entries (clear the filter). However, in the example shown, when the text box is cleared, all the entries are displayed.
What am I doing wrong?
You'll need to change your select to:
<select name="show-filter" ng-model="searchText" ...
instead of
<select name="show-filter" ng-model="searchText.accruedcard" ...
Explanation: From what I've seen, it's not common to use a hard-coded option along with ng-options and this is contributing to the problem. The filter uses the select's model, which currently is an object instead of a string as in the Angular example. Object patterns are okay but in this case the object's properties become null when All is selected because it is not wired into the select the same way as the rest of the options.
This is what causes the searchText filter to fail because it expects valid strings (even when using an object for the matching pattern).
By using a string primitive for the select's model, the All 'hack' is preserved because it causes the select's model to become ('') instead of null, which will match everything and all the results are shown.
I ran into the same problem. The way that I fixed it was using .toString() in the filter.

Select only drop-down menu that has changed

I have a table that includes a column for the user to select from a drop-down menu to populate the next column. Problem is the table contains the same drop-down menu for each row and on change when I select using the following syntax JQuery selects all drop-downs instead of just the one in that has actually changed. Below solution uses event.stopImmediatePropagation() to act similar to a break point and is the only solution I can think of that will work. Please let me know if there is a more elegant solution out there...
<table>
<tr>
<td>
<select name="selected_client[id]" id="selected_client_id" class="selected_client">
<option value=""></option>
<option value="240">CLIENT ONE</option>
<option value="195">CLIENT TWO</option>
</select>
</td>
</tr>
<tr>
<td>
<select name="selected_client[id]" id="selected_client_id" class="selected_client">
<option value=""></option>
<option value="240">CLIENT ONE</option>
<option value="195">CLIENT TWO</option>
</select>
</td>
</tr>
</table>
$j('.selected_client').change(function(event) {
var client_id = $j(this).val(); // <-- value of the drop down that was currently changed
var tmp_row = $j(this).parent('td').parent('tr');
// perform action
event.stopImmediatePropagation(); // prevents calling other matched rows
return false;
});
First off, id's need to be unique. A class would be better suited for this purpose.
$('.selected_client').change(function(){
$(this).val(); // <-- value of the drop down that was currently changed
});
May be you could differentiate the element IDs for each row, example: the first select element would have an id of "selected_client_id01", the second one "selected_client_id02" and so forth. And then only assign functions to all elements with that one class "selected_client".
using event.stopImmediatePropagation(); proved successfully and simply acts as a break which is useful for the scenario when you are dealing with dynamic entities where selecting by id does not quite solve the problem.

Categories