http://jsfiddle.net/4px4whk0/
I have two question
when first click the checkbox (a), the first console.log should be print the dom with empty data-selected-list attribute, I don't know why it filled what I click already (["a"]) ?
I have to set timeout wrap the container.attr('data-selected-list', selectedList); then it works like what I want.
when click other checkbox (b), I hope it will be ["a","b"] store in attribute. but it only store ["b"] , why?
I hope it can be solve by store data in html attribute not only store in jquery data api
$(document).ready(function() {
$('.container').on('click', 'input[type="checkbox"]', function() {
var container = $(this).closest('.container');
var input = $(this);
console.log(container);
var selectedList = container.data('selected-list');
if (selectedList == '') {
selectedList = [];
}
if (input.is(":checked")) {
selectedList.push(input.val());
}
console.log(selectedList);
selectedList = JSON.stringify(selectedList);
container.attr('data-selected-list', selectedList);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="container" data-selected-list="">
<input type="checkbox" value="a">a
<input type="checkbox" value="b">b
<input type="checkbox" value="c">c
</div>
You have several mistakes:
if you want to print the results of your array before you change it, then move the console.log call to before you push to the array
you were using attr and data interchangeably. These do two different things. attr stores the data in the DOM and data is a jquery method that stores the data somewhere within jquery itself.
finally, if you're using attr you need to do JSON.stringify to serialize your array before storing it (which you did do correctly) but when you pull the data out of the DOM you have to convert it back to an array with JSON.parse
jquery's attr returns undefined for an undefined DOM tag, not empty string
the right solution with these problems fixed is:
$(document).ready(function() {
var container = $('.container');
container.on('click', 'input[type="checkbox"]', function() {
var input = $(this);
console.log(container);
var selectedList = container.attr('data-selected-list');
if (!selectedList) {
selectedList = [];
}else{
selectedList = JSON.parse(selectedList);
}
console.log(selectedList);
if (input.is(":checked")) {
selectedList.push(input.val());
}
selectedList = JSON.stringify(selectedList);
container.attr('data-selected-list', selectedList);
});
});
here's a fiddle: http://jsfiddle.net/yLz6uv1q/
Related
Hello application must allow users filtration data contained in the data collection. The filter has to be supported by the checkboxes. The user selects (checkbox) it interesting data (name, address ...) and submit your selection. The table below displays the selected data from the data collection.
Does anyone have an idea how it should look like the code that retrieves data from the collection of data, taking into account filtration made by the user.
My idea was. Get the value of the checkbox and save them in the array and the later inclusion of data from the array in the code to retrieve data from the collection using the subroutine find ().
'change .cd-checkbox-1': function(event, target) {
var x = event.target.checked;
Session.set("statevalue", x);
var array = [];
if (Session.get("statevalue") === true) {
$( "[name='inputCheckboxPodmiot']:checked" ).each( function( index, element ) {
array.push( element.value );
});
};
var arrayLength = array.length;
for (var i = 0; i < arrayLength; i++) {
var abiRejestr = WkaRejestrAbi.find( {}, { fields: { array[i]: 1 } } );
}
}
One approach is to use Reactive Vars. Sessions are not recommended as they pollute the global namespace.
Example code :
In main.html
<template name="test">
<input type="checkbox" id="checkbox1" name="name" value="data">Check Me
<input type="checkbox" id="checkbox2" name="name" value="data">Check Me2
<input type="checkbox" id="checkbox3" name="name" value="data">Check Me2
{{showData}}
</template>
In Main.js
var check_status='';
//Reactive Var Initialization
Template.main.onCreated(function (){
check_status1=new ReactiveVar({});
check_status2=new ReactiveVar({});
check_status3=new ReactiveVar({});
});
Template.main.helpers({
showData : function(){
return Collection.find({$and : [{check_status1.get(),check_status2.get(),check_status3.get()}]}).fetch();
}
});
Template.main.events({
"change #checkbox1" : function(event) {
if($(event.currentTarget).is(":checked").val())
check_status1.set({field1: 'data1'});
else
check_status1.set({});
},
"change #checkbox2" : function(event) {
if($(event.currentTarget).is(":checked").val())
check_status2.set({field2: 'data2'});
else
check_status2.set({});
},
"change #checkbox3" :function(event) {
if($(event.currentTarget).is(":checked").val())
check_status3.set({field3: 'data2'});
else
check_status3.set({});
},
});
Explanation:
When we initialize the reactive var check_status we set the value equal to {}. In the helper, at the time of rendering, the same data is passed to the query Collection.find(check_status.get()) which is as good as show all data.
As soon as you click on the checkbox, the event described in the Template.main.events is triggered which sets the value of check_status to {field: data}. Since, this is a reactive var, the showData template is re run and this time the query is Collection.find({field: data}), so only fields, where field matched 'data' is returned.
You will need to add the reactive var package(meteor add reactive-var) before using these commands.
Alternatively, you can also use Tracker.autorun is you want to continue using session variables.
I have a drag and drop thing which uses clone. I am having a problem with the date clone though because of datepicker. Therefore, I need to make sure each cloned datepicker has a unique id. A cloned element looks like the following
<div data-type="date" class="form-group">
<label class="control-label col-sm-5" for="dateInput">Date Input:</label>
<div class="col-sm-3">
<input type="text" name="dateInput[]" class="form-control date_picker" id="dateInput">
</div>
</div>
So if I clone two date inputs, I will have two of the above. Now on submit, I clean all of the cloned html, doing things like removing the data-type. At this stage, if there is a cloned date input, I need to give it a unique id. At the moment I am doing this
$("#content").find(".form-group").each(function() {
var html = $(this).attr('class', 'form-group')[0].outerHTML.replace(/ data-(.+)="(.+)"/g, "");
var input = $(this).find('input');
var i = 0;
if(input.attr('id') == 'dateInput') {
alert("TEST");
input.attr("id",'dateInput' + i).datepicker();
i++;
}
console.log(html);
dataArray.push(html);
});
The TEST alert fires twice as it should do if I clone 2 date inputs. However, the id attributes do not seem to change when I output the html to the console. I have set up the following Fiddle to demonstrate that the id of the element is not changing.
Any advice on getting this to change appreciated.
Thanks
Try defining dataArray, i outside out submit event, .each() , using .map() , .get() , .attr(function() {index, attr}) , .outerHTML
$(function() {
// define `i` , `dataArray`
var i = 0, dataArray = [];
$('#content').submit(function(event) {
event.preventDefault();
$("#content").find(".form-group").each(function() {
var html = $(this).attr('class', '.form-group')[0]
.outerHTML.replace(/ data-(.+)="(.+)"/g, "");
dataArray.push($(html).map(function(_, el) {
// adjust `input` `id` here , return `input` as string
return $(el).find("input").attr("id", function(_, id) {
return id + (++i)
})[0].outerHTML
}).get()[0])
});
$("#output")[0].textContent = dataArray.join(" ");
console.log(dataArray)
});
});
jsfiddle https://jsfiddle.net/mLgrfzaL/2/
The code looks like this:
<div id="list">
<input type="checkbox" id="1">
<input type="checkbox" id="2">
<input type="checkbox" id="3">
</div>
In another html pane (a separate template), I want to store all those checkbox (checked/unchecked) booleans into an array. What I did looks like:
var array = [];
var checkboxli = document.getElementsByTagName("input");
for (var i = 0; i < checkboxli.length; i++)
{
array.push($("#input.prop('checked')"));
}
However, this doesn't work. I have other templates using tag name "input", so I need to limit the tag name to the ones under "#list" id (some sort of css selector perhaps). Currently, both document.getElementsByTagName("input") and $("#input.prop('checked')") won't work. There might be other syntax problems. Please help me resolve. Thanks.
EDIT: It seems like I didn't communicate my intention well. Here is what I want to get out of the list:
An array that looks like
[true, false, true, true, true...]
in which each boolean value represents whether the corresponding input checkbox is checked or not.
Since your are already using jquery, you can go like this:
Assuming this HTML
<div id="list">
<input type="checkbox" id="1" checked="checked">
<input type="checkbox" id="2">
<input type="checkbox" id="3" checked="checked">
</div>
And this script:
var array = [];
$("input[type='checkbox']","#list").each(function(){
array.push($(this).is(":checked"));
});
You would get something like this:
array = [ true, false, true ];
Instead of:
var checkboxli = document.getElementsByTagName("input");
you can use:
var checkboxli = document.querySelectorAll("#list>input[type=checkbox]"); //array of checkboxes
now you have all of the checkboxes under the list element.
if you want only the checked checkboxes you can use:
var checkboxli = document.querySelectorAll("#list>input[type=checkbox][checked]");
Try below code. It retrieves all IDs from all checked check-boxes, stores in an array and then stores in local-storage as an string:
var itemsChecked = [] ;
$('input[type=checkbox]:checked').each(function(index, item){
itemsChecked.push($(item).attr('id'));
})
localStorage.setItem('selectedItems', JSON.stringify(itemsChecked));
Later, to retrieved data from localstorage, use the following:
var items = JSON.parse(localStorage.getItem('selectedItems'));
// returns array of IDs
A more suitable approach would be to capture the XPath of each element starting from the body. You could use a getPath jQuery plugin, Thus you won't be dependent upon a specific string like the List.
jQuery.fn.extend({
getPath: function( path ) {
// The first time this function is called, path won't be defined.
if ( typeof path == 'undefined' ) path = '';
// If this element is <html> we've reached the end of the path.
if ( this.is('html') )
return 'html' + path;
// Add the element name.
var cur = this.get(0).nodeName.toLowerCase();
// Determine the IDs and path.
var id = this.attr('id'),
class = this.attr('class');
// Add the #id if there is one.
if ( typeof id != 'undefined' )
cur += '#' + id;
// Add any classes.
if ( typeof class != 'undefined' )
cur += '.' + class.split(/[\s\n]+/).join('.');
// Recurse up the DOM.
return this.parent().getPath( ' > ' + cur + path );
}
});
I'm getting the values of checkboxes when a user submits the form and storing their values as an array, so the form looks like this:
<!-- gym_create.html - I have removed the other inputs in the form for brevity -->
<form class="create-gym" role="form">
<input type="checkbox" name="gymTags" value="Bodybuilding" id="tagBodybuilding" class="tag-checkbox"/>
<input type="checkbox" name="gymTags" value="Powerlifting" id="tagPowerlifting" class="tag-checkbox"/>
<button type="submit" class="btn create-form-submit">Save gym</button>
</form>
And then I collect that information in my JS file associated with the form:
// gym_create.js - I have removed the other values I collect apart from the gymName value for brevity
Template.gymCreate.events({
"submit .create-gym": function (e) {
e.preventDefault();
var tagOutput = JSON.stringify({
tagOutput: $(':checkbox[name=gymTags]:checked').map(function() {
return $(this).val();
}).get()
});
// Collect values from form when submitted
var gymDetails = {
gymName: $(e.target).find('[name=gymName]').val(),
gymTags: tagOutput,
}
// Call method here
}
});
I can then output these in my template using {{gymDetails.gymTags}} but this produces the following in the browser:
"{"TAGOUTPUT":["BODYBUILDING","POWERLIFTING"]}"
What I want is a way to store the values as JSON so they are like so:
{"gymTags": {
"bodybuilding": "true",
"powerlifting": "false"
}}
So that I can output each tag on it's own and also access only tags which are 'true' (that were checked) later on.
Does anyone know how I go about this? I wrangled with it all yesterday and the best I could come up with was the =JSON.stringify
I don't want to pass the entire form to JSON, just the checkboxes, is JSON.stringify what I want to be doing or am I barking up the wrong tree.
I think this should do it. You were just returning the just the value of the inputs. You want to return a json object, where the value is the "index" and the checked property is the "value" of the object.
var tagOutput = JSON.stringify({
tagOutput: $(':checkbox[name=gymTags]').map(function() {
var op = {};
op[this.value] = this.checked;
return op;
}).get()
});
Edit: as noted by Da Rod, to use both checked and unchecked checkboxes, you must remove the ":checked" selector.
Since your selector is only grabbing items that are checked, they are all "true". That being the case, you need to change the way you are using "map" to add properties to tagOutput.
var tagOutput = {}
$(':checkbox[name=gymTags]').map(function() {
tagOutput[this.value] = this.checked;
})
});
The following code populates the second select statement with HTML data. The problem I'm facing is that I clone the two select statements and on submission of the form, I'd like to save all of the selected option values from the two selects into an Array().
What would be the best way to iterate through all of the drop-down values (there's a maximum of 5 that can be added for both Subject Matter and Category)?
Thanks in advance.
$(".SubjectCategory").live("click", function () {
var $this = $(this);
var $elem = $this.closest('div').nextAll('div').first().find('select');
var a = $this.val();
$.get("/userControls/BookSubjectHandler.ashx?category=" + a, {}, function (data) {
$elem.html(data);
});
});
<div class="singleField subjectField">
<label id="Category" class="fieldSml">Subject Matter</label>
<div class="bookDetails ddl"><select id="ddlSubjectMatter" class="fieldSml SubjectCategory"></select></div>
<label id="Subjects" class="fieldSml">Category</label>
<div class="bookDetails ddl" id="subjectMatter"><select id="ddlSubjects" class="fieldSml Subjects"></select></div>
</div>
Using jQuery .map function you can retrieve all values at once:
var arrayOfValues = $(".bookDetails.ddl select").map(function (i, el) { return $(el).val(); }).get();
fiddle: http://jsfiddle.net/e9zxY/