I'd like to embed radio buttons inside more radio buttons, like this : https://jsfiddle.net/xa6ow1jq/
The fiddle behaves exactly like I want it to, however it seems to be a lot of code just for a 2x3 grid, and I'm planning to have at least a 3xN grid (3 layers of N buttons each, N being at least 10, but many more if the user keeps scrolling)... So I was wondering if anyone knew/could think of more efficient ways to do this. (Using php and/or javascript and/or jquery and/or jquery UI)
(I'm a javascript & jquery noob, currently (self) learning it since yesterday, so I'd appreciate if you could be gentle with technical terms and give as much explications as possible).
Thanks in advance.
The javascript code in the fiddle :
// main buttons
$(document).ready(function(){
$(".ap").click(function(){
$(".a").toggle();
$(".b").hide();
$(".c").hide();
$(".a.l").hide();
});
});
$(document).ready(function(){
$(".bp").click(function(){
$(".a").hide();
$(".b").toggle();
$(".c").hide();
$(".b.l").hide();
});
});
$(document).ready(function(){
$(".cp").click(function(){
$(".a").hide();
$(".b").hide();
$(".c").toggle();
$(".c.l").hide();
});
});
//secondary buttons
//a
$(document).ready(function(){
$(".a1").click(function(){
$(".a1.l").toggle();
$(".a2.l").hide();
$(".a3.l").hide();
});
});
$(document).ready(function(){
$(".a2").click(function(){
$(".a1.l").hide();
$(".a2.l").toggle();
$(".a3.l").hide();
});
});
$(document).ready(function(){
$(".a3").click(function(){
$(".a1.l").hide();
$(".a2.l").hide();
$(".a3.l").toggle();
});
});
//b
$(document).ready(function(){
$(".b1").click(function(){
$(".b1.l").toggle();
$(".b2.l").hide();
$(".b3.l").hide();
});
});
$(document).ready(function(){
$(".b2").click(function(){
$(".b1.l").hide();
$(".b2.l").toggle();
$(".b3.l").hide();
});
});
$(document).ready(function(){
$(".b3").click(function(){
$(".b1.l").hide();
$(".b2.l").hide();
$(".b3.l").toggle();
});
});
//c
$(document).ready(function(){
$(".c1").click(function(){
$(".c1.l").toggle();
$(".c2.l").hide();
$(".c3.l").hide();
});
});
$(document).ready(function(){
$(".c2").click(function(){
$(".c1.l").hide();
$(".c2.l").toggle();
$(".c3.l").hide();
});
});
$(document).ready(function(){
$(".c3").click(function(){
$(".c1.l").hide();
$(".c2.l").hide();
$(".c3.l").toggle();
});
});
Make formation of your html below, so you can deal with 3xN rows, you need to pop into array shown in javascript as // here and your HTML accordingly to achieve,
$(document).ready(function() {
var groups = ['a', 'b', 'c'];
// creating simple js array too use for DOM manipulation
$.each(groups, function(k, id) {
// loops groups array we just created id variable contains a, b and then c
$('#' + id).hide();
// will evaluate as $('#a').hide();
$('#' + id + 'l').hide();
// will evaluate as $('#al').hide();
});
$(".button").click(function() {
// bind click event on DOM items having class name as 'button'
var button_id = $(this).data('id');
/* $(this) will get us which button has been clicked, every
time click event occurs on DOM items having button class
and $(this).data(id); will get us clicked button's data-id attribute */
$('#' + button_id).toggle(); // toogle
var hide = $.grep(groups, function(value) {
// http://api.jquery.com/jquery.grep/
return value != button_id;
});
$.each(hide, function(k, id) {
// http://api.jquery.com/each/
$('#' + id).hide();
});
});
var selector = []; // initialize blank array
$.each(groups, function(k) {
selector.push('.' + groups[k]);
/* push groups array's elements with an extra .
so, .a .b and .c */
});
// join array elements with ,
selector = selector.join(',');
// now selector is string, having value .a,.b,.c
// https://api.jquery.com/category/selectors/
$(selector).click(function() {
// binding an event to the string we just created, follow the link above to get more idea
var button_id = $(this).data('id'); // clicked button's data-id attribute
var class_id = $(this).attr('class'); // clicked button's class
var flag = $('.' + class_id + 'l').filter('[data-id="' + button_id + '"]').is(':visible');
/* for later use, will be true if elements with matched filter conditions is visible in DOM,
false otherwise */
$.each(groups, function(k, id) {
$('#' + id + 'l').children().hide();
// https://api.jquery.com/children/
});
$.each(groups, function(k, id) {
$('#' + id + 'l').hide();
});
$('#' + class_id + 'l').show();
if (flag)
$('.' + class_id + 'l').filter('[data-id="' + button_id + '"]').hide();
else
$('.' + class_id + 'l').filter('[data-id="' + button_id + '"]').show();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="button" data-id="a">Toggle a</button>
<button class="button" data-id="b">Toggle b</button>
<button class="button" data-id="c">Toggle c</button>
<div id="a">
<div class="a" data-id="1"><button>Toggle a1</button></div>
<div class="a" data-id="2"><button>Toggle a2</button></div>
<div class="a" data-id="3"><button>Toggle a3</button></div>
</div>
<div id="b">
<div class="b" data-id="1"><button>Toggle b1</button></div>
<div class="b" data-id="2"><button>Toggle b2</button></div>
<div class="b" data-id="3"><button>Toggle b3</button></div>
</div>
<div id="c">
<div class="c" data-id="1"><button>Toggle c1</button></div>
<div class="c" data-id="2"><button>Toggle c2</button></div>
<div class="c" data-id="3"><button>Toggle c3</button></div>
</div>
<div id="al">
<div class="al" data-id="1">this is line a1</div>
<div class="al" data-id="2">this is line a2</div>
<div class="al" data-id="3">this is line a3</div>
</div>
<div id="bl">
<div class="bl" data-id="1">this is line b1</div>
<div class="bl" data-id="2">this is line b2</div>
<div class="bl" data-id="3">this is line b3</div>
</div>
<div id="cl">
<div class="cl" data-id="1">this is line c1</div>
<div class="cl" data-id="2">this is line c2</div>
<div class="cl" data-id="3">this is line c3</div>
</div>
Related
I need some help.. the idea behind this is like a simple toggle button that can hide the object and replacing the empty area with ****.
I was thinking it was more like in a Password form input where you can hide password by clicking the Eye icon. However, I needed something that are not required input form, something that is just simple DIV
function toggler(divId) {
$("#" + divId).toggle();
.css('content', 'sadas');
}
.hidden {
display:none;
}
this is a test
<div id="myContent" class='hidden'>
<div>this is a test #1 </div>
</div>
I can hide the DIV but leaving the empty area, how can I replace this empty area with ***** ??
example:
My balance is $200 [hide]
My balance is **** [show]
https://jsfiddle.net/qobgfLh6/
I have written a fiddle.
There are some points that can be better managed.
But I think you are looking for something like that.
The idea is to add another div with the **** placeholder and use toggleClass() function of jQuery.
$("#" + divId).toggleClass('hidden');
$("#myPlaceholder").toggleClass('hidden');
https://jsfiddle.net/qze8fydv/
Try to use something like this.
$(document).ready(function () {
function handle(input, toggler) {
var inputValue = ""
var shouldShowAsterisks = false
input.change(function () {
inputValue = $(this).val()
})
toggler.click(function () {
shouldShowAsterisks = !shouldShowAsterisks
shouldShowAsterisks
? input.val("*".repeat(inputValue.length))
: input.val(inputValue)
input.prop("disabled", shouldShowAsterisks)
})
}
handle($(".enter"), $(".toggler"))
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" class="enter" />
<button class="toggler">Hide</button>
function toggleElementMask(element){
//Regex to find *
let reg = /^\*+$/g;
//If all * we are masked
let isMasked = element.innerText.match(reg);
if(!isMasked) {
//Store the original text
element.dataset.original = element.innerText;
//Replace the contente with the same amount of *
element.innerText = "*".repeat(element.innerText.length);
}else{
//Restore the text
element.innerText = element.dataset.original;
}
}
//Mask on page load
$(".masked").each(function(){
toggleElementMask(this);
});
//Click event handler
$(".toggleMask").on("click", function(e){
e.preventDefault();
toggleElementMask($($(this).attr("href"))[0]);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
this is a test
<div id="myContent" class='masked'>
<div>this is a test #1 </div>
</div>
this is a test
<div id="myContent2" class='masked'>
<div>Another one</div>
</div>
this is a test
<div id="myContent3" class='masked'>
<div>one with <span>a</span> span</div>
</div>
I have a tree of div elements with the same class but different id as we can see below:
<div class="resultsAnalitics" id="result_0">
<span class="successResults">Success</span>
</div>
<div class="resultsAnalitics" id="result_1">
<span class="warningResults">Warning</span>
</div>
<div class="resultsAnalitics" id="result_2">
<span class="dangerResults">Danger</span>
</div>
I have to check which class exists in each of these divs and show on the console. For this I created the following code:
$( ".resultsAnalitics" ).each(function( index ) {
var current = $(this).attr('id');
console.log("I'm on div: " + current);
if($(this).has('.successResults')){
console.log('The results is success');
}
if($(this).has('.warningResults')){
console.log('The results is warning');
}
if($(this).has('.dangerResults')){
console.log('The results is danger');
}
});
I expected to get the following results like this:
I'm on div: result_0 The results is success
I'm on div: result_1 The results is warning
I'm on div: result_2 The results is danger
But I'm getting the following results:
I'm on div: result_0 The results is success The results is warning The
results is danger
I'm on div: result_1 The results is success The results is warning The
results is danger
I'm on div: result_2 The results is success The results is warning The
results is danger
How I can solve this problem?
One efficiency solution is to use .children method, because you have to check if span children of each div has one certain class.
children method gets the children of each element in the set of matched elements, optionally filtered by a selector.
$( ".resultsAnalitics" ).each(function( ) {
var current = $(this).attr('id');
console.log("I'm on div: " + current);
if($(this).children('.successResults').length){
console.log('The results is success');
}
if($(this).children('.warningResults').length){
console.log('The results is warning');
}
if($(this).children('.dangerResults').length){
console.log('The results is danger');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="resultsAnalitics" id="result_0">
<span class="successResults">Success</span>
</div>
<div class="resultsAnalitics" id="result_1">
<span class="warningResults">Warning</span>
</div>
<div class="resultsAnalitics" id="result_2">
<span class="dangerResults">Danger</span>
</div>
You were close.
The problem is that the .has() method will still return a jQuery object even if an element isn't selected. As the relevant jQuery documentation states, the .has() method will "reduce the set of matched elements to those that have a descendant that matches the selector or DOM element".
This means that your conditional statements were always true, which is why the message was logged regardless of whether any elements were found.
To check if any elements are returned from the jQuery object, check the .length property of the jQuery object in your conditional statements. In doing so, the value will be 0 when an element isn't found.
Your updated code would be:
$(".resultsAnalitics").each(function(index) {
console.log("I'm on div: " + this.id);
if ($(this).has('.successResults').length) {
console.log('The results is success');
}
if ($(this).has('.warningResults').length) {
console.log('The results is warning');
}
if ($(this).has('.dangerResults').length) {
console.log('The results is danger');
}
});
You could go the other way and target each of the classes specifically and then find the id of the parent container. Notethat I added another success div at the bottom to demonstrate that all success divs give the parent ID and then the warning and then the danger.
$(".successResults" ).each(function(){
var parent = $(this).parent().attr('id');
console.log("I'm on div: " + parent + ' - The results is success');
});
$(".warningResults" ).each(function(){
var parent = $(this).parent().attr('id');
console.log("I'm on div: " + parent + ' - The results is warning');
});
$(".dangerResults" ).each(function(){
var parent = $(this).parent().attr('id');
console.log("I'm on div: " + parent + ' - The results is danger');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="resultsAnalitics" id="result_0">
<span class="successResults">Success</span>
</div>
<div class="resultsAnalitics" id="result_1">
<span class="warningResults">Warning</span>
</div>
<div class="resultsAnalitics" id="result_2">
<span class="dangerResults">Danger</span>
</div>
<div class="resultsAnalitics" id="result_3">
<span class="successResults">Success</span>
</div>
You could use .find() (checking length of search result) and use loop to make it more elegant and elastic for further changes.
http://codepen.io/themeler/pen/mRgKLP
$( ".resultsAnalitics" ).each(function( index ) {
var $this = $(this),
current = $this.attr('id'),
states = [
{
name: '.successResults',
msg: 'The results is success'
},
{
name: '.warningResults',
msg: 'The results is warning'
},
{
name: '.dangerResults',
msg: 'The results is danger'
}
];
for (var i = 0; i < states.length; i++) {
if ($this.find(states[i].name).length) console.log("I'm on div: " + current, states[i].msg)
}
});
// Grabs all classes that end with Results within resultsAnalitics
var results = $(".resultsAnalitics span[class$='Results']");
// loop through each, grabbing parent id and innerHTML
results.each(function(idx, node) {
console.log("I'm on div:", node.parentNode.id, "- Result are:", node.innerHTML);
})
You can always use jQuery "find" method to check out for specific elements in a particular element.It returns jQuery object. Using this object we can further check for number of elements by using 'length'.
<div class="resultsAnalitics" id="result_0">
<span class="successResults">Success</span>
</div>
<div class="resultsAnalitics" id="result_1">
<span class="warningResults">Warning</span>
</div>
<div class="resultsAnalitics" id="result_2">
<span class="dangerResults">Danger</span>
</div>
<script>
$( ".resultsAnalitics" ).each(function( index ) {
var current = $(this).attr('id');
console.log("I'm on div: " + current);
if($(this).find('.successResults').length){
console.log('The results is success');
}
if($(this).find('.warningResults').length){
console.log('The results is warning');
}
if($(this).find('.dangerResults').length){
console.log('The results is danger');
}
});
</script>
I'm trying to sort a list of divs with the properties shown by particular attributes (gender, level, name etc) using the following script:
html:
<div id="sortThis" class="col-xs-12 alert-container">
<div id="1" class="container-element sortable box box-blue" data-gender="1" data-level="4" data-name="AAA"> <h3>AAA</h3><div class="panel-body">AAA is resp</div>
</div>
<div id="2" class="container-element sortable box box-pink" data-gender="2" data-level="3" data-name="DDD"><h3>DDD</h3><div class="panel-body">DDD is a s</div>
</div>
<div id="3" class="container-element sortable box box-blue" data-gender="1" data-level="2" data-name="FFF"><h3>FFF</h3><div class="panel-body">FFF has mad</div>
</div>
<div id="4" class="container-element sortable box box-pink" data-gender="2" data-level="4" data-name="CCC"><h3>CCC</h3><div class="panel-body">CCC has ma</div>
</div>
<div id="5" class="container-element sortable box box-pink" data-gender="2" data-level="2" data-name=EEE><h3>EEE</h3><div class="panel-body">EEE is a f</div>
</div>
<div id="6" class="container-element sortable box box-blue" data-gender="1" data-level="3" data-name="BBB"><h3>BBB</h3><div class="panel-body">BBB is an ou</div>
</div>
</div>
<button id="sLevel" class="LbtnSort">Sort by Level</button><br/>
<button id="sGender" class="GbtnSort">Sort by Gender</button><br/>
js:
var LdivList = $(".box");
LdivList.sort(function(a, b){
return $(a).data("level")-$(b).data("level")
});
var GdivList = $(".box");
GdivList.sort(function(a, b){
return $(a).data("gender")-$(b).data("gender")
});
/* sort on button click */
$("button.LbtnSort").click(function() {
$("#sortThis").html(LdivList);
});
/* sort on button click */
$("button.GbtnSort").click(function() {
$("#sortThis").html(GdivList);
});
when the .sortable divs are static, the sort works fine, as this jfiddle shows, however if the contents of the #sortable div (i.e. .sortable divs) are dynamically generated (in this case as the result of a form submit), when the sort button is pressed, the entire contents of the #sortable div disappears, and I can't seem to get it to work.
Any help or suggestions would be appreciated.
edit: The code for dynamic generation of the list is as follows - effectively it's an AXAX form submit that pulls data from a sorted list of items and outputs them.
$('#formStep2').submit(function(event) {
// get the form data
var studentArray = [];
$(".listbox li").each(function() {
studentArray.push({
'name': ($(this).text()),
'gender': ($(this).closest('ol').attr('id')).substr(0, 1),
'level': ($(this).closest('ol').attr('id')).substr(2, 3),
'topic': ($('input[name=topic]').val())
})
});
var studentString = JSON.stringify(studentArray);
console.log(studentString);
var formData = {
'students': studentString,
};
// process the form
$.ajax({
type: 'POST', // define the type of HTTP verb we want to use (POST for our form)
url: 'process_step2.php', // the url where we want to POST
data: formData, // our data object
dataType: 'json', // what type of data do we expect back from the server
encode: true
})
// using the done promise callback
.done(function(data) {
if (!data.success) {
// error handling to go here.....
} else {
$('.alert-container').empty();
var obj = JSON.parse(data.message);
//sort the array alphabetically by name (default status)
var test = obj.sort(function(a,b){
var lccomp = a.name.toLowerCase().localeCompare(b.name.toLowerCase());
return lccomp ? lccomp : a.name > b.name ? 1 : a.name < b.name ? -1 : 0;
});
console.log(test);
var i=0;
test.forEach(function(st) {
console.log(st['name']);
var gen = (st['gender'] == 1) ? "blue" : (st['gender'] == 2) ? "pink" : NULL;
$('.alert-container').append('<div id="' + (i+1) + '" class="container-element sortable box box-' + gen + '" data-gender="' + st['gender'] + '" data-level="' + st['level'] + '" data-name="' + st['name'] + '"><h3>' + st['name'] + '</h3><div class="panel-body"><div class="col-xs-9"><i class="fa fa-quote-left fa-3x fa-pull-left fa-' + gen + '" aria-hidden=:true"></i>' + st['comment'] + '</div></div></div>');
i++;
});
// jump to the next tab
var $active = $('.wizard .nav-tabs li.active');
$active.next().removeClass('disabled');
nextTab($active);
}
})
// using the fail promise callback
.fail(function(data) {
// show any errors
// best to remove for production
console.log(data);
});
// stop the form from submitting the normal way and refreshing the page
event.preventDefault();
});
You are defining LdivList and GdivList inline with your code so they are defined on DOM ready. You have to wrap the definition of those inside a function and call it on click:
$(document).ready(function(){
$("button.LbtnSort").click(function() {
$("#sortThis").html(GenerateLdivList);
});
/* sort on button click */
$("button.GbtnSort").click(function() {
$("#sortThis").html(GenerateGdivList());
});
});
function GenerateLdivList(){
var LdivList = $(".box");
LdivList.sort(function(a, b){
return $(a).data("level")-$(b).data("level")
});
}
function GenerateGdivList(){
var GdivList = $(".box");
GdivList.sort(function(a, b){
return $(a).data("gender")-$(b).data("gender")
});
}
As #theduke said, the lists are probably empty at the time you sort them. Here's a simple change that will read and sort the lists when you click the buttons instead. (Not tested.)
var LdivList = function () {
return $(".box").sort(function(a, b){
return $(a).data("level")-$(b).data("level")
});
};
var GdivList = function () {
return $(".box").sort(function(a, b){
return $(a).data("gender")-$(b).data("gender")
});
};
/* sort on button click */
$("button.LbtnSort").click(function() {
$("#sortThis").html(LdivList());
});
/* sort on button click */
$("button.GbtnSort").click(function() {
$("#sortThis").html(GdivList());
});
i have one question about jquery on click.
This is DEMO from jsfiddle.net
When you click the demo you can see there is a green and yellwo div.
The question is when you click the data-id="1" and change this div class:
<div class="icon-kr icon-globe"></div>
change icon-globe to icon-contacs
and when you click data-id="2" then change:
change icon-globe to icon-lock-1
also same think is for data-id="0"
How can i do that anyone can help me in this regard ?
HTML
<div class="container" id="1">
<div class="icon_ar"><div class="icon-kr icon-globe"></div>1</div>
<div class="pr_type">
<div class="type_s change_pri" data-id="0"><div class="icon-pr icon-globe"></div>1</div>
<div class="type_s change_pri" data-id="1"><div class="icon-pr icon-contacs"></div>2</div>
<div class="type_s change_pri" data-id="2"><div class="icon-pr icon-lock-1"></div>3</div>
</div>
</div>
JS
$('.change_pri').click(function(){
var dataid = $(this).attr('data-id');
var id = $(this).closest('.container').attr('id');
$.ajax({
type: "POST",
url: "chage_number.php",
data: { dataid : dataid, id: id }
}).success(function(result){
alert(result);
});
});
One way to do this is below. I have only done the class changing bit based on click. I am not sure about your ajax code. Let me know if you need further help.
$('.change_pri').click(function(){
var class_name = $(this).find(".icon-pr").attr("class");
class_name = class_name.replace(/icon\-pr\s+/gi, "");
$(this).closest(".container").find(".icon-kr")
.removeClass().addClass("icon-kr " + class_name);
});
Updated fiddle
You need to use .data(), you are not accessing the data correctly.
https://api.jquery.com/jquery.data/
var dataid = $(this).data('id');
You are accessing this data-* attribute incorrectly,
Use this,
$('.change_pri').click(function(){
var dataid = $(this).data('id');
$(this).parent().siblings('.icon_ar').find('div').removeClass("icon-globe icon-contacs icon-lock-1");
if(dataid=="0")
{
$(this).parent().siblings('.icon_ar').find('div').addClass("icon-globe");
}
else if(dataid==1)
{
$(this).parent().siblings('.icon_ar').find('div').addClass("icon-contacs");
}
else
{
$(this).parent().siblings('.icon_ar').find('div').addClass("icon-lock-1");
}
//AJAX CODE.
});
I am trying to make a page where the user selects an item in a drop-down list, which then will create a duplicate drop-down list. The last drop-down list always needs to create a new one once an item is selected.
Using the following javascript code
<script type="text/javascript">
$(document).ready(function () {
$(function listselect() {
if (x == null) {
var x = 1;
}
//need to increment x after the completion of the following funciton so the function will trigger on different drop-down lists
$('#FooId' + x).change(function q() {
$('#FooId' + x).clone().attr('id', 'FooId' + (++x)).attr('name', 'Selected').insertAfter('#FooId' + (x - 1))
//return x;
});
//return x;
});
});
</script>
and the razor html
<div class ="container">
<div class="label">
#Html.LabelFor(Function(model) model.Foo, "Foo")
</div>
<div class="foo" id="foo">
#Html.DropDownList("FooId", Nothing, "--Select--", New With {.Name = "Selected", .Id = "FooId" & "1"})
//#*#Html.ValidationMessageFor(Function(model) model.Foo)*#
</div>
</div>
I am able to make the first list clone itself, but how do you return x from function q so that it can be used by its own function (Function q needs to trigger when an item is selected in Foo1, then Foo2, etc.).
(Sorry if this doesn't make sense, I am not sure how to word it. I am very new to coding). Thanks.
If I got you right, you don't need most of your code. And it's easier to use classes here. Just do it like this:
$(document).ready(function () {
$('.foo').on('change', function(e) {
var newFoo = $(e.target).clone();
$(e.target).after(newFoo);
});
});
And your markup part should be like this:
<div class ="container">
<div class="label">
#Html.LabelFor(Function(model) model.Foo, "Foo")
</div>
<div class="foo" id="foo">
#Html.DropDownList("FooId", Nothing, "--Select--", new {name = "Selected", #class = "foo" })
</div>
</div>
I don't remember Html.DropDownList signature so I created simple jsfiddle without it. I hope this is what you needed.
UPDATE:
I've corrected my fiddle as follows:
$(document).on('change', '.foo:last', function(e) {
var newFoo = $(e.target).clone();
$(e.target).after(newFoo);
});
Now it doesn't add extra selects if it's not the last select that was changed.