multiple selection shift+click from list - javascript

How to implement multiple selection with jquery (jscript) using Shift + click in list:
<div class="custom-multi-select-option">
<span class="custom-multi-select-option-label">Tollet</span>
</div>
<div class="custom-multi-select-option">
<span class="custom-multi-select-option-label">Present</span>
</div>
List on form
Simple selection implement by adding
toggleClass( "custom-multi-select-option-selected" );
I try this, but it not properly work:
var _onClickOnCustomMultiSelect = function( e ){
$( this ).toggleClass( "custom-multi-select-option-selected" );
$( this ).find(".custom-multi-select-option-label").toggleClass( "custom-multi-select-option-selected" );
if(e.shiftKey) {
$('div.custom-multi-select-option-selected').nextUntil(this).toggleClass( "custom-multi-select-option-selected" );
}
};

Related

How to convert jQuery code that manages the expanded/collapsed state of items in a navigation menu to pure JS

I'm trying to convert some old jQuery code that manages the expanded/collapsed state of items in a navigation menu to pure JS and I've hit a roadblock.
HTML menu code:
<nav class="main-navigation">
<ul class="menu">
<li class="menu-item">
Item 1
<button class="dropdown-toggle" aria-expanded="false">
<svg class="svg-icon"></svg>
<span class="screen-reader-text">Expand submenu</span>
</button>
<ul class="sub-menu">
<li class="menu-item">
Item a
</li>
<li class="menu-item">
Item b
</li>
<li class="menu-item">
Item c
</li>
...
jQuery code:
var container = $( '.main-navigation' );
container.find( '.dropdown-toggle' ).on( 'click', function( e ) {
var _this = $( this );
e.preventDefault();
// Remove toggle classes and attributes from all menu items except the active one and its parents.
container.find( '.dropdown-toggle.toggle-on' )
.not( _this )
.not( _this.parents( '.children, .sub-menu' )
.prev( '.dropdown-toggle' )
)
.removeClass( 'toggle-on' )
.attr( 'aria-expanded', false );
...
} );
My attempts at pure JS code:
var container = document.querySelector( '.main-navigation' );
container.querySelectorAll( '.dropdown-toggle' ).forEach( item => {
item.addEventListener( 'click', function( e ) {
var _this = e.target;
e.preventDefault();
// Remove toggle classes and attributes from all menu items except the active one and its parents.
container.querySelector( '.dropdown-toggle.toggle-on' );
// How to convert the rest of the chained methods to pure JS?
???.classList.remove( 'toggle-on' ));
???.setAttribute( 'aria-expanded', false );
...
} );
} );
Basically, I don't know how to convert the not() methods to pure JS. I've seen some people resort to the :not CSS selector but I don't know if it's possible in this case.
Any help would be appreciated.
var container = document.querySelector( '.main-navigation' );
container.querySelectorAll( '.dropdown-toggle' ).forEach( item => {
item.addEventListener( 'click', function( e ) {
var _this = e.target;
e.preventDefault();
// Remove toggle classes and attributes from all menu items except the active one.
container.querySelectorAll( '.dropdown-toggle.toggle-on' ).forEach(el => {
el.classList.remove('toogle-on');
el.setAttribute( 'aria-expanded', false );
}
// add class, change attribute to clicked el
e.target.classList.add('toogle-on');
e.target.setAttribute( 'aria-expanded', true );
});
} );

Javascript - Hide a div with a reset button

I need a UL, containing the search results (ul.job_listings) to hide after a reset button is pressed.
So far a reset has been set up to reset the search form:
$( '.job_filters' ).on( 'click', '.reset', function () {
var target = $( this ).closest( 'div.job_listings' );
var form = $( this ).closest( 'form' );
form.find( ':input[name="search_keywords"], :input[name="search_location"], .job-manager-filter' ).not(':input[type="hidden"]').val( '' ).trigger( 'chosen:updated' );
form.find( ':input[name^="search_categories"]' ).not(':input[type="hidden"]').val( 0 ).trigger( 'chosen:updated' );
$( ':input[name="filter_job_type[]"]', form ).not(':input[type="hidden"]').attr( 'checked', 'checked' );
target.triggerHandler( 'reset' );
target.triggerHandler( 'update_results', [ 1, false ] );
job_manager_store_state( target, 1 );
return false;
} );
How would I add to it to also hide the results div?
Thanks for any help,
Liz.
Since you seem to be using jQuery, it you could just add
target.hide();
before the return statement.
edit - see comments above :-)

JQuery UI Autocomplete Combobox highlight

I have a <select> which I need to transform in more functional combobox.
<span class="combo_box">
<select id="state" name="state" tabindex="24">
<option value="" disabled selected style="display:none"></option>
<!-- Some JSP here -->
</select>
</span>
And I transformed it in to widget (so original <select> with id "state" is still there but hidden) like this $("#state").combobox(); What i need is to add an error highlight to this custom widget on form submission if combobox is empty. jQuery UI has a custom CSS class ui-state-error for this.
Validation script (works fine as I debug it)
function setComboboxClassBeforeSubmit(elementID) {
var flag = true;
var element = document.getElementById(elementID);
var combobox = $(element).combobox();
combobox.removeClass('ui-state-error');
if (isEmpty(element)) {
combobox.addClass('ui-state-error');
flag = false;
}
return flag;
}
But adding this CSS class seems like have no effect on widget look. Also tried hardcode like it was shown here, something like $("#state").addClass('ui-state-error') and still no luck.
Also tried this solution, works fine for selectmenu but not for combobox.
Possible solution: (thanks to nowhere)
Editing _createAutocomplete: function() like this:
_createAutocomplete: function() {
var selected = this.element.children( ":selected" ),
value = selected.val() ? selected.text() : "";
this.input = $( "<input>" )
.appendTo( this.wrapper )
.val( value )
.attr( "title", "" )
.attr( "id", "ui-" + this.element.attr("id") + "-input" )
...
Issue is - default API doesn't generate unique ID's for combobox's elements.
Can you try with the code I've made here? I operated by using the jqueryui example: http://jsfiddle.net/b5e83x2q/
function checkValue(item){
item.removeClass('ui-state-error');
if(item.val()==""){
item.addClass('ui-state-error');
}
}
checkValue($(".custom-combobox input"));
.ui-state-error{
background-color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="custom-combobox">
<input title="" class="custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left ui-autocomplete-input" autocomplete="off" value="">
</span>
EDIT:
if you need to identify a specific select you should give it a specific id: if you used the same code of the jqueryui example you should have:
_create: function() {
this.wrapper = $( "<span>" )
.addClass( "custom-combobox" )
.insertAfter( this.element );
this.element.hide();
this._createAutocomplete();
this._createShowAllButton();
}
there you might try to add something like:
this.attr('id', 'specificId');
or edit the span wrapper:
_create: function() {
this.wrapper = $( "<span>" )
.addClass( "custom-combobox" )
.insertAfter( this.element )
.attr('id', 'specificId');
this.element.hide();
this._createAutocomplete();
this._createShowAllButton();
}
After that you can use:
checkValue($("#specificId input"));
to change only 1 select.

How to append modal dialog to div?

I've designed a modal dialog that opens on the click of a button, here is the javascript and html for it;
JAVASCRIPT
var ModalEffects = (function() {
function init() {
var overlay = document.querySelector( '.md-overlay' );
[].slice.call( document.querySelectorAll( '.md-trigger' ) ).forEach( function( el, i ) {
var modal = document.querySelector( '#' + el.getAttribute( 'data-modal' ) ),
close = modal.querySelector( '.md-close' );
function removeModal( hasPerspective ) {
classie.remove( modal, 'md-show' );
if( hasPerspective ) {
classie.remove( document.documentElement, 'md-perspective' );
}
}
function removeModalHandler() {
removeModal( classie.has( el, 'md-setperspective' ) );
}
el.addEventListener( 'click', function( ev ) {
classie.add( modal, 'md-show' );
overlay.removeEventListener( 'click', removeModalHandler );
overlay.addEventListener( 'click', removeModalHandler );
if( classie.has( el, 'md-setperspective' ) ) {
setTimeout( function() {
classie.add( document.documentElement, 'md-perspective' );
}, 25 );
}
});
close.addEventListener( 'click', function( ev ) {
ev.stopPropagation();
removeModalHandler();
});
} );
}
init();
})();
HTML
<div class="md-modal md-effect-16" id="modal-16">
<div class="md-content">
<h3>Remember Rules</h3>
<div>
<p>There are certain rules you must obey, if you don't your account will be banned:</p>
<ul>
<li><strong>Swearing:</strong> cursing or any other form of cursing is not allowed.</li>
<li><strong>Hacking:</strong> trying to hack any component of the application is a t.o.u violation.</li>
<li><strong>Heckling:</strong> constantly calling a moderator will kick you off the server.</li>
</ul>
<button class="md-close">Close me!</button>
</div>
</div>
</div>
<div id="interface">
<textarea name="para" placeholder="type your paragraph here"></textarea>
</div>
<center><button class="md-trigger" data-modal="modal-16">Blur</button></center>
For some reason I can't get it to append to the "interface" div, I've used the appendTo jquery which failed me, the interface div is 600x200, currently atm the modal dialog which has an overlay behind it, covers the entire body and I'd like it to specifically cover the interface div.
The CSS is very basic, a green dialog box with some text on it and an overlay behind it.
Here is a FIDDLE that at least partially addresses your question.
If you attach a .dialog to an element it tends to "become" or "coverup" that element.
So in the fiddle above, I've attached the .dialog to a smaller div that is not displayed within the larger div, and opened the dialog with a click on the larger div.
If you look at the jQuery documentation for .dialog, you'll see that the purpose of the modal is to block out every potential interaction on the page, forcing the user to interact with the modal only. So when you use the modal, the entire page/body/window with be grayed-out.
I suppose you could write your own modal and just gray-out the large div.
Do you really need to just gray-out the div?
edit: or you could add appendTo: '.bigdiv'
JS
var $dialogpopup = $( ".littlediv" ).dialog({
autoOpen: false,
width: 150,
height: 150,
modal: true,
position: {
my:'top center',
at: 'top center',
of: '.bigdiv'
}
});
$('.bigdiv').on('click', function(){
$dialogpopup.dialog('open');
});

jQuery multiple toggle hide all / show only one

Hello Dear Programmers,
I have a header menu, with "Search", "Language", "Time" toggle functions.
Regarding display onClick it works correctly, but I need If I Click on "Search" show only "Search" and hide all "Language", "Time".
My code
.js
$( '.search-toggle' ).on( 'click.twentyfourteen', function( event ) {
var that = $( this ),
wrapper = $( '.search-box-wrapper' );
that.toggleClass( 'active' );
wrapper.toggleClass( 'hide' );
if ( that.is( '.active' ) || $( '.search-toggle .screen-reader-text' )[0] === event.target ) {
wrapper.find( '.search-field' ).focus();
}
} );
$( '.language-toggle' ).on( 'click.twentyfourteenn', function( event ) {
var that = $( this ),
wrapper = $( '.language-box-wrapper' );
that.toggleClass( 'active' );
wrapper.toggleClass( 'hide' );
} );
$( '.time-toggle' ).on( 'click.twentyfourteennn', function( event ) {
var that = $( this ),
wrapper = $( '.time-box-wrapper' );
that.toggleClass( 'active' );
wrapper.toggleClass( 'hide' );
} );
and html
<div class="search-toggle">
<?php _e( 'Search', 'twentyfourteen' ); ?>
</div>
<div class="language-toggle">
<?php _e( 'Search', 'twentyfourteenn' ); ?>
</div>
<div class="time-toggle">
<?php _e( 'Search', 'twentyfourteennn' ); ?>
</div>
<div id="search-container" class="search-box-wrapper hide">
<div class="search-box">
<?php get_search_form(); ?>
</div>
</div>
<div id="language-container" class="language-box-wrapper hide">
<div class="language-box">
language
</div>
</div>
<div id="time-container" class="time-box-wrapper hide">
<div class="time-box">
time
</div>
</div>
If I understand what you mean you want to hide two different elements when clicking search you want the others to hide?
By using add you can group elements together then add classes to show or hide:
$('#element1_id').add('#element2_id').removeClass('show');
$('#element1_id').add('#element2_id').addClass('hide');
or just straight up hide them with jQuery.
$('#element1_id').add('#element2_id').hide();
You could also give the element you want to hide together a common class name:
ie: toggle
then you can simply use the class toggle to hide them:
$('.toggle').removeClass('show');
$('.toggle').addClass('hide');
or
$('.toggle').hide();
i think this will hide other parts, i have not tried this but hope will work for u
$( '.search-toggle' ).on( 'click.twentyfourteen', function( event ) {
var that = $( this ),
wrapper = $( '.search-box-wrapper' );
that.toggleClass( 'active' );
$( '.search-box-wrapper' ).hide();
$( '.time-box-wrapper' ).hide();
$( '.language-box-wrapper' ).hide();
if ( that.is( '.active' ) || $( '.search-toggle .screen-reader-text' )[0] === event.target ) {
wrapper.find( '.search-field' ).focus();
}
} );
$( '.language-toggle' ).on( 'click.twentyfourteenn', function( event ) {
var that = $( this ),
wrapper = $( '.language-box-wrapper' );
$( '.search-box-wrapper' ).hide();
$( '.time-box-wrapper' ).hide();
$( '.language-box-wrapper' ).hide();
that.toggleClass( 'active' );
} );
$( '.time-toggle' ).on( 'click.twentyfourteennn', function( event ) {
var that = $( this ),
wrapper = $( '.time-box-wrapper' );
$( '.search-box-wrapper' ).hide();
$( '.time-box-wrapper' ).hide();
$( '.language-box-wrapper' ).hide();
that.toggleClass( 'active' );
} );
This should solve the problem. You can view working demo with this link Working Demo
Summary of what I did.
I added some text as link in the html (just for testing)
I added .hide() Jquery class to hide the three wrapper classes before the click events
I added a little bit of animation to wrapper.toggle('slow')
I changed wrapper.toggleClass('slow') to wrapper.toggle('slow')
$('.search-box-wrapper').hide();
$('.language-box-wrapper').hide();
$('.time-box-wrapper').hide();
$('.search-toggle').on('click.SearchLink', function (event) {
var that = $(this),
wrapper = $('.search-box-wrapper');
that.toggleClass('active');
wrapper.toggle('slow');
if (that.is('.active') || $('.search-toggle .screen-reader-text')[0] === event.target) {
wrapper.find('.search-field').focus();
}
});
$('.language-toggle').on('click.LangLink', function (event) {
var that = $(this),
wrapper = $('.language-box-wrapper');
that.toggleClass('active');
wrapper.toggle('slow');
});
$('.time-toggle').on('click.TimeLink', function (event) {
var that = $(this),
wrapper = $('.time-box-wrapper');
that.toggleClass('active');
wrapper.toggle('hide');
});

Categories