jQuery Sortable in tab content moved to another content - javascript

I am trying to do jQuery sortable with items to be moved from tab contents to another div. It it working mostly fine, but the problem I am having is that I would like the item to be back to tab from which it was taken.
So let say that I have got tabs:
Shipping Address with items:
Street 1
Street 2
City
Country
Attributes with items:
Industry
Types
Full Name
The tab content is taking 50% of width on left and 50% of width on right is the div block to were I want to drop the items. If I would like to remove the item from div block, it should come back to the related tab, so e.g. Industry cannot go back to Shipping Addres , it needs to go to Attributes.
JSFiddle: http://jsfiddle.net/epxp5L48/
The screen how it looks like
My HTML code:
<div class="row">
<div class="col-xs-6">
<ul class="nav nav-tabs" role="tablist">
<li class="active">Attributes</li>
<li>InvoiceAddress</li>
<li>ShippingAddress</li>
</ul>
<div id="fields-draggable" class="tab-content">
<div class="tab-pane connectedSortable ui-sortable active" id="Attributes">
<button id="field_industry" class="btn btn-primary btn-lg btn-block ui-sortable-handle">industry</button>
<button id="field_types" class="btn btn-primary btn-lg btn-block ui-sortable-handle">types</button>
<button id="field_full_name" class="btn btn-primary btn-lg btn-block ui-sortable-handle">full_name</button>
</div>
<div class="tab-pane connectedSortable ui-sortable" id="InvoiceAddress">
<button id="field_street1" class="btn btn-primary btn-lg btn-block ui-sortable-handle">street1</button>
<button id="field_street2" class="btn btn-primary btn-lg btn-block ui-sortable-handle">street2</button>
<button id="field_id" class="btn btn-primary btn-lg btn-block ui-sortable-handle">id</button>
<button id="field_street3" class="btn btn-primary btn-lg btn-block ui-sortable-handle">street3</button>
<button id="field_postcode" class="btn btn-primary btn-lg btn-block ui-sortable-handle">postcode</button>
<button id="field_city" class="btn btn-primary btn-lg btn-block ui-sortable-handle">city</button>
<button id="field_stateId" class="btn btn-primary btn-lg btn-block ui-sortable-handle">stateId</button>
<button id="field_countryId" class="btn btn-primary btn-lg btn-block ui-sortable-handle">countryId</button>
</div>
<div class="tab-pane connectedSortable ui-sortable" id="ShippingAddress">
<button id="field_id" class="btn btn-primary btn-lg btn-block ui-sortable-handle">id</button>
<button id="field_street1" class="btn btn-primary btn-lg btn-block ui-sortable-handle">street1</button>
<button id="field_street2" class="btn btn-primary btn-lg btn-block ui-sortable-handle">street2</button>
<button id="field_street3" class="btn btn-primary btn-lg btn-block ui-sortable-handle">street3</button>
<button id="field_postcode" class="btn btn-primary btn-lg btn-block ui-sortable-handle">postcode</button>
<button id="field_city" class="btn btn-primary btn-lg btn-block ui-sortable-handle">city</button>
<button id="field_stateId" class="btn btn-primary btn-lg btn-block ui-sortable-handle">stateId</button>
<button id="field_countryId" class="btn btn-primary btn-lg btn-block ui-sortable-handle">countryId</button>
</div>
</div>
</div>
<div class="col-xs-6">
<div id="fields-sortable" class="connectedSortable well ui-sortable" style="min-height: 40px;">
</div>
</div>
</div>
and jQuery UI code:
$("#fields-sortable, #Attributes" ).sortable({
connectWith: ".connectedSortable",
placeholder: "btn btn-default btn-lg btn-block",
cancel: ''
});
$("#fields-sortable, #InvoiceAddress" ).sortable({
connectWith: ".connectedSortable",
placeholder: "btn btn-default btn-lg btn-block",
cancel: ''
});
$("#fields-sortable, #ShippingAddress" ).sortable({
connectWith: ".connectedSortable",
placeholder: "btn btn-default btn-lg btn-block",
cancel: ''
});
$( "#fields-sortable" ).sortable({
update: function (event, ui) {
var data = $(this).sortable( "serialize");
console.log(data);
}
});

I have managed to do it by adding the data-tab-id attribute to the buttons and adding over event to the sortable
over: function(event, ui) {
var overId = $(this).attr('id');
var elementId = $(event.toElement).data('tab-id');
if(overId != "fields-sortable" && overId != elementId) {
var aClick = $("#nav-types").find('a[href="#' + elementId + '"]');
aClick.click();
}
}

Related

Custom timepicker with jQuery and bootstrap

I build a custom timepicker with jQuery and bootstrap.
It's almost finished, but 1 "nice to have detail" is missing and I'm stucked getting to the result.
It should follow this rules:
Select the time on click
Only related times are possible to select.
Only 1 time range at once is possible (e.g. 09:00-11:00 works but can't pick another time range)
Disabled times are not possible to pick and if they are between a possible time range, only the range before or after disabled are allowed.
It should be possible to click the start time and the end time and if there are no obstacles in between, the times between should be selected as well.
1-4 are working but I'm stucked on point 5.
So what I want to achieve is that if I click on 13:00-14:00 and 15:00-16:00, 14:00-15:00 should be selected automatically if allowed by above rules.
$('.time-cal .time-btn').on('click',function(){
if($('.time-cal .time-btn.btn-success').length == 0)
{
$(this).not(".btn-danger").toggleClass('btn-success');
$(this).not(".btn-danger").toggleClass('btn-light');
}else{
if($(this).hasClass('btn-light'))
{
if($(this).next().hasClass('btn-success') || $(this).prev().hasClass('btn-success'))
{
$(this).not(".btn-danger").toggleClass('btn-success');
$(this).not(".btn-danger").toggleClass('btn-light');
}
}else{
let next = $(this).next();
let prev = $(this).prev();
if(!next.hasClass('btn-success') || ! prev.hasClass('btn-success'))
{
$(this).not(".btn-danger").toggleClass('btn-success');
$(this).not(".btn-danger").toggleClass('btn-light');
}
}
}
});
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<div class="time-cal col-lg-6 col-12">
<label>Pick times</label><br>
<button type="button" class="btn btn-xs time-btn btn-danger" data-start="07:00" data-end="08:00" disabled="">07:00 - 08:00</button>
<button type="button" class="btn btn-xs time-btn btn-danger" data-start="08:00" data-end="09:00" disabled="">08:00 - 09:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="09:00" data-end="10:00">09:00 - 10:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="10:00" data-end="11:00">10:00 - 11:00</button>
<button type="button" class="btn btn-xs time-btn btn-danger" data-start="11:00" data-end="12:00" disabled="">11:00 - 12:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="12:00" data-end="13:00">12:00 - 13:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="13:00" data-end="14:00">13:00 - 14:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="14:00" data-end="15:00">14:00 - 15:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="15:00" data-end="16:00">15:00 - 16:00</button>
<button type="button" class="btn btn-xs time-btn btn-danger" data-start="16:00" data-end="17:00" disabled="">16:00 - 17:00</button>
<button type="button" class="btn btn-xs time-btn btn-danger" data-start="17:00" data-end="18:00" disabled="">17:00 - 18:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="18:00" data-end="19:00">18:00 - 19:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="19:00" data-end="20:00">19:00 - 20:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="20:00" data-end="21:00">20:00 - 21:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="21:00" data-end="22:00">21:00 - 22:00</button>
<div class="form-group">
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.0.0/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
-edit altered behaviour based on the comments.
At startup each time'button' is divided into a specific timeblock so buttons in the same timeblock can be quickly handled together (there might be some additional/other behavioral requirements when reselecting)
const
disabledClass = 'btn-danger',
selectedClass = 'btn-success',
notselectedClass = 'btn-light',
timeButtons = $('.time-cal .time-btn'),
enabledButtons = timeButtons.not('.' + disabledClass ),
timeBlocks = [];
timeButtons.each((index,btn)=>{btn.enabled=!$(btn).hasClass(disabledClass);
if(btn.enabled){
if(index===0 || !timeButtons[index-1].enabled){
timeBlocks.push([]); //new timeblock
}
btn.timeBlock = timeBlocks[timeBlocks.length-1];
btn.timeBlock.push(btn);
}
prevEnabled = btn.enabled;
btn.index = index;btn.selected=false;
btn.setSelected = sel => {if(btn.selected===sel)return; btn.selected=sel;
$(btn).toggleClass(notselectedClass,!sel).toggleClass(selectedClass,sel);}
});
enabledButtons.click(function(){
if(this.selected){
//deselect and make sure times in this block after this button are deselected too
this.timeBlock.filter(btn=>btn.index >= this.index && btn.selected).forEach(btn=>btn.setSelected(false));
return;
}
//deselect other timeblocks
enabledButtons.toArray().filter(b=>b.timeBlock !== this.timeBlock).forEach(b=>b.setSelected(false));
//check if there are other selected
const selected = this.timeBlock.filter(b=>b.selected);
if(selected.length === 0)
this.setSelected(true); //no other buttons selected, simply select
else{
//select range withint the timeblock
let from = selected[0].index, to = this.index;
if(from > to)
[from,to] = [to,from];
for(let i = from;i<=to;i++)
timeButtons[i].setSelected(true);
}
});
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.0.0/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<div class="time-cal col-lg-6 col-12">
<label>Pick times</label><br>
<button type="button" class="btn btn-xs time-btn btn-danger" data-start="07:00" data-end="08:00" disabled="">07:00 - 08:00</button>
<button type="button" class="btn btn-xs time-btn btn-danger" data-start="08:00" data-end="09:00" disabled="">08:00 - 09:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="09:00" data-end="10:00">09:00 - 10:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="10:00" data-end="11:00">10:00 - 11:00</button>
<button type="button" class="btn btn-xs time-btn btn-danger" data-start="11:00" data-end="12:00" disabled="">11:00 - 12:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="12:00" data-end="13:00">12:00 - 13:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="13:00" data-end="14:00">13:00 - 14:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="14:00" data-end="15:00">14:00 - 15:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="15:00" data-end="16:00">15:00 - 16:00</button>
<button type="button" class="btn btn-xs time-btn btn-danger" data-start="16:00" data-end="17:00" disabled="">16:00 - 17:00</button>
<button type="button" class="btn btn-xs time-btn btn-danger" data-start="17:00" data-end="18:00" disabled="">17:00 - 18:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="18:00" data-end="19:00">18:00 - 19:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="19:00" data-end="20:00">19:00 - 20:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="20:00" data-end="21:00">20:00 - 21:00</button>
<button type="button" class="btn btn-xs time-btn btn-light" data-start="21:00" data-end="22:00">21:00 - 22:00</button>
<div class="form-group">
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.12.9/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.0.0/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>

need help getting values from a click function in javascript

So I have a problem getting the ID's from my buttons. My code is only returning the id value from the first tic button and not the rest of them when I click on them.
here is the HTML:
<div class="row">
<div class="col-lg-12">
<a class="btn btn-lg btn-primary tic" id="0">#</a>
<a class="btn btn-lg btn-primary tic" id="1">#</a>
<a class="btn btn-lg btn-primary tic" id="2">#</a>
</div>
</div>
and here is the javascript:
const tick = document.querySelector('.tic');
tick.addEventListener('click', () =>{
var slot = tick.id;
console.log(slot);
});
it only returns 0 when I click on the first button but it does not return 1 when I click on the second one. Instead, it doesnt do anything. Any help would be great. Thanks
querySelector returns the first element.
Instead, use querySelectorAll to select all elements, loop through each and add a click event listener:
const tick = document.querySelectorAll('.tic');
tick.forEach(e => {
e.addEventListener('click', () => {
var slot = e.id;
console.log(slot);
});
})
<div class="row">
<div class="col-lg-12">
<a class="btn btn-lg btn-primary tic" id="0">#</a>
<a class="btn btn-lg btn-primary tic" id="1">#</a>
<a class="btn btn-lg btn-primary tic" id="2">#</a>
</div>
</div>
Or, even better, use event delegation:
document.body.addEventListener('click', function(e) {
if (e.target.classList.contains("tic")) {
console.log(e.target.id);
}
})
<div class="row">
<div class="col-lg-12">
<a class="btn btn-lg btn-primary tic" id="0">#</a>
<a class="btn btn-lg btn-primary tic" id="1">#</a>
<a class="btn btn-lg btn-primary tic" id="2">#</a>
</div>
</div>

Changing button classes in Angular UI Datepicker

In this plunk I have an Angular UI Datepicker that uses a template. I need to change the colors of the "Today", "Clear" and "Close" buttons but changing them in popup.html doesn't work. It should show gray, orange and blue buttons.
I changed from
<li ng-if="showButtonBar" class="uib-button-bar">
<span class="btn-group pull-left">
<button type="button" class="btn btn-sm btn-info uib-datepicker-current" ng-click="select('today', $event)" ng-disabled="isDisabled('today')">{{ getText('current') }}</button>
<button type="button" class="btn btn-sm btn-danger uib-clear" ng-click="select(null, $event)">{{ getText('clear') }}</button>
</span>
<button type="button" class="btn btn-sm btn-success pull-right uib-close" ng-click="close($event)">{{ getText('close') }}</button>
</li>
to
<li ng-if="showButtonBar" class="uib-button-bar">
<span class="btn-group pull-left">
<button type="button" class="btn btn-sm btn-default uib-datepicker-current" ng-click="select('today', $event)" ng-disabled="isDisabled('today')">{{ getText('current') }}</button>
<button type="button" class="btn btn-sm btn-warning uib-clear" ng-click="select(null, $event)">{{ getText('clear') }}</button>
</span>
<button type="button" class="btn btn-sm btn-primary pull-right uib-close" ng-click="close($event)">{{ getText('close') }}</button>
</li>
Note that I changed the button class names to change the color, but when I inspect in the browser, the datepicker is still using the old classes. How to fix this?
To set a custom popup template use datepicker-popup-template-url attribute, for example:
<input datepicker-popup-template-url="popup.html" type="text" class="form-control" is-open="true" ng-model="dt" uib-datepicker-popup="MM-dd-yyyy"
datepicker-options="dateOptions" close-text="Close" popup-placement="bottom-left" on-open-focus="false" />
Demo

Bootstrap Container & Container Fluid have an issue

I am using Bootstrap 3.3.7.
I have used and to add content to the page.
When I use container-fluid, it will not span the content across the page but will limit the size to the page center area.
The same thing happened when I used container. It spans to the outside of the page> My screen resolution is 1366 x 768.
This is the code I have used
<div class="container">
<h4>Bootstrap Buttons</h4>
<!-- The Large size buttons -->
<p>
<button type="button" class="btn btn-default btn-lg">Default</button>
<button type="button" class="btn btn-primary btn-lg">Primary</button>
<button type="button" class="btn btn-success btn-lg">Success</button>
<button type="button" class="btn btn-info btn-lg">Info</button>
<button type="button" class="btn btn-warning btn-lg">Warning</button>
<button type="button" class="btn btn-danger btn-lg">Danger</button>
<button type="button" class="btn btn-link btn-lg">Link</button>
</p>
<!-- The default size buttons -->
<p>
<button type="button" class="btn btn-default">Default</button>
<button type="button" class="btn btn-primary">Primary</button>
<button type="button" class="btn btn-success">Success</button>
<button type="button" class="btn btn-info">Info</button>
<button type="button" class="btn btn-warning">Warning</button>
<button type="button" class="btn btn-danger">Danger</button>
<button type="button" class="btn btn-link">Link</button>
</p>
<!-- The small size buttons -->
<p>
<button type="button" class="btn btn-default btn-sm">Default</button>
<button type="button" class="btn btn-primary btn-sm">Primary</button>
<button type="button" class="btn btn-success btn-sm">Success</button>
<button type="button" class="btn btn-info btn-sm">Info</button>
<button type="button" class="btn btn-warning btn-sm">Warning</button>
<button type="button" class="btn btn-danger btn-sm">Danger</button>
<button type="button" class="btn btn-link btn-sm">Link</button>
</p>
<!-- The small size buttons -->
<p>
<button type="button" class="btn btn-default btn-xs">Default</button>
<button type="button" class="btn btn-primary btn-xs">Primary</button>
<button type="button" class="btn btn-success btn-xs">Success</button>
<button type="button" class="btn btn-info btn-xs">Info</button>
<button type="button" class="btn btn-warning btn-xs">Warning</button>
<button type="button" class="btn btn-danger btn-xs">Danger</button>
<button type="button" class="btn btn-link btn-xs">Link</button>
</p>
<!-- Bootstrap container & container-fluid -->
<!-- Bootstrap container example -->
<div class="container bootcontainer">
<h1>Hello, world! - Using Container</h1>
</div>
<!-- Bootstrap container-fluid example -->
<div class="container-fluid bootcontainerfluid">
<h1>Hello, world! - Using Container Fluid</h1>
</div>
This is the container that contains the other ones, so:
<!--Bootstrap Modal (Dialog Box / Pop-up Window) Example-->
<div class="container-fluid">
...
Then replace container with container-fluid everywhere you need it, worked for me.
I found the answer. Actually it's an HTML break. I hadn't put the <div> tag after declaring the 'Bootstrap Button Example'.
Thanks anyway!
Regards,
Chiranthaka

Differentiate between group of buttons

Is it possible to differentiate between a group of buttons? Given the following buttons.
<div id="slideout_inner">
<h2>Select Size</h2>
<p id="group1">
<button type="button" class="btn btn-primary btn-lg">Small $2.50</button>
<button type="button" class="btn btn-default btn-lg">Medium $3.50</button>
<button type="button" class="btn btn-default btn-lg">Large $4.50</button>
</p>
<h2>Select Milk</h2>
<p>
<button type="button" class="btn btn-default btn-lg">Full</button>
<button type="button" class="btn btn-default btn-lg">Trim</button>
<button type="button" class="btn btn-default btn-lg">Soy</button>
</p>
<button type="button" class="btn btn-primary btn-lg btn-block">Done</button>
<button type="button" class="btn btn-danger btn-lg btn-block cancelOrder">Cancel</button>
</div>
</div>
If I do the following I can highlight the selected button in group1
$('#group1 button').on("click", function(){
$('#group1 button').removeClass("btn-primary").addClass("btn-default");
$(this).removeClass("btn-default").addClass('btn-primary');
})
I expect the button list to be dynamic so I want to select buttons with <p> to highlight separately so remove the #group selector and just highlight buttons within each <p>.
So in this example I could highlight Medium $3.50 and then highlight Soy independently.
Try this code:
$(document).ready(function () {
$("button").on("click", function () {
$(this).siblings("button").removeClass("btn-primary").addClass("btn-default");
$(this).removeClass("btn-default").addClass('btn-primary');
});
});
Try selecting only children of the parent <p> instead of all #group1 buttons.
$(this).parent().find("button").removeClass("btn-primary").addClass("btn-default");
This way you are only accessing a subset of buttons within the parent element, instead of running the query on the entire DOM.
You can use .siblings to select all sibling elements so you can find all sibling elements of the clicked .btn element:
$("p .btn").on("click", function() {
$(this).siblings(".btn").removeClass("btn-primary").addClass("btn-default");
$(this).removeClass("btn-default").addClass('btn-primary');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="slideout_inner">
<h2>Select Size</h2>
<p id="group1">
<button type="button" class="btn btn-primary btn-lg">Small $2.50</button>
<button type="button" class="btn btn-default btn-lg">Medium $3.50</button>
<button type="button" class="btn btn-default btn-lg">Large $4.50</button>
</p>
<h2>Select Milk</h2>
<p>
<button type="button" class="btn btn-default btn-lg">Full</button>
<button type="button" class="btn btn-default btn-lg">Trim</button>
<button type="button" class="btn btn-default btn-lg">Soy</button>
</p>
<button type="button" class="btn btn-primary btn-lg btn-block">Done</button>
<button type="button" class="btn btn-danger btn-lg btn-block cancelOrder">Cancel</button>
</div>
</div>
You can use :contains() selector to identify which button is clicked. and then use the siblings() selector.
$( "button:contains('Small $2.50')" ).siblings()
Better approach would be to use different classes for each group. But the above should get you going.

Categories