Laravel 3 - Passing variables across multiple views - variables

I have two forms on two different views. I would like to post the form input to the second view, and then back to the first form upon posting the second form.
I have set up a test with a route that looks like this :
Route::get('/test1', function() {
return View::make('test1');
});
Route::post('/test2', function() {
$flash = Input::get();
return View::make('test2')->with('flash', $flash);
});
Route::post('/test1', function() {
return View::make('test1')->with('flash', $flash);
});
I am only able to pass $flash once. I'm misunderstanding why I cannot pass it again. I feel like I have to extract it again?

You need to add a form field in /test2 and resubmit the $flash data in order to pass it to /test1 via POST. It's a new request, the app will lose the $flash var otherwise.
A different approach could be to store $flash in a session with Session::put('flash', $flash); and accessing it in the next request.

The best method is to store your data in session. It will be available across multiple request . Using Input::flash() will only be available until the next request. See the Laravel docs for Input::flash() and Session

Related

CasperJS/PhantomJS how to keep old page open?

I have form with some dynamic input that need to be filled. The problem is that to fill the form I need to visit another page to get data that depends on input on the previous page. So after I got a data and then backed to form, the form is already changed so I need to keep that form open while I getting a data for it. So question is how to make it?
You could probably create two casper instances. Where your first instance will have first page, and when required create another instance and get the data from it. Store data in casper's global scope.
Make waitFor until your variable value set # first instance.
Maybe with casper.back() and casper.forward() :
https://github.com/n1k0/casperjs/blob/master/tests/suites/casper/history.js
I suppose your previous form will be saved in the previous step.I hope so, try it.
Edit :
getData(newPage) was an example of your own casper method, you could try something like that :
var password ="wtoc95a";
casper.getData = function (newPage, previousPageInputData) {
//visit another page
casper.open(newPage)
//or casper.open(newPage+previousPageInputData) if the new page opened use the previous input
.then(function() {
//here you do what you want using "input" argument of the previous page
//just return the data you need to fill the form
});
return dataNeeded;
};
And in your form :
this.fill('form[id="signup_frm"]', {
nick_name: "pseudo",
e_mail: "mail",
password: "password",
password2: password,
input : casper.getData(arg1,arg2)
http://docs.casperjs.org/en/1.1-beta2/extending.html

How to use store.filter / store.find with Ember-Data to implement infinite scrolling?

This was originally posted on discuss.emberjs.com. See:
http://discuss.emberjs.com/t/what-is-the-proper-use-of-store-filter-store-find-for-infinite-scrolling/3798/2
but that site seems to get worse and worse as far as quality of content these days so I'm hoping StackOverflow can rescue me.
Intent: Build a page in ember with ember-data implementing infinite scrolling.
Background Knowledge: Based on the emberjs.com api docs on ember-data, specifically the store.filter and store.find methods ( see: http://emberjs.com/api/data/classes/DS.Store.html#method_filter ) I should be able to set the model hook of a route to the promise of a store filter operation. The response of the promise should be a filtered record array which is a an array of items from the store filtered by a filter function which is suppose to be constantly updated whenever new items are pushed into the store. By combining this with the store.find method which will push items into the store, the filteredRecordArray should automatically update with the new items thus updating the model and resulting in new items showing on the page.
For instance, assume we have a Questions Route, Controller and a model of type Question.
App.QuestionsRoute = Ember.Route.extend({
model: function (urlParams) {
return this.get('store').filter('question', function (q) {
return true;
});
}
});
Then we have a controller with some method that will call store.find, this could be triggered by some event/action whether it be detecting scroll events or the user explicitly clicking to load more, regardless this method would be called to load more questions.
Example:
App.QuestionsController = Ember.ArrayController.extend({
...
loadMore: function (offset) {
return this.get('store').find('question', { skip: currentOffset});
}
...
});
And the template to render the items:
...
{{#each question in controller}}
{{question.title}}
{{/each}}
...
Notice, that with this method we do NOT have to add a function to the store.find promise which explicitly calls this.get('model').pushObjects(questions); In fact, trying to do that once you have already returned a filter record array to the model does not work. Either we manage the content of the model manually, or we let ember-data do the work and I would very much like to let Ember-data do the work.
This is is a very clean API; however, it does not seem to work they way I've written it. Based on the documentation I cannot see anything wrong.
Using the Ember-Inspector tool from chrome I can see that the new questions from the second find call are loaded into the store under the 'question' type but the page does not refresh until I change routes and come back. It seems like the is simply a problem with observers, which made me think that this would be a bug in Ember-Data, but I didn't want to jump to conclusions like that until I asked to see if I'm using Ember-Data as intended.
If someone doesn't know exactly what is wrong but knows how to use store.push/pushMany to recreate this scenario in a jsbin that would also help too. I'm just not familiar with how to use the lower level methods on the store.
Help is much appreciated.
I just made this pattern work for myself, but in the "traditional" way, i.e. without using store.filter().
I managed the "loadMore" part in the router itself :
actions: {
loadMore: function () {
var model = this.controller.get('model'), route = this;
if (!this.get('loading')) {
this.set('loading', true);
this.store.find('question', {offset: model.get('length')}).then(function (records) {
model.addObjects(records);
route.set('loading', false);
});
}
}
}
Since you already tried the traditional way (from what I see in your post on discuss), it seems that the key part is to use addObjects() instead of pushObjects() as you did.
For the records, here is the relevant part of my view to trigger the loadMore action:
didInsertElement: function() {
var controller = this.get('controller');
$(window).on('scroll', function() {
if ($(window).scrollTop() > $(document).height() - ($(window).height()*2)) {
controller.send('loadMore');
}
});
},
willDestroyElement: function() {
$(window).off('scroll');
}
I am now looking to move the loading property to the controller so that I get a nice loader for the user.

EmberJS Route to 'single' getting JSONP

I'm having trouble with EmberJS to create a single view to posts based on the ID, but not the ID of the array, I actually have a ID that comes with the json I got from Tumblr API.
So the ID is something like '54930292'.
Next I try to use this ID to do another jsonp to get the post for this id, it works if you open the api and put the id, and actually if you open the single url with the ID on it, works too, the problem is:
When, on the front page for example, I click on a link to go to the single, it returns me nothing and raise a error.
But if you refresh the page you get the content.
Don't know how to fix and appreciate some help :(
I put online the code: http://tkrp.net/tumblr_test/
The error you were getting was because the SingleRoute was being generated as an ArrayController but the json response was not an Array.
App.SingleController = Ember.ObjectController.extend({
});
Further note that the model hook is not fired when using linkTo and other helpers. This because Ember assumes that if you linked to a model, the model is assumed to be as specified, and it directly calls setupController with that model. In your case, you need to still load the individual post. I added the setupController to the route to do this.
App.SingleRoute = Ember.Route.extend({
model: function(params) {
return App.TKRPTumblr.find(params.id);
},
setupController: function(controller, id) {
App.TKRPTumblr.find(id)
.then(function(data) {
controller.set('content', data.response);
});
}
});
I changed the single post template a bit to reflect how the json response. One final change I made was to directly return the $.ajax. Ember understands jQuery promises directly, so you don't need to do any parsing.
Here is the updated jsbin.
I modified: http://jsbin.com/okezum/6/edit
Did this to "fix" the refresh single page error:
setupController: function(controller, id) {
if(typeof id === 'object'){
controller.set('content', id.response);
}else{
App.TKRPTumblr.find(id)
.then(function(data) {
controller.set('content', data.response);
});
}
}
modified the setupController, since I was getting a object when refreshing the page and a number when clicking the linkTo
Dont know if it's the best way to do that :s

client web - how to get current record id at any time

I'm trying to work on the "different permissions based on workflow state" issue but I'm struggling with the fact that it seems impossible to get the id of the current object 'at any time' that is necessary in order to get the permission of that object. What I mean is that I manage to get it from the client state following jquery bbq docs like:
$.bbq.getState().id
BUT it looks like this is doable only AFTER a complete page load. I investigated this by placing some alert in the main view events, like:
openerp.web.PageView = openerp.web.PageView.extend({
on_loaded: function(data) {
this._super(data);
alert('page load ' + $.bbq.getState().id);
},
do_show: function() {
this._super();
alert('page show ' + $.bbq.getState().id);
},
reload: function() {
this._super();
alert('page reload ' + $.bbq.getState().id);
},
on_record_loaded: function(record) {
this._super(record);
alert('record loaded ' + $.bbq.getState().id);
}
});
and I found that when you open the page view (by clicking on an item in a search view, for instance) you get always "undefined".
Then, you get it into "reload" and "on_record_loaded" when passing from an object to another using paged navigation. And then, you miss it again when you click on the "edit" button.
In the form view I successfully got it only on the 1st load because it seems that some caching is in-place. So that, if I place a pdb into web client's fields_view_get and I do this into the form "init_view":
var ids = [];
if ($.bbq.getState().id){
ids = [parseInt($.bbq.getState().id)];
}
console.log(ids);
return this.rpc("/web/view/load", {
"model": this.model,
"view_id": this.view_id,
"view_type": "form",
toolbar: this.options.sidebar,
context: context,
ids: ids,
}, this.on_loaded);
I get it only the 1st time that the page gets loaded. The same happen if I take ids from
this.dataset.ids
I looked anywhere at the core web module and I can't find a proper API for this and it looks weird (above all on dataset) that we don't have a proper way for getting/working on the current record/s. Even the context and the session do not have any information about that.
Probably I should store this into the view itself on 1st load...
Thanks in advance for any pointers.
try:
this.view.datarecord.id
OpenERP 7 in form view:
debugged using google chrome
Try the combination of the
this.dataset.ids and this.dataset.index
like
curr_id = this.dataset.ids[this.dataset.index]
this might solve your problem.

How do I get data from a background page to the content script in google chrome extensions

I've been trying to send data from my background page to a content script in my chrome extension. i can't seem to get it to work. I've read a few posts online but they're not really clear and seem quite high level. I've got managed to get the oauth working using the Oauth contacts example on the Chrome samples. The authentication works, i can get the data and display it in an html page by opening a new tab.
I want to send this data to a content script.
i'm having a lot of trouble with this and would really appreciate if someone could outline the explicit steps you need to follow to send data from a bg page to a content script or even better some code. Any takers?
the code for my background page is below (i've excluded the oauth paramaeters and other )
` function onContacts(text, xhr) {
contacts = [];
var data = JSON.parse(text);
var realdata = data.contacts;
for (var i = 0, person; person = realdata.person[i]; i++) {
var contact = {
'name' : person['name'],
'emails' : person['email']
};
contacts.push(contact); //this array "contacts" is read by the
contacts.html page when opened in a new tab
}
chrome.tabs.create({ 'url' : 'contacts.html'}); sending data to new tab
//chrome.tabs.executeScript(null,{file: "contentscript.js"});
may be this may work?
};
function getContacts() {
oauth.authorize(function() {
console.log("on authorize");
setIcon();
var url = "http://mydataurl/";
oauth.sendSignedRequest(url, onContacts);
});
};
chrome.browserAction.onClicked.addListener(getContacts);`
As i'm not quite sure how to get the data into the content script i wont bother posting the multiple versions of my failed content scripts. if I could just get a sample on how to request the "contacts" array from my content script, and how to send the data from the bg page, that would be great!
You have two options getting the data into the content script:
Using Tab API:
http://code.google.com/chrome/extensions/tabs.html#method-executeScript
Using Messaging:
http://code.google.com/chrome/extensions/messaging.html
Using Tab API
I usually use this approach when my extension will just be used once in a while, for example, setting the image as my desktop wallpaper. People don't set a wallpaper every second, or every minute. They usually do it once a week or even day. So I just inject a content script to that page. It is pretty easy to do so, you can either do it by file or code as explained in the documentation:
chrome.tabs.executeScript(tab.id, {file: 'inject_this.js'}, function() {
console.log('Successfully injected script into the page');
});
Using Messaging
If you are constantly need information from your websites, it would be better to use messaging. There are two types of messaging, Long-lived and Single-requests. Your content script (that you define in the manifest) can listen for extension requests:
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if (request.method == 'ping')
sendResponse({ data: 'pong' });
else
sendResponse({});
});
And your background page could send a message to that content script through messaging. As shown below, it will get the currently selected tab and send a request to that page.
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.sendRequest(tab.id, {method: 'ping'}, function(response) {
console.log(response.data);
});
});
Depends on your extension which method to use. I have used both. For an extension that will be used like every second, every time, I use Messaging (Long-Lived). For an extension that will not be used every time, then you don't need the content script in every single page, you can just use the Tab API executeScript because it will just inject a content script whenever you need to.
Hope that helps! Do a search on Stackoverflow, there are many answers to content scripts and background pages.
To follow on Mohamed's point.
If you want to pass data from the background script to the content script at initialisation, you can generate another simple script that contains only JSON and execute it beforehand.
Is that what you are looking for?
Otherwise, you will need to use the message passing interface
In the background page:
// Subscribe to onVisited event, so that injectSite() is called once at every pageload.
chrome.history.onVisited.addListener(injectSite);
function injectSite(data) {
// get custom configuration for this URL in the background page.
var site_conf = getSiteConfiguration(data.url);
if (site_conf)
{
chrome.tabs.executeScript({ code: 'PARAMS = ' + JSON.stringify(site_conf) + ';' });
chrome.tabs.executeScript({ file: 'site_injection.js' });
}
}
In the content script page (site_injection.js)
// read config directly from background
console.log(PARAM.whatever);
I thought I'd update this answer for current and future readers.
According to the Chrome API, chrome.extension.onRequest is "[d]eprecated since Chrome 33. Please use runtime.onMessage."
See this tutorial from the Chrome API for code examples on the messaging API.
Also, there are similar (newer) SO posts, such as this one, which are more relevant for the time being.