Refresh page after updating via AJAX request in Epi Server - javascript

I have an Epi server page template with following property:
[Display(
Name = "Selection Box",
GroupName = Global.GroupNames.Contact
)]
public virtual bool SelectionBox { get; set; }
In the view I have something like this:
#if (PageEditing.PageIsInEditMode)
{
#Html.CheckBoxFor(modelItem => Model.CurrentPage.SelectionBox,
new
{
#class = "toggle",
#data_url = Url.Action("UpdatePage", "DefaultPage"),
})
<script>
$(function () {
$('.toggle').change(function () {
var self = $(this);
var url = self.data('url');
var value = self.prop('checked');
$.ajax({
url: url,
data: { selected: value },
type: 'POST',
success: function (response) {
alert(response);
}
});
});
});
</script>
}
Basically what it does, it when I change checkbox value, it sends request to controller and updates the value on the page. What I'm missing is that when this sucesfully happens, I would like the page reload but I can't find a way to do it.
I'm not using OOTB on page editing here, as I'm looking for a way to give editors some adavnced editing for the component, yet I don't want to build a dojo widget. Any ideas how to make this work?

There is a chapter on "On-page editing with client-side rendering" in the developer guides, see https://world.episerver.com/documentation/developer-guides/CMS/editing/on-page-editing-with-client-side-rendering/

The purpose of using Ajax is to design a SPA (single page application) where no page reload is required. If you are looking for a page reload, you can probably do
window.location.reload();
But a page reload might cause you to lose data return by the Ajax call.

Related

How to auto refresh a partial view?

How to auto refresh a partial view?
public PartialViewResult Chat(string people)
{
if (User.Identity.IsAuthenticated)
{
var model = new MessageVM()
{
realReceiver = people,
messageList = db.messages.Where(x => x.sender == User.Identity.Name || x.sender == people).ToList().Take(30)
};
return PartialView("_Chat", model);
How to auto refresh this partialview
Just to test quickly, change your controller action for Chat from POST to GET. Then call it by pasting the address in your browser address bar. You can include the value for people parameter like this at the end of the URL:
?people=valueForPeople
Check the returned HTML and ensure that is what you are expecting. Once you have confirmed the action is returning the HTML you want, then you can change back to POST if you prefer. Then use the jQuery code below.
One option is to setup a timer on the client side which will call your controller and then you can do whatever you need with the returned data.
window.setInterval(function() {
// send get request to server
$.ajax({
url: '/Chat',
type: "POST", // or use GET
data: whateverYourArgumentsAre, // people
success: function (partialViewHtml) {
$("#divLt").html(partialViewHtml);
});
},
error: function () {
alert('Something went wrong');
}
});
}, 5000); // Every 5 seconds, 5000 ms
Html.Action("Messages","Chat", new { people= "give some data"})

Trying to pass error message from Controller to View without page reload (MVC)

I'm trying to get my View to display an error message when the ActionResult from my controller fails. (It's triggered when you press a button in the View.)
However, no matter what I try, the ActionResult always redirects to a different page. If I try to return View() it goes to the default yellow ASP.Net error page. If I try to return Content("Error message") it just opens a blank page with that text.
I've saved my canned error message in ViewBag.Error, but the javascript in my View never gets a chance to use it because as soon as you click my button, the ActionResult redirects me somewhere.
How do I get my View to stay put, but still pass a message if the ActionResult fails?
Here is the method I'm calling in the controller:
public ActionResult ElectrodeChecklist(int id)
{
var routeChecklist = _routeService.GetRouteChecklist(id);
// This is where I'm trying to catch this error.
if (routeChecklist.Count == 0)
{
ViewBag.Error = "This route has no checklist steps to print.";
return ???
}
...
blah blah stuff to download a PDF file when everything works
...
return new BinaryContentResult(buffer, "application/pdf", filename);
}
Edit: Here's the view:
... dropdown menu called #dd-route...
Generate PDF
<script type="text/javascript">
$(function () {
$('#dd-route').change(function () {
var $route = $(this).val();
var $url = '#Url.Action("electrodechecklist", "wip")?id=' + $route;
$('#btn-print').attr('href', $url);
});
$('#btn-print').click(function () {
var $error = ViewBag.Error;
if ($error != "") {
$('#alertbar').show();
$('#alert').html($error);
}
})
});
</script>
When the user chooses an item in the dropdown menu, the url to call my ActionResult is fed into the button's href attribute. Then when they click the button, it fires it off with the correct value from the dropdown.
The second part of the JavaScript is my attempt at displaying the error message if they hit that If statement in the Controller.
I'm only writing this because it won't fit comments.
OK so first thing to notice is that it WILL start navigating to the Action ElectrodeChecklist with the id and then do what ever BinaryContentResult does. I cannot see how var $error = ViewBag.Error; could possibly work, but then again I'm not sure how/what BinaryContentResult really does.
If you want the user to see the ViewBag.Error then you need to modify this part
if (routeChecklist.Count == 0)
{
TempData["Error"] = "This route has no checklist steps to print.";
return RedirectToAction("ACTION", "CONTROLLER");
}
as suggested by #StephenMuecke. The ACTION here is the page the user was on in the first place. You could redirect them to any error page and still access the TempData["Error"]. If this still doesn't do what you want let us know.
//What you are trying to do here is awesome
//but I'm not sure if it's even possible as you are moving away from the page when the user clicks the button/link
//I'd like other please comment on this. I could use it too
$('#btn-print').click(function () {
var $error = ViewBag.Error;
if ($error != "") {
$('#alertbar').show();
$('#alert').html($error);
}
})
Check below code for without refreshing you can show the error message on page :
$('#dd-route').change(function () {
var TestModel = {
"id": $("route").val()
}
$.ajax({
url: '/wip/electrodechecklist',
type: "Post",
async: false,
data: JSON.stringify(TestModel),
dataType: "html",
contentType: "application/json;charset=utf-8",
success: function (result) {
var $error = ViewBag.Error;
if ($error != "") {
$('#alertbar').show();
$('#alert').html($error);
}
}
});
});
Hope this will help you !!

Laravel 5 attach with Ajax?

I have this laravel code in my controller detach function.
$input = Input::all();
$product= Products::findOrFail($input['product_id']);
$product->tags()->detach($input['tag_id']);
$product= Products::where('customer_id', Auth::user()->customers_id)->get();
return view('products.tagsdelete', [
'products' => $product,
]);
This works fine, it deletes the tag realation from my pivot table. The only thing that bugs me it that I don't want to reload the page everytime I press the delete button on my view.
( Of course I could make a selection of all tags the user want to delete, but I want to to this live with Ajax )
My problem is, I couldn't find anything that helps me with detachment from laravel + Ajax. I'm quite okay with Javascript and Jquery but Ajax is still a new thing for me..
So can anybody help me there? I'm really stuck.
Thanks for taking your time :)
#Wiriya Rungruang
current controller code:
public function detach()
{
$input = Input::all();
$product= Products::findOrFail($input['product_id']);
$product->tags()->detach($input['tag_id']);
$product= Products::where('customer_id', Auth::user()->customers_id)->get();
}
my button:
<button type="submit" class="delete-tag-btn" data-product_id="{{ $product->id }}" data-tag_id="{{ $tag->id }}"><i class="glyphicon glyphicon-trash"></i></button>
at the bottom of the code the JS:
<script>
$(".delete-tag-btn").on('click', function(){
var url = "{{ route('detach') }}"; // Url to deleteTag function
url += "product_id=" + $(this).data('product_id');
url += "&tag_id=" + $(this).data('tag_id');
// Now url should look like this 'http://localhost/deletetag?product_id=2&tag_id=5
// Send get request with url to your server
$.get(url, function(response){
alert("success");
});
});
</script>
First : You should create function detach tag from product in your controller and return status success or failure(or nothing)
In your controller
function detachTag(){
$input = Input::all();
$product= Products::findOrFail($input['product_id']);
$product->tags()->detach($input['tag_id']);
$product= Products::where('customer_id', Auth::user()->customers_id)->get();
return "Some state for checking it a success or not";
}
Second : Create javascript function for checking when you click on delete button send request with parameter to function that we created in the first step and rerender or remove that tag from your HTML page
**Parameter is mean product_id and tag_id that your want to detach it
In your js
$(".delete-tag-btn").on('click', function(){
var url = "localhost/deletetag?"; // Url to deleteTag function
url += "product_id=" + $(this).data('product_id');
url += "&tag_id=" + $(this).data('tag_id');
// Now url should look like this 'http://localhost/deletetag?product_id=2&tag_id=5
// Send get request with url to your server
$.get(url, function(response){
// Do what you want
});
});
So when you click on .delete-tag-btn It will send request for detach it
While you can right a simple ajax call, send data and return html and replace it with the old html
lets begin :)
first step is to write ajax, and send it when form is submit or any button is clicked (as per your code)
this one is sample ajax, just fill in your data in it.
var BASEURL = window.location.origin + "/your_domain_name/";
$.ajax({
url: BASEURL + "your_route",
type: "POST/GET", //any_one
data: {
// Your data comes here (object)
},
beforeSend: function () {
},
success: function (response) {
console.log(response); // your html in return
},
complete: function (response) {
}
});
now a call will be send with your data to controller respective to specified route you mentioned, processing will be normal.
It will return only html. You can do whatever you want with this html.
One important problem you might face if considering these instructions is, right now the view you are returning is probably of whole page (because the page is been refresh every time), but if you are thinking to replace it with new html, your will only have to return that part of the page may be a single row or something like that. So break your view in many sub views. Php #include(//path) (blade) might come handy. Thats how I use to work. :)

using ViewBag - asp.net mvc

In a asp.net mvc project i have this on top of my index.cshtml file
$.ajax({
url: '#Url.Action("getLoggedUser", "Home")',
dataType: "html",
"async": true,
type: "GET",
success: function (data) {
},
});
And the method it uses is this one, that is on HomeController
public async Task getLoggedUser()
{
try
{
BenchesService benchService = new BenchesService();
UserTest LoggedUser = new UserTest();
string name = Request.RequestContext.HttpContext.User.Identity.Name;
name = name.Substring(name.LastIndexOf('\\') + 1);
LoggedUser = await benchService.getCurrentUser(name);
role = LoggedUser.role;
ViewBag.LoggedUser = LoggedUser.role;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
This does a GET to the server with getCurrentUser(name); and that returns a json with user info, that i use to fill a UserTest object (i checked with break and the LoggedUser is filled correctly).
I want to save the user Role, to use in the html / javascript part
Then again on my index.cshtml i have this other script
$(document).ready(function () {
setTimeout(function () {
console.log("TIMER!");
userRole = '#ViewBag.LoggedUser';
alert(userRole);
}, 5000);
My problem is that the alert shows a empty message, like the ViewBag.LoggedUser has nothing. am i using ViewBag wrong?
Are you reloading your page? If not, your ViewBag has the same content like in the moment when page was rendering. Razor render text from ViewBag only on creation of html page, and if you are not reloading page, it will be always empty. You have to return your data in some object (ex. json) to ajax request and then you can use it.

How to request a web page in JavaScript

In my site, there's a pervasive search bar that is a typeahead widget. The widget has a 'selected' callback that I am currently trying to implement.
In the callback, it determines whether or not it needs to make an AJAX request on the existing page or whether it needs to go to another page. My problem is that I cannot find anywhere a way to do a redirect with POSTed variables, like in a jQuery AJAX request. Is there any way to attain a page request with posted variables that will totally refresh the page, like clicking on a normal hyperlink?
Here is my code:
function getData(event, datum, dataset) {
event.preventDefault();
// get controller action portion of current url
var Controller = '<?= preg_replace('/\/.*/', '', preg_replace('/\/.*\/web\//', '', Yii::$app->request->url)) ?>';
var Key;
// get key out of key-value pair - will either be 'game', 'developer' or 'publisher'
for (var k in datum) {
Key = k;
}
// if the controller action is the same as key, then the request is ajax
// this works fine
if (Key === Controller) {
var req = $.ajax( {
type: 'POST',
url: 'getchilddata',
data: { data: datum[Key] },
})
.done(function(data) {
$('#display-div').html(data);
})
.fail(function() {
console.log("Failed");
})
} else { // else we need to go to a page on a different controller action according to Key
// this is the best i've got so far but want it to be better
window.location.href = Key + '/datastream?q=' + datum[Key];
}
}
The only way to achieve this is creating a form with hidden inputs, because you can't send post variables via Javascript, fortunately there is a Jquery plugin who will save you some code, but at the end the plugin just create a hidden form and simulate the redirect sending the form via POST, this is how to use it:
if (Key === Controller) {
$.ajax( {...})
} else {
$().redirect(Key + '/datastream, {'q': 'datum[Key]'});
}
Note: You can pass the method (GET or POST) as an optional third parameter, POST is the default

Categories

Resources