Multiple (but not all) card slots - javascript

Trying to recreate a game in which cards are sorted into card slots. I can make it so that card 'a' goes into the first card slot 'Even', but I want to make it so that card 'a' can also go in the the second card slot 'Even.' Similarly, I want card 'b' to be able to go into either 'Even' slot. Ditto cards 'c' and 'd' for either 'Odd' slot and 'e' and 'f' for the either 'Even and Odd' slots. Any ideas?
// Create the pile of shuffled cards
var equations = [];
equations [ 0 ] = {x:1, y:'a'};
equations [ 1 ] = {x:2, y:'b'};
equations [ 2 ] = {x:3, y:'c'};
equations [ 3 ] = {x:4, y:'d'};
equations [ 4 ] = {x:5, y:'e'};
equations [ 5 ] = {x:6, y:'f'};
equations.sort( function() { return Math.random() - .4 } );
for ( var i=0; i<6; i++ ) {
$('<div>' + equations[i].y + '</div>').data( 'number', equations[i].x ).attr( 'id', 'card'+equations[i].x ).appendTo( '#cardPile' ).draggable( {
containment: '#content',
stack: '#cardPile div',
cursor: 'move',
revert: true
} );
}
// Create the card slots
var words = [ 'Even', 'Even', 'Odd)', 'Odd', 'Even + Odd', 'Even + Odd' ];
for ( var i=1; i<=6; i++ ) {
$('<div>' + words[i-1] + '</div>').data( 'number', i ).appendTo( '#cardSlots' ).droppable( {
accept: '#cardPile div',
hoverClass: 'hovered',
drop: handleCardDrop
} );
}
}
function handleCardDrop( event, ui ) {
var slotNumber = $(this).data( 'number' );
var cardNumber = ui.draggable.data( 'number' );
// If the card was dropped to the correct slot,
// change the card colour, position it directly
// on top of the slot, and prevent it being dragged
// again
if ( slotNumber == cardNumber) {
ui.draggable.addClass( 'correct' );
ui.draggable.draggable( 'disable' );
$(this).droppable( 'disable' );
ui.draggable.position( { of: $(this), my: 'left top', at: 'left top' } );
ui.draggable.draggable( 'option', 'revert', false );
correctCards++;
}
// If all the cards have been placed correctly then display a message
// and reset the cards for another go
if ( correctCards == 6) {
$('#successMessage').show();
$('#successMessage').animate( {
left: '430px',
top: '150px',
width: '400px',
height: '180px',
opacity: 1
} );
}
}
});

Right now you have a one-to-one relationship between cards and slots, but it sounds like you want a one-to-many relationship.
So first thing you need to do is define the correct answer for each of your equations by adding a third value.
equations [ 0 ] = {x:1, y:'a', correct: 'Even'};
(You can make this an array if you want multiple correct answers.)
Next, you need to add this answer to the card's data.
.data( 'correct', equations[i].correct )
And finally check for the answer when you handle the drop
var slotAnswer = $(this).text();
var cardAnswer = ui.draggable.data( 'correct' );
if ( slotAnswer == cardAnswer) {
It might be better to store the slot answer in the data instead of just the text.
Also, you have a typo in the slot name of Odd)

Related

Matching drag'n'drop elements

I am trying to understand the drag and drop mechanics in JS and HTML. I have used some code I have found and am trying to adapt it into something different. I want the cardPile to include pictures, with names such as "motherboard.jpg" etc, and match it to the cardSlots with similar names. How could I do that? I tried changing the numeric values in cardPile into strings, but it does not work with dropping.
Any advice? (Sorry, it is my first time on StackOverflow :') )
JS code:
var correctCards = 0;
$( init );
function init() {
// Hide the success message
$('#successMessage').hide();
$('#successMessage').css( {
left: '580px',
top: '250px',
width: 0,
height: 0
} );
// Reset the game
correctCards = 0;
$('#cardPile').html( '' );
$('#cardSlots').html( '' );
// Create the pile of shuffled cards
var numbers = [ 1, "a", "b", "c", "d", "e", "f", "g", "h", "i" ];
numbers.sort( function() { return Math.random() - .5 } );
for ( var i=0; i<10; i++ ) {
$('<div>' + numbers[i] + '</div>').data( 'number', numbers[i] ).attr( 'id', 'card'+numbers[i] ).appendTo( '#cardPile' ).draggable( {
containment: '#content',
stack: '#cardPile div',
cursor: 'move',
revert: true
} );
}
// Create the card slots
var words = [ 'Motherboard', 'RAM', 'GPU', 'CPU', 'I/O', 'Power supply', 'Oprical Drive', 'HDD', 'SSD', 'Expansion slots' ];
for ( var i=1; i<=10; i++ ) {
$('<div>' + words[i-1] + '</div>').data( 'number', i ).appendTo( '#cardSlots' ).droppable( {
accept: '#cardPile div',
hoverClass: 'hovered',
drop: handleCardDrop
} );
}
}
function handleCardDrop( event, ui ) {
var slotNumber = $(this).data( 'number' );
var cardNumber = ui.draggable.data( 'number' );
// If the card was dropped to the correct slot,
// change the card colour, position it directly
// on top of the slot, and prevent it being dragged
// again
if ( slotNumber == cardNumber ) {
ui.draggable.addClass( 'correct' );
ui.draggable.draggable( 'disable' );
$(this).droppable( 'disable' );
ui.draggable.position( { of: $(this), my: 'left top', at: 'left top' } );
ui.draggable.draggable( 'option', 'revert', false );
correctCards++;
}
// If all the cards have been placed correctly then display a message
// and reset the cards for another go
if ( correctCards == 10 ) {
$('#successMessage').show();
$('#successMessage').animate( {
left: '380px',
top: '200px',
width: '400px',
height: '100px',
opacity: 1
} );
}
}

DataTable: How can I add custom buttons manual in HTML

I'm new to learn DataTable and I want to create manual customized in html of my table.
I know how to add elements in JS but how can I add buttons and search in HTML in manually same place like can I add in JS by DataTable and additionally I want that they would work in same way like they can be make in JS.
buttons: [
'pdf',
'pageLength',
'colvis',
/*{
text: 'Add',
name: 'add'
},*/
{
extend: 'selected',
text: 'Edit',
name: 'Edit'
},
{
extend: 'selected',
text: 'Delete',
name: 'delete'
},
]
How can i make this buttons in html with same actions like in specifications and place in DataTable.
DataTable provides an API you can tap into to add your own custom search fields/filtering
$.fn.dataTable.ext.search
A full example is available here: https://datatables.net/examples/plug-ins/range_filtering.html
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
var min = parseInt( $('#min').val(), 10 );
var max = parseInt( $('#max').val(), 10 );
var age = parseFloat( data[3] ) || 0; // use data for the age column
if ( ( isNaN( min ) && isNaN( max ) ) ||
( isNaN( min ) && age <= max ) ||
( min <= age && isNaN( max ) ) ||
( min <= age && age <= max ) )
{
return true;
}
return false;
});
$(document).ready(function() {
var table = $('#example').DataTable();
// Event listener to the two range filtering inputs to redraw on input
$('#min, #max').keyup( function() {
table.draw();
} );
} );

Detect number of columns in a bootstrap grid with javascript

I am using a javascript to set the height of divs to make sure that the each row of divs in a grid has the same height
The divs are each setup as:
<div class="col-xs-12 col-sm-6 col-md-4">
So that on different size devices they show as either 3 column, 2 column or a single column
My javascript is as follows:
function fitRows( $container, options ) {
var cols = options.numColumns,
$els = $container.children(),
maxH = 0, j,
doSize;
doSize = ( $container.width() != $els.outerWidth(true) );
$els.each(function( i, p ) {
var $p = $( p ), h;
$p.css( 'min-height', '' );
if ( !doSize ) return;
h = $p.outerHeight( true );
if ( i % 3 == cols - 1 ) {
for ( j=cols;j;j--) {
$p.css( 'min-height', maxH );
$p = $p.prev();
}
maxH = 0;
} else {
maxH = Math.max( h, maxH );
}
});
}
$(function() {
var opts = {
numColumns: 3
};
fitRows( $( '.tiles' ), opts );
$( window ).on( 'resize', function() {
fitRows( $( '.tiles' ), opts );
});
$( window ).on( 'load', function() {
fitRows( $( '.tiles' ), opts );
});
});
This works perfectly when either 3 columns or 1 column is shown. Is there anyway to detect when 2 columns are being display and change the javascript accordingly
In the end I went with an if statement based on the size of the window to workout the number of columns
if ($(window).width() >= 992 ){
$columns = 3;
}
else if ($(window).width() >= 768 ){
$columns = 2;
}
else {
$columns = 1;
}
var opts = {
numColumns: $columns
};
and then replaced i % 3 with i % cols
You could use a MediaQueryList, which is supported by modern browsers. A polyfill is available for older browsers.
Usage
if(window.matchMedia("(min-width:480px)").matches) //do something
https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Testing_media_queries
Javascript could "know" which columns we're positioned on the next row in two ways:
Use media-query-like javascript to determine when the wrapping occurs. Modernizr is great for this.
Check the offset.top of each column and compare. If they're next to each other the values will match. Any column at a different offset will obviously not be on the same row
It's a lot better/cleaner/easier to read than trying to judge based on element widths, etc.
However, you may want to look into display: table/table-cell for the columns and their parent, because that will give you equal heights as well.
I'm not fully sure I know what you're counting but I assume that you have columns that stop floating next to each other for smaller devices.

Draggable object doesn't recognize target Javascript Jquery

I'm new to Javascript, but I customized a code from an array of number to an array of letters in which I want to recognize the target in order to complete the game.
The error in the code is that its drops to any of the targets, that means that it doesn't recognize the respectively target.
The original code
and the code that I customized.
var correctCards = 0;
$(init);
function init() {
// Hide the success message
$('#successMessage').hide();
$('#successMessage').css({
left: '580px',
top: '250px',
width: 0,
height: 0
});
// Reset the game
correctCards = 0;
$('#vocalPile').html('');
$('#vocalSlots').html('');
// Create the pile of shuffled cards
var vocales = ["a", 'e','i' , 'o', 'u'];
vocales.sort( function() { return Math.random() - .5 } );
for ( var i=0; i<5; i++ ) {
$('<div>' + vocales[i] + '</div>')
.data('vocal', vocales[i])
.attr('id', 'vocal'+vocales[i])
.appendTo('#vocalPile')
.draggable({
containment: '#content',
stack: '#vocalPile div',
cursor: 'move',
revert: true
});
}
// Create the card slots
var words = ['a', 'e', 'i', 'o', 'u'];
for (var i = 1; i <= 5; i++ ) {
$('<div>' + words[i-1] + '</div>')
.data('vocal', i)
.appendTo('#vocalSlots')
.droppable({
accept: '#vocalPile div',
hoverClass: 'hovered',
drop: handleCardDrop
});
}
}
function handleCardDrop( event, ui ) {
var slotVocal = $(this).data('vocales');
var cardVocal = ui.draggable.data('vocales');
// If the card was dropped to the correct slot,
// change the card colour, position it directly
// on top of the slot, and prevent it being dragged
// again
if ( slotVocal == cardVocal ) {
ui.draggable.addClass('correct');
ui.draggable.draggable('disable');
$(this).droppable('disable');
ui.draggable.position({ of: $(this), my: 'left top', at: 'left top' });
ui.draggable.draggable('option', 'revert', false);
correctCards++;
}
// If all the cards have been placed correctly then display a message
// and reset the cards for another go
if (correctCards == 5) {
$('#successMessage').show();
$('#successMessage').animate( {
left: '380px',
top: '200px',
width: '400px',
height: '100px',
opacity: 1
});
}
}
I think that there's an error in the parameters that is passing through the functions. But I dont know how to change them in the if ==.
Thanks :)
PS. Is an array of vowels not number the one that I want to implement.
You have an error in
in create card slots:
$('<div>' + words[i-1] + '</div>')
.data( 'vocal',words[i-1])...
use words array
in handleCardDrop function fix data attribute to vocal not vocales as in your fiddle
function handleCardDrop( event, ui ) {
var slotVocal = $(this).data( 'vocal' );
var cardVocal = ui.draggable.data( 'vocal' );
working fiddle

Autoscrolling slide javascript

I have This javascript code for a slider that I downloaded , and can't figure out how to make it auto scrolling !!
I actually downloaded this code from http://tympanus.net/Tutorials/FullscreenSlitSlider/index2.html
It actually don't contain a next button so i can add an interval like the other sliders :(
$(function() {
var Page = (function() {
var $nav = $( '#nav-dots > span' ),
slitslider = $( '#slider' ).slitslider( {
onBeforeChange : function( slide, pos ) {
$nav.removeClass( 'nav-dot-current' );
$nav.eq( pos ).addClass( 'nav-dot-current' );
}
} ),
init = function() {
initEvents();
setInterval(initEvents,1000);
},
initEvents = function() {
$nav.each( function( i ) {
$( this ).on( 'click', function( event ) {
var $dot = $( this );
if( !slitslider.isActive() ) {
$nav.removeClass( 'nav-dot-current' );
$dot.addClass( 'nav-dot-current' );
}
slitslider.jump( i + 1 );
return false;
} );
} );
};
return { init : init };
})();
Page.init();
});
Like it says in the docs (Google is helpful):
slitslider = $( '#slider' ).slitslider({
autoplay : true
});
should do it.
If you don't want to read the whole thing, here's a short list of common config options:
$.Slitslider.defaults = {
// transitions speed
speed : 800,
// if true the item's slices will also animate the opacity value
optOpacity : false,
// amount (%) to translate both slices - adjust as necessary
translateFactor : 230,
// maximum possible angle
maxAngle : 25,
// maximum possible scale
maxScale : 2,
// slideshow on / off
autoplay : false,
// keyboard navigation
keyboard : true,
// time between transitions
interval : 4000,
// callbacks
onBeforeChange : function( slide, idx ) { return false; },
onAfterChange : function( slide, idx ) { return false; }
};

Categories

Resources