Consolidate multiple jQuery conditional statements to a single query? - javascript

On my web page, I output jQuery for each record that is rendered on the page like this:
if ($.trim($('#attachment<%# Eval("Id")%> .content').html()) == '') {
$('#attachmentClick<%# Eval("Id")%>').hide();
}
Notice there is server binding on the element ID to make sure each record has the jQuery processed. Is there a way to do this only once on the page by embedding the conditional statement, such as "for all $(this.ID + ' .attachmentsClick'), hide only if $('.attachments.content').html() trimmed is blank"?

You could use jQuery's filter function to reduce the set of potential elements to those with empty content, and then hide them:
$('.attachmentsClick').filter(function(){
return $.trim($(this).find('.content').html()) == '';
}).hide();
This assumes that you give the class of "attachmentsClick" to all of your row elements. It does not need the ID of the row elements. Just run this after your content has loaded, and it will hide all elements with a class of "attachmentsClick" that have a child with a class of "content" which is empty when trimmed.
Your HTML might look something like:
<div class="attachmentsClick"><!-- this one will be hidden -->
<div class="content"></div>
</div>
<div class="attachmentsClick"><!-- this one will be hidden too -->
<div class="content"> </div>
</div>
<div class="attachmentsClick"><!-- this one will NOT be hidden -->
<div class="content"><p>some content<p></div>
</div>

You can use .each(). .someCommonClass should be on each one that has the ID.
$('.someCommonClass').each(function(i, e) {
var $e = $(e);
if ($.trim($('.content', $e).html()) == '')
$e.hide();
});

Related

Using other attribute instead of id in html and javascript

I am making a project of a chat app, I made a code that if the user is not your user it will be in the left side, and if the user is your user it will be on the right side, the code I do works, but there is a single error. The problem is that I do this:
html
<div class="msg right-msg" id="side">
<div class="msg-img" style="background-image: url(https://image.flaticon.com/icons/svg/145/145867.svg)"></div>
<div class="msg-bubble">
<div class="msg-info">
<div class="msg-info-name">{{ chat.user }}</div>
<div class="msg-info-time"></div>
</div>
<div class="msg-text">{{ chat.message }}</div>
</div>
</div>
javascript
$( "#side" ).each(function() {
//console.log( index + ": " + $( this ));
var users = $(".msg-info-name").text()
if (users != me) {
$("#side").removeClass("msg right-msg");
$("#side").addClass("msg left-msg");
};
});
The problem is that there are many of the same html code(That has the same id, class, etc..), So I realized that I can use id in only one, I use id and this was the product Image of the product, it only change the place in the first one, So that doesn´t work.
So I try using class but instead of changing the first one side it change nothing, so class doesn´t works. What can I do?, is another way to loop into all of this, ALSO, the javascript example is using id's. thank for the help
use class not id for multiple elements.
$( ".msg" ).each(function() {
var users = $(this).find(".msg-info-name").text();
if (users != me) {
$(this).removeClass("msg right-msg");
$(this).addClass("msg left-msg");
};
});

getElementsByFieldName ? Get all elements of a radioenum that have a certain field name

I have a radioenum html that looks like
<div class="col-xs-12" type="radioenum" field="arr_c">
// elements
</div>
I'm trying to get the elements it contains, but not sure how to proceed
There's no function called getElementsByFieldName that can be called and class name is not unique so I can't use getElementsByClassName
Use either querySelector if you want to grab the first element on the page that matches the selector or querySelectorAll if you want to grab all of them.
(NB: enum is a reserved word so you can't call your variable names that I just found out)
const radios = document.querySelectorAll('[type="radioenum"');
radios.forEach(radio => console.log(radio.textContent));
<div class="col-xs-12" type="radioenum" field="arr_c">
Test 1
</div>
<div class="col-xs-12" type="not-radioenum" field="arr_c">
Test 2
</div>
<div class="col-xs-12" type="radioenum" field="arr_c">
Test 3
</div>
Edit
One thing I've just noticed is that both type and field are invalid attributes. You can use type on a number of elements but div is not one. So, first you should switch those attributes to data- attributes. You can pick up the data-attribute in the same way and then, in the loop, you can destructure the field attribute out from the current element and check its value.
const radios = document.querySelectorAll('[data-type="radioenum"]');
radios.forEach(radio => {
const { dataset: { field } } = radio;
if (field === 'arr_c') {
console.log('Found arr_c');
} else {
console.log(radio.textContent)
}
});
<div class="col-xs-12" data-type="radioenum" data-field="arr_a">
Test
</div>
<div class="col-xs-12" data-type="not-radioenum" data-field="arr_b">
Test 2
</div>
<div class="col-xs-12" data-type="radioenum" data-field="arr_c">
Test 3
</div>
Use querySelector() instead and you can select the element by its attributes. It will return the first matching Element, just like getElementById().
Example:
document.querySelector("[type=radioenum]");
If you need to capture multiple inputs, you can also use querySelectorAll(), but it will return a NodeList, instead of an Element:
document.querySelectorAll("[type=radioenum]");

How to take the inner text of id and assign it to a specific variable only for a specific inner text

I have different pages which populate a div tag with a specific id based on the id inner text:
here are some different example of pages with this div:
<div id="id_name">text page1</div>
<div id="id_name">text page2</div>
<div id="id_name">text page3</div>
I want to take only the inner text of second and fill a variable.
I try to use something like this:
if($("#id_name").length > 0 && $("#id_name").text() === "text page2") {
site.text = $("#id_name").text();
}
Do not use the same id for multiple elements. See Why is it a bad thing to have multiple HTML elements with the same id attribute?
Use classes instead
You can use :contains()
if ($(".class_name:contains(text page2)").length > 0) {
$('body').text("text page2");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<div class="class_name">text page1</div>
<div class="class_name">text page2</div>
<div class="class_name">text page3</div>
Try this:
$("[id*='id_name']").each(function(){
if ($(this).html() == "text page2"){
site.text($(this).html());
}
});
Try this:
if($("#id_name:eq(1)").length > 0 && $("#id_name:eq(1)").text() === "text page2") {
site.text = $("#id_name:eq(1)").text();
}
Hint use class instead of ID.

Add class to element with dynamically added data attribute

Ok, so I have a HTML file, that looks something like this:
while($stuff = $junk->fetch()){ ?>
<div class="top-div" data-place-id="<?php echo $place['id']; ?>"></div>
<div>
<article>
<div>
//some stuff
</div>
<div>
<span class="expand" data-place-id="<?php echo $place['id']; ?>"></span>
</div>
</article>
</div>
} ?>
As you can see, for each result from a database, a structure like this is being output. Naturally, there are going to be at least a few of these each time.
I wish to make it so, that each time the span is clicked, a class is added to the <div data-place-id=""> where the data-place-id is the same as the clicked elements.
I tried doing it this way:
expandOverlay = function(){
$(".expand").each(function(){
$(".top-div").addClass('is-expanded');
})
})
But, this just adds the class to every single element with this class.
Then I tried this:
expandOverlay = function(){
$(".expand").each('click', function(){
var dataAttr = $(this).data();
if($(".place-overlay").data() == dataAttr){
$(this).addClass("is-expanded);
}
})
});
But that didn't work either.
So, how do I get the .data() from my clicked element and how do I find other elements with the same data attribute, so I can assign it a class?
try this,
$('.expand').click(function(){
dataid = $(this).data('place-id');
$('div[data-place-id="'+dataid+'"]').addClass('is-expanded');
})
First grab the data attribute of clicked item
Mave a div selection where data-place-id is same as span's data-place id ny concatenating the attribute selector.
$('span.expand').click(function() {
$('div[data-place-id="' + $(this).data('place-id') + '"]').addClass('is-expanded');
});
Cristian has it right, but it may not need to be that complex. How about this?
$('span.expand').click(function() {
$(this).closest('div[data-place-id]').addClass('is-expanded');
});
Doesn't much matter what the data-place-id value is, does it?
this works?
$('span.expand').click(function() {
$(this).closest('div.top-div').addClass('is-expanded');
});

get sibling that has id

So I have the following structure:
<div id="some id">
<div>
<input id="some other id" ....>
.....bunch of other inputs with no id field....
<select onclick="findSiblingWithId()">
</div>
<div>
<input id="some other id" ....>
.....bunch of other inputs with no id field....
<select onclick="findSiblingWithId()">
</div>
<div>
<input id="some other id" ....>
.....bunch of other inputs with no id field....
<select onclick="findSiblingWithId()">
</div>
So in my findSiblingWithId i don't know the id I'm looking for, all I know is that for the other components in the same div, only one will have an id. How can I get that ?
Edit:
Since it seems I didnt explain well enough I'll try to add more info. So I want for example when the select component changes (here it could be a button or anything, it doesnt matter) to get the corresponding <input id="some other id" ..> from the same div.
Like I tried to explain above, I have one huge div, the <div id="some id">, now this contains a number of smaller <div> without ids.
Each of these smaller divs will have ONE inputfield with an ID and a bunch of other without an ID. Now on an action, doesn't matter if a button click or whatever, from a component located IN THE SAME div (I thought the correct work would be 'sibling') is there a way I can find the input that has an ID attribute?
Regards,
Bogdan
You could iterate over all children of the parent:
function findSiblingWithId(element) {
var siblings = element.parentNode.children,
sibWithId = null;
for(var i = siblings.length; i--;) {
if(siblings[i].id) {
sibWithId = siblings[i];
break;
}
}
if(sibWithId) [
// found it
}
};
You have to pass the clicked element (I hope you have a proper select field);
<select onclick="findSiblingWithId(this)">
Consider to attach the event handler for the change event, if you want to have it triggered when the user selected a value.
Recursively iterate through the parent div and add logic to separate the inputs that have IDs
function findSiblingWithId(element) {
var sibling = null;
if (element.parentNode != null) {
sibling = element.parentNode.nextSibling;
// Then go through the child elements of your sibling node and get the one with an id
}
}
Using jQuery:
<!--Modify HTML so input is -->
<select onclick="findSiblingWithId(this)">
findSiblingWithId(elem){
return $(elem).siblings("[id]"); //if you need all
//return $(elem).siblings("[id]:eq(0)"); //if you need only first
}
The most direct way to get the value that has this id among the siblings is to use the sibling's filter like this:
let my_id = ...
$(this).siblings(`div[id=${my_id}]`)

Categories

Resources