i try using ajax request for extjs calendar. the only problem is when creating new record .How to send back eventId to the form .I want to test the update record after receiving new record.When i try to update it send back auto increment internal record instead of return ajax response eventId.
What i do.
'eventadd': {
fn: function (win, rec) {
win.hide();
rec.data.IsNew = false;
rec.data.eventId = 'testing'; // tengok boleh tak bypass
this.eventStore.add(rec);
this.showMsg('Event ' + rec.data.Title + ' was added');
var data;
reminder = function (data) {
var remind;
if (!data) {
remind = null;
} else {
remind = data;
}
return remind;
};
Ext.Ajax.request({
url: '../controller/eventController.php',
params: {
method: 'create',
calendarId: rec.data.CalendarId,
eventTitle: rec.data.Title,
eventStart: rec.data.StartDate,
eventEnd: rec.data.EndDate,
eventIsAllDay: rec.data.IsAllDay,
eventReminder: rec.data.Reminder,
eventIsNew: rec.data.IsNew,
leafId: leafId
},
success: function (response, options) {
var jsonResponse = Ext.decode(response.responseText);
if (jsonResponse.success == true) {
title = systemLabel;
} else {
title = systemErrorLabel;
}
Ext.MessageBox.alert(title, jsonResponse.message);
},
failure: function (response, options) {
// critical bug extjs
var jsonResponse = Ext.decode(response.responseText);
Ext.MessageBox.alert(systemErrorLabel, jsonResponse.message);
}
});
},
scope: this
},
Response Output.
{"success":true,"message":"Record Created","data":{"eventId":13},"eventId":13}
When update the record.the only problem on me is eventId.
FireBug Console Parameter
calendarId 1
eventEnd 2011-08-11T01:00:00
eventId 10000
eventIsAllDay false
eventIsNew false
eventReminder
eventStart 2011-08-11T00:00:00
eventTitle oh update4d
leafId 516
method update
On create, the event window adds an auto-incremented id to the new record only so that it has a unique id in the local data store, before it gets sent to the server. It is the responsibility of the server code generating the response after an add to replace the id with the real database PK. Any subsequent CRUD actions would then use the correct id.
Related
I have a users table and lesson table. In users table I have watch_history column in which I want to store the data of current playing lesson_id and currentTime of video so the user can continue watching from skip or left video.
I am new to ajax so I don't know how to send the data continuously to database using ajax.
This is my JS code which is printing the currentTime in console.
<script>
var vid = document.getElementById("player");
$(function() {
var timeout;
$("#player").on("playing pause", function(e) {
// save reference
var v = this
// clear previous timeout, if any
clearTimeout(timeout)
// call immediately if paused or when started
performaction(v.currentTime, v.duration)
// set up interval to fire very 5 seconds
if (e.type === "playing") {
timeout = setInterval(function() {
performaction(v.currentTime, v.duration)
}, 3000)
}
})
function performaction(currentTime, duration) {
console.log(currentTime);
}
})
</script>
How can I send the timing of video with lesson id in one array using ajax in Laravel. I am using the plry.io video player. This above JS code is present on the Lesson_video.blade.php page on which I have the lesson id.
I am working on a college project.
In your html:
<input type="hidden" name="_token" value="{{csrf_token()}}"/>
In your javascript do this:
function performaction(currentTime, duration, videoId){//pass video id to this function where you call it.
var data = {time: currentTime, duration: duration}; //data to send to server
var dataType = "json"//expected datatype from server
var headers = { 'X-CSRF-TOKEN': $('input[name="_token"]').val()}
$.post({
url: '/saveTime/'+videoId, //url of the server which stores time data
data: data,
headers: headers,
success: function(data,status){
alert(status);
var data = JSON.parse(data)
alert(data['message']);
},
dataType: dataType
});
}
function resumePlayback(videoId){//Ajax request for getting the time
$.ajax({
url: '/getTime/'+videoId,
success: function(data,status){
var data = JSON.parse(data);
if(status == 200){
document.getElementById('player').currentTime = data['playbackTime'];
alert(playbackTime);
}
},
dataType: "json"
});
}
In your routes/web.php:
Route::post('/saveTime/{video}', 'InstructorCourseController#saveTime')->name('video.saveTime');
Route::get('/getTime/{video}', 'InstructorCourseController#getTime')->name('video.getTime');//Route for getting the saved time
In your InstructorCourseController.php:
public function saveTime(Request $request, $video){
$request->validate([
'time' => 'required',
'duration' => 'required'
]);
$user = Auth::user();
if($user === null){
return response()->json(['message' => 'User not authenticated', 403);
}
$user_id = $user->id;
$video = Video::where('id',$video)->first();
if($video === null){
return response()->json(['message' => 'Video not found', 404);
}
$currentTime = $request->time;
$duration = $request->duration;
//save them somewhere
return response()->json(['message' => 'Time saved', 200);//send http response as json back to the ajax call
}
public function getTime(Request $request, $video){
$user = Auth::user();
if($user === null){
return response()->json(['message' => 'User not authenticated', 403);
}
$video = Video::where('id',$video)->first();
//get the time from saved time where you saved it with this data
$playbackTime = Somemodel::where('video_id',$video->id)->where('user_id',$user->id)->get()->last();//use this one if you insert the time instead of updating an existing row each time a time is saved.
$playbackTime = Somemodel::where('video_id',$video->id)->where('user_id',$user->id)->first();//use this one if you update the time instead of inserting a new row each time a time is saved.
if($playbackTime === null){
//there's no saved time
$playbackTime = 0;
}else{
$playbackTime = $playbackTime->currentTime;//use what column you saved the time in.
}
return response()->json(['playbackTime' => $playbackTime, 200);
}
I have some code that sends a variable (pin) to php via AJAX the database is then queried and if a result is found the php echo's a value of 1. Everything is working fine, except that the Ajax does not recognise the value returned by the php.
Here is my code
$(document).ready(function () {
$("form.submit").submit(function () {
var pin = $(this).find("[name='pin']").val();
// ...
$.ajax({
type: "POST",
url: "http://www.example.com/pin.php",
data: {
pin : pin,
},
success: function (response) {
if (response == "1") {
$("#responsecontainer").html(response);
window.location.href = "home.html?user=" + user;
// Functions
} else { // Login failed
alert("LOGIN FAILED");
}
}
});
this.reset();
return false;
});
});
And here is my PHP code, I know that the code below returns a value of 1. When Ajax is triggered it returns a value that generates a login fail message. Is there a way to see what Ajax is sending, if i swap out the ajax and directly submit the for to the server it also returns a 1 on the php echo.
$pin = $_GET["pin"];
$db = new PDO("mysql:host=localhost;dbname=xxxxx;charset=utf8", "xxxx", "xxxx");
$count = $db->query("SELECT count(1) FROM users WHERE pin='$pin'")->fetchColumn();
echo $count;
It's recommended to return JSON data as result for an ajax request.
So try this :
Edit: I've updated the php code to make the sql query with PDO prepare() method taking into account #Dominik's commentary
$pin = $_POST['pin'];
$db = new PDO('mysql:host=localhost;dbname=xxxxx;charset=utf8', 'xxxx', 'xxxx');
$stmt = $pdo->prepare('SELECT count(1) FROM users WHERE pin = :pin');
$stmt->execute(array('pin' => $pin));
return json_encode([
"count" => $stmt->fetchColumn()
]);
And in your ajax success callback :
...
success: function(response) {
var count = JSON.parse(response).count;
if (count == "1") {
$("#responsecontainer").html(response);
window.location.href = "home.html?user="+ user;
} else {// Login failed
alert("LOGIN FAILED");
}
},
error: function(error) {
...
}
Hope it's helps you :)
I am using Twitter Typeahead (v0.11.1). I have configured an ajax call to get suggestion list upon typing each letter in textbox.
On entering every character an ajax call gets send and it brings results. If typed continuously in textbox then previous ajax calls are aborted and new ajax call is sent on pause of last character entered.
So, while this process if found some results after two characters and paused then it showing suggestion list. Now, if continue to type then exiting list goes away.
I would like to retain suggestion list for each ajax call till user not selected an item from it.
Below is the code used:
var typeahead_pre_written_xhr = null;
var helper_typeahead = $( "#input-box" ).typeahead({
highlight: true,
minLength: 0
},
{
name: "Search Suggestions",
display: ["title"],
templates: {
empty: function () {
return '<div class="tt-suggestion tt-selectable">No matching helper comment found</div>';
}
},
source: function (query, processSync, processAsync) {
if( typeahead_pre_written_xhr != null ) {
typeahead_pre_written_xhr.abort();
typeahead_pre_written_xhr = null;
}
action_url = "suggestion_list";
return typeahead_pre_written_xhr = $.ajax({ cache: false
, url: action_url + query
, type: 'POST'
, data: { 'search': query }
, dataType: 'json'
, success: function (data)
{
return processAsync(data.res);
}
});
}
}).bind("typeahead:selected", function(evt, item) {
// do some stuff
});
At this moment I am using laravel. In this context I am having a form which is successfully submitted by using ajax to a controller. and that controller make it to the database. But the problem is as the ajax is doing its job the whole page remain unmoved / unchanged after the submission even the database is updated.
Now what I want
I want to give feedback to the user that your post is successfully submitted there. or what I want to do in further, I want to refresh the section in which the post is collected from the database as this post can be retrieved from there. But by using ajax only.
So there is no need to collect the whole page or refresh.
here is my form structure
`
{{ Form::open(array('route' => array('questions.store'), 'class' => 'form-horizontal' )) }}
blah blah blaaa .......
<script type="text/javascript">
$(".form-horizontal").submit(function(e){
$(this).unbind("submit")
$("#ask").attr("disabled", "disabled")
var that = $(this),
url = that.attr('action'),
type = that.attr('method'),
data = {};
that.find('[name]').each(function(index, value){
var that = $(this),
name = that.attr('name'),
value = that.val();
data[name] = value;
});
$.ajax({
url: url,
type: type,
data: data,
success: function(response){
console.log(response);
}
});
return false;
});
</script>
{{ Form::close() }}
`
As it is very much visible that the post is updated through a route & controller I want to have another dive and a success message at this script to be displayed after the success of posting. I am looking for some professional structure using what there is minimal need to have interaction with the server side and give user a better page viewing experience.
Thanks a lot for helping me in this research.
I am not sure if I understand you well, but if you want to notify the user about the result of an ajax-called db update you need to have
a route for the ajax save db call - it should point to a method that does the db update.
the db update method should return some value indicating the success/failure of update (for example OK or FAIL)
the only result of calling the method will be just plain text page with OK or FAIL as body
fetch the result by ajax and inform user accordingly (after form submit button)
check out the below code for ajax call itself (inside the form submit handler) to see what I mean
var db_ajax_handler = "URL_TO_YOUR_SITE_AND_ROUTE";
var $id = 1; //some id of post to update
var $content = "blablabla" //the cotent to update
$.ajax({
cache: false,
timeout: 10000,
type: 'POST',
tryCount : 0,
retryLimit : 3,
url: db_ajax_handler,
data: { content: $content, id: $id }, /* best to give a CSRF security token here as well */
beforeSend:function(){
},
success:function(data, textStatus, xhr){
if(data == "OK")
{
$('div.result').html('The new Question has been created');
}
else
{
$('div.result').html('Sorry, the new Question has not been created');
}
},
error : function(xhr, textStatus, errorThrown ) {
if (textStatus == 'timeout') {
this.tryCount++;
if (this.tryCount <= this.retryLimit) {
//try again
$.ajax(this);
return;
}
return;
}
if (xhr.status == 500) {
alert("Error 500: "+xhr.status+": "+xhr.statusText);
} else {
alert("Error: "+xhr.status+": "+xhr.statusText);
}
},
complete : function(xhr, textStatus) {
}
});
EDIT: as per comment, in step 2 (the method that is called with AJAX) replace
if($s)
{
return Redirect::route('questions.index') ->with('flash', 'The new Question has been created');
}
with
return ($s) ? Response::make("OK") : Response::make("FAIL");
EDIT 2:
To pass validation errors to the ajax-returned-results, you cannot use
return Response::make("FAIL")
->withInput()
->withErrors($s->errors());
as in your GIST. Instead you have to modify the suggested solution to work on JSON response instead of a plain text OK/FAIL. That way you can include the errors in the response and still benefit from the AJAX call (not having to refresh the page to retrieve the $errors from session). Check this post on the Laravel Forum for a working solution - you will get the idea and be able to fix your code.
I've been trying for days to get this working and I just cannot figure out why when I have my view to destroy a model which belongs to a collection (which properly has a url attribute for the beginning fetch of models' data), only fires the destroy 'event' which is bubbled up to the collection for easy binding by my list view. But it does not ever send an actual DELETE request or any request to the server at all. Everywhere I look, I see everyone using either the collection's url attr, or urlRoot if the model is not connected to a collection. I've even tested before the actual this.model.destroy() to check the model < console.log(this.model.url());
I have not overwritten the destroy nor sync methods for backbone. Also each model does have an id attribute which is populated via the collection's fetch (from database records).
The destroy takes place in the list item view, and the collection's "destroy" event is bound in the list view. All that works well (the event handling), but the problem, again, is there's no request to the server.
I was hoping that backbone.js would do it automatically. That was what the documentation implies, as well as the numerous examples everywhere.
Much thanks to anyone who can give some useful input.
FYI: I'm developing on wampserver PHP 5.3.4.
ListItemView = BaseView.extend({
tagName: "li",
className: "shipment",
initialize: function (options) {
_.bindAll(this);
this.template = listItemTemplate;
this.templateEmpty = listItemTemplateEmpty;
},
events: {
'click .itemTag' : 'toggleData',
'click select option' : 'chkShipper',
'click .update' : 'update',
'click button.delete' : 'removeItem'
},
// ....
removeItem: function() {
debug.log('remove model');
var id = this.model.id;
debug.log(this.model.url());
var options = {
success: function(model, response) {
debug.log('remove success');
//debug.log(model);
debug.log(response);
// this.unbind();
// this.remove();
},
error: function(model, response) {
debug.log('remove error');
debug.log(response);
}
};
this.model.destroy(options);
//model.trigger('destroy', this.model, this.model.collection, options);
}
});
Collection = Backbone.Collection.extend({
model: Model,
url: '?dispatch=get&src=shipments',
url_put : '?dispatch=set&src=shipments',
name: 'Shipments',
initialize: function () {
_.bindAll(this);
this.deferred = new $.Deferred();
/*
this.fetch({
success: this.fetchSuccess,
error: this.fetchError
});
*/
},
fetchSuccess: function (collection, response) {
collection.deferred.resolve();
debug.log(response);
},
fetchError: function (collection, response) {
collection.deferred.reject();
debug.log(response);
throw new Error(this.name + " fetch failed");
},
save: function() {
var that = this;
var proxy = _.extend( new Backbone.Model(),
{
url: this.url_put,
toJSON: function() {
return that.toJSON();
}
});
var newJSON = proxy.toJSON()
proxy.save(
newJSON,
{
success: that.saveSuccess,
error: that.saveError
}
);
},
saveSuccess: function(model, response) {
debug.log('Save successful');
},
saveError: function(model, response) {
var responseText = response.responseText;
throw new Error(this.name + " save failed");
},
updateModels: function(newData) {
//this.reset(newData);
}
});
ListView = BaseView.extend({
tagName: "ul",
className: "shipments adminList",
_viewPointers: {},
initialize: function() {
_.bindAll(this);
var that = this;
this.collection;
this.collection = new collections.ShipmentModel();
this.collection.bind("add", this.addOne);
this.collection.fetch({
success: this.collection.fetchSuccess,
error: this.collection.fetchError
});
this.collection.bind("change", this.save);
this.collection.bind("add", this.addOne);
//this.collection.bind("remove", this.removeModel);
this.collection.bind("destroy", this.removeModel);
this.collection.bind("reset", this.render);
this.collection.deferred.done(function() {
//that.render();
that.options.container.removeClass('hide');
});
debug.log('view pointers');
// debug.log(this._viewPointers['c31']);
// debug.log(this._viewPointers[0]);
},
events: {
},
save: function() {
debug.log('shipments changed');
//this.collection.save();
var that = this;
var proxy = _.extend( new Backbone.Model(),
{
url: that.collection.url_put,
toJSON: function() {
return that.collection.toJSON();
}
});
var newJSON = proxy.toJSON()
proxy.save(
newJSON,
{
success: that.saveSuccess,
error: that.saveError
}
);
},
saveSuccess: function(model, response) {
debug.log('Save successful');
},
saveError: function(model, response) {
var responseText = response.responseText;
throw new Error(this.name + " save failed");
},
addOne: function(model) {
debug.log('added one');
this.renderItem(model);
/*
var view = new SB.Views.TicketSummary({
model: model
});
this._viewPointers[model.cid] = view;
*/
},
removeModel: function(model, response) {
// debug.log(model);
// debug.log('shipment removed from collection');
// remove from server
debug.info('Removing view for ' + model.cid);
debug.info(this._viewPointers[model.cid]);
// this._viewPointers[model.cid].unbind();
// this._viewPointers[model.cid].remove();
debug.info('item removed');
//this.render();
},
add: function() {
var nullModel = new this.collection.model({
"poNum" : null,
"shipper" : null,
"proNum" : null,
"link" : null
});
// var tmpl = emptyItemTmpl;
// debug.log(tmpl);
// this.$el.prepend(tmpl);
this.collection.unshift(nullModel);
this.renderInputItem(nullModel);
},
render: function () {
this.$el.html('');
debug.log('list view render');
var i, len = this.collection.length;
for (i=0; i < len; i++) {
this.renderItem(this.collection.models[i]);
};
$(this.container).find(this.className).remove();
this.$el.prependTo(this.options.container);
return this;
},
renderItem: function (model) {
var item = new listItemView({
"model": model
});
// item.bind('removeItem', this.removeModel);
// this._viewPointers[model.cid] = item;
this._viewPointers[model.cid] = item;
debug.log(this._viewPointers[model.cid]);
item.render().$el.appendTo(this.$el);
},
renderInputItem: function(model) {
var item = new listItemView({
"model": model
});
item.renderEmpty().$el.prependTo(this.$el);
}
});
P.S... Again, there is code that is referenced from elsewhere. But please note: the collection does have a url attribute set. And it does work for the initial fetch as well as when there's a change event fired for saving changes made to the models. But the destroy event in the list-item view, while it does trigger the "destroy" event successfully, it doesn't send the 'DELETE' HTTP request.
Do your models have an ID? If not, the HTTP request won't be sent. –
nikoshr May 14 at 18:03
Thanks so much! Nikoshr's little comment was exactly what I needed. I spent the last 5 hours messing with this. I just had to add an id to the defaults in my model.