Create an array from a string - javascript

I have a webpage where a user can select multiple items from a jquery list.
Based on the item(s) selected I need to add each item into the database.
When someone selects one item the value returned to my Javascript is similar to "4~2"
The value 4 would be used in my example for one column named "skill_id" in the database and the value 2 would be used for another column called "category_id" in the same row.
When someone selects two items it is comma-delimited and similar to "4~2,6~7" and so on if they select more than 2.
I'm thinking I need to do a for loop with an array or a jquery.each() function but not certain how the best way to approach this is.

What you're looking for is the split() method.
"4~2,6~7".split(',') // ['4~2', '6~7']

Here is one way you could extract the skill_id and category_id:
$.each("4~2,6~7".split(','), function(index, value) {
var nums = value.split("~");
var skill_id = nums[0];
var category_id = nums[1];
});

Related

Comparing the data attribute value of 2 arrays and checking the innerHTML of the selected checkbox

I am using Vanilla JS and PHP. I have a series of checkboxes for blog posts. Each post has its own associated checkbox and on each checkbox there is a value which is the equivalent of the postID from the mysql db. I have a foreach checking the checkboxes to see which one is clicked and then it pushes that value onto an empty array.
I also have a 2nd array that is filled with the posts id using a separate data attribute as the elements are not on the same DOM level. The 2nd array values contain a status within a <span> that either say 'Published' or 'Draft'. The span has its own data- attribute identifying the post id. I want to compare ids from both arrays and check the innerHTML of the span belonging to the 2nd array. Right now I have a check in place but it only checks the first value int the 2nd array.
Checkbox foreach
//Store post id from checkbox
let checkBox = document.querySelectorAll('.postCheckBox');
let postIDs = [];
let blogIDs = [];
checkBox.forEach(function (element) {
if (element.checked) {
//Store POST ids
postIDs.push(element.value);
//Store BLOG ids
blogIDs.push(element.dataset.blog);
}
});
and in the dom it looks like (the value is the postID)
<input type="checkbox" class="postCheckBox" value="5" data-blog="1">
My 2nd array with values
let customPostIds = [];
Array.prototype.slice.call(postStatus).forEach(post => {
customPostIds.push(post);
})
console.log(customPostIds)
which when consoled returns
And in each of those elements I do see dataset and the innerHTML just not sure how to use it to compare it to the first array AND extract the innerHTML to do a check.
If you need more info to give feedback let me know so I can add whatever info is needed.
The end result I am hoping to achieve is to have a valid if statement check. Pseudo code:
if((postID.id === customPostIds.id) && customPostIds.innerHTML === 'Draft') {return true;}
The tricky part is that customPostIds needs 2 values extracted from it... 1) The data-post-id and the innerHTML from each item in the array. However, the dataset.postId and the innerHTML from the customPostIds array which I want to extract, do not live on the same HTML element in the DOM.

How to use a index value of a dynamic array (which get filled by a click event) for filtering a new array

I'm working on a filter, which filters a array of nested arrays down to the value of one last index.
This happens in 5 steps. At each step you choose which index value (string) get used to filter the array further.
Example: You have 5 categories, each have 6 themes. Each of these 6 themes has 6 focusses(sub themes). Each focus has 6 questions. Each question has 1 answer. First you pick a categorie. This narrows the arrays down to all arrays with that categorie. Then a theme, which narrows the array down to only the arrays with that theme... etc...
So far I managed to filter down to the right question.
You can find the code here: https://github.com/okestens/vertical-filter.git
To get this work, I hardcoded the string "Deskundigheid" as a condition for the equality operator (===) that get used for the filter.
Example:
// FILTER QUESTIONS // I tried to use state.focus[0] but it does not work
let unique_questionsA = [. // now this is hardcoded
...new Set(formsA.filter((i) => i[2] === "Deskundigheid").map((i) => i[3])),
]; --------------
// FUNCTION
function displayQuestionsA() {
state.questions = [];
unique_questionsA.forEach(function (question, index) {
document.getElementById("question" + index).innerHTML = question;
state.questions.push(question);
});
------
// the state object
let state = {
category: [],
themes: [],
focus: [],
question: [],
answer: [],
};
But. What I want this filter to use is not a hardcoded string (deskundigheid) but the exact string that is visible in the div (coming from a click event which creates this filtered array and get stored in the state object). See image.
I thought: I need to track these arrays (with an object called 'state', capturing these dynamic arrays). If I then want to filter the right questions, by using the value (string) of the chosen focus (For example 'Deskundigheid', which is visible to the user), I just refer to the corresponding index value (state.focus[0]) of that chosen focus string, coming from the dynamic state object.
But, if I use the index state.focus[0] for the filter which creates the questions array, I get an empty array :(
My thought: Although the empty focus array (inside the state object), which get filled by a click event, eventually is filled with the right strings, the filter for the new array (unique_questionsA), which uses 'state.focus[0]' does not read the filled array as ‘filled’ but as empty.
I have not idea why :(
I hope I'm clear. If so, and you maybe have a clue, I would love to have a chat! Thanks O
The question can be summed up to
how do I get the text of the element when clicked, in an onclick event
listener callback function.
Your focusScript.js can be modified to
function displayQuestionsA(e) {
state.questions = [];
let unique_questionsA = [...new Set(formsA.filter((i) => i[2] === e.target.innerText).map((i) => i[3]))];
}
document.querySelector(".focus__A").addEventListener("click", displayQuestionsA);
Notice the e.target.innerText which contains the text inside the element that triggered the event(which you clicked).
if I got you correctly - both map and filter functions can give your callback second parameter - the index.
arr.map((n,i)=>{console.log(`[${i}]:${n}`)})

How to get an unflattened array of multiselect values and single inputs together?

I have some dynamically created filters on a web app's page where the filter "entry" is at times the combination of a few different inputs and the values for the collection are gathered into an array to send back to the server. If these were all just single inputs then an array of values would be easy to map over to the inputs on the backend, however when one or more is a multiselect with multiple options, a flattened array of values mixing the multiselect's values and the individual input values isn't appropriate.
As an example: if I have two inputs for a given filter on a search control page, one being a multiselect and another being a text input, I would like to gather an array of two elements, the first being an array of selected values and the second as the value entered in the text input. So if in the first multiselect I select "A", "B" and the text input I enter "Joe" and the code below gathers the input values:
Coffeescript:
filters = []
$(#customFilterElements.selector).each ->
filterName = $(#).find('.filter_entry .filter_name:input').val()
filterValues = $(#).find('.filter_entry .filter_value:input').map(->
if $(#).data('multiselect')
$(#).find('option:selected').map(->
$(#).val()
).get()
else
$(#).val()
).get()
filters.push({name: filterName, value: filterValues})
Javascript: (converted from above)
var filters = [];
$(this.customFilterElements.selector).each(function() {
var filterName, filterValues;
filterName = $(this).find('.filter_entry .filter_name:input').val();
filterValues = $(this).find('.filter_entry .filter_value:input').map(function() {
if ($(this).data('multiselect')) {
return $(this).find('option:selected').map(function() {
return $(this).val();
}).get();
} else {
return $(this).val();
}
}).get();
return filters.push({
name: filterName,
value: filterValues
});
});
Current result for filterValues: ["A","B","Joe"]
The above code ends up producing an array ["A","B","Joe"] for filterValues.
I think this may be because the .get() is converting everything to a flattened array. I tried using $.makeArray() instead of .get() and I get the same results but perhaps I missed something.
Desired result for filterValues: [["A","B"],"Joe"]
What I am hoping to produce is [["A","B"],"Joe"] so it is clear that the first element (in this example) is a collection of selected values from a multiselect to the backend.
How can I adjust the above code to get the desired result (for any combination or ordering of multiselects and single inputs together) in a fairly elegant manner?
The code is intended to be applied to any dynamically created filter, so reusable instead of hardcoding to each filter.
Ok, after a full night's rest the answer came to me right away and it seems so obvious now - just need to wrap the multiselect in an array bracket after the .get()! - doh. Sometimes documenting the problem here forces a solution to bubble up or highlight what I was missing.
filters = []
$(#customFilterElements.selector).each ->
filterName = $(#).find('.filter_entry .filter_name:input').val()
filterValues = $(#).find('.filter_entry .filter_value:input').map(->
if $(#).data('multiselect')
[$(#).find('option:selected').map(->
$(#).val()
).get()]
else
$(#).val()
).get()
filters.push({name: filterName, value: filterValues})

How to use filter in controller in angularjs

I have given code in my function.
$scope.FilteredList = $filter('filter')(ProductService.Products, $scope.FilterExpr, false);
where $scope.FilterExpr is bind with text field.
Above filter works as expected for me, and when user types something in text field, $scope.FilteredList gets populated with filtered items.
ProductService.Products is an array of objects with following fields in object. name, mrp, sp, incart.
I want to create another filter which filters all the items where incart value is > 0.
what should i use instead of ????? in below line.
$scope.FilteredList = $filter('filter')(ProductService.Products, ?????, false);
You don't need to use $filter again. Do use .filter over $scope.FilteredList collection to get desired result.
var result = $scope.FilteredList.filter(function(item){
return item.incart > 0;
});

Taffydb dynamic like 'and' query

I recently started working with taffydb. Assuming I have this as my data
db= TAFFY([
{OrderNo:'prod1',range: 3,description:'one two'},
{OrderNo:'prod2',range: 2,description:'one two three'},
{OrderNo:'prod3',range: 2,description:'one three two'},
{OrderNo:'prod4',range: 6,description:'one two four three'},
{OrderNo:'prod5',range: 5,description:'three'},...
if I wanted to write a query to find all records with "one two" and "three" I'd do something like
db({description:{likenocase:"one two"}},{description:{likenocase:"three"}}).get()
this would return products 2 and 4. Unfortunately I can't figure out how to do this with a dynamic query that will have an unknown number of variables to search for. I'm doing this to let the user search for their own supplied words.
Anyone got any ideas?
As a precursor, this will not be the best answer to your problem. But it will work. :)
So the user will have the option of searching a database with an "unknown number of variables". Let's add a maximum amount of variables--perhaps 10?
Now we catch all the user's search variables in an array:
// Create a dynamic array
var userSearchVars = [];
// Fill the array from 10 HTML input type=text fields
// You can fill your array however you fancy. This is just one example!
$("#myForm input[type=text]").each(function() {
userSearchVars.push( $(this).val());
}
// Note: by default an empty input will return the empty string: ""
Using your code snippet, just query the database with the array:
db(
{description:{likenocase:userSearchVars[0]}},
{description:{likenocase:userSearchVars[1]}},
{description:{likenocase:userSearchVars[2]}},
{description:{likenocase:userSearchVars[3]}},
{description:{likenocase:userSearchVars[4]}},
{description:{likenocase:userSearchVars[5]}},
{description:{likenocase:userSearchVars[6]}},
{description:{likenocase:userSearchVars[7]}},
{description:{likenocase:userSearchVars[8]}},
{description:{likenocase:userSearchVars[9]}}
).get()
Adapting #Jacob-IT's answer so that its dynamic. Used Taffy for the first time tonight and just discovered you can pass an array of objects as the query argument.
// Create a dynamic array
var userSearchVars = [];
// Fill the array from 10 HTML input type=text fields
// You can fill your array however you fancy. This is just one example!
$("#myForm input[type=text]").each(function() {
// This is my edit - push the whole query on to the array.
userSearchVars.push({description:{likenocase: $(this).val() }});
}
// Then pass the whole query array in...
db( userSearchVars ).get()
Tested the above - and it worked for me.
You can do it like this
let items = [];
items.push({description:{likenocase:"one two"}});
items.push({description:{likenocase:"three"}});
db(...items).get()

Categories

Resources