Laravel render for differend controller method - laravel

I'm struggling with the render() method in Laravel 5.
When $whatever->render() is runned, it takes the controller method name as the route by default.
Example:
When i run this command in DelasController#updateFilter, the pagination route is set to whatever.com/marketplace/updateFiler?page=2, which does not make a sense to me.
Problem:
I want to keep the route as simple as whatever.com/marketplace?page=2.
Question:
Can anybody gives me a hint on how to solve this?
Thank you for your time and a discussion.
Looking forward for a reply.

I have an application in which various paginated lists are displayed in "windows" on the page and are updated via AJAX calls to the server. Here's how I did it:
Set up a route to render the whole page, something like this:
Route::get('/marketplace', function ($arguments) {
....
});
Set up a route which will return the current page of the list. For example, it might be something like this:
Route::get('/marketplace/updateFiler', function ($arguments) {
....
});
In your Javascript code for the page, you need to change the pagination links so that, instead of loading the new page with the URL for the link, it makes the AJAX request to the second route. The Javascript could look something like this:
$('ul.pagination a').on('click', function (event) {
// stop the default action
event.stopPropagation();
event.preventDefault();
// get the URL from the link
var url = $(event.currentTarget).attr('href');
// get the page number from the URL
var page = getURLParameterByName(url, 'page');
$.get('marketplace/updateFiler', { page: page }, function (data){
// do something with the response from the server
});
});
The getURLParameterByName function is simply a helper that extracts the named parameter from a URL:
var getURLParameterByName = function (url, name, defaultValue) {
// is defaultValue undefined? if so, set it to false
//
if (typeof defaultValue === "undefined") {
defaultValue = false;
}
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(url);
return results === null ?
defaultValue :
decodeURIComponent(results[1].replace(/\+/g, " "));
};
I adapted this code from an answer I found here on Stack Overflow: https://stackoverflow.com/a/901144/2008384.

Related

Send Multiple data with ajax

I want to use ajax for add data in database and i found following code in net and it is working fine.
<script language='javascript'>
reqObj=null;
function saveCust(){
document.getElementById('res').innerHTML='processing';
if(window.XMLHttpRequest){
reqObj=new XMLHttpRequest();
}else {
reqObj=new ActiveXObject('Microsoft.XMLHTTP');
}
reqObj.onreadystatechange=processSave;
reqObj.open('POST','./custSave?reqObj.open('POST','./cName?id='+document.getElementById('CustCode').value,true);,true);
reqObj.send(null);
}
function processSave(){
if(reqObj.readyState==4){
document.getElementById('res').innerHTML=reqObj.responseText;
}
}
</script>
Above code sends only one String but, i have 5 Strings in my form.
Please anybody alter the code for sending multiple data.
The problem is that you're sending a single parameter in the reqObj.open function:
reqObj.open('POST','./custSave?reqObj.open('POST','./cName?id='+document.getElementById('CustCode').value,true);,true);
Note that the only parameter you send is id.
You can add more parameters in the flavor of QueryString:
id=something&otherParameter=else //and more parameters
IMO the easiest way to handle an ajax request would be using jQuery, as shown and heavily explained by BalusC in How to use Servlets and Ajax?.
Based on the samples there and jQuery Ajax POST example with PHP, you can come with the following code:
Assuming the 5 Strings are in the form
function saveCust(){
$('#res').html('processing');
var $form = $(this);
var serializedData = $form.serialize();
$.post('./custSave', serializedData, function(responseText) {
$('#res').html(responseText);
});
}
Assuming there's data outside the form
function saveCust(){
$('#res').html('processing');
var $form = $(this);
var serializedData = $form.serialize() + "&id=" + $('#CustCode').val();
$.post('./custSave', serializedData, function(responseText) {
$('#res').html(responseText);
});
}
And you can even enhance this using more jQuery functions, but that's outside the scope of this answer.

redirect to another page after ajax function

Can anyone help me with, I am trying to create a download counter to my website.
I have a ajax script that counts up by 1 when the users clicks the download link, the issue I am having is on some browsers it goes to the download link before completing the ajax count script.
Is there a way that I can redirect to the download file once the script has completed. At the moment I have as follows
This is the link :-
<a href='downloads/".$downfile."' onclick=\"Counter('$referid');\"'>Download File</a>
This is the counter script:-
<script type="text/javascript">
function Counter(id)
{
$.get("clickcounter.php?id="+id);
{
return false;
}
}
</script>
This is the php script (clickcounter.php)
<?php
include('dbutils.php');
$referid = $_GET['id'];
$q = "SELECT * FROM downloads WHERE downid =".$referid;
$r = mysql_query($q);
while ($row = mysql_fetch_array($r))
{
$click = stripslashes(trim($row['downcount']));
$download = $row['downfile'];
}
$countup = $click + 1;
$qUpdate = "UPDATE downloads
SET downcount=$countup
WHERE downid=$referid";
$rUpdate = mysql_query($qUpdate);
?>
A few relatively small modifications should solve the problem. First, change the onclick to the following:
onclick=\"Counter('$referid', this); return false;\"
What we have done is to send in this as the second argument to the Counter function so we have a reference to the clicked link. Secondly, we have added return false, which blocks the browser from navigating to the url specified in the href.
The modified counter function looks like this:
function Counter(id, link) {
$.get("clickcounter.php?id=" + id, function() {
location.href = $(link).attr("href");
});
}
We now have a reference to the clicked link. A function has now been specified as the second argument to $.get(). This is the success-function, which is called when the ajax call has been successfully called. Inside that function we now redirect to the url specified in the href attribute on the clicked link.
I feel I should point out that the recommended way is to bind the onclick using jQuery separate from the html. The referid can be stored in a data attribute (which I chose to call data-rid):
<a href='downloads/".$downfile."' class='dl' data-rid='$referid'>Download File</a>
Then you bind the onclick for all download links (a elements with a "dl" class):
$(function() {
$("a.dl").click(function() {
var id = $(this).attr("data-rid");
var href = $(this).attr("href");
$.get("clickcounter.php?id=" + id, function() {
location.href = href;
});
return false;
});
});​
(I feel I should point out that the code has not been tested, so it's possible that a typo has snuck in somewhere)

How do I repopulate form fields after validation errors with express-form?

Using node.js and express (2.5.9) with express-form.
How should I repopulate form fields with the submitted values?
I have a get and a post route. If there are validation errors when the form is posted, I redirect the user back to the get, the problem is that the repopulated locals don't show up (I do have autoLocals: true, so I assume it's because I am redirecting and res is reset.)
So how do you guys repopulate and what's your application flow, do you res.send instead of res.redirect and set up the whole thing again? That seems repetitive.
Here's an example of my post route:
app.post(
'/projects/:id'
, form(field("title").required("title", "Title is required)
, function (req, res){
if (!req.form.isValid){
res.redirect('/project/'+req.params.id+'/edit');
}
else{
// save to db
}
});
I am working with expressjs4.0 to repopulate the forms fields after validation you do:
router.route('/posts/new')
.get(function(req, res) {
res.render('posts/new', new Post({}));
});
The second argument in res.render below will set some variables in the view.
res.render('posts/new', new Post({}));
In my view I then set my form fields as follows:
...
<input type="text" name="title" value="<%- post.title %>">
<textarea name="article"><%- post.article %></textarea>
...
When you submit this form, it should be caught by your router like so:
router.route('/posts')
.post(function(req, res) {
var post = new Post(req.body)
post.save(function(err) {
if (err) {
res.locals.errors = err.errors;
res.locals.post = post;
return res.render('posts/new');
}
return res.redirect('/posts');
});
...
})
This line of code, resets the form fields in your view
res.locals.post = post;
I hope someone finds this useful ;)
Not sure if it's best practice, but when I have validation failure, I don't redirect I just re-render the view (often by passing control to the 'get' callback). Somethign like this:
function loadProject(req,res, id){ /* fetch or create logic, storing as req.model or req.project */}
function editProject(req,res){ /* render logic */ }
function saveProject(req,res){
if(!req.form.isValid){
editProject(req,res);
}else{
saveToDb(req.project);
res.redirect('/project'+req.project.id+'/edit');
}
}
app.param('id', loadProject);
app.get('/projects/:id/edit', editProject);
app.post('/projects/:id', saveProject);
I had to work on similar problem recently and used two node modules: validator and flashify.
In the form view I configured my form fields as follows:
div.control-group
label.control-label Description
div.controls
textarea(name='eventForm[desc]', id='desc', rows='3').input-xxlarge= eventForm.desc
div.control-group
label.control-label Tag
div.controls
select(id='tag', name='eventForm[tag]')
tags = ['Medjugorje', 'Kibeho', 'Lourdes', 'Fatima']
for tag in tags
option(selected=eventForm.tag == tag)= tag
Notice the naming convention of the form fields. Then in my config file I set one global variable, which is really just a placeholder for when the form first loads:
//locals
app.locals.eventForm = []; // placeholder for event form repopulation
The validation logic is in my router file and looks like this:
app.post('/posts', function(req, res){
var formData = req.body.eventForm;
var Post = models.events;
var post = new Post();
post.text = formData.desc;
post.tag = formData.tag;
// run validations before saving
var v = new Validator();
var isPostValid = true;
// custom error catcher for validator, which uses flashify
v.error = function(msg) {
res.flash('error', msg);
isPostValid = false;
}
v.check(post.text, "Description field cannot be empty").notEmpty();
v.check(post.tag, "Tag field cannot be empty").notEmpty();
Then I check to see there are errors, and if so, pass the form data back to the view:
// reject it
res.render('Event.jade', {page: req.session.page, eventForm: formData});
Notice this evenForm data gets passed back to the view, which repopulates the default values.
The final step is to include the flashify component in your form view.
div(style='margin-top: 60px').container-fluid
include flashify
The code for the flashify view looks like this:
if (flash.error != undefined)
div.container
div.alert.alert-error
b Oops!
button(type='button', data-dismiss='alert').close ×
ul
each error in flash.error
li= error
if (flash.success != undefined)
div.container
div.alert.alert-success
b Success!
button(type='button', data-dismiss='alert').close ×
ul
each success in flash.success
li= success

MVC3 redirect to action after ajax call

In an ASP.NET MVC3 Application I have a button in the view.
When the button is clicked a function is called and it jquery ajax call is made to save items to the database
function SaveMenuItems() {
var encodeditems = $.toJSON(ids);;
$.ajax({
type: 'POST',
url: '#Url.Action("SaveItems", "Store")',
data: 'items=' + encodeditems + '&storeKey=#Model.StoreID',
complete: function () {
}
}
});
}
What i want is after the items are saved to the database I want to redirect to another view. (Redirect to action)
How can I do that?
I tried to use return RedirectToAction("Stores","Store") in the controller at the end of the SaveItems function. But it is not working
I also tried to add window.location.replace("/Store/Stores"); in the complete function of the ajax call but didn't work either
Any help is greatly appreciated
Thanks a lot
You can use javascript to redirect to the new page. Set the value of window.location.href to the new url in your ajax call's success/complete event.
var saveUrl = '#Url.Action("SaveItems","Store")';
var newUrl= '#Url.Action("Stores","Store")';
$.ajax({
type: 'POST',
url: saveUrl,
// Some params omitted
success: function(res) {
window.location.href = newUrl;
},
error: function() {
alert('The worst error happened!');
}
});
Or in the done event
$.ajax({
url: someVariableWhichStoresTheValidUrl
}).done(function (r) {
window.location.href = '#Url.Action("Stores","Store")';
});
The above code is using the Url.Action helper method to build the correct relative url to the action method. If your javascript code is inside an external javascript file, you should build the url to the app root and pass that to your script/code inside external js files and use that to build the url to the action methods as explained in this post.
Passing parameters ?
If you want to pass some querystring parameters to the new url, you can use this overload of the Url.Action method which accepts routevalues as well to build the url with the querystring.
var newUrl = '#Url.Action("Stores","Store", new { productId=2, categoryId=5 })';
where 2 and 5 can be replaced with some other real values.
Since this is an html helper method, It will work in your razor view only,not in external js files. If your code is inside external js file, you need to manually build the url querystring parameters.
Generating the new url at server side
It is always a good idea to make use of the mvc helper methods to generate the correct urls to the action method. From your action method, you can return a json strucutre which has a property for the new url to be redirected.
You can use the UrlHelper class inside a controller to do this.
[HttpPost]
public ActionResult Step8(CreateUser model)
{
//to do : Save
var urlBuilder = new UrlHelper(Request.RequestContext);
var url = urlBuilder.Action("Stores", "Store");
return Json(new { status = "success", redirectUrl = url });
}
Now in your ajax call's success/done callback, simply check the return value and redirect as needed.
.done(function(result){
if(result.status==="success")
{
window.location.href=result.redirectUrl;
}
else
{
// show the error message to user
}
});
In action you can write this:
if(Request.IsAjaxRequest()) {
return JavaScript("document.location.replace('"+Url.Action("Action", new { ... })+"');"); // (url should be encoded...)
} else {
return RedirectToAction("Action", new { ... });
}
Try
window.location = "/Store/Stores";
Instead.

Passing the signed_request along with the AJAX call to an ActionMethod decorated with CanvasAuthorize

This is a follow-up to AJAX Call Does Not Trigger Action Method When Decorated With CanvasAuthorize
So I found the following links and it seems that this is a common problem:
http://facebooksdk.codeplex.com/discussions/251878
http://facebooksdk.codeplex.com/discussions/250820
I tried to follow the advice by prabir but I couldn't get it to work...
Here's my setup:
I have the following snippet in the page where the button that triggers the whole post to facebook is located:
#if (!string.IsNullOrEmpty(Request.Params["signed_request"]))
{
<input type="hidden" id="signedReq" value="#Request.Params["signed_request"]" />
}
And then I have this snippet (inside a script tag inside the same page):
var signedRequest = $('#signedReq').val();
$('.facebookIcon').click(function () {
var thisItem = $(this).parent().parent();
var msg = thisItem.find('.compItemDescription').text();
var title = thisItem.find('.compareItemTitle').text();
var itemLink = thisItem.find('.compareItemTitle').attr('href');
var img = thisItem.find('img').first().attr('src');
postOnFacebook(msg, itemLink, img, title, signedRequest);
});
And finally, inside an external js file I have the following function:
/*Facebook post item to wall*/
function postOnFacebook(msg, itemLink, pic, itemTitle, signedReq) {
console.log(signedReq);
var siteUrl = 'http://www.localhost:2732';
$.ajax({
url: '/Facebook/PostItem',
data: {
'message': msg,
'link': siteUrl + itemLink,
'picture': siteUrl + pic,
'name' : itemTitle,
'signed_request': signedReq
},
type: 'get',
success: function(data) {
if(data.result == "success") {
alert("item was posted on facebook");
}
}
});
}
But signedReq is always undefined. And I'm not really sure I should be passing the 'signed_request' field inside the data object. Any thoughts?
Make sure you hidden input field is being populated.
Also, when you try to pull the ID of the input field via JQuery, you might not be referencing the proper element since .NET butcher's ID's of anything that's run on the server.
When I use the hidden input field trick, I set the jquery value like so:
var signedRequest = $('#<%=signedReq.ClientID %>').val();
This way, I'm getting the identifier that .NET is giving to the HTML element.
Hope that helps.
Just a guess - in your hidden field: id="signed_request" instead of id="signedReq"

Resources