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"})
Related
I'm trying to fetch messages when user clicks on a specific chat (you can say div which has hidden input fields for ids) just like messenger. The view is same on which i'm sending the data. First time when inbox opens up a chat list is added at the left side and the right is blank until user clicks on a chat.
Here is my code from which I get id when user clicks on the specific chatlist. I get ids through which i can fetch all messages. I'm using different models as I've different queries for both.
I dont know how to get json data which i got from ajax into php variable so that I've to loop through and display messages.
Attaching codes and pictures for references.
Model
public function get_msg($employer_id)
{
$query1 = $this->db->select()
->where('msg_from_id', $employer_id)
->group_by('msg_from',$employer_id)
->from('inbox')
->get('');
return $query1->result();
}
public function get_all_msgs($msg_from_id,$msg_to_id)
{
$conditions = array('msg_from_id' => $msg_from_id, 'msg_to_id' =>
$msg_to_id);
$query1 = $this->db->select()
->where($conditions)
->from('inbox')
->get('');
return $query1->result_array();
}
Controller:
public function get_all_msgs()
{
$postData = $this->input->post();
$msg_to_id= $postData['msg_to_id'];
$msg_from_id=$postData['msg_from_id'];
$this->load->model('employermodel');
$get_all_msgs=$this->employermodel->get_all_msgs($msg_from_id,$msg_to_id);
if($get_all_msgs!=NULL){
echo json_encode($get_all_msgs);
}
}
public function inbox(){
$emp = $this->session->userdata('user_email');
$emp_id = $this->session->userdata('user_id');
$employer_id=$emp_id;
if($emp_id == NULL){
return redirect('users/index');
}
$this->load->model('employermodel');
$get_msgs=$this->employermodel->get_msg($employer_id);
if($get_msgs!=NULL){
$this->load->view('inbox',['get_msgs'=>$get_msgs,]);
}
}
Javascript/ajax on same view page i.e. "Inbox" :
$('.msgs-ConversationListPane').click(function (e) {
if ($('.msgs-ConversationListPane').hasClass('is-active')) {
$(this).removeClass('is-active');
$('.msgs-ConversationPane').addClass('is-active');
$('.msgs-ConversationPane').removeClass('is-splash');
// $('.msgs-ConversationPane').load('.msgs-Conversation'.href);
$(".msgs-ConversationPane").html($("." + $(this).attr('rel')).html());
var msg_to_id = $('#msg_to_id').val();
var msg_from_id = $('#msg_from').val();
var get_all_msgs;
$.ajax({
type: "POST",
url:'<?=base_url()?>employer/get_all_msgs',
data: {msg_to_id: msg_to_id,
msg_from_id:msg_from_id},
dataType: 'json',
cache: false,
success: function (data) {
// JSON.stringify
get_all_msgs = data;
$("#res").html(get_all_msgs);
// console.log(get_all_msgs);
$(".msgs-ConversationPane").css('display', 'block');
},
error: function(xhr, status, error) {
console.log(error);
},
})
// .done(function(get_all_msgs) {
;
} else if ($('.msgs-ConversationPane').hasClass('is-splash')) {
$(this).removeClass('is-splash');
$(this).addClass('is-active');
$('.msgs-ConversationListPane').addClass('is-splash');
$('.msgs-ConversationListPane').removeClass('is-active');
}
});
You dont want to get the json data into a php variable. Php is executed server side, ajax is executed client side. The benefit of ajax usage is to dynamicly change the content after server execution is finished. You want to update the screen content via JavaScript (So only on the users end).
The next step is to extract the json data and to add a message div to the message container div.
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.
I am experiecing some issues with AJAX updating the page. The actual data in the database is updated but this is not always reflecting in real time on the web page.
For example, I have the following event:
$("#add_note").click(function(e) {
//e.preventDefault();
$("#add_note_form").validate({
rules: {
contact_note: {
required: true
}
},
submitHandler: function(form) {
contact.modal_update({
'obj' : $('#add_note_form'),
'uri' : '/contact/add_note/'
});
}
});
});
This function when a new note is created calls a callback to validate the form fields first and then if successful calls a callback inside a seperate class to conduct the update. See the modal_update class below:
// Update modal
this.modal_update = function(data)
{//
// Declare a few variables for the data object we've received
obj = data.obj // The form element to serialize
uri = data.uri;
// Get the form ID from the data-target attribute
id = obj.attr('data-target');
// URL to send to
url = this.site_url + uri + id;
// The form object
this.post_data(obj.serialize(),url);
// Hide Modal
obj.closest('.modal').modal('hide');
// Refresh
this.refresh();
}
This then figures out the correct route to ajax and calls a ajax call back inside the same class:
// AJAX post
this.post_data = function(obj,uri)
{
$.ajax({
data: obj,
dataType: 'json',
type: 'post',
url: uri,
headers: { "cache-control": "no-cache" },
cache: false,
success: function (response) {
if (response.success == true)
{
$("#alert_success .msg").html(response.message);
$("#alert_success").fadeIn(200).delay(2000).fadeOut(200);
}
else
{
$("#alert_error .msg").html(response.error);
$("#alert_error").fadeIn(200).delay(2000).fadeOut(200);
console.log(response.error);
}
}
});
}
I am then running another class callback to "refresh" the data in all the elements on the page:
this.refresh = function()
{
// Refresh the ajax requests
this.get_contact_data();
this.get_notes();
this.get_contact_log();
this.get_contact_tasks();
}
This class re loads the functions which run on page load to get the inial data into the tables/fields on the page. See "get_notes" below:
// Get notes
this.get_notes = function()
{
// Get all notes and populate table
var log_uri = this.site_url + "/contact/get_notes/" + this.contact_id;
this.get_data(log_uri,function(data) {
notes = $("#contact_notes ul");
notes.empty("");
// Populate the contact fields, assuming there is a result to play with
if (data != false) {
//alert(JSON.stringify(data));
$("#notes-tab .count").html("(" + data.length + ")");
$.each( data, function( key, value ) {
notes.append("<li class='list-group-item' modal-id='editNoteModal' data-target='" + value.ID + "'><div class='row'><div class='col-lg-3'><i class='fa fa-sticky-note mr-3'></i>" + value.timestamp + "</div><div class='col-lg-7'>" + value.note + "</div><div class='col-lg-2'><a href='#' class='edit mr-3'><i class='fa fa-edit mr-1'></i>Edit</a><a href='#' class='delete'><i class='fa fa-times mr-1'></i>Remove</a></div></div></li>");
});
console.log('Notes loaded');
} else {
notes.append("<li>There are currently no notes for this contact</li>");
}
});
}
Now the problem:
For some reason this does not update consistently in real time. The data is updated fine on the server side but on the client side the update/refresh does not always update. I might add a note and get a correct update response but the refresh method seems to be receiving the old data and always be one note behind. So the next time I add a note, the one I added before then appears and so forth.
Another problem I am experiencing is the methods seem to stack on each event so if I add one note (or one of the other methods) I will see the console say "notes loaded" but on the second note it says "notes loaded" twice, then on the 3rd note added 3 times and so forth.
I am sure there must be something fatal flaw in the design of my code here but I am not experienced enough with javascript/jquery to notice what direction I am going wrong so I can fix it.
I thought that this was an issue with ajax caching and not refreshing the result so I have adjusted the ajax request as cache none and also to send no cache headers. I am running in wamp.
In your case, your refresh code will always run before your data got updated. Because ajax is asynchronous so the code behind and below ajax will always execute nearly the time your ajax running.
At the time you run your post_data function to call the API, the refresh function got run too. So it's done before your data got updated.
You should run refresh function inside ajax callback. For example:
this.post_data = function(obj,uri, callback)
{
$.ajax({
data: obj,
dataType: 'json',
type: 'post',
url: uri,
headers: { "cache-control": "no-cache" },
cache: false,
success: function (response) {
if (response.success == true)
{
$("#alert_success .msg").html(response.message);
$("#alert_success").fadeIn(200).delay(2000).fadeOut(200);
}
else
{
$("#alert_error .msg").html(response.error);
$("#alert_error").fadeIn(200).delay(2000).fadeOut(200);
console.log(response.error);
}
callback();
}
});
}
And in modal_update, you pass refresh function to post_data as a callback:
this.modal_update = function(data)
{//
// Declare a few variables for the data object we've received
obj = data.obj // The form element to serialize
uri = data.uri;
// Get the form ID from the data-target attribute
id = obj.attr('data-target');
// URL to send to
url = this.site_url + uri + id;
// The form object
this.post_data(obj.serialize(),url, this.refresh);
// Hide Modal
obj.closest('.modal').modal('hide');
}
You should read more about asynchronous ajax. You can use other tricky solution is setTimeout to run this.refresh but I do not recommend that because you not sure when the update is done.
so this is a hard one for me to try and explain. I have a razor page that when a button is clicked it calls a javascript function which makes an ajax call to a handler in the back end. The handler does some stuff and gets a id that I want to pass to another page. I am trying to use the RedirectToPage function in the back end but the screen never opens. It successfully calls the handler but when the handler does its return, nothing happens. Is there a way to do this?
Here is the javascript/ajax code that gets called from a button being clicked.
#section scripts{
<script>
// Get the account ID Data from the row selected and return that to the program.
function getIDData(el) {
var ID = $(el).closest('tr').children('td:first').text();
var iddata = {
'ID': ID
}
console.log(iddata);
return iddata;
}
// Submit the data to a function in the .cs portion of this razor page.
$('.copybtn').click(function () {
var accountid = JSON.stringify(getIDData(this));
$.ajax({
url: '/Copy_Old_Account?handler=CopyData',
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
type: 'POST',
dataType: 'json',
data: { offenderid: offenderid },
success: function (result) {
},
});
});
</script>
}
For my code behind code that I am calling from the ajax call, that's below here:
public ActionResult OnPostCopyData (string accountid)
{
// Do my other stuff here
return RedirectToPage("Account_Information", new { id = account.Account_ID });
}
Any help would be appreciated and if doesn't make sense, I can try and clear up any questions.
I think this is what you want, I did something similar in an MVC 5 project and I haven't tested it in Razor Pages yet:
This would be your method, note that you should add your Controller to the Url.Action, and I personally haven't tried passing a parameter along with the url but I image it'll work just fine
[HttpPost]
public ActionResult SubmitSomething()
{
return Json(new { redirectUrl = Url.Action("Account_Information", "YOUR_CONTROLLER_NAME", new { id = account.Account_ID }) });
}
And then this would be your Ajax request, I updated the success portion
// Submit the data to a function in the .cs portion of this razor page.
$('.copybtn').click(function () {
var accountid = JSON.stringify(getIDData(this));
$.ajax({
url: '/Copy_Old_Account?handler=CopyData',
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
type: 'POST',
dataType: 'json',
data: { offenderid: offenderid },
success: function (result) {
if (result.redirectUrl !== undefined) {
window.location.replace(result.redirectUrl);
} else {
// No redirect found, do something else
}
},
});
});
This isn't tested, so I can only hope that it works for you right now
Edit: Updated the Url.Action to use OP's view names and parameters
Redirect to page returns a 301 response, which will be in the format:
HTTP/1.1 301 Moved Permanently
Location: http://www.example.org/index.asp
To redirect after the ajax call you can redirect to the requested url by:
success: function (result) {
window.location = result.getResponseHeader('Location');
}
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.