I am creating an audio player of sorts and i have run into a brick wall. I have added a progress bar that updates according to the song being played.
However, I want the progress bar to be clickable and to jump to the time of the track when its clicked (like every regular player).
<div class="music-stream-wrapper">
<ul class="music-stream">
<li>
<div class="player-wrapper">
<div class="album-art">
<img src="https://i1.sndcdn.com/artworks-000108593302-0ek7n6-t120x120.jpg" alt="" />
</div>
<div class="meta-controls">
<div class="play-controls">
<!-- Content -->
<div class="track">
<h4 class="title">Tail toddle - Unknown</h4>
<span class="author">john.doe</span>
<span class="uploaded">a few seconds ago</span>
</div>
<div class="spectrum">
<div class="play-pause-button">
</div>
<div class="spectrum-wrapper">
<div id="spectrum_11"></div>
<div class="progress">
<progress value="0" max="1"></progress>
</div>
</div>
</div>
</div>
<div class="intent">
<ul class="buttons">
<li>Like</li>
<li>Download</li>
<li>Share</li>
</ul>
<ul class="meta">
<li><span class="liked">♥ 13</span></li>
<li><span class="played">► 123</span></li>
<li><span>♥ 3</span></li>
</ul>
</div>
</div>
</div>
</li>
</ul>
</div>
<audio src="http://tonycuffe.com/mp3/tailtoddle_lo.mp3" id="mockSong"></audio>
I have created a mock player in CodePen heres the url: View in CodePen
I ended up using a jQuery UI slider and updating it dynamically as the track position changed.
It will help you. try to evaluate what you desire for
http://jsfiddle.net/ryanhagz/8u76B/20/
HTML
<div id="progress"></div>
<div id="back">back</div>
<div id="cont">cont</div>
JAVASCRIPT
//PROGRESS BAR
$("#progress").progressbar({
value: 0
});
//UPDATING PROGRESS BAR WHEN CONTINUE BUTTON CLICKED
var currValue = 0,
toValue = 0;
$("#cont").button().click(function () {
currValue = $("#progress").progressbar("value");
if (currValue + 25 <= 100) {
toValue = currValue + 25;
animateProgress();
}
});
//DECREASING PROGRESS BAR WHEN GO BACK BUTTON CLICKED
$("#back").button().click(function () {
currValue = $("#progress").progressbar("value");
if (currValue - 25 >= 0) {
toValue = currValue - 25;
animateProgress();
}
});
function animateProgress() {
if (currValue < toValue) {
$("#progress").progressbar("value", currValue + 1);
currValue = $("#progress").progressbar("value");
setTimeout(animateProgress, 4);
} else if (currValue > toValue) {
$("#progress").progressbar("value", currValue - 1);
currValue = $("#progress").progressbar("value");
setTimeout(animateProgress, 4);
}
}
Related
I have a sidebar item which contains a list of comments. I want this item to show only if there are any available comment in the beginning and in order for my template to work I have to put a different style to the first comment than the rest. All the comments are being passed on my Model.
Here is my approach:
#if(Model.Comments?.Count > 0) {
<div class="sidebar_item">
<div class="item_inner slider">
<h4>See what students say:</h4>
<div id="single_banner">
<ul class="slides">
#for (int i = 0; i < Model.Comments.Count; i++)
{
if (i > 0){
<li style="display:none;">
}
#if( i == 0)
{
<li>
}
#Model.Comments[i].Comment
<div class="carousal_bottom">
<div class="thumb">
<img src="img/courses/testi_thumb.png" draggable="false" alt="" />
</div>
<div class="thumb_title">
<span class="author_name">#Model.Comments[i].Student</span>
</div>
</div>
</li>
}
</ul>
</div><!--end banner-->
</div><!--slider-->
</div><!--end sidebar item-->
}
The problem is that this doesn't work and I get errors that some curly brackets are missing or that some elements haven't closed properly. Any help appreciated.
I get errors that [...] some elements haven't closed properly.
The following code isn't recommended because the engine isn't smart enough to determine start/ends for html elements in c# code:
if (i > 0){
<li style="display:none;">
}
#if( i == 0)
{
<li>
}
So I generally put the logic directly in the tag:
<li style="#(i > 0 ? "display:none;" : string.Empty)">
However I'm not really a fan of logic in my view. Additionally to make things easier IMHO, I would have a comment display template. And I personally think there is no good reason to not use classes. Eventually my code would look like:
controller:
foreach(var comment in Model.Comments)
{
comment.IsVisible = comment == Model.Comments.First();
}
view:
// Update Model with Property
// bool HasComments { get { return Comments.Any(); } }
// Then the code actually reads/documents itself
#if(Model.HasComments) {
<div class="sidebar_item">
<div class="item_inner slider">
<h4>See what students say:</h4>
<div id="single_banner">
<ul class="slides">
#Html.DisplayFor(m => m.Comments);
</ul>
</div><!--end banner-->
</div><!--slider-->
</div><!--end sidebar item-->
}
displaytemplates/comments.cshtml
#{
// View logic, it only deals with html/css/javascript
var liClass = model.IsVisible ? string.Empty : "is-not-visible";
}
<li class="#liClass">
#Model.Comments[i].Comment
<div class="carousal_bottom">
<div class="thumb">
<img src="img/courses/testi_thumb.png" draggable="false" alt="" />
</div>
<div class="thumb_title">
<span class="author_name">#Model.Student</span>
</div>
</div>
</li>
Less code and more encapsulated.
I'd also recommend reading Philip Walton - Decoupling Your HTML, CSS, and JavaScript
App doesn't cover all display on mobile - there is a slim black bar on the bottom.
<body>
<div data-role="page" id="main" data-theme="b" data-fullscreen="true">
<div data-role="header" data-fullscreen="true">
<h1>Scheduler</h1>
Dodaj
</div>
<div data-role="main" class="ui-content" id="list">
</div>
<div data-role="footer" data-position="fixed" data-fullscreen="true" data-tap-toggle="false">
<div data-role="navbar">
<ul>
<li>Settings</li>
<li>Info</li>
</ul>
</div>
</div>
</div>
<!--Adding goals-->
<div data-role="page" id="adding">
<div data-role="header">
<h1>Adding new goal</h1>
</div>
<div data-role="main" class="ui-content">
<form data-theme="e">
<form onsubmit="return false;">
<label>
NEW GOAL:<input type="text" id="goal" />
</label>
<input type="button" value="ADD" id="addBtn"/>
</form>
</form>
</div>
</div>
<!--Settings-->
<div data-role="page" id="settings">
<div data-role="header">
<h1>Settings</h1>
</div>
<div data-role="main" class="ui-content">
<form data-theme="e">
<input type="button" value="Clear all elements" id="delBtn"/>
</form>
</div>
</div>
<!-- Info -->
<div data-role="page" id="info">
<div data-role="header">
<h1>Info</h1>
</div>
<div data-role="main" class="ui-content">
Here help will be. ~~Yoda
</div>
</div>
CSS code is like this:
#main{height:100% !important;}
html,body{
margin:0;
padding:0;
border:none;
}
javascript code:
var db = new PouchDB('goals');
var remoteCouch = 'goals_remote';
db.changes({
since: 'now',
live: true
}).on('change', createList);
createList();
//creating goals
document.getElementById('addBtn').addEventListener('click', function(){
var txt = document.getElementById('goal').value;
var goal = {
_id: new Date().toISOString(),
text: txt,
completed: false
}
db.put(goal, function callback(err, result){
if(!err){
console.log('success');
refresh();
}
});
}, false);
//deleting elements
document.getElementById('delBtn').addEventListener('click', function(){
db.destroy().then(function() {
refresh();
});
}, false);
function refresh(){
location.reload(true);
}
//pressing goal
function pressGoal(goal){
if(goal.completed){
goal.completed = false;
} else {
goal.completed = true;
}
db.put(goal);
createList();
}
function createList() {
var completedTasks = [];
var notCompletedTasks = [];
db.allDocs({
include_docs: true,
descending: true
}).then(function(result) {
for(var k = 0; k < result.rows.length; k++){
if(result.rows[k].doc.completed){
completedTasks.splice(completedTasks.length, 0, result.rows[k].doc);
} else {
notCompletedTasks.splice(notCompletedTasks.length, 0, result.rows[k].doc);
}
renderList(completedTasks, notCompletedTasks);
}
}).catch(function(err) {
console.log(err);
});
}
function renderList(completedTasks, notCompletedTasks){
var code = '';
var notCode = '';
var elementsArr = [];
//creating lists
for(var i = 0; i < notCompletedTasks.length; i++){
code += '<div class="ui-checkbox" id="'+notCompletedTasks[i]._id+'"><label class="ui- checkbox-off ui-btn ui-btn-corner-all ui-fullsize ui-btn-icon-left ui-btn-up-b" data-corners="true" data-shadow="false" data-iconshadow="true" data- wrapperels="span" data-icon="checkbox-off" data-theme="b" data-mini="false"> <span class="ui-btn-inner"><span class="ui-btn-text">'+notCompletedTasks[i].text+'</span><span class="ui-icon ui-icon-checkbox-off ui-icon-shadow"> </span></span></label><input type="checkbox"></div>';
}
for(var j = 0; j < completedTasks.length; j++){
notCode += '<div class="checked" id="'+completedTasks[j]._id+'">'+'<div class="ui-icon ui-icon-check">'+'</div>'+'<span class="field">'+completedTasks[j].text+'</span>'+'</div>';
}
//build
document.getElementById('list').innerHTML = code + notCode;
for(var k = 0; k < notCompletedTasks.length; k++){
(function(){
var arg = notCompletedTasks[k];
document.getElementById(arg._id).addEventListener('click', function(){
pressGoal(arg);
}, false);
})();
}
for(var k = 0; k < completedTasks.length; k++){
(function(){
var arg = completedTasks[k];
document.getElementById(arg._id).addEventListener('click', function(){
pressGoal(arg);
}, false);
})();
}
}
I hope that code will be enough. I don't know why CSS code doesn't work like it should.
Is there any way to do this? I couldn't find answer to this question.
Edit: I added javascript code. Unfortunately I don't know what created that problem so code is kinda huge. Sorry for that.
I used pouchDB for storing users data and compiled with cocoon.io for mobiles.
You may look at this post from Omar: set content height 100% jquery mobile. It is updated with a working solution for the current JQM 1.4.5 version and is also covering the issues related to html{ height: 100%; }.
Im attempting to implement the following Flexbox table from Vasan Subramanian with vue.
That table is built manually, but That doesnt give much help when trying to make a component of it.
So Im willing to make it dinamically. and my first obstacle is to group each pair of two rows inside one div. Like the following
<div class="Table">
<div class="Table-row Table-header">
<div class="Table-row-item" v-for="key in cols" v-bind:style="{'flex-basis':basis, 'flex-grow':key.grow}">
<a #click="sortBy(key)">{{key.title}} <i v-if="key.sortField==sort" class="{{reverse==1?'fa fa-sort-desc':'fa fa-sort-asc'}}" aria-hidden="true"></i></a>
</div>
</div>
The previous code gives the normal table header
<div class="Table-row-item">
firstname
</div>
<div class="Table-row-item">
lastname
</div>
<div class="Table-row-item">
email
</div>
<div class="Table-row-item">
company
</div>
Im trying to achieve the following:
<div class=divider>
<div class="Table-row-item">
firstname
</div>
<div class="Table-row-item">
lastname
</div>
</div>
<div class=divider>
<div class="Table-row-item">
email
</div>
<div class="Table-row-item">
company
</div>
</div>
My Issue is I dont know how to represent that in code.
Any help would be very appreciated. I couldnt find any good examples about responsive tables with Flexbox. just the previous and this other from Jonathan Lehman An excellent Lecture using Sass.
You want to group your columns, and then loop over the columns within each group. Use a computed to do the grouping. Your grow specification doesn't quite fit this model; it seems like you want to have one grow spec per group, but I don't know exactly what the goal is there.
This code makes column groups of whatever size you choose and puts them in your dividers.
new Vue({
el: '.Table',
data: {
columns: ['firstname', 'lastname', 'email', 'company'].map((n) => ({
title: n,
sortField: n
})),
perDivider: 2,
basis: '50%',
grow: 1,
sort: null
},
computed: {
colGroups: function() {
return this.by(this.perDivider, this.columns);
}
},
methods: {
by: function(n, arr) {
const result = [];
for (var i = 0; i < arr.length; i += n) {
result.push(arr.slice(i, i + n));
}
return result;
}
}
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.min.js"></script>
<div class="Table">
Table here
<div class="Table-row Table-header">
<div class="Table-row-item" v-for="colGroup in colGroups" v-bind:style="{'flex-basis':basis, 'flex-grow':grow}">
<a v-for="key in colGroup" #click="sortBy(key)">
{{key.title}} <i v-if="key.sortField==sort" class="{{reverse==1?'fa fa-sort-desc':'fa fa-sort-asc'}}" aria-hidden="true"></i>
</a>
</div>
</div>
</div>
I Started with a computed property
odd(){
var numberOdds = 0;
var arr = [];
for (var i = 0; i < this.cols.length; i++) {
if (i % 2 == 0) {
numberOdds++;
}
}
var j=0;
for (i=0;i<numberOdds;i++){
this.arr[i]=j;
j+=2;
}
return numberOdds;
}
so..
<div class="Table">
<div class="Table-row Table-header">
<div class="divider" v-for="number in odd">
{{cols[arr[number]].title}}
{{cols[arr[number]+1].title}}
</div>
</div>
<div class="Table-row" v-for="item in items.data" >
<div class="divider" v-for="number in odd">
<div class="Table-row-item">
{{item[cols[arr[number]].name]}}
</div>
<div class="Table-row-item">
{{item[cols[arr[number]+1].name]}}
</div>
</div>
</div>
</div>
This works. testing purposes
I have a question about my CCS code.
I got a button with above that a loading bar (that shows when you click on the button).
If I press the button, the loading bar comes but it pushes the button down and I've tried to make the button to position `fixed'.
Can someone tell me if there is another way or can you give a solution to my own code.
My HTML code with the button and loading bar:
<div class="row">
<div class="col s12 m8 l6">
<div id="loader" class="center"></div>
<a id="submitForm" class="btn green waves-effect waves-light">Add Contact
<i class="material-icons right">add</i>
</a>
</div>
</div>
This is my CSS for the button, the .btn selector is a class from materialize:
.btn{
background-color: #88969c !important;
position: fixed !important;
margin-top: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.7/js/materialize.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.7/css/materialize.css" rel="stylesheet"/>
<div class="row">
<div class="col s12 m8 l6">
<div id="loader" class="center"></div>
<a id="submitForm" class="btn green waves-effect waves-light">Add Contact
<i class="material-icons right"></i>
</a>
</div>
</div>
<script>
(function () {
$('#submitForm').on('click', function (e) {
e.preventDefault();
if($("#submitForm").hasClass('disabled')){
return;
}
$('#submitForm').addClass('disabled');
var randId = Math.floor((Math.random() * 19990307) + 1);
$('#loader').append('<div id="'+ randId +'" class="progress"><div class="indeterminate"></div></div>');
var name = $("#name").val();
var phonenumber = $("#phonenumber").val();
$("#name").val('');
$("#phonenumber").val('');
var data = {
name: name,
phonenumber: phonenumber
};
$.ajax({
url: 'addNew',
data: data,
method: 'post',
success: function (data) {
Materialize.toast(' '+ data +' ', 4000, 'cool white-text');
console.log(data);
$('#'+ randId +'').fadeOut(150, function () {
$('#'+ randId +'').remove();
$('#submitForm').removeClass('disabled');
});
},
})
})
})();
</script>
First of all you should make .btn { position: static; }. So that when ever loading bar comes your btn also shift itself down. And for making this happen (shifting and all). You have to use javascript or jquery.
<ion-slide ng-repeat="category in uniqueCategories" ng-if="$index % 4 === 0">
<div class="row" id="rowInSlider">
<div class="col col-25" ng-if="$index < uniqueCategories.length" ng-click="CategorySelected(uniqueCategories[$index], $index)">
<span class="img-centered img-padding imageDiv button button-icon">
<img class="smaller" src="img/south-indian-category-thumb.png">
</span>
<p class="smaller">{{uniqueCategories[$index]}}</p>
</div>
<div class="col col-25" ng-if="$index+1 < uniqueCategories.length" ng-click="CategorySelected(uniqueCategories[$index+1])">
<div class="img-centered img-padding imageDiv button button-icon">
<img class="smaller" src="img/south-indian-category-thumb.png">
</div>
<p class="smaller">{{uniqueCategories[$index+1]}}</p>
</div>
</ion-slide>
How can I set the background color for selected div?
This is what I tried:
<div class="col col-25" ng-if="$index < uniqueCategories.length" ng-click="CategorySelected(uniqueCategories[$index], $index)" ng-class="{selectedCategory: selectedCategory[$index]" >
controller:
$scope.CategorySelected=function(categoryName, indexNumber){
console.log(indexNumber)
$rootScope.readyToRender=false;
var selectedCategory={}
selectedCategory[indexNumber]=true;
}
But it does not work and I get no background color.
You wrote:
ng-class="{selectedCategory: selectedCategory[$index]"
First, there is a missing curly bracket, but there is also another problem: you have to expose selectedCategory on the $scope:
$scope.CategorySelected = function (indexNumber){
$scope.selectedCategory = {};
$scope.selectedCategory[indexNumber] = true;
}
Then:
ng-class="{selectedCategory: selectedCategory[$index]}"
That said, what you want to achieve here is probably better done by adding a flag isSelected to the category object.