I'm adding new rows dynamically to the existing table, the first column of the table holds the Edit & Delete buttons. I'm facing 2 problems with this:
Not able to Edit and Delete newly added rows, tried .live but couldn't make it work
Not able to get the record id of the newly added rows (ajax returns the record when new rows are added).
Code looks like this:
Adding new rows:
<script type="text/javascript">
$(function() {
$('#btnSubmit').click(function() {
var oEmployee = new Object();
oEmployee.Title = $("#Title").val();
oEmployee.Middlename = $("#MiddleName").val();
oEmployee.Lastname = $("#LastName").val();
oEmployee.Email = $("#Email").val();
var DTO = {'employee': oEmployee};
var options = {
type: "POST",
url: "WebService.asmx/InsertEmployee",
data: JSON.stringify(DTO),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(response) {
if (response.d != "") {
if (parseInt(response.d) >= 1) {
var contactID;
contactID = parseInt(response.d);
$('#tblEmployee tbody tr:first').after("<tr id=" + contactID + "><td><input type='button' class='newContactID' value='Edit'/> <input type='button' value='Delete'/></td><td align=center>" + contactID + "</td><td align=center>" + oEmployee.Title + "</td><td align=center>" + oEmployee.Middlename + "</td><td align=center>" + oEmployee.Lastname + "</td><td align=center>" + oEmployee.Email + "</td><tr>"); // need to hook up editing and deleting function to the newly added rows }
else {
alert("Insert Failed \n" + response.d);
}
}
}
};
//Call the webservice
$.ajax(options);
});
});
</script>
Code for editing and deleting:
$(function() {
$("#tblEmployee > tbody > tr ").each(function() {
var TRID = $(this).attr("id");
$(this).find("td:first > input[value=Edit]").click(function() {
ResetOtherRowEdit();
ChangeTableCellToTextbox(TRID);
$(this).hide();
$("#tblEmployee > tbody > tr[id=" + TRID + "] > td:first> input[value=Delete]").hide();
return false;
});
$(this).find("td:first > input[value=Update]").click(function() {
UpdateRow(TRID);
});
$(this).find("td:first > input[value=Delete]").click(function() {
DeleteRow(TRID);
});
$(this).find("td:first > input[value=Cancel]").click(function() {
CancelEdit(TRID);
});
});
});
What is the best way to approach this? Editing and deleting of records work fine when they're pulled off the database.
Update
This is how the code looks like now, just began dabbling with Jquery a month back, still trying to get my head around it.
$(function() {
$("#tblEmployee > tbody > tr ").live('click', function(e) {
var TRID = $(this).attr("id");
var $target = $(e.target);
if ($target.is('#btnEdit')) {
$(this).find("td:first > input[value=Edit]").click(function() {
ResetOtherRowEdit();
ChangeTableCellToTextbox(TRID);
$(this).hide();
$("#tblEmployee > tbody > tr[id=" + TRID + "] > td:first> input[value=Delete]").hide();
return false;
});
}
else if ($target.is('#btnUpdate')) {
$(this).find("td:first > input[value=Update]").click(function() {
UpdateRow(TRID);
});
}
else if ($target.is('#btnCancel')) {
$(this).find("td:first > input[value=Cancel]").click(function() {
CancelEdit(TRID);
});
}
else if ($target.is('#btnDelete')) {
$(this).find("td:first > input[value=Delete]").click(function() {
DeleteRow(TRID);
});
}
});
});
HTML codes looks like this:
<ItemTemplate>
<tr id='<%# Eval("ContactID") %>'>
<td width="10%">
<input type="button" value="Edit" id="btnEdit"/>
<input type="button" value="Delete" id="btnDelete"/>
<input type="button" value="Update" style="display:none" id="btnUpdate" />
<input type="button" value="Cancel" style="display:none" id="btnCancel"/>
</td>
<td width="10%" align="center"><%# Eval("ContactID")%></td>
<td width="20%" align="center"><%# Eval("Title")%></td>
<td width="20%" align="center"><%# Eval("MiddleName")%></td>
<td width="20%" align="center"><%# Eval("LastName")%></td>
<td width="20%" align="center"><%# Eval("EmailAddress")%></td>
</tr>
</ItemTemplate>
You could take advantage of DOM traversal and .live() to make this work. Add a listener using .live() to the rows of the table. Inside this method, determine which element was clicked (e.currentTarget). You can use a simple conditional to check if it was a button that needs to react. Then, use DOM traversal to nail down what you want to have happen. For example, if e.currentTarget is the delete button, the you can use $(this).closest('tr').remove(); to delete the row. If you need to interact with the data through ajax, make your ajax function support passing in whatever valus you'd need (id) to perform the delete. In order to obtain the id, you'll need to get it from the ajax call and put it somewhere inside the DOM so you can retrieve it when you need it. You can always toss in a 'title' attribute when the tr is generated.
Here is a same script with php
http://www.amitpatil.me/add-edit-delete-rows-dynamically-using-jquery-php/
// Add new record
$(document).on("click","."+editbutton,function(){
var id = $(this).attr("id");
if(id && editing == 0 && tdediting == 0){
// hide editing row, for the time being
$("."+table+" tr:last-child").fadeOut("fast");
var html;
html += "<td>"+$("."+table+" tr[id="+id+"] td:first-child").html()+"</td>";
for(i=0;i<columns.length;i++){
// fetch value inside the TD and place as VALUE in input field
var val = $(document).find("."+table+" tr[id="+id+"] td[class='"+columns[i]+"']").html();
input = createInput(i,val);
html +='<td>'+input+'</td>';
}
html += '<td><img src="'+updateImage+'"> <img src="'+cancelImage+'"></td>';
// Before replacing the TR contents, make a copy so when user clicks on
trcopy = $("."+table+" tr[id="+id+"]").html();
$("."+table+" tr[id="+id+"]").html(html);
// set editing flag
editing = 1;
}
});
Related
So I have already written the testing script which:
1) Logs into the application framework, then
2) Clicks menu to launch the app which I am testing ("MyAwesomeApp.html" for this post)
And my main problem is: In navpanel-spec.js below, I want to target the https://server/apps/Default.aspx?r=1 URL, then click within the iframe where MyAwesomeApp is running.
**** ERROR Trying to switch to the iframe this way, but it does NOT work:
browser.switchTo().frame(element(by.id('1')).getWebElement());
Error in cmd prompt:
Started
[15:43:29] E/launcher - No element found using locator: By(css selector, *[id="\31 "])
...
sat-navpanel-spec.js:52:24)
So there are two URLs going on here:
1) https://server/apps/Default.aspx?r=1 (the main app framework with menu system in top nav).
2) https://server/apps/MyAwesomeApp.html (the web app which the test script launches within the <iframe> tag.
The html looks like this, where the application renders within the <iframe> :
<body>
<div id="top">
<!-- top nav menu systems rendered here -->
</div>
<div id="middle">
<div id="m1">
<div id="m2" class="hidden">
<div id="m3">
<div id="right" class="hidden">
<div>
<div id="frame_holder" style="height: 940px;">
<iframe style="width: 100%; height: 100%;" name="1" id="1" src="https://server/apps/MyAwesomeApp.html">
</iframe>
</div>
</div>
</div>
</div>
<div id="left" style="display: none;"></div>
</div>
</div>
</div>
</body>
In my Protractor.config.js file I have a few specs :
specs: [
'spec/login.js',
'spec/launch-awesome-app.js',
'spec/navpanel-spec.js',
'spec/another-spec.js',
'spec/yet-another-spec.js'
]
login.js and launch-awesome-app.js work fine. They log into the menu system, then click thru the menus in order to launch myAwesomeapp - no problem.
MY PROBLEM:
In navpanel-spec.js I want to target the https://server/apps/Default.aspx?r=1 URL, then click within the iframe where MyAwesomeApp is running.
However, it is NOT selecting any of my elements.
If I target https://server/apps/MyAwesomeApp.html in navpanel-spec.js, of course it launches a new browser window and runs the test just fine.
Here's my navpanel-spec.js test spec:
describe('Testing My Awesome App', function () {
var panelObj = new PanelObjects();
var urlDefault = 'https://server/apps/Default.aspx?r=1';
var urlApp = 'https://server/apps/MyAwesomeApp.html';
browser.get(urlApp); // Runs my AwesomeApp tests okay, HOWEVER it launches a new browser window.
browser.get(urlDefault); // Launches app framework with top nav menus and embedded <iframe>,
// HOWEVER I cannot select iframe and successfully run tests here.
beforeEach(function () {
browser.sleep(5000);
browser.waitForAngular();
});
// USE-CASE OBJECT !!
var items = browser.params.useCaseJsonFile["navigatePanels"];
browser.getAllWindowHandles().then(function (handles) {
handles.map(function (win, idx) {
browser.driver.getCurrentUrl().then(function (curr) {
if (curr.indexOf('Default.aspx') >= 0) {
browser.driver.switchTo().window(handles[idx]);
}
});
});
});
browser.switchTo().frame(element(by.id('1')).getWebElement());
var testId = element(by.id('middle'));
console.log(testId);
items.map(function (item) {
if (item.enableTest) {
var specItem = it(item.name, function () {
console.log('------------------------------');
console.log('---- ' + item.describe);
browser.waitForAngular();
// select panels, etc..
panelObj.panelClick(item.panelName).then(function () {
// ...
});
panelObj.getPanelText(item.panelName).then(function (title) {
expect(title).toContain(item.panelTitle);
});
});
}
});
});
UPDATE
var LoginObjects = require('../pageObjects/login-objects.js');
describe('Testing My Awesome App', function () {
var panelObj = new PanelObjects();
var loginObj = new LoginObjects();
//var urlDefault = 'https://server/apps/Default.aspx?r=1';
//browser.get(urlApp); // Runs my AwesomeApp tests okay, HOWEVER it launches a new browser window.
browser.ignoreSynchronization = true;
// LOGIN AND LAUNCH APP !!!
loginObj.Login();
loginObj.Launch();
beforeEach(function () {
browser.sleep(5000);
browser.waitForAngular();
});
// USE-CASE OBJECT !!
var items = browser.params.useCaseJsonFile["navigatePanels"];
// SWITCH TO iframe ELEMENT
loginObj.switchWindowAndFrame();
items.map(function (item) {
if (item.enableTest) {
var specItem = it(item.name, function () {
console.log('------------------------------');
console.log('---- ' + item.describe);
browser.waitForAngular();
// select panels, etc..
panelObj.panelClick(item.panelName).then(function () {
// ...
});
panelObj.getPanelText(item.panelName).then(function (title) {
expect(title).toContain(item.panelTitle);
});
});
}
});
});
and my page objects :
module.exports = function(){
this.Login = function(){
var url = browser.params.loginUrl;
browser.driver.get(url);
browser.sleep(200);
var userName = browser.params.credential.userId;
var password = browser.params.credential.password;
element(by.id('username')).clear().then(function(){
element(by.id('username')).sendKeys(userName);
element(by.id('password')).sendKeys(password);
});
browser.sleep(1000);
var that = this;
var submitElement = element(by.id('bthLogin'));
submitElement.click().then(function () {
browser.getAllWindowHandles().then(function (handles) {
// LOGIN MESSAGE WINDOW
browser.driver.getCurrentUrl().then(function(curr){
if (curr.indexOf('LoginMsg.aspx') >= 0){
// Do we really need to close the login successful browser ???
browser.driver.close();
}
});
browser.driver.switchTo().window(handles[1]);
});
});
},
this.Launch = function(){
var sel = '#TheMenu1 > ul > li:first-child';
var elem = element(by.css(sel));
elem.click().then(function(){
browser.sleep(1000);
var elem2 = element(by.cssContainingText('.rmLink', 'The First Menu Item'));
elem2.click();
// Select menu item; sleep before attempting to click().
var subElem = element(by.cssContainingText('.rmLink', 'My Awesome App'));
browser.sleep(1000);
subElem.click();
browser.waitForAngular();
});
},
this.switchWindowAndFrame = function(){
browser.getAllWindowHandles().then(function (handles) {
handles.map(function(win, idx){
browser.driver.getCurrentUrl().then(function(curr){
if (curr.indexOf('Default.aspx') >= 0){
browser.driver.switchTo().window(handles[idx]);
}
});
});
});
browser.switchTo().frame(element(by.css('[name="1"]')).getWebElement());
}
};
As mentioned in the comments above, protractor has a bug which prefixes '\3' to your id element with number.
The temporary way is to change you locator. :P
I would like to create a form that allows anyone to upload multiple files to my drop box. But I would also like for the person that uploads the file to receive a confirmation email. The following code uploads the files but does send the email. Please help!
Here is the .gs
function doGet(e) {return HtmlService.createHtmlOutputFromFile('form.html');}
function sendEmails(form) {
var message= ", your abstract was submitted. Send other work by APR 20";
var subject = "Application Received";
MailApp.sendEmail(form.myEmail, subject, message);
}
function uploadFiles(form) {
try {
var dropbox = "New Abstracts";
var folder, folders = DriveApp.getFoldersByName(dropbox);
if (folders.hasNext()) {
folder = folders.next();
} else {
folder = DriveApp.createFolder(dropbox);
}
var blob = form.myFile1;
var file = folder.createFile(blob);
file.setDescription("Uploaded by " + form.myName);
var blob = form.myFile2;
var file = folder.createFile(blob);
file.setDescription("Uploaded by " + form.myName);
return "File uploaded successfully " + file.getUrl();
} catch (error) {
return error.toString();
}
}
And here is the .html portion
<form id="myForm">
<input type="text" name="myName" placeholder="Your name..">
<input type="email" name="myEmail" placeholder ="Your email..">
<input type="file" name="myFile1" >
<input type="file" name="myFile2" >
<input type="submit" value="Upload File"
onclick="this.value='Uploading..';
google.script.run.withSuccessHandler(fileUploaded)
.uploadFiles(this.parentNode).sendEmails(this.parentNode);
return false;">
<script>
function fileUploaded(status) {
document.getElementById('myForm').style.display = 'none';
document.getElementById('output').innerHTML = status;
}
</script>
<style>
input { display:block; margin: 20px; }
</style>
I trying this based on the codes found at:
http://www.labnol.org/internet/receive-files-in-google-drive/19697/
You can't append multiple calls to the script like this:
google.script.run.withSuccessHandler(fileUploaded)
.uploadFiles(this.parentNode).sendEmails(this.parentNode);
Only uploadFiles (the first one being called) gets executed. Everything after that is getting ignored.
You can add the code inside sendEmails() to the uploadFiles() as one solution? Or add it to the success handler? Or have uploadFiles() call sendEmails() once it is done...
I want . Auto complete text box with multiple keyword. it's from database. if I use jQuery and do operation in client side mean. If the database size is huge, it leads to some issues. I need to know how this is done on the server side and get proper result.
I have already seen this topic but the operation is done on the client side. I need it from the database directly.
<html>
<head>
<title>Testing</title>
<link href="css/jquery-ui-1.10.3.custom.css" rel="stylesheet" type="text/css" />
<style type="text/css">
.srchHilite { background: yellow; }
</style>
<script src="scripts/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="scripts/jquery-ui-1.10.3.custom.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
NewAuto();
});
function NewAuto() {
var availableTags = ["win the day", "win the heart of", "win the heart of someone"];
alert(availableTags); // alert = win the day,win the heart of,win the heart of someone
$("#tags").autocomplete({
source: function(requestObj, responseFunc) {
var matchArry = availableTags.slice(); // Copy the array
var srchTerms = $.trim(requestObj.term).split(/\s+/);
// For each search term, remove non-matches.
$.each(srchTerms, function(J, term) {
var regX = new RegExp(term, "i");
matchArry = $.map(matchArry, function(item) {
return regX.test(item) ? item : null;
});
});
// Return the match results.
responseFunc(matchArry);
},
open: function(event, ui) {
// This function provides no hooks to the results list, so we have to trust the selector, for now.
var resultsList = $("ul.ui-autocomplete > li.ui-menu-item > a");
var srchTerm = $.trim($("#tags").val()).split(/\s+/).join('|');
// Loop through the results list and highlight the terms.
resultsList.each(function() {
var jThis = $(this);
var regX = new RegExp('(' + srchTerm + ')', "ig");
var oldTxt = jThis.text();
jThis.html(oldTxt.replace(regX, '<span class="srchHilite">$1</span>'));
});
}
});
}
</script>
</head>
<body>
<div>
<label for="tags">
Multi-word search:
</label>
<input type="text" id="tags" />
</div>
</body>
</html>
take a look to Select2 it may help you.
Select2 is a jQuery based replacement for select boxes. It supports
searching, remote data sets, and infinite scrolling of results.
link
In your code, you have provided source as array. As you mentioned in comments, problem is how to get the data to source in jquery.
To make this work,
You need to do following
load jquery in header, which is you have already done.
Provid array,string or function for the source tag. [See api for
the source tag][1]
[1]: http://api.jqueryui.com/autocomplete/#option-source
In your serverside script, provid Jason encoded string.
If you check the API, you can see they have clear mentioned this.
Here is the jquery code
$(function() {
$( "#option_val" ).autocomplete({
dataType: "json",
source: 'search.php',
minLength: 1,
select: function( event, ui ) {
log( ui.item ?
"Selected: " + ui.item.value + " aka " + ui.item.id :
"Nothing selected, input was " + this.value );
}
});
});
</script>
Here is the php code, Sorry if you use differnt serverside script language.
<?php
// Create connection
$con=mysqli_connect("localhost","wordpress","password","wordpress");
// Check connection
if (mysqli_connect_errno($con))
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result=mysqli_query($con,"select * from wp_users");
while($row = mysqli_fetch_array($result))
{
$results[] = array('label' => $row['user_login']);
}
echo json_encode($results);
mysqli_close($con);
?>
I'm implementing a search form that displays suggestions as you start typing but can't get it to work..the problem is that when you start typing it doesn't shows any suggestion. Can you help me to get the code right? Many thanks!
This is the code:
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>
<div><input id="autocomplete" type="text"></div>
<script>
$("input#autocomplete").autocomplete({
source: [
{ id : "Google", value : "Google"},
{ id : "Yahoo", value : "Yahoo"},
],
minLength: 1,
open: function(event, ui) {
$("ul.ui-autocomplete").unbind("click");
var data = $(this).data("autocomplete");
console.log(data);
for(var i=0; i<=data.options.source.length-1;i++)
{
var s = data.options.source[i];
$("li.ui-menu-item a:contains(" + s.value + ")").attr("href", "/" + s.id);
}
}
});
/*
$("input#autocomplete").bind("autocompleteselect", function(event, ui) {
//alert(ui.item.id + ' - ' + ui.item.value);
//document.location.href = ui.item.id + '/' + ui.item.value;
//event.preventDefault;
} );
*/
</script>
Here Is the code:
<div id="search">
<input list="results" id="project" onkeydown="if (event.keyCode == 13) { checkInput(this.value); return false; }" />
</div>
The avaible results...
<datalist id="results">
<option>Demo</option>
<option>Example</option>
<option>pizza</option>
</datalist>
Finally the javascript
function checkInput(searchQuery)
{
if(searchQuery=="Home")
{
window.location = "Home.html";
}
else if(searchQuery == "Contact")
{
window.location = "Contact.html";
}
else if(searchQuery == "Sitemap")
{
window.location = "Sitemap.html";
}
else
{
window.location = "noresult.html";
}
}
So that way when ever someone goes to search they have a limited amount of options in the pre-populated list and which ever one they select leads them to your target page! I can't take all the credit, but I hope that helps!
I've read that WebSockets work on iOS 4.2 and above. And I can verify that there is indeed a WebSocket object. But I can't find a single working WebSocket example that works on the phone.
For example http://yaws.hyber.org/websockets_example.yaws will crash the Mobile Safari app. Has anyone got WebSockets working successfully on the phone?
I may have found the solution. Mobile Safari only crashes with websockets when you have setup a proxy over wifi.
It is supported, but bear in mind regarding the standard that iOS Safari browser implements, it is not RFC 6455, but HyBi-00/Hixie-76.
You can test as well using this browser: http://websocketstest.com/
As well check this great post that have most of info regarding versions: https://stackoverflow.com/a/2700609/1312722
OBS!, this is an old answer.
I have checked through the webpage mentioned in this post combined with browserstack.com:
iPhone4S
iPhone5
iPhone5S
iPhone6
iPhone6 Plus
iPhone6S
iPhone6S Plus
All using RFC 6455
I had a similar problem and even looked to this post to find a fix for it. For me, it had nothing to do with being on a wifi connection. It appears to be a bug in the iOS implementation of websockets (even up to the current version 5.1). Turning on a bunch of XCode's debugging I found that it has something to do with memory management because I would get something along the lines of "message sent to a deallocated instance." Most likely there was an object that didn't have the correct reference count and was cleaned up way too early.
This blog has a lot of great information about the symptoms of the problem and how to debug it, but doesn't have a workaround: http://dalelane.co.uk/blog/?p=1652
Eventually though, I found this workaround, and my app has almost entirely stopped crashing now.
me = this // strange javascript convention
this.socket = new WebSocket(url);
// put onmessage function in setTimeout to get around ios websocket crash
this.socket.onmessage = function(evt) { setTimeout(function() {me.onMessageHandler(evt);}, 0); };
I got them working on Chrome and Safari, iPhone and iPad (and other mobile devices too, but I guess you don't mind about them). Here is the Javascript code I am using :
<script language="javascript" type="text/javascript">
var wsUri = document.URL.replace("http", "ws");
var output;
var websocket;
function init()
{
output = document.getElementById("output");
wsConnect();
}
function wsConnect()
{
console.log("Trying connection to " + wsUri);
try
{
output = document.getElementById("output");
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt)
{
onOpen(evt)
};
websocket.onclose = function(evt)
{
onClose(evt)
};
websocket.onmessage = function(evt)
{
onMessage(evt)
};
websocket.onerror = function(evt)
{
onError(evt)
};
}
catch (e)
{
console.log("Exception " + e.toString());
}
}
function onOpen(evt)
{
alert("Connected to " + wsUri);
}
function onClose(evt)
{
alert("Disconnected");
}
function onMessage(evt)
{
alert('Received message : ' + evt.data);
}
function onError(evt)
{
alert("Error : " + evt.toString());
}
function doSend(message)
{
websocket.send(message);
}
window.addEventListener("load", init, false);
Sending data from client to server is done calling doSend() function. Receiving data from server also works, I've tested it from a custom C++ server.
Here is a working sample
Web socket client
<!DOCTYPE html>
<meta charset="utf-8" />
<head>
<title>WebSocket Test</title>
<script language="javascript" type="text/javascript">
var websocket;
function OpenWebSocket()
{
try {
websocket = new WebSocket(document.getElementById("wsURL").value);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
}
catch(err) {
writeToScreen(err.message);
}
}
function CloseWebSocket()
{
websocket.close();
}
function FindWebSocketStatus()
{
try {
if (websocket.readyState == 1){
writeToScreen("Websocket connection is in open state")
}
else if (websocket.readyState == 0){
writeToScreen("Websocket connection is in connecting state")
}
else{
writeToScreen("Websocket connection is in close state")
}
}
catch(err) {
writeToScreen(err.message);
}
}
function FindWebSocketBufferedAmount(){
try {
writeToScreen(websocket.bufferedAmount)
}
catch(err) {
writeToScreen(err.message);
}
}
function SendMessageThroughSocket(){
doSend(document.getElementById("wsMessage").value);
}
function onOpen(evt)
{
writeToScreen("Socket Connection Opened");
}
function onClose(evt)
{
writeToScreen("Socket Connection Closed");
}
function onMessage(evt)
{
writeToScreen('<span style="color: blue;">SERVER RESPONSE: ' + evt.data+'</span>');
}
function onError(evt)
{
writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
}
function doSend(message)
{
try{
writeToScreen("CLIENT SENT: " + message);
websocket.send(message);
}
catch(err) {
writeToScreen(err.message);
}
}
function writeToScreen(message)
{
var output = document.getElementById("output");
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message;
output.appendChild(pre);
}
</script>
</title>
</head>
<body>
<table>
<tr>
<td>
WebSocket URL
</td>
<td>
<input type="text" id="wsURL" value="ws://echo.websocket.org/"/>
</td>
</tr>
<tr>
<td>
WebSocket Message
</td>
<td>
<input type="text" id="wsMessage" value="Hi"/>
</td>
</tr>
<tr>
<td colspan="2" style="text-align:left;">
<input type="button" value="Open Socket Connection" onclick="OpenWebSocket();"/>
</td>
</tr>
<tr>
<td colspan="2" style="text-align:left;">
<input type="button" value="Send Message" onclick="SendMessageThroughSocket();"/>
</td>
</tr>
<tr>
<td colspan="2" style="text-align:left;">
<input type="button" value="Close Socket Connection" onclick="CloseWebSocket();"/>
</td>
</tr>
<tr>
<td colspan="2" style="text-align:left;">
<input type="button" value="Find Socket Status" onclick="FindWebSocketStatus();"/>
</td>
</tr>
<tr>
<td colspan="2" style="text-align:left;">
<input type="button" value="Find Socket Buffered Amount" onclick="FindWebSocketBufferedAmount();"/>
</td>
</tr>
</table>
<div id="output"></div>
</body>
</html>
Web Socket server
Creating your own socket server is also simple Just install the Node.js and socket.io then proceed to install web socket via npm
#!/usr/bin/env node
var WebSocketServer = require('websocket').server;
var http = require('http');
var server = http.createServer(function(request, response) {
console.log((new Date()) + ' Received request for ' + request.url);
response.writeHead(404);
response.end();
});
server.listen(8888, function() {
console.log((new Date()) + ' Server is listening on port 8888');
});
wsServer = new WebSocketServer({
httpServer: server,
// You should not use autoAcceptConnections for production
// applications, as it defeats all standard cross-origin protection
// facilities built into the protocol and the browser. You should
// *always* verify the connection's origin and decide whether or not
// to accept it.
autoAcceptConnections: false
});
function originIsAllowed(origin) {
// put logic here to detect whether the specified origin is allowed.
return true;
}
wsServer.on('request', function(request) {
if (!originIsAllowed(request.origin)) {
// Make sure we only accept requests from an allowed origin
request.reject();
console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
return;
}
var connection = request.accept();
console.log((new Date()) + ' Connection accepted.');
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log('Received Message: ' + message.utf8Data);
connection.sendUTF('Message received at server:'+message.utf8Data);
}
else if (message.type === 'binary') {
console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
connection.sendBytes(message.binaryData);
}
});
connection.on('close', function(reasonCode, description) {
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
});
});
save the above file as .js and run it like node filename.js from terminal or command prompt
The above file is like we have first created a http server using node then we're passing the created http server instance to Websocketserver then subsequently to Socket.iO instance
I was debugging a similar issue and found that if you have used https to get the web page iOS will trap if you use the pass a the "ws:" protocol into WebSocket. If you use "wss:" everything will work and there will be no traps.