I am trying to use COMET with dojo and it fails on the first line of the example with the message
dojox is not defined
I must miss something obvious
this is the page (the error is on the first line of the BODY):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
<script src="dojo/dojo.js"
data-dojo-config="async:true, parseOnLoad:true">
</script>
<script>
require( ["dojox/socket"] );
</script>
</head>
<body>
<script type="text/javascript">
var socket = dojox.socket( "/cometd" );
function send( data ) {
return socket.send( dojo.toJson( data ) );
}
socket.on( "connect", function () {
// send a handshake
send( [
{
"channel":"/meta/handshake",
"version":"1.0",
"minimumVersion":"1.0beta",
"supportedConnectionTypes":["long-polling"] // or ["callback-polling"] for x-domain
}
] )
socket.on( "message", function ( data ) {
// wait for the response so we can connect with the provided client id
data = dojo.fromJson( data );
if ( data.error ) {
throw new Error( error );
}
// get the client id for all future messages
clientId = data.clientId;
// send a connect message
send( [
{
"channel":"/meta/connect",
"clientId":clientId,
"connectionType":"long-polling"
},
{ // also send a subscription message
"channel":"/meta/subscribe",
"clientId":clientId,
"subscription":"/foo/**"
}
] );
socket.on( "message", function ( data ) {
alert( "message from server " + data )
} );
} );
} );
</script>
</body>
</html>
You are mixing AMD and old-style module syntax. The new, AMD style, require will not create a global variable for your namespace, like the old dojo.require did.
Either rewrite the code to fully use the new AMD style or remove the async=true flag you added when loading dojo to re-enable support for the old module style.
Anyway, it should not be hard to rewrite this in AMD style...
require([
'dojo/_base/json', //_base is for things that used to be in the root dojo namespace.
'dojox/socket'
],function(
json,
dojox_socket
){
var socket = dojox_socket( "/cometd" );
function send( data ) {
return socket.send( json.toJson( data ) );
}
// and so on...
});
(BTW, you can also remove the "parseOnLoad" flag if you aren't using any declarative widgets in your original html)
Related
I don't want to refresh a page when I am searching through a database eg. on post, so I had help in using a $.post call which works for sending information. There is a .done(function( data ){ line which I haven't used yet.
I also came across this question which I'm not sure if this ties to my question.
Return $.get data in a function using jQuery
I'm trying to search through a database, string match, and return the rows with matching strings. But I want to do this without refreshing the page so I would think that I am using the $.post call and using the .done(function( data ){ which is triggered by javascript (a button).
So I have two parts, the page I'm on and a separate PHP page that processes the call when made.
How do I make the bridge where I can return the data back? Or is there an easier way to do this?
The method .done(function(){}) is exactly what You would like to use, but You can also take a look at third argument (callback) of $.post function.
On server side, do all the queries and prepare the stuff in jsoned array like:
// set up data to send
$contentArray = [
'content' => 'Some content',
'foo' => 'bar',
];
$jsonResults = json_encode($contentArray);
// you can always send header('Content-Type: application/json'); instead of using simple die function.
die($jsonResults);
Then on client side:
<div class="content-container"></div>
<script type="text/javascript">
function someFunc() {
(...)
$.post(addr, values, function(res) {
var response = $.parseJSON(res);
$('.content-container').html(response.content);
});
}
</script>
This should update the content of the .content-container class only. You can send as much as you want, even prepared view to be displayed in the container. This is up to You.
EDIT:
Just to be sure, you're calling someFunc() on some button click event, right? If not, do it as follows:
<div class="content-container"></div>
Click here
<script type="text/javascript">
function changePageContent(addr, contentId) {
$.post(addr, {contentId:contentId}, function(res) {
var response = $.parseJSON(res);
$('.content-container').html(response.content);
});
}
$('.callMe').on('click', function() {
changePageContent($(this).attr('href'), $(this).attr('data-content-id'));
return false;
});
</script>
someScript.php:
<?php
// you should force your script to allow only XML HTTP request here
if(empty($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
die('AJAX requests only..');
}
// always remember to escape somehow your post values before you use them
$contentId = is_numeric($_POST['contentId']) ? intval($_POST['contentId']) : null;
if (null == $contentId) (...) // throw exception or return status=false
// do your mysql query like: "SELECT * FROM content WHERE id=".$contentId;
// well, it would be better to send headers instead of that
die(json_encode([
'status' => true, // this is a good practice to send some info, if everything is fine, if mysql row has been found etc..
'result' => $result, // mysql row, this is just in case you need other values to display
'content' => $result['content'], // I assume you have 'content' column in your mysql
]));
?>
Take a look at the docs for Ajax, there really is a lot of info there which will help.
In short, you could do something like this:
function myPost() {
// Set the data
var data = {
'key' : 'value',
'key_2' : 'value_2'
};
// Do the post
$.post( '/your-url/', data, callBack );
}
function callBack( data ) {
// If the $.post was successful
success: function( data ) {
// do stuff
console.log( data ); // returned from your endpoint
},
// If there was an error
error: function( jqXHR, textStatus ) {
// do stuff
console.log( "Request failed: " + textStatus );
}
}
// On click of your element, fire the post request
$('#element').on('click', function() {
myPost();
});
I use phonegap for create an android application.
I did these steps :
1. Wrote html, css and jquery mobile codes.
2. Include phonegap.js into .
3. Create the database via sqlite manager firefox extension and copy to root the project directory (beside index.html).
4. use this code:
<script>
$(function() {
onDeviceReady();
queryDB();
$("#links").niceScroll();
});
</script>
<script type="text/javascript" charset="utf-8">
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady()
{
var db = window.openDatabase("shia.sqlite", "1.0", "shia", 100000);
}
function queryDB(tx) {
tx.executeSql('SELECT * FROM posts', [], querySuccess, errorCB);
}
function querySuccess(tx, results) {
console.log("Returned rows = " + results.rows.length);
// this will be true since it was a select statement and so rowsAffected was 0
if (!results.rowsAffected) {
console.log('No rows affected!');
return false;
}
// for an insert statement, this property will return the ID of the last inserted row
console.log("Last inserted row ID = " + results.insertId);
}
function errorCB(err) {
alert("Error processing SQL: "+err.code);
}
</script>
This error displayed into console :
Uncaught TypeError: Cannot read property 'executeSql' of undefined
Please help me .
#Behzad,
your code has the function
function queryDB(tx) {
tx.executeSql('SELECT * FROM posts', [], querySuccess, errorCB);
}
However, when you call queryDB, you did not pass the handle. So in this function the parameter tx is null because you did not pass the handle.
Does reactjs works fine with IE8? I am using React v0.11.1.
Following code is NOT working in IE8. Works fine on all the other browsers
SCRIPT438: Object doesn't support property or method 'isArray'
File: react.js, Line: 17372, Column: 37
SCRIPT5009: 'React' is undefined
File: myreact.js, Line: 3, Column: 1
SCRIPT438: Object doesn't support property or method 'map'
File: JSXTransformer.js, Line: 12637, Column: 3
/** #jsx React.DOM */
var MyComponent = React.createClass({displayName: 'MyComponent',
getDefaultProps:function(){
return{
text:"",
numbers:0
}
},
getInitialState:function(){
return {txt:"initial", id:0}
},
updateText: function(event){
this.setState({text:event.target.value})
},
propTypes:{
text:React.PropTypes.string,
numbers: React.PropTypes.number.isRequired
},
render:function(){
return (
React.DOM.div(null,
Widget({text: this.state.text, update: this.updateText}),
Widget({text: this.state.text, update: this.updateText})
)
)
}
});
var Widget = React.createClass({displayName: 'Widget', render:function(){
return(
React.DOM.div(null,
React.DOM.input({type: "text", onChange: this.props.update}),
React.DOM.div(null, this.props.text)
)
)
}
});
React.renderComponent(
MyComponent({text: "HI there", numbers: 34}),
document.getElementById("content")
);
You need to use the following shims/pollyfills as noted in the react docs. es5-shim will resolve the specific isArray bug you are seeing.
I've managed to launch my React app in IE8 using the following code:App.js:
require('core-js'); //Important!
var React = require('react');
var ReactDOM = require('react-dom');
var Application = React.createClass({ ... });
ReactDOM.render(React.createElement(Application,null), document.getElementById("app-container"));
index.html:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.5.7/es5-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.5.7/es5-sham.min.js"></script>
<script type="text/javascript" src="bundle.js" defer></script>
</head>
<body>
<div id="app-container"></div>
</body>
</html>
Comments: bundle.js will be loaded after es5-shim/es5-sham because of defer html attribute
I'm newbie of angularjs developing and i wrote this simple app, but don't understand how i can update view, after the model il loaded from ajax request on startup!
This code don't work when I add delay into photos.php, using:
sleep(3);
for simulate remote server delay! instead if search.php is speedy it work!!
<!doctype html>
<html ng-app="photoApp">
<head>
<title>Photo Gallery</title>
</head>
<body>
<div ng-view></div>
<script src="../angular.min.js"></script>
<script>
'use strict';
var photos = []; //model
var photoAppModule = angular.module('photoApp', []);
photoAppModule.config(function($routeProvider) {
$routeProvider.when('/photos', {
templateUrl: 'photo-list.html',
controller: 'listCtrl' });
$routeProvider.otherwise({redirectTo: '/photos'});
})
.run(function($http) {
$http.get('photos.php')//load model with delay
.success(function(json) {
photos = json; ///THE PROBLEM HERE!! if photos.php is slow DON'T update the view!
});
})
.controller('listCtrl', function($scope) {
$scope.photos = photos;
});
</script>
</body>
</html>
output of photos.php
[{"file": "cat.jpg", "description": "my cat in my house"},
{"file": "house.jpg", "description": "my house"},
{"file": "sky.jpg", "description": "sky over my house"}]
photo-list.html
<ul>
<li ng-repeat="photo in photos ">
<a href="#/photos/{{ $index }}">
<img ng-src="images/thumb/{{photo.file}}" alt="{{photo.description}}" />
</a>
</li>
</ul>
EDIT 1, Defer solution:
.run(function($http, $q) {
var deferred = $q.defer();
$http.get('photos.php')//load model with delay
.success(function(json) {
console.log(json);
photos = json; ///THE PROBLEM!! if photos.php is slow DON'T update the view!
deferred.resolve(json);//THE SOLUTION!
});
photos = deferred.promise;
})
EDIT 2, Service solution:
...
//require angular-resource.min.js
angular.module('photoApp.service', ['ngResource']).factory('photoList', function($resource) {
var Res = $resource('photos.php', {},
{
query: {method:'GET', params:{}, isArray:true}
});
return Res;
});
var photoAppModule = angular.module('photoApp', ['photoApp.service']);
...
.run(function($http, photoList) {
photos = photoList.query();
})
...
The short answer is this:
.controller('listCtrl', ['$scope', '$timeout', function($scope, $timeout) {
$timeout(function () {
$scope.photos = photos;
}, 0);
}]);
The long answer is: Please don't mix regular javascript and angular like this. Re-write your code so that angular knows what's going on at all times.
var photoAppModule = angular.module('photoApp', []);
photoAppModule.config(function($routeProvider) {
$routeProvider.when('/photos', {
templateUrl: 'photo-list.html',
controller: 'listCtrl'
});
$routeProvider.otherwise({redirectTo: '/photos'});
});
photoAppModule.controller('listCtrl', ['$scope', function($scope) {
$scope.photos = {};
$http.get('photos.php') // load model with delay
.success(function(json) {
$scope.photos = json; // No more problems
});
}]);
use broadcast
//service
var mydata = [];
this.update = function(){
$http.get(url).success(function(data){
mydata = data;
broadcastMe();
});
};
this.broadcastMe = function(){
$rootScope.$broadcast('mybroadcast');
};
//controller
$scope.$on('mybroadcast', function(){
$scope.mydata = service.mydata;
};
http://bresleveloper.blogspot.co.il/
EDIT:couple of days ago i've learned the best practice
http://bresleveloper.blogspot.co.il/2013/08/breslevelopers-angularjs-tutorial.html
I think you're better off using high level angular services for data transfer, also look into promises and services:
http://docs.angularjs.org/api/ng.$q
You need to bind an element in your view to a property (simple or object) of your $scope object. Once the $scope object is updated the view should be updated on its own. That is the beauty of AngularJS.
EDIT:
Please register your controller as
photoAppModule.controller('listCtrl', function($scope){
$scope.photos = photos;
});
If photos variable is not available, then you might have to create a service with the variable and inject in the controller.
Using soundManager2, I made a simple anchor with onclick="mySound.play()", but there is a big gap (almost half a second) before the sound is actually heard! This is, even though I pre-loaded the sound. How can I get a better response-time?
Here is the source code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" >
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="author" content="Shawn Inder" />
<title>jeuReno</title>
<style type="text/css">
<!--
-->
</style>
<!-- include SM2 library -->
<script type="text/javascript" src="soundManager/script/soundmanager2.js"></script>
<!-- configure it for your use -->
<script type="text/javascript">
soundManager.url = 'soundManager/swf/'; // directory where SM2 .SWFs live
// Note that SoundManager will determine and append the appropriate .SWF file to the URL,
// eg. /path/to/sm2-flash-movies/soundmanager2.swf automatically.
// Beta-ish HTML5 audio support (force-enabled for iPad), flash-free sound for Safari + Chrome. Enable if you want to try it!
// soundManager.useHTML5Audio = true;
// do this to skip flash block handling for now. See the flashblock demo when you want to start getting fancy.
soundManager.useFlashBlock = false;
// disable debug mode after development/testing..
// soundManager.debugMode = false;
// Option 1: Simple onload() + createSound() method
/*soundManager.onload = function() {
// SM2 has loaded - now you can create and play sounds!
soundManager.createSound('helloWorld','sounds/crash.mp3');
soundManager.play('helloWorld');
};*/
// Option 2 (better): More flexible onload() + createSound() method
/*soundManager.onload = function() {
var mySound = soundManager.createSound({
id: 'aSound',
url: 'sounds/kick.mp3'
// onload: [ event handler function object ],
// other options here..
});
mySound.play();
}*/
// Option 3 (best): onready() + createSound() / ontimeout() methods for success/failure:
/*soundManager.onready(function() {
// SM2 has loaded - now you can create and play sounds!
var mySound = soundManager.createSound({
id: 'aSound',
url: 'sounds/snare.mp3'
// onload: [ event handler function object ],
// other options here..
});
mySound.play();
});*/
soundManager.useHighPerformance = true;
soundManager.ontimeout(function() {
// (Optional) Hrmm, SM2 could not start. Show an error, etc.?
alert("wtf");
});
</script>
<script type="text/javascript">
/*var snare = soundManager.createSound({
id: 'snare',
url: 'sounds/snare.mp3'
});
var kick = soundManager.createSound({
id: 'kick',
url: 'sounds/kick.mp3'
});
var crash = soundManager.createSound({
id: 'crash',
url: 'sounds/crash.mp3'
});
var highHat = soundManager.createSound({
id: 'highHat',
url: 'sounds/highHat.mp3'
});*/
soundManager.onready(function() {
// SM2 has loaded - now you can create and play sounds!
mySound = soundManager.createSound({
id: 'aSound',
url: 'sounds/snare.mp3'
// onload: [ event handler function object ],
// other options here..
});
mySound.load();
// mySound.play();
});
</script>
</head>
<body>
click
</body>
</html>
I don't see where the song gets preloaded. You want to set autoLoad to true in the default or createSound section (the defaults should be inherited by createSound).
In the default section it would be soundManager.autoLoad = true;
Or in the createSound method autoLoad:true, id: 'aSound', url: 'sounds/kick.mp3'