I have implemented aria-autocomplete and twitter/bloodhound typeahead.
Problem: It is partially working in the sense that it retrieves the value, but I want it to be automatically selected.
When I type in a Member ID, I want it to automatically select the name in a div below, and in a hidden textbox (which is later checked if there is a value, before allowing user to go to next screen)
What I've tried:
I have read the following:
https://msdn.microsoft.com/en-us/ie/hh968240(v=vs.94)
https://www.w3.org/TR/wai-aria-practices/examples/combobox/aria1.1pattern/listbox-combo.html
I then changed "aria-autocomplete": "list" to "both" as well as "inline" and neither had an affect.
I then changed my textbox from autocomplete off to autocomplete on with no effect:
I then read about typeahead, but I am not understanding why the autocompleted is not having an affect either. Here is the code for that:
.
displayKey: function (item) { return item.Subscriber_ID },
templates: {
//Template to show if there are no results
empty: function (context) {
// console.log(1) // put here your code when result not found
$(".tt-dataset").text('No Results Found');
},
suggestion: function (item) {
return '<div class=""> ' + item.First_Name + " " + item.Last_Name + '</div>';
}
}
})
.
I resolved this by adding some code to the suggestion function, to add a TextBox that the c# should look at , instead of having it look at it after the click:
$('#suggestionName').val(item.First_Name + " " + item.Last_Name); //used to check whether there is a value when hitting submit (hidden field)
$('#divDisplayMemberName').html(item.First_Name + " " + item.Last_Name); //displays it in a <p> tag underneath the TextBox
return '<div class=""> ' + item.First_Name + " " + item.Last_Name + '</div>'; //displays the actual suggestion
I'm relatively new with aspx and just tried to start moving my html page with youtube api with javascript into visual studio and aspx in order to move data into a database. In html the page seems to work fine and the next page button will successfully pass the pageToken. However, when I moved my html code to aspx, I noticed the page seems to refresh and drops my next page token, reloading the same front page. It also gives me a warning code that only occurs in aspx and not the html:
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/.
Setting 'XMLHttpRequest.withCredentials' for synchronous requests is deprecated.
I am not adding any scripts using my jquerys, which I believe is the main cause of this warning. My nextPage function however does recall the api for additional requests.
In terms of moving the html to aspx all I do is copy all my html code and put it into the header and body respectively. Am I missing a step in migrating? Do I have to change my code when using aspx instead of html?
Here is my current ASPX page:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" %>
<DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link href="StyleSheet1.css" rel="stylesheet" />
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript" src="JavaScript1.js"></script>
<script type="text/javascript" src="https://apis.google.com/js/client.js?onload=onClientLoad"></script>
<style type="text/css">
#courses {
width: 566px;
}
.auto-style1 {
width: 556px;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<div id="video-container">
<table><tr>
<td class="auto-style1">
<h1> Rutgers Accounting Digital Library Directory </h1>
</td>
<td align="right"><div id="summary"></div></td>
</tr>
<tr><td class="auto-style1"><form action="search_results.asp" method="Post"><input type="text" name="search1" placeholder="Search Here" size="20"><input type="Submit" name="Submit" value="Submit"></form></td><td><form method="link" action="my_uploads.html" ><input type="Submit" name="Clear" value="Clear Filters"></form></td></tr>
<tr><td colspan="2">
<form>
<select id="courses" onchange="show()">
<option selected disabled>Select a Course</option>
</select>
</form>
</td></tr>
<div class="button-container">
<tr>
<td class="auto-style1"><button id="prev-button" class="paging-button" onclick="previousPage();">Previous Page</button></td>
<td align="right"><button id="next-button" class="paging-button" onclick="nextPage();">Next Page</button></td>
</tr>
<tr>
<table id="results"></table>
</tr>
</table>
</div>
</div>
</form>
</body>
</html>
Here is my javascript page:
// Define some variables used to remember state.
var playlistId, nextPageToken, prevPageToken, status, cid;
var totalr = 0;
var rpp = 0;
var sum;
var dur = '';
function onClientLoad() {
gapi.client.load('youtube', 'v3', handleAPILoaded);
}
// After the API loads, call a function to get the uploads playlist ID.
function handleAPILoaded() {
gapi.client.setApiKey('APIKEY');
requestUserUploadsPlaylistId();
}
// Call the Data API to retrieve the playlist ID that uniquely identifies the
// list of videos uploaded to the currently authenticated user's channel.
function requestUserUploadsPlaylistId() {
// See https://developers.google.com/youtube/v3/docs/channels/list
var request = gapi.client.youtube.channels.list({
part: 'contentDetails',
forUsername: 'rutgersweb'
});
request.execute(function (response) {
cid = response.result.items[0].id;
dropdown(cid);
playlistId = response.result.items[0].contentDetails.relatedPlaylists.uploads;
requestVideoPlaylist(playlistId);
});
}
// Retrieve the list of videos in the specified playlist.
function requestVideoPlaylist(playlistId, pageToken) {
console.log(pageToken);
$('#results').html('');
console.log(pageToken);
var requestOptions = {
playlistId: playlistId,
part: 'snippet',
maxResults: 50
};
if (pageToken) {
requestOptions.pageToken = pageToken;
}
var request = gapi.client.youtube.playlistItems.list(requestOptions);
request.execute(function (response) {
totalv = response.pageInfo.totalResults;
rrp = response.pageInfo.resultsPerPage;
sum = '<td>Results Per Page: ' + rrp + '</td><td>Total Pages: ' + Math.ceil(totalv / rrp) + '<td>Total Videos: ' + totalv + '</td>';
$(sum).replaceAll('#summary');
// Only show pagination buttons if there is a pagination token for the
// next or previous page of results.
nextPageToken = response.result.nextPageToken;
var nextVis = nextPageToken ? 'visible' : 'hidden';
$('#next-button').css('visibility', nextVis);
$('#next-button2').css('visibility', nextVis);
prevPageToken = response.result.prevPageToken
var prevVis = prevPageToken ? 'visible' : 'hidden';
$('#prev-button').css('visibility', prevVis);
$('#next-button2').css('visibility', nextVis);
var playlistItems = response.result.items;
if (playlistItems) {
$.each(playlistItems, function (index, item) {
displayResult(item.snippet);
});
} else {
$('#results').html('Sorry you have no uploaded videos');
}
});
}
function getVideoDetails(mmp, ddp, yyyyp, dur, vidId, videoTitle, used) {
var request = gapi.client.youtube.videos.list({
part: 'contentDetails',
id: vidId
});
request.execute(function (response) {
var str = JSON.stringify(response.result.items[0].contentDetails.duration);
str = str.replace(/"/g, "");
str = str.replace(/PT/g, "");
str = str.replace(/H/g, ":");
str = str.replace(/M/g, ":");
str = str.replace(/S/g, "");
str = str.split(':');
var ftime;
if (str[1] < 10) {
ftime = str[1];
str[1] = '0' + ftime;
}
if (str[2] < 10) {
ftime = str[2];
str[2] = '0' + ftime;
}
displayOutput(mmp, ddp, yyyyp, str, vidId, videoTitle, used);
});
}
// Create a listing for a video.
function displayResult(videoSnippet) {
var videoTitle = videoSnippet.title;
var videoId = videoSnippet.resourceId.videoId;
var videoDescription = videoSnippet.description;
var videoPub = videoSnippet.publishedAt;
//dur =
//PublishedAt Formatting to compare
ar3 = videoPub.split("T");
uselessd = ar3[0];
re = new RegExp("-", "g");
uselessd2 = uselessd.replace(re, "/");
usedd = uselessd2.split("/");
ddp = usedd[2];
mmp = usedd[1];
yyyyp = usedd[0];
//Description trimming to leave time stamps only
ar = undefined;
useless = undefined;
useless2 = undefined;
used = undefined;
ar2 = undefined;
ar = videoDescription.split("Time Stamps:");
useless = ar[0];
useless2 = ar[1];
if (useless2 != undefined) {
ar2 = useless2.split("Summary");
ar = ar2[0];
re = new RegExp("\n", "g");
useless = ar.replace(re, "<br>");
used = useless;
}
else
used = " ";
// outputArray=[mmp, ddp, yyyyp, dur, videoId, videoTitle,used]
// displayOutput(outputArray);
getVideoDetails(mmp, ddp, yyyyp, dur, videoId, videoTitle, used)
}
function displayOutput(mmp, ddp, yyyyp, dur, videoId, videoTitle, used) {
//output = '<tr><td colspan="3" align="right">Published On: '+oarray[0]+'/'+oarray[1]+'/'+oarray[2]+'<br>'+dur+'</td></tr><tr><td><img src="http://img.youtube.com/vi/'+oarray[4]+'/1.jpg"></img></td><td>'+oarray[5]+'</td></tr><tr><td colspan="2" align="right">'+oarray[6]+'<hr>';
if (dur[2])
output = '<tr><td colspan="3" align="right">Published On: ' + mmp + '/' + ddp + '/' + yyyyp + '<br>Length: ' + dur[0] + ':' + dur[1] + ':' + dur[2] + '</td></tr><tr><td><img src="http://img.youtube.com/vi/' + videoId + '/1.jpg"></img></td><td>' + videoTitle + '</td></tr><tr><td colspan="2" align="right">' + used + '<hr>';
else
output = '<tr><td colspan="3" align="right">Published On: ' + mmp + '/' + ddp + '/' + yyyyp + '<br>Length: ' + dur[0] + ':' + dur[1] + '</td></tr><tr><td><img src="http://img.youtube.com/vi/' + videoId + '/1.jpg"></img></td><td>' + videoTitle + '</td></tr><tr><td colspan="2" align="right">' + used + '<hr>';
//Append to results listStyleType
$('#results').append(output);
}
// Retrieve the next page of videos in the playlist.
function nextPage() {
console.log(nextPageToken);
requestVideoPlaylist(playlistId, nextPageToken);
}
// Retrieve the previous page of videos in the playlist.
function previousPage() {
requestVideoPlaylist(playlistId, prevPageToken);
}
function dropdown(cid) {
var requestOptions = {
channelId: cid,
part: 'snippet',
maxResults: 50
};
var request = gapi.client.youtube.playlists.list(requestOptions);
request.execute(function (response) {
var plists = response.result.items;
if (plists) {
$.each(plists, function (index, item) {
var drp = document.getElementById("courses");
var optn = document.createElement("OPTION");
optn.text = item.snippet.title;
optn.value = item.id;
drp.add(optn);
});
} else;
});
}
function show() {
var e = document.getElementById('courses');
var txt = e.options[e.selectedIndex].value;
requestVideoPlaylist(txt);
}
I know the code is a little messy, still trying to get better coding habits, and I should probably fix some useless variables.
Set the type="button" on your button controls to prevent them from submitting the page each time they are pressed:
For example, in your ASPX page use:
<td class="auto-style1"><button type="button" id="prev-button" class="paging-button" onclick="previousPage();">Previous Page</button></td>
<td align="right"><button type="button" id="next-button" class="paging-button" onclick="nextPage();">Next Page</button></td>
I'm using the following to load posts into a index page of a wordpress site. The problem is when it gets to the last page and there are no more posts to load. Its just keeps reloading the last page.
Any ideas of how I might stop this from happening? Thanks.
var $content = '#content';
var $nav_wrap = '.navigation';
var $anchor = '.navigation a.next';
var $text = 'Load More';
var $next_href = $($anchor).attr('href'); // Get URL for the next set of posts
$($nav_wrap).html('<a id="almc-load-more" href="' + $next_href + '">' + $text + '</a>');
$('#almc-load-more').click(function(e) {
e.preventDefault();
$.get($(this).attr('href'), '', function(data) {
var $timestamp = new Date().getTime();
var $new_content = $($content, data).wrapInner('<div class="almc-loaded" id="almc-' + $timestamp + '" />').html(); // Grab just the content
$next_href = $($anchor, data).attr('href'); // Get the new href
$('html,body').animate({scrollTop: $($nav_wrap).position().top}, 'slow'); // Animate scroll
$($nav_wrap).before($new_content); // Append the new content
$('#almc-' + $timestamp).hide().fadeIn('slow'); // Animate load
$('#almc-load-more').attr('href', $next_href); // Change the next URL
$('.almc-loaded ' + $nav_wrap).remove(); // Remove the original navigation
});
});
Above code taken from here: http://kaspars.net/blog/wordpress/jquery-script-for-loading-more-posts
You could add some code to check if the new href is different than the current href, and then only try to add a new post if they're different. Then, if they aren't, you could have a message saying there are no more posts.
var lastLink;
$('#almc-load-more').click(function(e) {
if ( $anchor == $('.navigation a.next').last() ) {
lastLink = 1;
}
if (lastLink == 1) {return} else {
...
}
...
After the comment from Mr. Mayers (Thanks) I gave up on the code and used this tutorial:
http://www.problogdesign.com/wordpress/load-next-wordpress-posts-with-ajax/
Has / does everything I needed.
I have this form where the user can insert a quantity in an input field, and see the total in another input field. It works when you insert the numbers manually and I want it to work with buttons too, but i just can't get it to work.
Here's the code:
HTML
<form id="buyForm" method="post" action="cart.php">
<label>Choose quantity</label>
<div>
(+)increase
<input type="text" id="qty1" name="qty[]"/>
(-)decrease
</div>
<input type="text" id="cost1" value="50" style="display:none; visibility:hidden;" name="cost[]" />
<input type="text" id="price1" name="price[]" />
</form>
Js
// Calculate
function calc(idx) {
var price = parseFloat(document.getElementById("cost"+idx).value)*
parseFloat(document.getElementById("qty"+idx).value);
// alert(idx+":"+price);
document.getElementById("price"+idx).value= isNaN(price)?"0.00":price.toFixed(2);
}
window.onload=function() {
document.getElementsByName("qty[]")[0].onkeyup=function() {calc(1)};
document.getElementsByName("cost[]")[0].onkeyup=function() {calc(1)};
}
//Increase/decrease buttons
$(function() {
$(".button").click(function() {
var $button = $(this);
var oldValue = $button.parent().find("input").val();
if ($button.text() == "+") {
var newVal = parseFloat(oldValue) + 1;
// AJAX save would go here
} else {
// Don't allow decrementing below zero
if (oldValue >= 1) {
var newVal = parseFloat(oldValue) - 1;
// AJAX save would go here
}
}
$button.parent().find("input").val(newVal);
});
});
Here it is as jsfiddle: http://jsfiddle.net/rcheH/5/
Can someone please help me with this?
Thanks in advance!
I'm experiencing a problem to solve the newly added "Prix" in my Soiree Form
I've embedded the PRixForm in my SoireeForm and i'm using ajax calls to add as many prix as we want.
The problem is, when I want to add a new PRix by clicking on the "+" and after filling my fields nothing is saved...
When i'm editing or filling the first default embedded form prix it works which is weird. Only those added by ajax are not saved..
Here is my code
in my form, SoireeForm:
public function addNewPrix($number){
$new_prix = new BaseForm();
for($i=0; $i <= $number; $i+=1){
$pri = new Prix();
$pri->setSoiree($this->getObject());
$prix_form = new PrixForm($pri);
$new_prix ->embedForm($i, $prix_form);
}
$this->embedForm('new', $new_prix);
}
public function saveEmbeddedForm($con = null, $forms = null){
$dataForms = $this->getEmbeddedForm('new')->getEmbeddedForms();
foreach ($dataForms as $dataForm)
$dataForm->getObject()->setSoiree($this->getObject());
parent::saveEmbeddedForm($con, $forms);
}
In my action:
public function executeAdd($request)
{
$this->forward404unless($request->isXmlHttpRequest());
$number = intval($request->getParameter("num"));
$this->form = new SoireeForm();
$this->form->addNewPrix($number);
return $this->renderPartial('addPri',array('form' => $this->form, 'num' => $number));
}
my partial addPri:
<li>
<?php echo $form['new'][$num]['titre']->renderLabel();?>
<?php echo $form['new'][$num]['titre']->render()?>
<?php echo $form['new'][$num]['montant']->renderLabel();?>
<?php echo $form['new'][$num]['montant']->render();?>
<br />
<br />
and my prix.js file:
newfieldscount = 0;
function addPri(num) {
return $.ajax({
type: 'GET',
url: '/backend_dev.php/soiree/add?num='+num,
async: false
}).responseText;
};
var removeNew = function(){
$('.removenew').click(function(e){
e.preventDefault();
$(this).parent().remove();
})
};
$(document).ready(function(){
$('#add_prix').click(function(e) {
e.preventDefault();
$("ul#extraprix").append(addPri(newfieldscount));
newfieldscount = newfieldscount + 1;
$('.removenew').unbind('click');
removeNew();
});
});
I guess the problem comes from my saveEmbed method in my form, but i don't understand why or how to make everything work as it should.
Thank you in advance you guys
So you want save an 1:n relation, so you should find everything you need here
http://www.thatsquality.com/articles/stretching-sfform-with-dynamic-elements-ajax-a-love-story
http://www.symfony-project.org/more-with-symfony/1_4/en/06-Advanced-Forms
If not, please provide information or code of your PrixForm->configure() function !
PS: Your saveEmbeddedForm() function is unneeded, you'll find more information about the form saving process in the second link in chapter 6 !