I want to perform multiple tail select using checkbox than a dropdown , i checked a code ,but i was not able to convert it to checkbox , Can anyone help me .
var projects = tail.select("select.projects", {
deselect: true,
multiContainer: ".projects-selected",
multiple: true,
});
projects.config("multiple", false, true);
projects.on('change', changeFirst);
let tests = tail.select("select.tests", {
multiContainer: ".tests-selected",
disabled: true
});
function getData() {
var size = Math.floor(Math.random() * 6) + 5;
var randomEntry = function() {
var tmp = CryptoJS.MD5(Math.floor(Math.random() * 1000).toString()).toString();
console.log(tmp);
return {
id: 'ID_' + tmp,
name: tmp
};
};
return Array.from({
length: size
}, randomEntry);
}
function changeFirst(opt, event) {
if (event == 'select') {
let data = getData();
let items = {};
data.forEach(function(entry) {
items[entry.id] = entry.name
});
tests.config('items', items);
tests.config('disabled', false);
} else if (event == 'unselect') {
tests.config('disabled', true);
tests.config('items', {});
}
}
<div class="left">
<select class="projects">
<option>Project 1</option>
<option>Project 2</option>
</select>
</div>
<div class="right">
<span class="projects-selected"></span>
<span class="tests-selected"></span>
</div>
i tried editing this code , but am not getting what i wanted , so can anyone help me to sort it out .
Output should be something like this :
so when we click on the span generated it should unselect . , but whatever try to provide checkbox is not working
NOTE :
tail. select is a rewritten version of the jQuery tail. select plugin that can be used to beautify & enhance the default select box with no dependency
https://www.cssscript.com/single-multiple-select-tail/#:~:text=Description%3A,select%20box%20with%20no%20dependency.
I don't know whether this can be done using tail.select , If not possible , can anyone suggest any other way to do this .
Related
I am trying to generate link on the button when multiple Checkbox is clicked based on the value. I have used the below link and it's working fine and I am able to generate link.
Create a dynamic link based on checkbox values
The issue is that when I select the checkbox for the first time it generates a link to /collections/all/blue+green but when I again select/deselect the different value its duplicates and ADDs the values with old Link → to collections/all/blue+green+blue+green
For Live Issue check on mobile View Click on filter on bottom => https://faaya-gifting.myshopify.com/collections/all
$("input[type=checkbox]").on("change", function() {
var arr = []
$(":checkbox").each(function() {
if ($(this).is(":checked")) {
arr.push($(this).val())
}
})
var vals = arr.join(",")
var str = "http://example.com/?subject=Products&checked=" + vals
console.log(str);
if (vals.length > 0) {
$('.link').html($('<a>', {
href: str,
text: str
}));
} else {
$('.link').html('');
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<input type="checkbox" name="selected" value="Blue" class="products"> Blue<br>
<input type="checkbox" name="selected" value="Green" class="products"> Green<br>
<input type="checkbox" name="selected" value="Purple" class="products"> Purple
<br>
<span class="link"></span>
For Live Issue check on mobile View Click on filter on bottom => https://faaya-gifting.myshopify.com/collections/all
I see what's going on now. What's causing the duplicate is actually multiple checkboxes having the checked value.
If you run this code in your console, you should see that you have twice of the item checked as its length:
// Run this in your browser console
$('input[type=checkbox]:checked').length
For example, if I have Wood and Metal checked and clicked Apply, running the code above gives length of 4 instead of just 2. Meaning, you have a duplicate checkbox input for each filter hidden somewhere in your code. I have verified this.
As options, you can:
Try to remove the duplicate checkbox input – Best Option; or
Add class to narrow down your selector to just one of the checkbox input containers.
Here's a screenshare of what's going on: https://www.loom.com/share/2f7880ec3435427a8378050c7bf6a6ea
UPDATED 2020/06/09:
If there's actually no way to modify how your filters are displayed, or add classes to narrow things down, we can opt for an ad hoc solution which is to actually, just remove the duplicates:
// get all your values
var arr = []
$(":checkbox").each(function() {
if ($(this).is(":checked")) {
arr.push($(this).val().toLowerCase())
}
})
// removes duplicates
var set = new Set(arr)
// convert to array and join
var vals = [...set].join(",")
I am bit bad in jquery. Am I doing right?
Should I just add the script which I have written below
$("input[type=checkbox]").on("change", function() {
var arr = []
$(":checkbox").each(function() {
if ($(this).is(":checked")) {
arr.push($(this).val().toLowerCase())
}
})
// removes duplicates
var set = new Set(arr)
// convert to array and join
var vals = [...set].join(",")
var str = "http://example.com/?subject=Products&checked=" + vals
console.log(str);
if (vals.length > 0) {
$('.link').html($('<a>', {
href: str,
text: str
}));
} else {
$('.link').html('');
}
})
Am I right?
Or should I add any values on var set = new Set(arr) or var vals = [...set]
Thank you for you help Algef
I will post the part of a function that is adding numbers that are clicked into selected input field.
So, I need to separate it with a comma (,). I tried some of the examples but it seems not to be working on the function that I wrote.
var rowRange = 'abcdefghijklmnopqrstuvwxyz'.split('');
var $cart = $('#seats'),
$counter = $('#counter'),
sc = $('#seat-map').seatCharts({
map: [
'aaaaa__aaaaa',
'aaaaa__aaaaa'
],
naming : {
top : false,
getLabel : function (character, row, column) {
return rowRange[row - 1].toUpperCase() + column;
},
},
click: function () {
if (this.status() === 'available') {
$('#seats').split(",")
.attr('id', 'cart-item-'+this.settings.id)
.val(this.settings.label)
.appendTo($cart);
$counter.text(sc.find('selected').length+1);
return 'selected';
});
});
Seat is a input field where comma needs to be added after every click on any number.
.split(",")
when I remove this part the code works like it should, but without adding comma.
.split() doesn't work on jquery objects. Instead use it on the values in your select.
Here is an example on how it could work.
$selected = $('#selected');
$(".seat").on("click", function() {
const cur = $selected.val();
const valToInsert = $(this).text();
$selected.val(cur.length === 0 ? valToInsert : cur.split(',').concat(valToInsert).join(','));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="selected">
<button class="seat">a</button>
I'm currently trying to do a survey system. I have a dynamic dropdown that displays one column 'questiontitle' from my table database. Here's my code of displaying the 'questiontitle' in the dropdown.
<?php
$query=mysqli_query($con, "SELECT * FROM question");
while($row=mysqli_fetch_array($query))
{
?>
echo "<option value='$row[question_id]'>";
echo $row["questiontitle"];
echo "</option>";
<?php
}
?>
echo "</select>";
And here's my database table.
My main question is how do I display the 'Option_1 to Option_10 columns' depending on the 'answer_type' column when a data is clicked from the dropdown in real time without refreshing the page? Like if the 'answer_type' is checkbox, it will display the option1-10 as checkbox and if it's radiobutton, it will display the option1-10 as radiobuttons.
There is a lot work to be done to achieve what you want to do. But I can give you a small snippet which you can use to start.
What you still have to do is
Show a page with all questions in the select box. This is done in PHP
checking how ajax works. Expand the showQuestion() function with ajax functionality so your question & answer data is retrieved from the server. this is a good read. When you got your answer, call the appropriate function to display your question and answers. OR store all your information locally...
add a button so that you can send the answers to the server. Listen to the click event and send data (small modifications are required to what I have wrote though) to the server (read the link that I have shown in point 2)
// question object
var questions = {
json1: {
questiontitle: 'How frequently ...',
answertype: 'radiobutton',
options: ['Heavy user', 'serious user', 'regular user', 'light user']
},
json2: {
questiontitle: 'What part of the day...',
answertype: 'checkbox',
options: ['Morning', 'Afternoon', 'Early evening', 'lat evening']
},
json3: {
questiontitle: 'To what extend does the ...',
answertype: 'radiobutton',
options: ['1-5 times', '6-10 times', '> 10 times']
}
};
// function that adds the "questions" input elements to the container
function insertToQuestionBox(els) {
var box = document.getElementById('questionBox');
// cleanup box
while(box.firstChild) box.removeChild(box.firstChild);
// populate with els
for(var i = 0; i < els.length; ++i) box.appendChild(els[i]);
}
// creates the input element based on args
function createInput(type, name, text) {
var i = document.createElement('input');
i.type = type;
i.name = name;
var l = document.createElement('label');
l.textContent = text;
var s = document.createElement('section');
s.appendChild(l);
s.appendChild(i);
return s;
}
// create element with question in it
function createQuestionEl(question) {
var s = document.createElement('span');
s.textContent = question;
return s;
}
// function that is called if the question is of type radio
function handleRadioButtons(data) {
var inputs = [];
inputs.push(createQuestionEl(data.questiontitle));
for(var i = 0; i < data.options.length; ++i) {
inputs.push(createInput('radio', 'rraaddioo', data.options[i]));
}
insertToQuestionBox(inputs);
}
// create checkboxes
function handleCheckboxes(data) {
var inputs = [];
inputs.push(createQuestionEl(data.questiontitle));
for(var i = 0; i < data.options.length; ++i){
inputs.push(createInput('checkbox', 'nana' + i, data.options[i]));
}
insertToQuestionBox(inputs);
}
// gets called each time the drop down has changed
function showQuestion() {
var data = questions[this.value];
switch(data.answertype) {
case 'radiobutton': handleRadioButtons(data); break;
case 'checkbox': handleCheckboxes(data); break;
// todo when default? error ?
}
}
// listen to select changes
document.getElementById('showQuestion').addEventListener('change', showQuestion);
<select id="showQuestion">
<option>please choose</option>
<option value="json1">show json1</option>
<option value="json2">show json2</option>
<option value="json3">show json3</option>
</select>
<div id="questionBox"></div>
On select box change event pass questionid to server side and query your database for answer_type and options and in that method add a condition
$options = '';
if(anwsertype=='radio') {
$options .= <input type="radio" /> Your option
} else {
$options .= <input type="checkbox" />Your option
}
The above condition should be in a loop for each option.
I have an angular page that will have a dynamic number of select elements on it. Each select will have the same option collection but once an option is selected from one, that option should be removed from all of the subsequent select elements.
I found this: http://jsfiddle.net/Zv5NE/63/ which works exactly how I'd like (when an option is selected from one select, it's removed from the others and then if that same select is changed, it adds the previously selected option back to the others).
The problem is, this is using a hard coded number of select elements and also using hard coded filters for each select element...that won't work for my purposes because, as I said, my users are going to need to be able to dynamically add n number of select elements.
I've done some playing around trying to create my own filter to accommodate for this, but I'm super green to angular (angular 1 btw) and I've hit the wall.
this is a small snippet from what I've tried. Essentially I've just tried creating an array and adding selected items to that array then checking against the values in the array for the filter (I would have to add some logic for changing options obviously, but I'm really not sure this is the right direction to go):
$scope.filter = function (item) {
for (i = 0; i < $scope.names.length; i++) {
if (item == $scope.names[i]) {
return false;
}
}
return true;
};
any guidance would be greatly appreciated.
I shelved this for a while but came back to it this morning. I was able to come up with a working solution.
Here's what I wrote up. May not be the most elegant way to do it, but it works for my purposes:
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta name="viewport" content="width=device-width" />
<title>AngularTest</title>
</head>
<body ng-controller="HellowWorldCtrl">
<select ng-model="selectname0" ng-options="item as item.name for item in classes | customFilter:'selectname0':this">
<option value="">- select -</option>
</select>
<div id="selectsDiv"></div>
<br />
<input type="button" value="Add Select" ng-click="addSelect()" ng-show="cnt < classes.length -1" />
<script src="~/Scripts/angular.js"></script>
<script type="text/javascript">
var app = angular.module('app', []).controller('HellowWorldCtrl', function ($scope, $compile) {
$scope.cnt = 0;
$scope.selectsAdded = [];
$scope.selectsAdded.push('selectname0');
$scope.addSelect = function () {
$scope.cnt++;
$scope.selectsAdded.push('selectname' + $scope.cnt);
var newSelect = $compile('<div><select ng-model="selectname' + $scope.cnt + '" ng-options="item as item.name for item in classes | customFilter:\'selectname' + $scope.cnt + '\':this"><option value="">- select -</option></select></div>')($scope);
angular.element(document.getElementById('selectsDiv')).append(newSelect);
};
$scope.classes = [
{
id: 1,
name: 'Biology 101',
courseid: '12345'
},
{
id: 2,
name: 'Chemistry 101',
courseid: '12374'
},
{
id: 3,
name: 'Psychology 101',
courseid: '32165'
},
{
id: 4,
name: 'Geology 101',
courseid: '78945'
},
{
id: 5,
name: 'Math 101',
courseid: '65478'
}
];
});
app.filter('customFilter', function () {
return function (items, which, scope) {
var alreadySelectedCourses = [];
var courses = [];
for (i = 0; i < items.length; i++) { // loop over all of the items in the class array...cwc
for (j = 0; j < scope.selectsAdded.length; j++) { // loop over all of the selects added to the page...cwc
if (which == scope.selectsAdded[j]) { // check if the calling select is the same one in the loop...cwc
if (scope['selectname' + j] && scope['selectname' + j].id) { // check if the calling select has alraedy been selected...cwc
if (scope['selectname' + j].id == items[i].id) { // check if the selected value of the calling select is the same as the item in the iteration and add it to the return array if so...cwc
courses.push(items[i]);
alreadySelectedCourses.push(items[i]);
}
}
} else { // not the calling select so find out the value and don't add it to the return array...cwc
if ((scope['selectname' + j] && scope['selectname' + j].id)) { // other selects (not calling select) have values selected so add them to the alreadyselectedarray...cwc
if (scope['selectname' + j].id == items[i].id) {
alreadySelectedCourses.push(items[i]);
}
}
}
}
if (alreadySelectedCourses.indexOf(items[i]) > -1) {
continue;
} else {
courses.push(items[i]);
}
}
return courses;
}
});
</script>
</body>
</html>
Just to give you a better idea I am making a computer customization page with a bunch of dropdown lists
that display the Part name and have the PartID as the data value. I wish to append all the part name text values for all options excluding the currently selected option with the price difference between the price of this part and the currently selected one.
i.e:
[Intel i7 950] - selected visible option
[Intel i7 960 (+ $85)] - not selected but in the drop down list
[Intel i7 930 (- $55)] - not selected but in the drop down list
I do not have the price, so I would need to retrieve the price for all the option data values (PartID)
and return it as a json collection ({PartID, Price}) key value pairs as the page loads in Ajax call. I would only need to make one Ajax call and use this data for all onchange events for my dropdown list.
Then using Javascript/Jquery, for each option, using its data value (PartID) as key, find its price from the returned Json collection and append to the end of the non selected options text value the difference between its price and the currently selected options price. This will have to run every time (onchange) that a new option is selected.
Using ASP.NET MVC3/Razor
Here's what my dropdown list html looks like, I have about ten such dropdown lists:
<select id="partIdAndCount_0__PartID" name="partIdAndCount[0].PartID">
<option value="">Select processor</option>
<option value="3">Intel Core i7 950</option>
<option value="4">Intel Core i7 930</option>
</select>
Someone has now suggested I take the easier approach and simply add the cost to each option as additional attribute. In my view I have code as follows:
#Html.DropDownList("partIdAndCount[0].PartID", new SelectList(Model.Processor.Products, "ProductID", "Name"), "Select processor" )
I can add additional attributes but only to the select tag and not option?
new { datacost = Model.Processor.Products[0].ListPrice }
I know how to get at the text value of all the options/option and to change it entirely, but not how to append to it or use javascript to use the options data values to find their price in the json collection and then only append to the non selected options text values etc. Also no idea how initially gather all options data values and pass them in an ajax call to my action method that will return the json result.
<script type="text/javascript">
$(document).ready(function () {
var arr = new Array();
$('select option').each(function () {
arr.push($(this).val());
});
$.ajax({
type: "POST",
url: "/Customise/GetPartPrice",
data: { arr: arr },
traditional: true,
success: function (data) { mydata = data; OnSuccess(data) },
dataType: "json"
});
});
$('select').change(function () { OnSuccess(mydata); });
function OnSuccess(data) {
$('select').each(function () {
var sov = parseInt($(this).find('option:selected').attr('value')) || 0; //Selected option value
var sop; //Selected Option Price
for (i = 0; i <= data.length; i++) {
if (data[i].partid == sov) {
sop = data[i].price;
break;
}
};
$(this).find('option').each(function () {
$(this).append('<span></span>');
var uov = parseInt($(this).attr('value')) || 0; //Unselected option value
var uop; //Unselected Option Price
for (d = 0; d <= data.length; d++) {
if (data[d].partid == uov) {
uop = data[d].price;
break;
}
}
var newtext = uop - sop;
var text = $(this).attr("text");
$(this).find('span').html(newtext);
});
});
};
//$(document).ready(function () { $("#partIdAndCount_0__PartID").prepend('<option value="0">Select Processor<option>'); });
</script>
Maybe it would be easier if you just included the price of each item in the option (inside of a data-cost attribute, or whatever), like this (just guessing on the prices):
<select id="partIdAndCount_0__PartID" name="partIdAndCount[0].PartID">
<option value="">Select processor</option>
<option data-cost="210" value="5">Intel Core i7 930</option>
<option data-cost="250" value="3">Intel Core i7 950</option>
<option data-cost="280" value="4">Intel Core i7 960</option>
</select>
Then use this script to update the options instead of needing to make numerous calls to your server to get more json data. Here is a demo.
$('select')
.find('option').each(function() {
// add spans to the option, done here because it doesn't
// seem to work if you include the span in the markup
$(this).append(' <span></span>');
}).end()
.change(function() {
var v, diff,
// get cost of selected option
sel = parseFloat($(this).find('option:selected').attr('data-cost'), 10) || 0;
// Add cost difference to option
$(this).find('option[data-cost]').each(function() {
v = parseFloat($(this).attr('data-cost'), 10);
diff = '(' + (sel > v ? '-' : '+') + ' $' + Math.abs(sel - v) + ')';
if (sel === v) {
diff = '';
}
$(this).find('span').html(diff);
});
})
// show values on init
.trigger('change');