I have a list of checkboxes, I'm trying to check these based on the value of a textbox.
var codes = $('#textbox1').val().split(','); // this contains [ "Dept1" and "Dept2" ]
var allDeptChecks = $('.Dept-help input:checkbox'); // this contains all of my checkboxes
allDeptChecks.attr('checked', false);
$.each(codes, function() {
var chkDept = allDeptChecks.find("[value='"+this+"']"); // no matter what I try, this selector matches 0 elements
chkDept.attr('checked', true);
});
<li title="Dept 1">
<input type="checkbox" name="chkDept1" value="Dept1">
<span>Dept1</span>
<span>Description Numero Uno</span>
</li>
<li title="Dept 2">
<input type="checkbox" name="chkDept2" value="Dept2">
<span>Dept2</span>
<span>Description Numero Dos</span>
</li>
Shouldn't this work?
EDIT: Here's a JSFiddle
Here you go
$('#lnkGo').click(function () {
var codes = $('#textbox1').val().split(','); // this contains [ "Dept1" and "Dept2" ]
var allDeptChecks = $('input:checkbox'); // this contains all of my checkboxes
allDeptChecks.prop('checked', false);
$.each(codes, function () {
var chkDept = allDeptChecks.filter("input[value='" + this + "']"); // no matter what I try, this selector matches 0 elements
chkDept.prop('checked', true);
});
});
Try this :
$.each(codes, function(i, value) {
$("input[value='"+value+"']").prop('checked', true);
});
Related
I want to pass(return) data-filter value and children text , I am able to pass the data-filter value but I am unable to pass the children text. My HTML and JQuery as following:
$(document).ready(function() {
$('.sidebar-filter').on('click', function() {
var filterobj = {};
$(".sidebar-filter").each(function(index, ele) {
var filterval = $(this).children('a').text();
var filterkey = $(this).data('filter');
filterobj[filterkey] = Array.from(document.querySelectorAll('li[data-filter=' + filterkey + '].active')).map(function(el) {
return ele.value;
});
});
console.log(filterobj);
});
});
<ul>
<li class="sidebar-filter " data-filter="category" data-value="1">
Item Name
</li>
</ul>
My return will be like:
category: Array [ undefined ]
I want value inside the array instead of undefined.
Your lis don't have attribute value, actually you want to read attribute data-value, you can achieve your goal by converting return ele.value; to return el.getAttribute('data-value');
$(document).ready(function() {
$('.sidebar-filter').on('click', function() {
var filterobj = {};
$(".sidebar-filter").each(function(index, ele) {
var filterval = $(this).children('a').text();
var filterkey = $(this).data('filter');
filterobj[filterkey] = Array.from(document.querySelectorAll('li[data-filter=' + filterkey + '].active')).map(function(el) {
return el.getAttribute("data-value");
});
});
console.log(filterobj);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<ul>
<li class="sidebar-filter active" data-filter="category" data-value="1">
Item Name
</li>
</ul>
Posting answer, might be of help to someone others too
filterobj[filterkey]= Array.from(document.querySelectorAll
('li[data-filter=' + filterkey+'].active')).map(function(el){
return $(el).data("value")
});
I am trying to keep an array in a particular order, and I've learned about the splice function to insert in a specific index location, but it doesn't seem to do the right thing.
Here's a fiddle of what I have so far: http://jsfiddle.net/drumichael/7r2pV/277/
In section 1, you can select one or many of the options, however "First" should always be 1st, "second" 2nd, and "Fourth" after both of those. If you only choose "First" & "Fourth", they should be in that order regardless of the order in which you checked the boxes.
In section 2 - you may only choose ONE of Options A, B, & C... and that option should always be in the 3rd position of the array (unless you didn't choose ANY items from Section 1 of course, it would be all by itself inside the array).
Honestly I'm not sure where to go from here. I've tried this:
var array_position = $(this).attr('id');
var messagePart = $(this).attr('data-message');
message.splice(array_position, 0, messagePart);
But they still dont end up in the proper order.
Since the id's are numbered in the order you want, you can sort $('.mycheckbox:checked') by id. Then use the $.each function.
$(".mycheckbox").on("change", function() {
var message = [];
$('.mycheckbox:checked').sort(function(a, b) {
return parseInt(a.id) > parseInt(b.id);
}).each(function() {
var messagePart = $(this).attr('data-message');
message.push(messagePart);
});
$(".summary").html(message.join(", "));
});
DEMO:
http://jsfiddle.net/kom7hd5o/
Resource:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
When using splice() the index the item is inserted to should be 0-indexed. For example:
var arr = [1,2,3,5,6];
arr.splice(3, 0, 4);
will insert 4 into the 3rd 0-indexed location.
Also, you need to use 0 as the 2nd parameter in splice when inserting a value like you want.
To make your code work you should change the id parameter of each input to be 0-indexed, and then use splice() to insert the item.
$(".mycheckbox").on("change", function() {
var message = [];
$('.mycheckbox:checked').each(function() {
var messagePart = $(this).attr('data-message');
message.splice($(this).attr('id'), 0,messagePart);
});
$(".summary").html(message.join(", "));
});
Here's a working example:
$(".mycheckbox").on("change", function() {
var message = [];
$('.mycheckbox:checked').each(function() {
var messagePart = $(this).attr('data-message');
message.splice($(this).attr('id'), 0,messagePart);
});
$(".summary").html(message.join(", "));
});
$("input:checkbox").on('click', function() {
// in the handler, 'this' refers to the box clicked on
var $box = $(this);
if ($box.is(":checked")) {
// the name of the box is retrieved using the .attr() method
// as it is assumed and expected to be immutable
var group = "input:checkbox[name='" + $box.attr("name") + "']";
// the checked state of the group/box on the other hand will change
// and the current value is retrieved using .prop() method
$(group).prop("checked", false);
$box.prop("checked", true);
} else {
$box.prop("checked", false);
}
});
.selection_area {
border: 1px solid gray;
margin-bottom: 10px;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="selection_area">
<h4>Select as many of these options as desired</h4>
<p>Should appear in numerical order</p>
<input type="checkbox" class="mycheckbox" id="1" data-message="Second" />Second
<br/>
<input type="checkbox" class="mycheckbox" id="0" data-message="First" />First
<br/>
<input type="checkbox" class="mycheckbox" id="3" data-message="Fourth" />Fourth
<br/>
</div>
<h5>Summary of Selections:</h5>
<div class="summary"></div>
Here's an updated JSFiddle.
Am struggling hard to bind an array object with list of span values using watcher in Angularjs.
It is partially working, when i input span elements, an array automatically gets created for each span and when I remove any span element -> respective row from the existing array gets deleted and all the other rows gets realigned correctly(without disturbing the value and name).
The problem is when I remove a span element and reenter it using my input text, it is not getting added to my array. So, after removing one span element, and enter any new element - these new values are not getting appended to my array.
DemoCode fiddle link
What am I missing in my code?
How can I get reinserted spans to be appended to the existing array object without disturbing the values of leftover rows (name and values of array)?
Please note that values will get changed any time as per a chart.
This is the code am using:
<script>
function rdCtrl($scope) {
$scope.dataset_v1 = {};
$scope.dataset_wc = {};
$scope.$watch('dataset_wc', function (newVal) {
//alert('columns changed :: ' + JSON.stringify($scope.dataset_wc, null, 2));
$('#status').html(JSON.stringify($scope.dataset_wc));
}, true);
$(function () {
$('#tags input').on('focusout', function () {
var txt = this.value.replace(/[^a-zA-Z0-9\+\-\.\#]/g, ''); // allowed characters
if (txt) {
//alert(txt);
$(this).before('<span class="tag">' + txt.toLowerCase() + '</span>');
var div = $("#tags");
var spans = div.find("span");
spans.each(function (i, elem) { // loop over each spans
$scope.dataset_v1["d" + i] = { // add the key for each object results in "d0, d1..n"
id: i, // gives the id as "0,1,2.....n"
name: $(elem).text(), // push the text of the span in the loop
value: 3
}
});
$("#assign").click();
}
this.value = "";
}).on('keyup', function (e) {
// if: comma,enter (delimit more keyCodes with | pipe)
if (/(188|13)/.test(e.which)) $(this).focusout();
if ($('#tags span').length == 7) {
document.getElementById('inptags').style.display = 'none';
}
});
$('#tags').on('click', '.tag', function () {
var tagrm = this.innerHTML;
sk1 = $scope.dataset_wc;
removeparent(sk1);
filter($scope.dataset_v1, tagrm, 0);
$(this).remove();
document.getElementById('inptags').style.display = 'block';
$("#assign").click();
});
});
$scope.assign = function () {
$scope.dataset_wc = $scope.dataset_v1;
};
function filter(arr, m, i) {
if (i < arr.length) {
if (arr[i].name === m) {
arr.splice(i, 1);
arr.forEach(function (val, index) {
val.id = index
});
return arr
} else {
return filter(arr, m, i + 1)
}
} else {
return m + " not found in array"
}
}
function removeparent(d1)
{
dataset = d1;
d_sk = [];
Object.keys(dataset).forEach(function (key) {
// Get the value from the object
var value = dataset[key].value;
d_sk.push(dataset[key]);
});
$scope.dataset_v1 = d_sk;
}
}
</script>
Am giving another try, checking my luck on SO... I tried using another object to track the data while appending, but found difficult.
You should be using the scope as a way to bridge the full array and the tags. use ng-repeat to show the tags, and use the input model to push it into the main array that's showing the tags. I got it started for you here: http://jsfiddle.net/d5ah88mh/9/
function rdCtrl($scope){
$scope.dataset = [];
$scope.inputVal = "";
$scope.removeData = function(index){
$scope.dataset.splice(index, 1);
redoIndexes($scope.dataset);
}
$scope.addToData = function(){
$scope.dataset.push(
{"id": $scope.dataset.length+1,
"name": $scope.inputVal,
"value": 3}
);
$scope.inputVal = "";
redoIndexes($scope.dataset);
}
function redoIndexes(dataset){
for(i=0; i<dataset.length; i++){
$scope.dataset[i].id = i;
}
}
}
<div ng-app>
<div ng-controller="rdCtrl">
<div id="tags" style="border:none;width:370px;margin-left:300px;">
<span class="tag" style="padding:10px;background-color:#808080;margin-left:10px;margin-right:10px;" ng-repeat="data in dataset" id="4" ng-click="removeData($index)">{{data.name}}</span>
<div>
<input type="text" style="margin-left:-5px;" id="inptags" value="" placeholder="Add ur 5 main categories (enter ,)" ng-model="inputVal" />
<button type="submit" ng-click="addToData()">Submit</button>
<img src="../../../static/app/img/accept.png" ng-click="assign()" id="assign" style="cursor:pointer;display:none" />
</div>
</div>
<div id="status" style="margin-top:100px;"></div>
</div>
</div>
I have a selectable:
<ol id="selectable">
<li class="ui-widget-content">1</li>
<li class="ui-widget-content">2</li>
<li class="ui-widget-content">3</li>
</ol>
I want to capture every selected item body into a hidden input separated by a comma, so after selecting some items it would look for example like this:
<input type="hidden" id="bad_times" name="bad_times" value="1,3" />
where 1,3 are bodies of the items selected. Any examples from the web I tried failed to work. Please note that only selected items have to be captured, if I select some item, then unselect, then select again it should appear only once. How to achieve it?
Following assumes that jQuery UI selectable plugin is being used
If so you can try something like this and build on it
$(function() {
$("#selectable").selectable({
filter: "li" ,
unselected:mapSelected,
selected:mapSelected
});
});
function mapSelected(event,ui){
var $selected = $(this).children('.ui-selected');
var text = $.map($selected, function(el){
return $(el).text()
}).join();
$('#bad_times').val(text)
}
DEMO
What have you tried so far and where were you running into issues?
Based on the docs the selected items have the class 'ui-selected'
So you should just be able to iterate over the selected items something like:
var str = "";
$( ".ui-selected").each(function(i) {
if (i > 0)
str += ",";
str += $(this).text();
});
$('#bad_times').val(str);
I would be in favor of using a data attribute, say, data-value and using an array, [1,3], instead of a list 1,3.
Special Note: The demo and code below simply help to verify the concept and do not use the selectable plugin.
HTML:
<input type="hidden" id="bad_times" name="bad_times" data-value="[]" />
JS:
$(function() {
var hidden = $('#bad_times');
$('#selectable li').on('click', function() {
var val = +$(this).text();
hidden.data()['value'].indexOf(val) > -1 || hidden.data()['value'].push(val);
console.log( hidden.data()['value'] );
});
});
$(function() {
var hidden = $('#bad_times');
$('#selectable li').on('click', function() {
var val = +$(this).text();
hidden.data()['value'].indexOf(val) > -1 || hidden.data()['value'].push(val);
$('pre.out').text( JSON.stringify( hidden.data()['value'] ) );
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ol id="selectable">
<li class="ui-widget-content">1</li>
<li class="ui-widget-content">2</li>
<li class="ui-widget-content">3</li>
</ol>
<input type="hidden" id="bad_times" name="bad_times" data-value="[]" />
<pre class="out"></pre>
I would like to search by any term (name, user, from, price), and display the div into top and hide the ones who doesn't have the typed value.
Here's the jsfiddle: http://jsfiddle.net/Sc9ys/10/
I would like to have the same result as the jquery mobile table filter http://demos.jquerymobile.com/1.4.0/filterable/
Where you can search for any term.
I know that for search for any term I should use $(list).find("li *:)... but I can't figure out how to display the items properly. If you test my jsfiddle it doesn't work very well.
Edit: As asked by the user below, here's some more info.
<ul id='list'>
<li>
<div class='row'>
<div class='middle'>
<ul>
<li><h3>Stackoverflow</h3></li>
<li><span>User</span></li>
<li><span>London</span></li>
</ul>
</div>
<div style='clear: both'></div>
</div>
</li>
</ul>
$("#search").change( function () {
$(list).find("li *:not(:Contains(" + filter + "))").parent().hide();
});
DEMO
The idea is in
$("#ul_container").find("li").filter(function () {//your comparing logic here });
Here, try this out. Honesty I couldn't read thru your code, so I made this example. I added the sub items (spans that contain data to be searched) in an array datalist by their class name.
Generic Search Function.
HTML
<input type="text" id="search" />
<ul id="ul_container">
<li class="listItem">
<span class="car">Honda</span>
<span class="country">Japan</span>
</li>
<li class="listItem">
<span class="car">BMW</span>
<span class="country">Germany</span>
</li>
</ul>
Script:
//Capture user input
$("#search").on("keyup change", function () {
var str = $.trim($(this).val());
if (str) {
search(str);
} else {
// if no input, then show all
$(".listItem").show();
}
});
//the search part.
var datalist = ["car", "country"];
function search(toFind) {
//select all li and loop thru them one by one
$("#ul_container").find("li").filter(function () {
var $li = $(this);//hold current li in a variable
//loop thru all sub spans by their class and check if the toFind keyword is there
// you modify this step, i use it to specify which sub span to be searched. Sometimes I don't want all field to be searched, only the ones I select.
for (var i = 0; i < datalist.length; i++) {
//hold the span in a var called $item
var $item = $li.children("." + datalist[i]);
var content_str = $item.html();//get the actual string
//the comparing code
if (content_str.toLowerCase().indexOf(toFind.toLowerCase()) >= 0) {
$li.show();
break;
} else {
$li.hide();
}
}
});
}
Solved guys. Thank you all.
You can see the following example working at: http://jsfiddle.net/Sc9ys/29/
$('#search').on('keyup change', function(){
var str = $.trim($(this).val());
if (str) {
search(str, $("#list"));
} else {
$("#list").find('li').show();
/* The <li> are display: none, to show them again if the input type is clear,
we must find those <li> and show them. Showing only the #list isn't enough. */
}
});
function search(toFind, list){
$(list).find('li').filter(function() {
$li = $(this);
$li.find(".middle :contains(" + toFind +")").parent().parent().slideDown();
$li.find(".middle").not(":contains(" + toFind + ")").parent().parent().slideUp();
});
}
/* Function to search with the input lowercase */
$.expr[":"].contains = $.expr.createPseudo(function(arg) {
return function( elem ) {
return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
};
});
Edit: Made some adjustments according to the help of user #Joraid.