Hello I can't find out how to delete a specific value from string when clicking on an element with the string value. its for my todo list.
if (window.localStorage.fullName !== undefined) {
alert('Your browser does not support localStorage');
} else {
$(function () {
console.log('localSorage compitability detected. proceeding...');
global vars & functions
var tdli = [];
add list items
$('#tdladd').click(function () {
$('.todolist ul ul').append("<li class='tdli'>" + $('#tdlinput').val() + "</li>");
tdli.push($('#tdlinput').val());
$('#tdlinput').val('');
var array = tdli + "";
localStorage.setItem('tdlis', array);
console.log(array);
$('#todolist').hide().fadeIn('fast');
});
remove list items
$('li').click(function () {
var itemtoRemove = $(this);
tdli.splice($.inArray(itemtoRemove, tdli), 1);
console.log(tdli);
});
$('#clearall').click(function () {
localStorage.clear();
location.reload();
});
load list items
var tdlitems = localStorage.getItem('tdlis');
var array = tdlitems.split(',');
tdli.push(array);
for (var i = 0; i < array.length; i++) {
array[i] + "<br>";
$('.todolist ul ul').append("<li>" + array[i] + "</li>");
};
console.log(array);
});
}
Assuming that tdli is a jQuery wrapped set (which itself is an array-like-object), it will have DOM nodes stored instead of another jQuery objects. That means, just go like
var itemtoRemove = this;
and you should be fine.
After you posted your complete code, we can see you're actually pushing string values into your tdli Array, but you try to .splice() objects respectively DOM nodes, which of course doesn't make any sense at all (comparing apples to oranges).
Related
Intro
I have a search bar I implemented into my website which searches through member cards to find matching cards. I also used Twitter's typeahead.js for this. The results are updated as you type, so I set an event listener on the input box - $('#members-search .typeahead').on("input", changeFunction); I also needed to set a click event listener on the suggestions, as I did - $('.tt-suggestion').on("click", changeFunction);
Problem
It seems like the suggestion boxes are created on the fly, so you can't set an event listener for all (or even any!) of them at the beginning. My first idea was to fire a function when an element was appended in the containing div. However, you would need an event listener for that, and I couldn't find one. Is there any way to implement this?
Code
The JavaScript:
var substringMatcher = function(strs) {
return function findMatches(q, cb) {
var matches, substringRegex;
// an array that will be populated with substring matches
matches = [];
// regex used to determine if a string contains the substring `q`
substrRegex = new RegExp(q, 'i');
// iterate through the pool of strings and for any string that
// contains the substring `q`, add it to the `matches` array
$.each(strs, function(i, str) {
if (substrRegex.test(str)) {
matches.push(str);
}
});
cb(matches);
};
};
var children = document.getElementById("members-list").children;
var names = [];
var whoIsWho = [];
var selected = [];
var listOfAttributeNames = ["data-member-name", "data-member-username", "data-member-nickname"];
for(var i = 0; i < children.length; i++){
for(var j = 0; j < listOfAttributeNames.length; j++){
var a;
if(a = children[i].getAttribute(listOfAttributeNames[j])){
names.push(a);
whoIsWho.push(children[i]);
}
}
}
$('#members-search .typeahead').typeahead({
hint: true,
highlight: true,
minLength: 1
},
{
name: 'names',
source: substringMatcher(names)
});
var previousValue = "";
function changeFunction(e){
var v;
if($("#members-search .typeahead").val() === ""){
previousValue = "";
}
else if(((v = $('#members-search .typeahead+pre').text())) !== previousValue){
previousValue = v;
}
else if(v !== $("#members-search .typeahead").val()){
previousValue = $("#members-search .typeahead").val();
}
selected = [];
v = $('#members-search .typeahead+pre').text();
for(var i = 0; i < names.length; i++){;
if(!(new RegExp(v, "i").test(names[i])) && !(selected.includes(whoIsWho[i]))){
whoIsWho[i].style.display = "none";
}
else{
selected.push(whoIsWho[i]);
whoIsWho[i].style.display = "block";
}
}
}
$('#members-search .typeahead').on("input", changeFunction);
$('.tt-suggestion').on("click", changeFunction);
The (important) HTML:
<div id="members-search">
<input class="typeahead" type="text" placeholder="Search">
</div>
Alternate, Backup Solutions
I could copy the bloodhound script over to my code and modify where the elements are appended, but I'd rather not, as it uses this weird format of IIFE that I won't take the time to understand. Or is there another solution and this question is part of the X/Y problem?
It turns out I had the wrong approach. I just added an event listener to the current suggestions every time the input value was changed.
$('#members-search .typeahead').on("input", function(){
$('.tt-suggestion').on("click", changeFunction);
});
I have a list of checkboxes while selecting checkboxes i have to add the values to arrays and while unchecking i have to remove that from array.
following code am using.
but it is not deleting while unchecking
<tr><td class="tdstyleSelect"><input type="checkbox" name="joblist" onclick="toNfroVmps(this.id);" id="' + i + '" checked>
var toNfroVmps = function(id) {
if($('#' + id).is(':checked'))
elementIds.push(id);
else
delete elementIds[elementIds.indexOf(id)]
}
Use Array.splice (which is, btw, a native JS method):
var index = elementIds.indexOf(id);
if (index !== -1) {
elementIds.splice(index, 1);
}
You might consider using hashes (instead or a plain Array) to store your data: with each key corresponding to an ID, and value either true or false.
var elementIds = {
el1: true,
el2: true,
el3: false
// ...
};
This way adding/removing an element will be even more straight-forward:
elementIds[id] = $('#' + id).is(':checked'); // either true or false
... and you still will be able to process this hash as array, using various jQuery list comprehension functions. For example, that's how you collect ids of all the checked elements:
var checkedIds = $.grep(elementIds, function(el) { return el; });
You can use the splice method to remove array items.
var toNfroVmps = function(id)
{
if($('#' + id).is(':checked'))
elementIds.push(id);
else
{
// Select the index
var i = elementIds.indexOf(id);
// Check if the index exists, to prevent any errors that might happen
// If exists, delete
if(i !== -1)
elementIds.splice(i, 1);
}
}
I'm trying to do some validation on a user selecting items from a list. I want to make sure an item is not added twice by checking if the <li> is already in the array. This is what I'm trying and its not working.
$(".List").on("click", "li", function () {
var i = 0;
var checkArr = [];
var div = $("#AddedItems");
var parent = $(this).closest("ul");
var itemtoadd = parent.find("[data-id]").attr("data-id");
var name = parent.find("[data-name]").attr("data-name");
alert(itemtoadd + name);//checking
var itemtoadd = ("<li id = " + itemtoadd + " class = \"itemAdd\">" + name + "</li>");
checkArr.push(itemtoadd); //put one in to check against?
checkArr.forEach(item)
{
if (item == itemtoadd)
alert("this item has already been added");
else {
checkArr.push(itemtoadd);
alert(itemtoadd);
$(itemtoadd).appendTo(div);
}
}
// div.html(itemtoadd);
});
You have at least three problems here:
You aren't using Array.forEach correctly -- it takes a function that takes an item.
Immediately before you do your check, you're adding the item you're looking for. You will always hit the alert case.
You're using checkArr as a local variable -- you're getting an empty array each time you enter the function.
That all being said, you can accomplish your goal without keeping an array at all. I believe you can replace everything from your first alert down with this:
if ($('#' + itemtoadd, div).length == 0) {
itemtoadd = ("<li id = " + itemtoadd + " class = \"itemAdd\">" + name + "</li>");
div.append(itemtoadd);
}
else {
alert("this item has already been added");
}
I need to output inputs and their values into a div. However, because I need to match the correct labels to the correct inputs, and some fields allow null values, I'm running into matching issues. Using the following code to pull each label/input into an array, and then output:
var inputArr = $('input, select').map(function(){
return "<p>" + $(this).val() + "</p>";
}).get()
var labelArr = $('label').map(function(){
return "<p>" + $(this).text() + "</p>";
}).get()
function setValuesForConfirm() {
//Clear Div Contents
$("#test-output-1, #test-output").html('');
for (var i = 0; i < labelArr.length; i++) {
$("#test-output-1").append(labelArr[i]);
}
for (var i = 0; i < inputArr.length; i++) {
$("#test-output").append(inputArr[i]);
}
}
So if any of the input's are blank, the fields do not match the labels.
My question is, can I name the array keys to the field name or ID in JS using the .map() function as I am currently?
JSFiddle Here
You could create an object using the inputs:
var formObj={};
$('input, select').each(function(){
formObj[this.name]={val: this.value, labelText: $(this).prev('label').text()};
});
then when loop over object can throw together html
$.each(formObj, function(key, item){
var labelHtml='<p>'+item.labelText+'</p>';
var inputHtml='<p>Name: '+ key+', value: '+item.val+'</p>';
/* do something with html*/
})
While what you have seems to work okay to me, .map creates an array and you can only have numeric ordinal keys in arrays in JavaScript, so you would need an object.
var inputArr = {};
$('input, select').each(function(){
inputArr[$(this).attr('name')] = "<p>" + $(this).val() + "</p>";
});
http://jsfiddle.net/Mz9Vy/1/
How can I create an array from inside of the '.each loop' and use it outside of the loop?
My .each loop:
// Loop through all but button with class .apply
$('.profile-nav ul li a').not('.apply').each( function() {
// if currently loop through element has .cur class
if( $(this).hasClass('cur') ) {
//Get the first class of the match element
var ClassesToApply = $(this).prop('class').split(' ')[0];
}
//How can I create an array from all ClassesToApply?
//var arr = jQuery.makeArray(ClassesToApply);
// This will create an array, but with one element only
});
How can I create an array from all var = ClassesToApply?
And than how can I do something with this array?
e.g
$( allClasses from an array as a selectors).doStuff();
If you declare a variable outside of the each, it will be accessible inside the each:
var yourArray = [];
$('.profile-nav ul li a').not('.apply').each(function() {
if($(this).hasClass('cur')) {
yourArray.push($(this).prop('class').split(' ')[0]);
}
});
//Here, yourArray will contain the strings you require.
Although as others have shown, there are ways to shorten your code significantly.
fxnReqValidation = function () {
var InputTagArray = new Array;
InputTagArray = document.getElementsByTagName("input");
for (var iCnt = 1; iCnt <= InputTagArray.length; iCnt++) {
if ((g_Json[InputTagArray[iCnt].name].required == true) && (InputTagArray[iCnt].value == "")) {
$("#errormsg").text("please enter all required fields");
}
return false;
}
}
You could do:
var arr = $( 'a.cur:not(.apply)', '.profile-nav' ).map( function () {
return $( this ).prop( 'class' ).split( ' ' )[0];
}).get();
var list = $(".profile-nav ul li a.cur:not(.apply)");
list.each(function(){
// do your thing!
});
var arraySelectors = $('.profile-nav ul li a.cur:not(.apply)')
.toArray()
.map(e => '.' + Array.from(e.classList).join('.'));
This snippet is probably not the most elegant but it tries to accomodate to the objective the OP was describing.
I prefer not splitting a className because you never know how many consecutive spaces there is.
Exiting from the jQuery array and getting to a native array seems to be the best solution.
Array.from() is ES6 circa 2015
jQuery.toArray() appeared in jQuery 1.4