invocing two jquery statements in one function - javascript

the function user_delete should
loop over options of a select box and get the class name if the value matches the provides argument
store them in variable
then loop over the document
and delete all elements with that particular class
exception if a span has that class element
only delete the value of that element
the query statements work separately
inserting them into on function seems not to have an effect
function user_delete(filename) {
$("#select_updateFile option").each(function(i){
if ($(this).val() === filename ) {
var class_name = $(this).attr('class');
}
document.querySelectorAll(class_name).forEach(function (e) {
if ($(e).prev().is("span")) {
$(e).empty();
} else {
e.remove();
}
}
);
});
}

You can grab the value of the option without looping through by using a selector.
Then if that value exists, find the class. Then for spans, set the innerHTML to empty.
Then you can find the non spans with the same class and remove them from the dom altogether.
The CSS is just there to make it obvious the span is empty but still exists.
function user_delete(filename) {
opt = document.querySelector("#select_updateFile option[value='" + filename + "']")
if(opt){
_class = opt.getAttribute("class")
spans = document.querySelectorAll("span." + _class)
spans.forEach(function(span){
span.innerHTML = "";
})
nonspans = document.querySelectorAll("." + _class + ":not(span)")
nonspans.forEach(function(el){
el.remove();
})
}
}
user_delete("aa")
span.test{display:block;background:red;height:40px;width:140px;}
<span class="test">EMPTY ME</span>
<div class="test">DELETE ME</div>
<select id="select_updateFile">
<option class="test" value="aa">33</option>
<option class="testa" value="bb">22</option>
</select>

Related

Append and remove div with select input in jQuery

I'm trying to add and remove a div depending on the value of a select menu. This code works well a first: when the value of the select is 2 div appears. When I return to the first value (1), the div disappears. However if I select the value 2 again, the div is not add again. Any idea ?
<select id="interv_base_youorthird" name="interv_base[youorthird]" class="form-control">
<option value="1">Pour moi</option>
<option value="2">Pour un tiers</option>
</select>
<input type="hidden" id="extra-counter" value="0">
$("#interv_base_youorthird").change(function(){
if( $(this).val() == "2" ){
const index = +$('#extra-counter').val();
const tmpl = 'hello world';
//Add sub form
$('#interv_base_intervExtras').append(tmpl);
$('#extra-counter').val(index + 1);
}
else{
$('#interv_base_intervExtras').remove();
}
});
The problem is because you remove() the #interv_base_intervExtras element when you select the first option again. When you move back to the second option #interv_base_intervExtras no longer exists in order to read the data-prototype attribute from it.
To fix this use empty(), instead of remove(), to clear the content of the element instead of removing the entire element:
var $interv = $('#interv_base_intervExtras');
$("#interv_base_youorthird").change(function(){
if ($(this).val() === "2") {
const index = parseInt($('#extra-counter').val(), 10);
const tmpl = $interv.data('prototype').replace(/__name__/g, index);
$('#interv_base_intervExtras').append(tmpl);
$('#extra-counter').val(index + 1);
} else {
$('#interv_base_intervExtras').empty(); // <-- amend this
}
});
Note that I amended the logic slightly in the above example to cache the #interv_base_intervExtras element and to explicitly use parseInt() instead of coercing the string to an int using the + operator.

Passing id into function from onclick method

I know there are many of these types of questions already on here, but I can't find one that matches my specific case.
I just want to pass an id variable into a function from an onclick event, but there's something not right about the way I've got is set up
The goal is to be able to remove the rows that have been added when the X is clicked
$(document).ready(function () {
$("#subjectlist")
.change(function () {
console.log("hit");
$("select option:selected").each(function () {
console.log($("select option:selected"));
var id = 1;
$('#overview').append("<tr id='id'><td>" +
$(this).text() + "</td><td id='id'
onclick='removeItem(id)'>" + "X" + "</td></tr>");
id = id + 1;
});
})
.trigger("change");
$(".btn1").click(function () {
$("#subjectlist").toggle();
});
});
function removeItem(id) {
console.log(id.val);
console.log(id);
$('#overview').find('tr td').eq(id).remove();
}
If your goal is to remove the 'td' element that is clicked. Try this...
$(document).ready(function () {
var id = 1;
$("#subjectlist")
.change(function () {
console.log("hit");
$("select option:selected").each(function () {
console.log($("select option:selected"));
//var id = 1; moved this initialization up a scope level
//on the line below I corrected the concatenation to have unique id's, and removed inline click event.
$('#overview').append("<tr id='id'><td>" + $(this).text() + "</td><td id="+id+">" + "X" + "</td></tr>");
id = id + 1;
});
})
.trigger("change");
$(".btn1").click(function () {
$("#subjectlist").toggle();
});
// added click event to your dynamic element
$("#overview").on('click','td', function() {
$(this).parent().remove();
});
});
/* removed
function removeItem(id) {
console.log(id.val);
console.log(id);
$('#overview').find('tr td').eq(id).remove();
}*/
Your appending string is incorrectly formatted.
Drop the id attribute on the table column since your removeItem() function should be targeting the table row.
You can use back ticks to generate template literals like so...
$('#overview').append(`<tr id="${id}">
<td>${$(this).text()}</td>
<td onclick="removeItem(${id});"> X </td>
</tr>`);
The jQuery.eq() function is an index based filter, not an selector filter. You can then utilise the id selector...
function removeItem (id) {
$(`#${id}`).remove();
}
Try changing this
$('#overview').append("<tr id='id'><td>" + $(this).text() + "</td><td id='id' onclick='removeItem(id)'>" + "X" + "</td></tr>");
To this... should be less confusing, regarding the quote-nesting... notice the use of backticks (`) on the outermost quote level. Also restyled it to make it easier to read, and match html syntax more visually.
$('#overview').append(
`<tr id=x_id_`+id+`>` +
`<td>` +
$(this).html() +
`</td>` +
`<td onclick="$('#x_id_` +
id +
`').remove()">` +
`X` +
`</td>` +
`</tr>`
);
You can ditch the removeItem function entirely.
Since I don't have the rest of your code, not totally sure about the change to the $().html vs $().text, but this should produce a clickable element that will remove the whole row with that id label, which is coded into the rows id and the onclick function.
This will produce html like:
<tr id=x_ix_1><td>PREVIOUS STUFF HERE</td><td onclick='removeItem(`x_id_1`)'>X</td></tr>
Couple things:
First, keep in mind you can only have one element with a particular id at a time. Duplicates will cause errors (but you can remove an element with a particular id and make a new one with that same id, they just can't co-exist).
If you don't want the row removed, but just the td, move the bit about the elements id from the tr to the td-- can't have same id on both.
The quote-nesting was incorrect with the id variable, so was adding it as litteral text (just the string 'id', not the variable content)...
And html id's need to start with a letter. So I re-nested it so the id will parse as variable contents, and the html output will contain 'x_id_' prepended to the variable content... i.e. x_id_0 x_id_1 etc.

get second element by class name if it exists

I'm trying to get the ID of an element by class name like this
var prod_id2 = document.getElementsByClassName('select-selected')[1].id
document.getElementById('hidden-input-2').value = prod_id2;
This works fine, but my issue is that if there's only one element with that class it breaks the functionality, so I need some sort of if statement to only define this var if there is a second div with that class.
Any ideas?
Try this:
const elements = document.querySelectorAll('.test');
if (elements[1]) {
elements[1].innerText = 'Hithere';
}
<div class="test">hi</div>
<div class="test">hi</div>
<div class="test">hi</div>
document.querySelectorAll('.test'); selects all elements with the class test and returns a nodelist.
Then we can access the second element via of the nodelist with elements[1].
Here is how to check for the second element.
You can also set another fallback , different to null:
document.addEventListener("DOMContentLoaded", function(event) {
var selectedElements = document.querySelectorAll('.selected-selected'),
prod_id2 = selectedElements[1] || null;
alert(prod_id2)
});
<div id="test" class="selected-selected"></div>
You can also check that value then:
if (prod_id2) { // do some other stuff with the set value }
It breaks the functionality I think because you are grabbing the 2nd element specifically. You can do:
const prod_id2 = document.querySelectorAll('.select-selected');
and loop over the elements and grab the ID
prod_id2.forEach((prod, index) => {
if(index === 2) {
document.getElementById('hidden-input-2').value = prod.id;
}
})

Determine if $(this) element within jQuery each loop hasClass like a string

Within a jQuery each loop, how can I determine if a selected $(this) element contains a class with a name 'like' a specific value. Initially hasClass() looked promising, but it's unclear to me how to use that function to handle this.
Here is the markup.
<div class="command_buttons">
<a class="download_left_button" style="display:none;" href="#"></a>
<a class="bookmark_left_button" href="#"></a>
<a class="search_right_button" href="#"></a>
</div>
Here is the JavaScript.
findButtonPositionOnCommandBar = function (buttonType) {
/* This function returns 'solo', 'left', 'center', or 'right' text
to tell the button position. The buttonType param should match
a button class prefix like 'bookmark', 'search', or 'download'. */
if ($('.command_buttons').length == 0) { return ''; } // Command bar not found.
// How many visible buttons are on the first command bar found on the page?
var $visibleButtons = $('.command_buttons:first a:visible');
var numberOfButtons = $($visibleButtons).length;
if (numberOfButtons == 0) { return ''; }
if (numberOfButtons == 1) { return 'solo'; }
// This is where I'm having difficulty.
// Find the button with a class name LIKE buttonType_.
buttonSelector = 'class*=' + buttonType + '_';
$($visibleButtons).each(function (index) {
if ($(this).hasClass(buttonSelector)) {
alert('true: ' + index);
} else {
alert('false: ' + index);
}
});
},
For instance, with the above function if we passed 'bookmark' to the buttonType parameter, then it needs to locate anchor tag which has a class of 'bookmark_left_button'.
We have a variety of buttons that can appear in various positions. So I would prefer to find 'bookmark_' rather than write a select for all the permutations of classes that we can apply to the buttons (i.e. bookmark_left_button, bookmark_center_button, bookmark_right_button, download_left_button, etc).
Thanks for your help.
Try this...
buttonSelector = buttonType + '_';
$($visibleButtons).each(function (index) {
if ($(this).attr("class").search(buttonSelector) != -1) {
alert('true: ' + index);
} else {
alert('false: ' + index);
}
});
It just does a string search in the class attribute to see if buttonType_ is there.
It's sufficient to do:
if ($(this).hasClass(buttonType)) {
So:
.hasClass("bookmark")
You're trying to do a partial match. This indicates that your class names aren't set up properly.
If you have classes like:
.bookmark-item {}
.bookmark-header {}
.search-item {}
.search-header {}
And you want to match all bookmark-* elements you should reorganize your classes to:
.bookmark.item {}
.bookmark.header {}
.search.item {}
.search.header {}
/* ^- note that there is no space here */
Your html will be: <div class="bookmark item"></div>
This allows you to match classes with .hasClass("bookmark")
In case you're unclear about the CSS syntax:
.bookmark .item {}
Matches:
<div class="bookmark"><div class="item"></div></div>
Whereas
.bookmark.item {}
Matches:
<div class="bookmark item"></div>
When looping over elements using each(), the function callback uses two variables: index, a number that increments with each pass, and value, the actual node itself; so you need to reference value.
$($visibleButtons).each(function (index, value) {
if ($(value).hasClass(buttonType)) {
alert('true: ' + index);
} else {
alert('false: ' + index);
}
});

jQuery/javascript - list box item deselect/show/hide not working in IE?

I have the following javascript/jquery code, the purpose of which is to -
Deselect a previously selected item from the list, if the selected item value exists in an array
Hide/display each list item dependent on whether they exist in the array
var list = $(row).find("select > option")
var selectedValue = $(row).find("select > option:selected")
if (selectedValue) {
if ($.inArray(selectedValue[0].value, dependencyListItemValues) == -1) {
alert('deselect');
$(selectedValue).attr("selected", false);
}
}
$(list).each(function () {
var value = this.value;
if (value != "") {
if ($.inArray(value, dependencyListItemValues) > -1) {
alert('show');
$(this).show();
}
else {
alert('hide');
$(this).hide();
}
}
});
This is working fine in chrome and firefox, but not in IE9. When running in IE, the alert lines are hit, but the following lines seemingly do nothing:
$(selectedValue).attr("selected", false);
$(this).show();
$(this).hide();
Do I need to use alternative code so this will work in IE?
First: You can use
list.each
instead of $(list).each.
Second, you cannot hide an OPTION element in crossbrowser way.
So, you must remove it (for hide) and re-create it (for show).
You can store all options (and them parent) in array, like so:
var cache_options= [];
list.each(function(index) {
cache_options.push({el:$(this), parent:$(this).parent()});
});
and after
for(var i = 0; i<cache_options.length; i++) {
var value = cache_options[i].el[0].value;
if (value != "") {
if ($.inArray(value, dependencyListItemValues) > -1) {
cache_options[i].parent.append(cache_options[i].el);
}
else {
cache_options[i].el.remove();
}
}
}
Tested!
OK my solution was as follows ... this is based on the answer by meder (thanks!) on this question - Hide select option in IE using jQuery
Firstly, in place of this line:
$(selectedValue).attr("selected", false);
I did this:
$(row).find("select")[0].selectedIndex = -1;
And to show/hide the relevant list items, I had to first wrap those that I needed to hide in a span and then apply the .hide() command, and for those I needed to display, replace the span with the original option element:
//first we need to hide the visible list values that are not in the list of dependent list values.
//get the list values which are currently displayed, these will be the 'option' elements of the 'select' element (list).
//the hidden values are within a span so will not be picked up by this selector
var displayedListValues = $(row).find("select > option")
//loop through the displayed list values
$(displayedListValues).each(function () {
//get the value from this 'option' element
var displayedValue = this.value;
//ignore empty values (first blank line in list)
if (displayedValue != "") {
//if the value is not in the list of dependent list values, wrap in span and apply .hide() command
if ($.inArray(displayedValue, dependencyListItemValues) == -1) {
$(this).wrap('<span>').hide();
}
}
});
//now we need to display the hidden list values that are in the list of dependent list values.
//get the list values which are currently hidden, these will be the 'span' elements of the 'select' element (list).
//the visible values are within an 'option' so will not be picked up by this selector
var hiddenListValues = $(row).find("select > span")
//loop through the hidden list values
$(hiddenListValues).each(function () {
//find the 'option' element from this 'span' element and get its value
var opt = $(this).find('option');
var hiddenValue = opt[0].value;
//ignore empty values (first blank line in list)
if (hiddenValue != "") {
//if the value is in the list of dependent list values, apply .show() command on the 'option' element
//(not sure why the .show() command works in this case?)
//and then replace the 'span' element with the 'option' element, which is effectively removing the span wrapper
if ($.inArray(hiddenValue, dependencyListItemValues) > -1) {
$(opt).show();
$(this).replaceWith(opt);
}
}
});
Which works fine ... although rather annoying I had to do this rather messy re-coding just because IE doesn't support .show() and .hide() of list values!!!!!
Here is a good solution:
http://ajax911.com/hide-option-elements-jquery/

Categories