Sencha Touch 2 - Changing Views after an Ajax.Request - sencha-touch-2

This may sound weird but ive been banging my head for the past 2 hours because of this problem. I have a function that triggers once I press a login button, when pressed it starts an Ajax Request.
onEnter: function () {
Ext.Viewport.mask();
var email = Ext.getCmp('email').getValue();
var pass = Ext.getCmp('pw').getValue();
var consegui = 0;
Ext.Ajax.request({
controller: 'AP4.controller.MainCont',
url: 'myurl',
method: 'POST',
callbackKey: 'callback',
jsonData:{"username":'user', "password":'pass'},
success: function(result) {
//Se o webservice nao der erro ele entra aqui, nao quer dizer que tenha
//sido correctamente criado session
// Unmask the viewport
Ext.Viewport.unmask();
Ext.Msg.alert("Login Done! Congrats!");
Ext.Viewport.setActiveItem(this.getRegisto()); **//THIS LINE IS NOT WORKING**
},
failure: function(result){
Ext.Msg.alert("Username ou Palavra passe Incorrectas!");
},
});
},
For some reason, The setActiveItem is not working and I dont know why. Can anyone help me ?

i think you are accessing this.getRegisto; function in wrong scope,
have you checked this keyword points to the object which you want in the success callback?
to change the scope of success callback you can simply add scope argument in the Ext.Ajax.request call, like this
Ext.Ajax.request({
url: 'myurl',
method: 'POST',
success: function(result) {
// this will point to ViewPort object here
},
failure: function(result){
Ext.Msg.alert("Username ou Palavra passe Incorrectas!");
},
scope : Ext.Viewport // this is used just for illustration, please specify correct scope here
});

If Registo is in your viewport, why not use setActiveItem(some number) like if Registro is the first item in your viewport then do setActiveItem(0);

Related

vue.js how to show progress if processing data

I have a page build in vue.js where an API is called (using axios) getting a large json object (1k+).
While I am processing this object, I want to show user the progress of the operation - nothing fancy like progress bars, just a simple "Processed X from Y".
I have found example on how to do this in jquery of pure JS, but I can get this to work in vue.
Any help is appreciated.
Here is my skeleton code:
<div>Processed {{processed.current}} of {{processed.total}} records</div>
<script>
data() {
return {
progress:{
current:0,
total: 0
},
records: [],
};
},
mounted() {
this.getRecords();
},
methods: {
getRecords(){
axios({
method: "GET",
url: process.env.VUE_APP_REPORTING_API + "/Reports/orders",
headers: {
"content-type": "application/json",
Authorization: this.$cookie.get("wwa_token")
}
}).then(
result => {
this.progress.total = result.data.length;
//and here where the loop should happen, something like this
//obviously the below won't work :)
result.data.forEach(function(item) {
this.records.push(item);
this.progress.current++;
}
},
error => {
}
);
}
}
</script>
Well, the obvious problem with the posted code is that it has a syntax error (missing a closing parenthesis) and it establishes a new context. The code would (sort of) "work" if it was changed it to use arrow functions:
result.data.forEach(item => {
this.records.push(item);
this.progress.current++;
});
However, I don't think that's going to do what you want. The JavaScript code will process all the items before the user interface updates, so all the user would see would be "Processed N of N records". Even if you inserted a this.$forceUpdate() in the loop to make the interface update at each iteration, the changes would still be too fast for any user to see.
The real problem is that "processing" all the items only takes a few milliseconds. So it's always going to happen too quickly to show intermediate results.
If you're trying to show the progress of the AJAX request/response, that's an entirely different question which will require coordination between the client and the server. Search for HTTP chunked responses for a start.

titanium - fire event - Listener callback is of a non-supported type: NSNull

I'm writing a simple script that simulates the change page.
var square = $.UI.create('View',{page : info, classes : ["box"]});
square.addEventListener('click', function(e){
Ti.API.info(JSON.stringify({title:e.source.page.title,page : e.source.page.id,menu:true});
Ti.App.fireEvent('index:page',{title:e.source.page.title,page : e.source.page.id,menu:true});
});
and in another controller I wrote
Ti.App.addEventListener('index:page',startup);
var startup = function(data){
global_data = data;
Alloy.Collections.menu.fetch();
...
}
the problem is that when I tap into the "square" button, I got
Listener callback is of a non-supported type: NSNull
the line Ti.API.info(JSON.stringify({title:e.source.page.title,page : e.source.page.id,menu:true}); gives me {"title":"News","page":5,"menu":"true"}
have no idea why. it seems like a parameter I pass to the startup function has null value, but the output doesn't say so.
any suggestions?
the problem was the order of the declaration-invocation:
var startup = function(data){
global_data = data;
Alloy.Collections.menu.fetch();
...
};
Ti.App.addEventListener('index:page',startup);
instead of
Ti.App.addEventListener('index:page',startup);
var startup = function(data){
global_data = data;
Alloy.Collections.menu.fetch();
...
};

Pass data-attribute value of clicked element to ajax settings

For an implementation of Magnific Popup, I need to pass a post id to the ajax settings. The post id is stored in a data attribute of the element to which Magnific Popup is bound. I would like this to work:
html element:
<a data-id="412">Clicke me</a>
Javascript:
$('.element a').magnificPopup({
type: 'ajax',
ajax: {
settings: {
url: php_array.admin_ajax,
type: 'POST',
data: ({
action:'theme_post_example',
id: postId
})
}
}
});
Where postId is read from the data attribute.
Thanks in advance.
$('.element a').magnificPopup({
callbacks: {
elementParse: function(item){
postData = {
action :'theme_post_example',
id : $(item.el[0]).attr('data-id')
}
var mp = $.magnificPopup.instance;
mp.st.ajax.settings.data = postData;
}
},
type: 'ajax',
ajax: {
settings: {
url: php_array.admin_ajax,
type: 'POST'
}
}
});
Here is how to do it:
html:
<a class="modal" data-id="412" data-action="theme_post_example">Click me</a>
jquery:
$('a.modal').magnificPopup({
type: 'ajax',
ajax: {
settings: {
url : php_array.admin_ajax,
dataType : 'json'
}
},
callbacks: {
elementParse: function() {
this.st.ajax.settings.data = {
action : this.st.el.attr('data-action'),
id : this.st.el.attr('data-id')
}
}
},
parseAjax: function( response )
{
response.data = response.data.html;
}
});
php
function theme_post_example()
{
$id = isset( $_GET['id'] ) ? $_GET['id'] : false;
$html = '<div class="white-popup mfp-with-anim">';
/**
* generate your $html code here ...
*/
$html .= '</div>';
echo json_encode( array( "html" => $html ) );
die();
}
As this answer was the original question regarding inserting data into Magnific's ajax call, I'll post this here.
After many hours of trying to figure this out, you should know that if you're using a gallery with the ability to move between gallery items without closing the popup, using elementParse to set your AJAX data will fail when you visit an item after already viewing it (while the popup is still open).
This is because elementParse is wrapped up in a check that it makes detect if an item has already been 'parsed'. Here's a small explanation as to what happens:
Open gallery at item index 2.
Item has not been parsed yet, so it sets the parsed flag to true and runs the elementParse callback (in that order). Your callback sets the ajax options to fetch this item's data, all is well.
Move (right) to item index 3.
Same as above. The item has not been parsed, so it runs the callback. Your callback sets the data. It works.
Move (left) back to item index 2.
This time the item has been parsed. It skips re-parsing the item's element for assumed potential performance reasons.Your callback is not executed. Magnific's ajax data settings will remain the same as if it were item index 3.
The AJAX call is executed with the old settings, it returns with item index 3's data instead, which is rendered to the user. Magnific will believe it is on index 2, but it is rendering index 3's data.
To resolve this, you need to hook onto a callback which is always executed pre-ajax call, like beforeChange.
The main difference is that the current item isn't passed through into the callback. Fortunately, at this point, magnific has updated their pointers to the correct index. You need to fetch the current item's element by using:
var data = {}; // Your key-value data object for jQuery's $.ajax call.
// For non-closures, you can reference mfp's instance using
// $.magnificPopup.instance instead of 'this'.
// e.g.
// var mfp = $.magnificPopup.instance;
// var itemElement = mfp.items[mfp.index].el;
var itemElement = this.items[this.index].el;
// Set the ajax data settings directly.
if(typeof this.st.ajax.settings !== 'object') {
this.st.ajax.settings = {};
}
this.st.ajax.settings.data = data;
This answer can also be used as a suitable alternative to the currently highest voted, as it will work either way.
You may use open public method to open popup dynamically http://dimsemenov.com/plugins/magnific-popup/documentation.html#public_methods
postId = $(this).attr('data-id')
$(this) retrieve the current element (the link you clicked on), and attr the value of the specified attribute.

Loading store with params

What I am trying to do is load store with params like below so I only get the first ten items of my store.
app.stores.actualites.load({
params : {
start:0,
limit:10,
},
callback : function(records, operation, success) {
app.loadmask.hide();
}
});
But this is not working, it returns all the 18 store items.
If I put the start param to 1, it will return 17 items, so this param is working but not the other.
Update : Store code
app.stores.actualites = new Ext.data.Store({
model: 'app.models.Actualites',
proxy: {
type: 'ajax',
url: app.stores.baseAjaxURL + '&jspPage=%2Fajax%2FlistActualites.jsp',
reader: {
type: 'json',
root: 'actualite',
successProperty: 'success',
totalProperty: 'total',
idProperty: 'blogEntryInfosId'
}
}
});
The weird thing here is when I try the URL in a browser and add &start=0&limit=1 it works just fine...
Update : Try with extraParams
I also tried to do it with extraParams but this still doesn't work
app.stores.actualites.getProxy().extraParams.start = 1;
app.stores.actualites.getProxy().extraParams.limit = 2;
app.stores.actualites.load({
callback : function(records, operation, success) {
app.loadmask.hide();
}
});
The pagination functionality has to be actually implemented at your server side. Sencha will only maintain the pages and will send you proper start and limit values. You need to access these values at your server side script and return appropriate results depending on those.
If you are using a list, then you can use Sencha's inbuilt ListPaging plugin which takes care of the start/limit parameter in its own.
This might sound weird, but I changed to name of the param 'limit' to 'stop' both on the client and the server and it worked...
it should be something like that:
app.stores.actualites.getProxy().setExtraParams({
start:1,
limit:2
})

Dojo lightbox problem

I made a custom basic lightbox with Dojo to be used with forms and data. Not really dealing with images or such.
The problem that I seem to be facing is this. When Dojo makes a call via AJAX to ajaxtb.php with specific code for example; ?f=login or ?f=register the page is loaded. When you I close the lightbox and try to view something different say ?f=stuff the lightbox will show what ever was before it be it ?f=login or what ever, it will show it until ?f=stuff is fully loaded.
Here is the code for the lightbox, also can some one tell me how to optimize it since its pretty redundant at the moment and very basic.
dojo.ready(function(){
#loads logout confirmation
dojo.query("#jsLogoutPromp").connect("onclick", function(){
dojo.byId("qpbox-title-text").innerHTML = "Logout Confirmation";
dojo.query("#qpbox-content").style("display", "block");
dojo.query("#qpbox-overlay").style("display", "block");
dojo.xhrGet({
url: "ajaxtb.php?f=logout",
load: function(newContent) {
dojo.byId("utm").innerHTML = newContent;
},
// The error handler
error: function() {
// Do nothing -- keep old content there
}
});
});
#loads options to upload profile photo
dojo.query("#jsUserPhotoPromp").connect("onclick", function(){
dojo.byId("qpbox-title-text").innerHTML = "Upload Photo";
dojo.query("#qpbox-content").style("display", "block");
dojo.query("#qpbox-overlay").style("display", "block");
dojo.xhrGet({
url: "ajaxtb.php?f=display_pic",
load: function(newContent) {
dojo.byId("utm").innerHTML = newContent;
},
// The error handler
error: function() {
// Do nothing -- keep old content there
}
});
});
#closes everything when clicked well technically hides everything
dojo.query("#qpbox-close").connect("onclick", function(){
dojo.query("#qpbox-content").style("display", "none");
dojo.query("#qpbox-overlay").style("display", "none");
});
#shows up for logout only, same as above code, but does not work since the original id is included in ajax.php?f=logout
dojo.query("#qpbox-stay").connect("onclick", function(){
dojo.query("#qpbox-content").style("display", "none");
dojo.query("#qpbox-overlay").style("display", "none");
});
});
The functions responsible for closing everything is qpbox-close and qpbox-stay. Technically both only hide the lightbox not close. The other problem is with qpbox-stay. qpbox-stay id is located in ajax.php?f=logout and when clicked it does not close the lightbox so not sure whats the problem with it.
here is the code for ajax.php
if($_GET['f'] == 'logout') {
echo '
<p>Are you sure you want to exit right now?</p>
<br>
<button type="submit">Logout</button> No, I wana Stay
';
}
Thanks
You can use dojo.empty(dojo.byId('utm')) before showing the lightbox to delete all the contents.
Also, you can refactor your code quite a bit. Both click handlers do basically the same thing. So why not refactor them in a function?
dojo.ready(function() {
function showLightBox(title, url) {
var utm = dojo.byId('utm');
dojo.empty(utm);
dojo.byId("qpbox-title-text").innerHTML = title;
dojo.style(dojo.byId("qpbox-content"), "display", "block");
dojo.style(dojo.byId("qpbox-overlay"), "display", "block");
dojo.xhrGet({
url: url,
load: function(newContent) {
utm.innerHTML = newContent;
},
// The error handler
error: function() {
// Do nothing -- keep old content there
}
});
}
function hideLightBox() {
dojo.style(dojo.byId("qpbox-content"), "display", "none");
dojo.style(dojo.byId("qpbox-overlay"), "display", "none");
}
dojo.connect(dojo.byId('jsLogoutPromp'), 'onclick', function() {
showLightBox("Logout Confirmation", "ajaxtb.php?f=logout");
});
// ...
dojo.connect(dojo.byId('qpbox-close'), 'onclick', hideLightBox);
});
You can try and connect to #qpbox-stay after you've loaded the content, or if using Dojo 1.6, you can use NodeList.delegate like:
dojo.require('dojox.NodeList.delegate');
dojo.query('#utm').delegate('#qpbox-stay', 'onclick', hideLightBox);
That will connect to #utm which is already loaded, but work for #qpbox-stay only. It works with event bubbling, similar to jquery.live(). See http://davidwalsh.name/delegate-event