backbone.js , waiting for external post request to complete - ajax

I have an image uploader on my index.php page, when the image starts uploading (initiated by dragging image onto upload box) , the POST request is created (FYI HTML5 + php Uploader)
POST http://localhost:8888/backbone_images/post_file.php
Inside of my post_file.php , I retrieve the URL of my uploaded image by inserting it in my exit_status, than later in my script assigning it to a global javascript variable 'globe'
if(move_uploaded_file($pic['tmp_name'], $upload_dir.$pic['name'])){
exit_status($pic['name']);
}
Inside of my backbone script file, I check for the drop event into the dropbox, which works,
App.Views.AddImage = Backbone.View.extend({
el: '#addImage',
events: {
'drop': 'submit'
},
so the image has been dragged onto the dropbox, and I call my submit function to create a new model
and assign the url of the new image (which I pass through a javascript variable)
to the url of my new model
submit: function(e) {
e.preventDefault(); // preventing default submission..
var newImage = globe; // assign globe --url of the newly created image--to new model
var imager = new App.Models.Person({ url: newImage });//creating a new img object
this.collection.add(imager);
}
The problem is that when my backbone submit function is triggered after an image is dropped, my POST to /post_file.php hasn't run yet, as a result my variable 'globe' doesn't contain the new URL, and my newly created model ends up lacking a url
So question: is there any way for me to wait for the POST to finish within my backbone events before executing my 'submit' function, after an image drop?
I tried to use: $.when( $.ajax("/post_file.php") ) inside of my submit function, but all this does is run another POST request, leaves my variable value, than run the original POST request retrieving the image URL that I'm waiting for.
My preferred workflow would be
a. drag/upload image, (POST performs)
b. new model is added to
collection with URL of uploaded image,
but I end having to add an additional click function first otherwise the POST doesn't finish
a. drag/upload image, (POST peforms)
b. click on a submit button
c. model is added to collection

Related

How do i request an Array from the controller from inside a javascript code

I am using Spring boot, JPA with mysql, and thymeleaf and openlayers for the map.
So i have a map, and on this map there are dynamically generated markers for different places. What I want is when I click any of those markers to send the name of the marker to my controller and in response get an array of fishes that can be caught in this specific area and then display the names and pictures of the fishes in a dynamically generated list located on the sidebar . I cant think on how I can achieve that. Ive made a HTML page to show how I want it to look.
I was thinking about making a get request and giving the name as a path variable but then idk how I can do that request from the javascript when the button is clicked. Any ideas or concepts that I can read about are apreciated.
Most DOM elements in html are accessible in javascript via something like document.getelementbyid and typically if I remember this correctly most of the objects you can do something like domobject.addEventListener("click", myScript); and in myScripy make an http call to spring requesting the list of fish. I recommend setting some breakpoints in your JavaScript code via the dev console in your browser and looking through some of the objects that are produced
You can make a get request like described here. developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
Clicking on the markers would be similar to this example https://openlayers.org/en/latest/examples/icon.html, but instead of showing a popup you make a GET request for more data
map.on('click', function (evt) {
const feature = map.forEachFeatureAtPixel(evt.pixel, function (feature) {
return feature;
});
if (feature) {
const name = feature.get('name');
// now make get request
// ....
}
});
If you are requesting an image you could use xhr as in https://openlayers.org/en/latest/apidoc/module-ol_Tile.html#~LoadFunction or you could use fetch, similar to:
fetch(url).then(function(response) {
if (response.ok) {
return response.blob();
}
}).then(function(result) {
if (result) {
const imagesrc = URL.createObjectURL(result);
}
});

ng-grid does not refresh with $resource service

ng-grid is not updating my list.
I am trying to create a object in one view and on creating I redirect my page to list view where i want to see all my added objects. I am able to create a new object through api call and on success I call the view which should ideally show list of all objects, however I dont see the latest added object (On refresh I do see the same object)
Save function call in my create view:
$scope.save = function() {
SERVICE.$save();
$location.path('listview');
}
ListViewCtrl has and init() function which sets the ng grid option
SERVICE.query().
$promise.then(function (data) {
$scope.ngGridOptionVariable = data;
});
I dont see the new data that is being added
Any clue how to handle this issue?

Sending data from listener (of httpRequestObserver) to addon panel (iframe)

I am trying to create a fire-bug like extension for firefox which is actually dev-tool extension. I have registered httpRequestObserver to observe http-on-examine-response event. I have a listener with below method implemented.
onDataAvailable: function(request, context, inputStream, offset, count) {
//I get the request URL using request.name
var responseData = getResponseData(); // gets data from inputStream
// Now I need to render this responseData into panel's iframe
}
I have created the above script as a module and included it in main.js. I could not find out how the data from this script could be sent to the script included in panel's HTML.
I read about Content Script and port.emit & port.on but I think Content Script won't come into picture since I don't want to touch the actual page's DOM. Want I want to do is intercept the HTTP response and log it into devtool panel.
Thanks in advance.
Take the response string received and make a data url out of it. Then with your content script do a document.write(dataurl) or do window.location = dataurl.
How to make dataurl:
var responseData = getResponseData();
var dataurl = 'data:text/html,' + encodeURIComponent(responseData);
I hear that widgets in sdk have a content option where you can specify this data url:
'content' option in panel, which would enable you to specify HTML content directly, as you can with a widget, as a result of which I've raised bug 692675.
Can also be done like this:
var HTML = '<html><p>Hi there</p></html>';
var panel = require('panel').Panel({
contentURL: "data:text/html, " + encodeURIComponent(HTML)
});
panel.show();

Handle ajax response with node.js

I am trying to scrape information from a specified website. This site uses authentication first, thus a i use zombie.js:
var Browser = require("zombie");
var browser = new Browser();
browser.visit("https://*****login.aspx", function(){
browser.fill('#user', '*****');
browser.fill('#pwd', '*****');
var button = browser.querySelector('#btnSubmit');
browser.fire('click', button, function(){
//scraping main.aspx
});
});
It's working, i can scrape the main.aspx: there is a <table>, containig information about new messages(from, date, subject,), the problems comes here: the subject field is clickable, and clicking on it makes a new window appear with the actual message. However it is an ajaxgrid, and when i perform a click:
var field = browser.querySelector('#VeryLongIdOfTheField');
browser.fire('click', field, function(){
console.log(browser.querySelector('#VeryLongIdOfTheFieldContainingTheMessage').innerHTML);
});
it returns an error message, saying that undefined has no innerHTML. I suppose its because this action handled with some ajax magic. I am new in this js/nodejs/jquery/.. world, some help needed to enlight me.
Since the data is populated using async ajax, I'm guessing there's a lag between your click and the actual DOM population inside the node. How about waiting for a bit before checking the content inside the node.
browser.fire('click', field, function(){
setTimeout(function(){
console.log(browser.querySelector('#VeryLongIdOfTheFieldContainingTheMessage').innerHTML);
}, 3000)
});
If the time taken is not very predictable, you could also run it inside a loop until you find the content or exit after a reasonable number of retries.

TinyMCE not working in http request xhr ajax generated page

So i I have a page that contains links that call an httpRequest. The request calls a php file that grabs data from mysql and pre populates a form which is then returned to the browser/webpage. My problem is that when the page is returned to the browser via the httpRequest/ajax the text area does not display the tinymce editor, it just displays a normal text area. It looks like my request and ajax is working fine the text area just doesn't have the tinycme editor on it.
When i don't use ajax it works fine but when i put it in a separate file and call it via ajax it doesn't bring in the tinymce editor.
Does anyone know how to fix this problem so that my ajax generated page displays the text area with the tinymce editor. Thank you.
Lets presume that your thinyMCE instance is initialized with code below
// initialize tinyMCE in page
tinyMCE.init({
mode: "textareas",
theme: "advanced"
});
and you have some kind of button somewhere in the page. For purpose of this tip, i will not give it any ID but you may. Now, using jQuery you can easily attach event handler to that button which will call through AJAX your server and take content which you want to put tinyMCE editor. Code which will do such job would look somehow like below.
$(function() {
$("button").bind("click", function() {
var ed = tinyMCE.get('content');
ed.setProgressState(1); // Show progress
$.getJSON('/page/12.json', { /* your data */
}, function(data) {
ed.setProgressState(0); // Hide progress
ed.setContent(data["body"]);
}
});
});
});
You can see that on button.click ajax will call url /page/12.json which will return JSON as response. bare minimum of that response could be:
{
title: "Page title",
body: "<html><head><title>Page title</title>......</html>"
}
I attached anonymous function as callback which will handle response from server. and hide progress indicator which is shown before ajax call.
About JSON
JSON is shorten of JavaScript Object Notation. It is JavaScript code!!! So don't be confused about it. Using JSON you can make javascript object which can have attributes you can use later in your code to access particular peace of data which that object "holds". You can look at it as some kind of data structure if it is easier to you.
Anyway, to show you how this JSON can be created by hand look at examples below
var data = new Object();
data.title = "Page title";
data.body = "<html....";
or
var data = {
title: "page title",
body: "<html...."
};
it is very same thing.
If you want to learn more about JSON point your browser to http://json.org.
===== alternative =====
Alternative to json solution could be just plane ajax call to server and response can be plain HTML (from your question I can assume that you have something like this already). So instad of calling $.getJSON you can use $.get(url, callback); to do same thing. The code at the top of my answer will not dramatically change. Instead of geting JSON in response you will get string which is HTML.
----------- BOTTOM LINE -------
I prefer JSON since it can be easily extended later with other attributes, so there is no painful code changes later ;)
Problem here will be that when you return the full page and render it using the ajax response, your tinymce instance has not been shut down before.
In order to do this you can call this small piece of code before you render the ajax response:
tinymce.execCommand('mceRemoveControl',true,'editor_id');
In this case the editor should initialize correctly. You are not allowed to initialize a tinymce editor with the same id before shutting the first one down.
Strangely i ran into this problem yesterday. Following code should work, but YMMV. Trick is to use the correct steps in ajax events. I used the Regular TinyMCE and made use of the jQuery library already included.
Following goes into your tinyMCE initialization tinyMCE.init() . All of the below block should be outside the document.ready.
myTinyInit = {
//.......All essential keys/values ...........
setup : function(ed) {
ed.onChange.add(function( ed ) {
tinyMCE.triggerSave();
}) }
//.....................
};
// Init the tinyMCE
tinyMCE.init(myTinyInit);
This ensures the content is being saved regularly onto the textarea that holds the value. Next step is setting up the request events.
Normally tinyMCE mceAddControl before the ajax post and mceRemoveControl after the ajax success should do the trick. But I found that often does not work.
I used the form as the jQuery selector in my case.
jQuery( '.myForm' )
.find( 'textarea#myTextArea' )
.ajaxStart(function() {
// If you need to copy over the values, you can do it here.
// If you are using jQuery form plugin you can bind to form-pre-serialize event instead.
// jQuery( this ).val( tinyMCE.get( jQuery( this ).attr( 'id' )).getContent() );
}).ajaxSend( function() {
// ! - step 2
// My case was multiple editors.
myEds = tinyMCE.editors;
for( edd in myEds ) {
myEds[ eds ].remove();
}
// tinyMCE.get( 'myTextarea' ).remove();
// strangely mceRemoveControl didnt work for me.
// tinyMCE.execCommand( 'mceRemoveControl', false, jQuery( this ).attr('id'));
}).ajaxSuccess(function() {
// Now we got the form again, Let's put up tinyMCE again.
txtID = jQuery( this ).attr( 'id' );
// ! - step 3
tinyMCE.execCommand( 'mceAddControl', false, txtID );
// Restore the contents into TinyMCE.
tinyMCE.get( txtID ).setContent( jQuery( this ).val());
});
Problems i came across :
Using mceRemoveControl always gave me r is undefined error persistently.
If you get a blank tinyMCE editor, check the DOM whether the ID of the textarea is replaced with something like mce_02, this means that TinyMCE is being initialized again or something is wrong with the order. If so, the tinyMCE is duplicated with each save.
if you are new to JS, I recommend using jQuery with the form plugin, it might be easier for you. But do use the regular non-jquery tinyMCE, as it is well documented.
I fixed this problem by recalling the function after the ajax call. In this part of my ajax:
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("Content").innerHTML=xmlhttp.responseText;
tinymce();
Now it works fine.

Resources