Dynamic jQuery AppendTo Selector - javascript

I have an HTML page that is adding a toolbar to an item. That page is using some static IDs to make this happen. The most important line of code looks like this:
$('#tb').appendTo('.item-toolbar');
The above works as expected for a single item. But now, I'm trying to make this so that it work with multiple items. In an attempt to do this, I've created this fiddle. The most important code looks like this:
function moveNugget() {
var selected = $('#selector').val();
var tb = $('#tb');
var items = $('.item-container');
// The following line is the one that is giving me problems.
//.appendTo('.item-toolbar');
}
If you visit the Fiddle, it will be more clear. Basically, a user can choose 1, 2, or 3 from a drop down. Once selected, the tool bar should be "appended to" the corresponding item-toolbar. My challenge is, I can't figure out how to create the selector to a dynamically selected item and use the appendTo function.
I really want to use the appendTo because my actual code is more complicated. I've tried to strip it down to the part that is giving me the issue. It's clearly my approach to using appendTo. Right now, I'm trying:
$(tb).appendTo('.item-toolbar');
However, this approach completely disregards the selected item. I'm not sure how to use the selected items toolbar within the context of appendTo.

One of the variant of realization:
Add unique ids on each item-toolbar (For example view-0, view-1, view-2)
It will look like this:
<select id="selector">
<option value="0">1</option>
<option value="1">2</option>
<option value="2">3</option>
</select>
<button onclick="moveNugget();">
Move
</button>
<br /><br />
<div class="view">
<div class="item-container">
<div class="item-title">
[title]
</div>
<div id="view-0" class="item-toolbar">
[tb]
</div>
</div>
</div>
<br />
<hr />
<br />
<div class="view">
<div class="item-container">
<div class="item-title">
[title]
</div>
<div id="view-1" class="item-toolbar">
[tb]
</div>
</div>
</div>
<br />
<hr />
<br />
<div class="view">
<div class="item-container">
<div class="item-title">
[title]
</div>
<div id="view-2" class="item-toolbar">
[tb]
</div>
</div>
</div>
<br /><br /><br />
<ul id="tb" style="list-style-type: none;">
<li>[1]</li>
<li>[2]</li>
<li>[3]</li>
</ul>
Then when you click on button you can append your toolbar to appropriate block
Here is changed function code:
function moveNugget() {
var selected = $('#selector').val();
var tb = $('#tb');
var items = $('.item-container');
// Add toolbar to appropriate block
tb.appendTo('#view-' + selected);
}
Fiddle

Try:
function moveNugget() {
var selected = $('#selector').val();
var tb = $('#tb');
var items = $('.item-container .item-toolbar')[selected];
// The following line is the one that is giving me problems.
tb.appendTo(items);
}

Related

Add a Like + Sort Function to existing dynamic funcion

I wrote a function that dynamically creates a webpage for me based on a json database.
Now I want to add 2 functions:
If you click the like img (its got the id button) the like counter should increase on the webpage by 1. Pretty easy just a on(click) with jQuery variable++ and then .text(variable)
A sort function - based on the likes one item received, you should be able to sort it (most liked div first, 2nd, 3rd....
I can write it for each individually with individual variables when I give all the like buttons and outputs a separate id but I wanted to make it dynamic so if you add new data to json file it dynamically works with the like and sort function.
The likes are not saved anywhere for now.
Since sitting on it for 3h and google so much and so much stackoverflow I think I overloaded my brain with different stuff and now nothing seems to work ^^
function filmInsert(insert) {
$.each(film, function(i, data) { //.each statt loop
let box =
`<div class="boxwrapper">
<div class="imgbox">
<img src="${data.img}" alt="${data.titel}">
</div>
<div class="textbox">
<h3>${data.titel}</h3>
<p>${data.beschreibung}</p>
<p> <a id="button${data.id}">
<img src="img/budspencer_official.png"> Like
</a>
<span class="output${data.id}">${data.likes}</span>
</p>
</div>
</div>`;
insert.append(box);
});
}
I've added a container element for the boxwrapper items as I assume you have one and as it's better to have one instead of just adding the sorted items to the body of the HTML document.
$(document).on("click", ".textbox a", function() {
let likes = parseInt($(this).closest(".textbox").find("span").text());
$(this).closest(".textbox").find("span").text(likes + 1);
});
$("#sort").on("click", function() {
let divs = $(".boxwrapper")
let sorted = divs.sort(function(a, b) {
return $(a).find("span").text() < $(b).find("span").text() ? 1 : -1;
});
$(".container").html(sorted);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="boxwrapper">
<div class="imgbox">
<img src="example.gif" alt="Title">
</div>
<div class="textbox">
<h3>Titel</h3>
<p>Description</p>
<p> <a id="button1">
<img src="https://dummyimage.com/40x40/000/fff&text=1"> Like
</a>
<span class="output1">0</span>
</p>
</div>
</div>
<div class="boxwrapper">
<div class="imgbox">
<img src="example.gif" alt="Title">
</div>
<div class="textbox">
<h3>Titel 2</h3>
<p>Description 2</p>
<p> <a id="button2">
<img src="https://dummyimage.com/40x40/000/fff&text=2"> Like
</a>
<span class="output2">0</span>
</p>
</div>
</div>
</div>
<button id="sort">
Sort
</button>

How to show element only if other element contains something using jQuery?

My guess is what I want to achieve should be easy, but due to my lack of knowledge of front-end development, I cannot manage to solve issue. Have a page that works with AJAX-filters that users can select. Filters that are currently applied show up within <div> with id=current-filters.
HTML looks like this:
<div id="current-filters-box">
<div style="margin-bottom: 15px">
<strong>Current filters:</strong>
<div id="current-filters">
<!-- here every single applied filter is displayed -->
</div>
</div>
</div>
Need to hide the the entire DIV current-filters-box in case no filter is applied.
The page uses a Javascript file, bundle.js which is massive, but contains the following line:
s=document.getElementById("current-filters")
Therefore tried the following if-statement to hide the DIV:
if(s.length<1)$('#current-filters-box').hide()
and
if(s=0)$('#current-filters-box').hide()
But this does not seem to have any effect. Can someone tell, what I did wrong?
Demo of page can be found here
EDIT: this is what the HTML looks like when filters are applied:
<div id="current-filters-box">
<div style="margin-bottom: 15px">
<strong>Current filters:</strong>
<div id="current-filters">
<div class="badge-search-public">
<strong>Humanities & Languages</strong> <span class="x" data-property="disciplines" data-value="4" onclick="filter.removeFilter(this)">×</span>
</div>
<div class="badge-search-public">
<strong>January</strong> <span class="x" data-property="months" data-value="1" onclick="filter.removeFilter(this)">×</span>
</div>
</div>
</div>
Both of your conditions are incorrect or I would say they are not doing what you think they do.
s.length will always prints undefined so instead of s.length<1 you could use s.children.length
and the second one is not a condition rather it is an assignment
s==0 // condition
s=0 //assignment
the correct condition for your requirement would be
if(s.children.length<1){
I have assigned snippets for illustration.
Without filters
s = document.getElementById("current-filters")
console.log(s.children.length);
if (s.children.length < 1) {
$('#current-filters-box').hide(1000)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="current-filters-box">
filter box
<div style="margin-bottom: 15px">
<strong>Current filters:</strong>
<div id="current-filters">
<!-- here every single applied filter is displayed -->
</div>
</div>
</div>
Without filters
s = document.getElementById("current-filters")
console.log(s.children.length);
if (s.children.length < 1) {
$('#current-filters-box').hide(1000)
}
<div id="current-filters-box">
<div style="margin-bottom: 15px">
<strong>Current filters:</strong>
<div id="current-filters">
<div class="badge-search-public">
<strong>Humanities & Languages</strong> <span class="x" data-property="disciplines" data-value="4" onclick="filter.removeFilter(this)">×</span>
</div>
<div class="badge-search-public">
<strong>January</strong> <span class="x" data-property="months" data-value="1" onclick="filter.removeFilter(this)">×</span>
</div>
</div>
</div>
Try this .
if( $('#current-filters').is(':empty') ) {
$('#current-filters-box').hide()// or $('#current-filters-box').css("display","none")
}
You are performing an assignment, try..
if (s.children.length)
Using vanilla JavaScript, you can check if the current-filters div is empty or not and toggle the parent div current-filters-box like this:
s= document.getElementById("current-filters");
t= document.getElementById("current-filters-box");
if(s.children.length<1) {
t.style.display = 'none';
// t.style.visibility= 'hidden'; <<-- use this if you want the div to be hidden but maintain space
}
else {
t.style.display = 'block';
// t.style.visibility= 'visible'; <<-- use this if you used visibility in the if statement above
}
You can achieve this by adding your own variable which counts or maintains your applied filters, e.g.
var applied_filter_count = 0;
at every time filter is applied
applied_filter_count++;
if(applied_filter_count) {
$('#current-filters-box').show()
}
and at every time filter is removed
applied_filter_count--;
if(!applied_filter_count) {
$('#current-filters-box').hide()
}
and by default current-filters-box should be display:none

Using AngularJS to show divs based on select value

I'm trying to use an HTML select element's value to show or hide certain div tags with AngularJS. Here is my code:
<body ng-app="kiosk" id="ng-app" >
<div class="page" ng-controller="kiosk-controller" ng-cloak="true">
<section class="signin">
<div class="intro">
<h1 id="service-desk-name">{{servicedeskname}}</h1><br></br>
<h4 id="welcome">{{welcome}}</h4>
</div>
<hr></hr>
<form id="form" name="form">
<div>
<label>Do you have an ID?</label><br></br>
<select type="select"
ng-model="user.affiliated"
ng-required="true"
ng-options="opt as opt.name for opt in affiliate.affiliateOptions">
<option value="">--Select an answer--</option>
</select>
</div>
<div ng-switch="user.affiliated">
<div ng-switch-when="Yes">
<!--><-->
</div>
<div ng-switch-when="No">
<!--><-->
</div>
</div>
And here is the Javascript snippet:
var kiosk = angular.module('kiosk',[]);
kiosk.controller('kiosk-controller', ['$scope', function($scope, $user) {
$scope.servicedeskname = 'Service Desk';
$scope.welcome = 'Please sign in and a consultant will be with you shortly.';
$scope.affiliate = {affiliateOptions:[]};
$scope.affiliate.affiliateOptions = [
{ name: 'Yes' },
{ name: 'No' }
];
/*other stuff*/
};
I can't figure out the proper way to reference the select options in the HTML tags using ng directives. Unless it's not super clear, I want to be able to show one div if the select value is "Yes", and show another if the select value is "No".
I think the switch statement you use need small modification
<div ng-switch on="user.affiliated">
<div ng-switch-when="Yes">
<!--><-->
</div>
<div ng-switch-when="No">
<!--><-->
</div>
</div>
check this ng-switch documentation for more help
I believe you're looking for ng-show and ng-hide.
<div ng-show="user.affiliated === 'Yes'"></div>
<div ng-show="user.affiliated === 'No'"></div>
And try changing this line to this:
ng-options="opt.name as opt.name for opt in affiliate.affiliateOptions">
You forgot the name property in the switch statement.
- <div ng-switch="user.affiliated">
+ <div ng-switch="user.affiliated.name">
As can be viewed in jsfiddle
you just have a little mistake. you must have user.affiliated.name instead of user.affiliated
like this
<div ng-switch="user.affiliated.name">
<div ng-switch-when="Yes">
yes
</div>
<div ng-switch-when="No">
no
</div>
</div>

How to calculate child div length from parent div; using classnames; in JQuery?

The parent div have class name 'panel'.
It contains further child divs have class name 'clonablePart' and also one button.
We need to check
1) if there are multiple clonablePart then the button which is by default disable should turn enable
2) if there is one clonable part then button should remain disabled
Note: Class name 'panel' in parent div panel; can also exist in its child div's. Also 'Input' can be multiple
Please see fiddle for more details for HTML structure.
https://jsfiddle.net/k2rbs70m/
Following is JQuery in Use:
$('.myclass').each(function () {
var lengthOfClones = $(this).closest('div.panel').find('.clonablePart').length;
var typeOfClone = $(this).data("type");
console.log('Length of Clones:' + typeOfClone + " - " + lengthOfClones);
lengthOfClones > 1 ? $('#delete' + typeOfClone).attr('disabled', false) : $('#delete' + typeOfClone).attr('disabled', true);
});
If anything unclear please write.
Following is HTML for an idea:
<div id="Bank_panel" class="panel">
<div id="Bank_panel1" class="clonablePart">
1) Bank Account
</div>
<div id="Bank_panel1" class="clonablePart">
2) Account Name
</div>
<input type="button" value="delete" id="deleteBank" data-type="Bank" disabled /> <i> Make it Enable onload as it have two values</i>
</div>
If you have only one input child per panel class, you can target it like this:
$(this).find('input')
In your code, this would give:
lengthOfClones > 1 ? $(this).find('input').attr('disabled', false) : $(this).find('input').attr('disabled', true);
https://jsfiddle.net/ggngygzy/
EDIT
IF you have more than one input child per panel, you can find a unique property and target it. Like this for example:
$(this).find('input[type=button]')
There are problem in your code
$(this).data("type") always returns Clones, which is incorrect.
So, give a custom attribute data-type to each of the div under .panel, say for Bank, give data-type="Bank" and so on.
So the HTML becomes:
<div id="Bank_panel" class="panel" data-type="Bank">
<div id="Bank_panel1" class="clonablePart">
1) Bank Account
</div>
<div id="Bank_panel1" class="clonablePart">
2) Account Name
</div>
<input type="button" value="delete" id="deleteBank" data-type="Bank" disabled /> <i> Make it Enable onload as it have two values</i>
</div>
<br/>
<div id="insurance_panel" class="panel" data-type="Insurance">
<div id="insurance_panel1" class="clonablePart">
1) Insurance Account
</div>
<div id="insurance_panel1" class="clonablePart">
2) Insurance Name
</div>
<input type="button" value="delete" id="deleteInsurance" data-type="insurance" disabled /> <i> Make it Enable onload as it have two values</i>
</div>
<br/>
<div id="economy_panel" class="panel" data-type="economy">
<div id="economy_panel1" class="clonablePart">
1) Economy Account
</div>
<input type="button" value="delete" id="deleteeconomy" data-type="economy" disabled /> <i> Keep it disable</i>
</div>
See the working fiddle here: "http://jsfiddle.net/k2rbs70m/7/"
You can use the following code:
$('.panel').each(function () {
var lengthOfClones = $(this).find('.clonablePart').length;
var flagDisable = lengthOfClones == 1
$(this).find("input[type='button']").prop('disabled',flagDisable);
});
It will fix your problem.
https://jsfiddle.net/k2rbs70m/9/
This will solve your issue you presented in the Fiddle:
$('.panel').each(function () {
// Find the button with a value of `delete`
var button = $(this).find("input[value='delete']");
var clones = $(this).find('.clonablePart');
if(clones.length > 1)
button.removeAttr('disabled')
else
button.attr('disabled', true) ;
});
The trick is: you only want children to be counted, so use .find(). Then, find the button inside your wrapper and enable and disable that by the amount of results found.
//Will take outer panels only
$('.panel').each(function () {
var button = $(this).find("input[value='delete']");
var clones = $(this).find('.clonablePart');
var type = button.data("type");
if(clones.length > 1)
button.removeAttr('disabled')
else
button.attr('disabled', true) ;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<div id="Bank_panel" class="panel">
<div id="Bank_panel1" class="clonablePart">
1) Bank Account
</div>
<div id="Bank_panel1" class="clonablePart">
2) Account Name
</div>
<input type="button" value="delete" id="deleteBank" data-type="Bank" disabled /> <i> Make it Enable onload as it have two values</i>
</div>
<br/>
<div id="insurance_panel" class="panel">
<div id="insurance_panel1" class="clonablePart">
1) Insurance Account
</div>
<div id="insurance_panel1" class="clonablePart">
2) Insurance Name
</div>
<div class="panel"></div> <!--Remember outer panel can have inner panel-->
<input type="button" value="delete" id="deleteInsurance" data-type="insurance" disabled /> <i> Make it Enable onload as it have two values</i>
</div>
<br/>
<div id="economy_panel" class="panel">
<div id="economy_panel1" class="clonablePart">
1) Economy Account
</div>
<input type="button" value="delete" id="deleteeconomy" data-type="economy" disabled /> <i> Keep it disable</i>
</div>

How to show particular div id on the page using jquery?

I want to show a particular div with particular id on the page. I am able to show the div with class information but when I try to access it by giving div id then it is not working, this is how am trying to access it from javascript.
if((document.getElementById("apMain.stageId").value) == "11"){
doShow();
}else{
alert('else');
}
function doShow(){
$(".bill_info").show();
}
I want to access div with id= stg_Pdel, I have tried using
function doShow(){
$('#stg_Pdel').show();
}
but am not able to get the div open on the page, what should be the right approach of doing it ?
My div is:
<div class="bill_info">
<h3>Additional required fields</h3>
<div id="stg_install">
<div class="row">
<span class="label">
<form:label path="billingInfo.otc" cssClass="normalText" cssErrorClass="normalTextRed" >OTC:</form:label>
</span>
<span class="formw">
<form:input path="billingInfo.otc" cssClass="normalField" cssErrorClass="validationError" size="25" disabled='true'/>
</span>
<span class="error">Values for all charge fields must be numeric.</span>
</div>
</div>
<div id="stg_Pdel">
<div class="row">
<span class="label">
<form:label path="billingInfo.priceId" cssClass="normalText" cssErrorClass="normalTextRed" >Price Type:</form:label>
</span>
<span class="formw">
<form:select path="billingInfo.priceId" cssErrorClass="validationError" disabled='true'>
<form:options items="${priceTypes}" itemValue="key" itemLabel="value" />
</form:select>
</span>
</div>
</div>
<div id='stg_closed'>
<div class="row">
<span class="label">
<form:label path="billingInfo.billingClassId" cssClass="normalText" cssErrorClass="normalTextRed" >Billing:</form:label>
</span>
<span class="formw">
<form:select path="billingInfo.billingClassId" cssErrorClass="validationError" disabled='true'>
<form:option value="" label="--Select--" />
<form:options items="${billingTypes}" itemValue="key" itemLabel="value" />
</form:select>
</span>
</div>
</div>
<div style="clear:both"></div><br/>
</div>
You're missing a closing </div> tag right before that one, so it's inside the previous one ("stg_install"). An outer "display: none" will override (sort-of) the "display: block" (or whatever) on the inner <div>.
If it's not the <div> nesting issue that was present in the initial post of the question, then perhaps there's a hint of the problem where you mention showing the <div> with class "bill_info". If that whole thing is currently not showing, then calling .show() on another <div> (the "stg_Pdel" <div>) will have no effect. Again, the outer block will hide it no matter what it's "display" style is set to.
If the ".bill_info" <div> is hidden, you need to do something like this:
function doShow(stage) {
$('.bill_info').show()
.children('div').hide().end()
.find('#' + stage).show();
}
You'd pass "doShow" either "stg_Pdel", "stg_install", or "stg_closed", and it would make sure one of those inner <div> elements is showing. edit for more detail — The idea is to do the following things:
Make sure that the over all "bill_info" block is visible;
Find the immediate child <div> elements and hide them all;
Find the target "stg" <div> and make it visible
Note that using .find() is not really necessary because you're searching by "id" value, but it should work.
If you need the function to work on more than one stage, you could do it like this:
function doShow() {
$('.bill_info').show()
.children('div').hide();
for (var ac = 0; ac < arguments.length; ++ac) {
var stg = arguments[ac];
$('#' + stg).show();
}
}

Categories

Resources