Can't push item into empty array - javascript

I have this function where when I click a button I loop over some divs and get the id of that div along with some checkbox inputs id's if they are marked.
To store this values I have a dictionary which is suppose to store the items like this:
{
1: [4,5],
2: [2,3]
}
The keys represent the id's of each div and the values are the checkbox items id's that are clicked.
Full code:
$(document).on('click', '.trimite-rasp', function(){
var formData = {}
$.each($('.single-question'), function(){
var listIds = [];
var qId = $(this).attr('qid');
console.log(qId);
$.each($('.form-check-input'), function(){
if($(this).is(':checked')){
var thisId = ($(this).attr('aid'));
$(listIds).push(thisId);
}
});
formData[qId] = listIds;
});
console.log(formData);
});
The only problem here is that listIds array is always empty. I can't push the values to that array, and I'm sure the checkbox id is correct because I console.log it and it's taken correctly.

It is because you are using the array as a jQuery selector
use
var thisId = $(this).attr('aid');
listIds.push(thisId);
instead of
$(listIds).push(thisId);

Try this
listIds.push(thisId);

Related

How to get selected values of Kendo Multi Select?

I'm using Kendo multi select as follow but i can't get selected values
var multiselect = $("#SelectRoles").data("kendoMultiSelect");
var selectedData= [];
var items = multiselect.value();
for (var itm in items)
{
selectedData.push(itm);
}
but array selectedData return indices of items in multiselect not values .
You can also assign the array, returned from the value() method, directly to the variable, e.g.:
var ms = $("#multiselect").kendoMultiSelect({
value: ["1", "2"]
}).data('kendoMultiSelect');
var selectedItems = ms.value();
console.log(selectedItems); // ["1", "2"]
Use this other one returns indices.
var multiselect = $("#SelectRoles").data("kendoMultiSelect");
var selectedData= [];
var items = multiselect.value();
for (var i=0;i<items.length;i++)
{
selectedData.push(items[i]);
}
Your original code doesn't look wrong. Are you sure you are getting only indices? Perhaps you should post your MultiSelect code as well. I found this question because I had the same problem and used the other answers for reference, but I found them overcomplicated. So let me answer in another complicated way :)
Here's what I've got. I know it's more code than you need, but I think it's important to see the full picture here. First let me set this up. There's a problem with the Kendo().MultiSelect.Name("SomeName") property if you are using it more than once. "Name" sets not only the html name, but the id as well, and you never want two ids with the same identifier. So in my code, I am appending a unique Id to my MultiSelect.Name property to ensure a unique id. I am putting the MultiSelect in each row of a table of people. I am showing this to make sure you are using the DataValueField property so you are able to get the selected values (not the text you see in the ui). If you are just showing a list of text values with no id behind them, perhaps that is why you are getting the wrong data?
#foreach (var cm in Model.CaseMembers)
{
<tr>
<td>
#(Html.Kendo().MultiSelect()
.Name("IsDelegateFor" + cm.CaseMemberId)
.Placeholder("is a delegate for..")
.DataTextField("FullName")
.DataValueField("CaseMemberId")
.BindTo(Model.Attorneys)
)
</td>
</tr>
}
then, later on, in my jQuery where I attempt to extract out the DataValueField (CaseMemberId), which is the array of selected values of the MultiSelect...
var sRows = [];
$('#cmGrid tr').each(function () {
// 'this' is a tr
$tr = $(this);
// create an object that will hold my array of selected values (and other stuff)
var rec = {};
rec.IsADelegateFor = [];
// loop over all tds in current row
$('td', $tr).each(function (colIndex, col) {
if (colIndex === 3) {
// make sure our MultiSelect exists in this td
if ($(this).find("#IsDelegateFor" + rec.CaseMemberId).length) {
// it exists, so grab the array of selected ids and assign to our record array
rec.IsADelegateFor = $(this).find("#IsDelegateFor" + rec.CaseMemberId).data("kendoMultiSelect").value();
}
}
}
// add this tr to the collection
sRows.push(rec);
}
so this is all a super verbose way of saying that this single line, as the other people mentioned works perfectly to grab the ids. There is no need to iterate over the .value() array and push the contents to another array!
rec.IsADelegateFor = $(this).find("#IsDelegateFor" + rec.CaseMemberId).data("kendoMultiSelect").value();
So in your original code, there is no reason the following should not work,
var multiselect = $("#SelectRoles").data("kendoMultiSelect");
var selectedData = [];
selectedData = multiselect.value();
console.log(selectedData);
unless
you don't have your MultiSelect set up properly in C# with DataValueField
you have multiple MultiSelects on the page with the exact same id and it's reading from a different one than you think.
You don't even have value fields, just a list of text.
var selected = $("#multi").data("kendoMultiSelect").value();
The solution given by volvox works.
Below is jquery version,
var multiselect = $("#SelectRoles").data("kendoMultiSelect");
var selectedData= [];
var items = multiselect.value();
$.each(items ,function(i,v){
selectedData.push(v);
});

Reference javascript array inside click function by dynamically creating the array name

So I have an array something like this:
var first_array = ['foo','bar','foobar'];
I am running a click function and trying to get the name of the array and loop through the array which has first as the ID name something like this
$('element').on('click',function(){
var id = $(this).attr('id');
var arr = id+"_array";
$.each(arr,function(index,value){
console.log(value);
})
})
Now the arr gives a variable name first_array and not the array. Hence the each loop fails. Is there a way to reference the array? I need to dynamically create the array variable name and get the array elements. I have also tried declaring the array globally and inside the click function but does not work.
Like Rayon Dabre said in the comments, you should use a parent object containing your first_array, and more, like that :
var parent_array = {
first_array: ['foo','bar','foobar'],
second_array: ['foo2', 'bar2', 'foobar2']
};
$('element').on('click',function(){
var id = $(this).attr('id');
var arr = parent_array[id+"_array"];
$.each(arr,function(index,value){
console.log(value);
})
});
You can put all your arrays into a javascript object or a parent array and access them by key/name like parentArr["first_array"]

Empy array values are created when adding to array

I have the below code:
var changes = new Array();
$(".item_prices").on("blur", function(){
var item_id = $(this).attr("id");
var item_price = $(this).html();
changes[item_id] = item_price;
});
Every time a new value is entered, I want to save the item's ID as the key and its price as the value. If I save items with IDs 4 and 6 and prices 1.99 and 2.99, respectively, I get the following array:
{,,,,1.99,,2.99}
How do I add to the array without incurring empty values?
Use object, not Array:
var changes = {};
The rest is the same.
Key-value should always be saved in an object.
Since you're using jQuery, here is another answer to an unasked question,
Use native javascript functions when it's possible and simple, specially when it's even simpler:
var item_id = $(this).attr("id");
var item_price = $(this).html();
Can and should be:
var item_id = this.id
var item_price = this.innerHTML;
You don't want an array, a simple object will form a collection of key value pairs for you:
var changes = {};
If / when the time comes to enumerate these changes:
for (var name in changes) {
if (changes.hasOwnProperty(name)) {
var value = changes[name];
...
}
}
Arrays are a special case of objects, whose elements have consecutive integer keys. You don't have consecutive keys, so Array is "filling the gaps" for you.
Use a barebones Object instead:
var changes = {};

Writing checked items to an array

These are my many checkboxes and I need to grab the selected ones on a save and create an array/string of numbers that will be saved.
<asp:CheckBox ID="4" runat="server" ClientIDMode="Static"/>
Do I need to add a value with a number so that i can get the number that the checkbox is so i can get something like "1,4,8,9"(checkboxes selected) or can I get it from ID?
I was looking at something like this as an example:
$(function(){
$('#btnClick').click(function(){
var val = [];
$(':checkbox:checked').each(function(i){
val[i] = $(this).val();
});
});
});
EDIT:
Is there a way to get the checkboxes specifically by starting ID as to not get every single one from the page?
You can use .push on Array's like so:
val.push(this.id);
Here is an example: http://jsfiddle.net/dpMp2/3/
or
you can just do this:
var val = $.makeArray($(':checkbox:checked'));
information on makeArray can be found here: http://api.jquery.com/jQuery.makeArray/
note as am not i am stated below, the array will be objects and you will have to get the id or value from each obj. Read the docs for more info.
I would use map
$(':checkbox:checked').map(function(){ return $(this).val(); })
Since val is an object, so you'll have to use push function to assign the data.
$(function(){
$('#btnClick').click(function(){
var val = [];
$(':checkbox:checked').each(function(i){
val.push($(this).val());
});
});
});

Looping over elements in jQuery

I want to loop over the elements of an HTML form, and store the values of the <input> fields in an object. The following code doesn't work, though:
function config() {
$("#frmMain").children().map(function() {
var child = $("this");
if (child.is(":checkbox"))
this[child.attr("name")] = child.attr("checked");
if (child.is(":radio, checked"))
this[child.attr("name")] = child.val();
if (child.is(":text"))
this[child.attr("name")] = child.val();
return null;
});
Neither does the following (inspired by jobscry's answer):
function config() {
$("#frmMain").children().each(function() {
var child = $("this");
alert(child.length);
if (child.is(":checkbox")) {
this[child.attr("name")] = child.attr("checked");
}
if (child.is(":radio, checked"))
this[child.attr("name")] = child.val();
if (child.is(":text"))
this[child.attr("name")] = child.val();
});
}
The alert always shows that child.length == 0. Manually selecting the elements works:
>>> $("#frmMain").children()
Object length=42
>>> $("#frmMain").children().filter(":checkbox")
Object length=3
Any hints on how to do the loop correctly?
don't think you need quotations on this:
var child = $("this");
try:
var child = $(this);
jQuery has an excellent function for looping through a set of elements: .each()
$('#formId').children().each(
function(){
//access to form element via $(this)
}
);
Depending on what you need each child for (if you're looking to post it somewhere via AJAX) you can just do...
$("#formID").serialize()
It creates a string for you with all of the values automatically.
As for looping through objects, you can also do this.
$.each($("input, select, textarea"), function(i,v) {
var theTag = v.tagName;
var theElement = $(v);
var theValue = theElement.val();
});
I have used the following before:
var my_form = $('#form-id');
var data = {};
$('input:not([type=checkbox]), input[type=checkbox]:selected, select, textarea', my_form).each(
function() {
var name = $(this).attr('name');
var val = $(this).val();
if (!data.hasOwnProperty(name)) {
data[name] = new Array;
}
data[name].push(val);
}
);
This is just written from memory, so might contain mistakes, but this should make an object called data that contains the values for all your inputs.
Note that you have to deal with checkboxes in a special way, to avoid getting the values of unchecked checkboxes. The same is probably true of radio inputs.
Also note using arrays for storing the values, as for one input name, you might have values from several inputs (checkboxes in particular).
if you want to use the each function, it should look like this:
$('#formId').children().each(
function(){
//access to form element via $(this)
}
);
Just switch out the closing curly bracket for a close paren. Thanks for pointing it out, jobscry, you saved me some time.
for me all these didn't work. What worked for me was something really simple:
$("#formID input[type=text]").each(function() {
alert($(this).val());
});
This is the simplest way to loop through a form accessing only the form elements. Inside the each function you can check and build whatever you want. When building objects note that you will want to declare it outside of the each function.
EDIT
JSFIDDLE
The below will work
$('form[name=formName]').find('input, textarea, select').each(function() {
alert($(this).attr('name'));
});

Categories