Add object routedValue in Confirmation dialog of a Ajax.BeginForm - javascript

What I want is to add an object routed value when the user submits the form (ajax.beginform)
Depending on what the user chooses in the ConfirmDone function, i want to add an integer (SaveOption)
But i don't really know how to do it.
The confirmdone function is called but that's it, my controller action is'nt called. I probably need to return something?
Some Code: the start of the form
#using (Ajax.BeginForm("CreateFunctiebeschrijvingPartial", "Functiebeschrijving", new AjaxOptions { UpdateTargetId = "Functiebeschrijving", OnBegin = "return ConfirmDone()", OnSuccess = "handleSuccess" }, new {#id = frmID}))
{
The confirmdone function
function ConfirmDone() {
if (confirm("This form saves default as Concept, would you like to save it as completed? 1 = Completed, 2 = Concept")) {
//option 1: save as completed
$('#frmID').attr("SaveOption", 1);
}
else {
//Option 2: save as concept
}
}
The start of my controller action
//
// POST: /FunctieBeschrijving/CreateFunctiebeschrijvingPartial
[HttpPost]
public ActionResult CreateFunctiebeschrijvingPartial(NieuweFunctiebeschrijvingViewModel nfvm, int SaveOption)
{
When i don't use the confirm function, everything is posted as it should be!

function addDataToUrl(url, name, value){
var sep = url.indexOf('?') === -1 ? '?' : '&';
return url + sep + name + '=' + value;
}
function ConfirmDone() {
var form = document.getElementById('frmID');
if (confirm("This form saves default as Concept, would you like to save it as completed? 1 = Completed, 2 = Concept")) {
//option 1: save as completed
form.setAttribute('action',
addDataToUrl(form.getAttribute('action'), 'SaveOption', '1'));
}
else {
// Option 2: save as concept
}
}

Related

Avoid identical client ajax request on refresh

I would like to test if the ajax request is identical so it can be aborted or some other alert action taken?
In reality clients can change the request via a few form elements then hit the refresh button.
I have made a poor attempt at catching the identical request. Need to keep the timer refresh functionality.
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
var current_request_id = 0;
var currentRequest = null;
var lastSuccessfulRequest = null;
function refreshTable() {
$('#select').html('Loading');
window.clearTimeout(timer);
//MY CATCH FOR DUPLICATE REQUEST NEEDS WORK
if (lastSuccessfulRequest == currentRequest)
{
//currentRequest.abort();
alert('Duplicate query submitted. Please update query before resubmission.');
}
var data = {
"hide_blanks": $("#hide_blanks").prop('checked'),
"hide_disabled": $("#hide_disabled").prop('checked'),
};
json_data = JSON.stringify(data);
current_request_id++;
currentRequest = $.ajax({
url: "/calendar_table",
method: "POST",
data: {'data': json_data},
request_id: current_request_id,
beforeSend : function(){
if(currentRequest != null) {
currentRequest.abort();
}
},
success: function(response) {
if (this.request_id == current_request_id) {
$("#job_table").html(response);
$("#error_panel").hide();
setFixedTableHeader();
}
},
error: function(xhr) {
if (this.request_id == current_request_id) {
$("#error_panel").show().html("Error " + xhr.status + ": " + xhr.statusText + "<br/>" + xhr.responseText.replace(/(?:\r\n|\r|\n)/g, "<br/>"));
}
},
complete: function(response) {
if (this.request_id == current_request_id) {
$("#select").html("Refresh");
window.clearTimeout(timer);
stopRefreshTable();
window.refreshTableTimer = window.setTimeout(refreshTable, 10000);
lastSuccessfulRequest = currentRequest;
}
}
});
}
//TIMER STUFF TO refreshTable()
//THIS SECTION WORKS FINE
var startDate = new Date();
var endDate = new Date();
var timer = new Date();
function startRefreshTable() {
if(!window.refreshTableTimer) {
window.refreshTableTimer = window.setTimeout(refreshTable, 0);
}
}
function stopRefreshTable() {
if(window.refreshTableTimer) {
self.clearTimeout(window.refreshTableTimer);
}
window.refreshTableTimer = null;
}
function resetActive(){
clearTimeout(activityTimeout);
activityTimeout = setTimeout(inActive, 300000);
startRefreshTable();
}
function inActive(){
stopRefreshTable();
}
var activityTimeout = setTimeout(inActive, 300000);
$(document).bind('mousemove click keypress', function(){resetActive()});
</script>
<input type="checkbox" name="hide_disabled" id="hide_disabled" onchange="refreshTable()">Hide disabled task<br>
<br><br>
<button id="select" type="button" onclick="refreshTable();">Refresh</button>
I'd use the power of .ajaxSend and .ajaxSuccess global handlers.
We'll use ajaxSuccess to store a cache and ajaxSend will try to read it first, if it succeeds it will trigger the success handler of the request immediately, and abort the request that is about to be done. Else it will let it be...
var ajax_cache = {};
function cache_key(settings){
//Produce a unique key from settings object;
return settings.url+'///'+JSON.encode(settings.data);
}
$(document).ajaxSuccess(function(event,xhr,settings,data){
ajax_cache[cache_key(settings)] = {data:data};
// Store other useful properties like current timestamp to be able to prune old cache maybe?
});
$(document.ajaxSend(function(event,xhr,settings){
if(ajax_cache[cache_key(settings)]){
//Add checks for cache age maybe?
//Add check for nocache setting to be able to override it?
xhr.abort();
settings.success(ajax_cache[cache_key(settings)].data);
}
});
What I've demonstrated here is a very naïve but functional approach to your problem. This has the benefit to make this work for every ajax calls you may have, without having to change them. You'd need to build up on this to consider failures, and to make sure that the abortion of the request from a cache hit is not getting dispatched to abort handlers.
One valid option here is to JSON.Stringify() the objects and compare the strings. If the objects are identical the resulting serialised strings should be identical.
There may be edge cases causing slight differences if you use an already JSONified string directly from the response so you'll have to double check by testing.
Additionally, if you're trying to figure out how to persist it across page loads use localStorage.setItem("lastSuccessfulRequest", lastSuccessfulRequest) and localStorage.getItem("lastSuccessfulRequest"). (If not, let me know and I'll remove this.)

MVC prompt on actionlink

I found this code for confirm window, but I want to create a prompt window and pass the info user provided to controller (dunno how to grab the value and put it into routeValues :/ ).
It should work like this :
user clicks action link
prompt
controller gets the values from prompt
Code :
<%= Html.ActionLink(
"Add",
"Add",
new { id = item.foo},
new { onclick = "return confirm('foo');" }) %>
If you just need a prompt with one parameter, you can try to use Window prompt() here: http://www.w3schools.com/jsref/met_win_prompt.asp
If you need more parameters, you can try Modal of bootstrap: http://www.w3schools.com/bootstrap/bootstrap_ref_js_modal.asp (the last example)
Hi
If you have an action in MVC Control Like :
public ActionResult SetOkReject(int? RequestId,string MSG="")
{
//. . .
}
Convert ActionLink to a tag Like this:
<a href='#' onclick = 'return Reject(#Model.ElementAt(I).ID)'
> Reject the request</a>
And In Javascript write a function like:
<script>
function Reject(RequestId)
{
var T = confirm(' Do you reject this request?');
if (T)
{
var Prom = prompt("Please enter the reason for
rejecting the request", "");
if (Prom == null || Prom == "") {
// nothing
} else {
var curl = ActRejext + '?RequestId=' + RequestId + '&MSG=' + Prom;
window.location.href = curl;
return true;
}
return true;
}
return false;
}
</script>

How to show View after Ajax call to a Controller

I cant figured out how to show whole page after Ajax call to Controler. After 'Order' buton click I call javascript function where I make Ajax call to controler action to get XML in string and with that string I call another controller action where I return model. In last step I want to call third controller action with return View(model) but I get null object parameter.
function order(model) {
$('#details-container').html("<h2>Loading Complete Frame Module. Please wait...</h2>");
$.p({
url: '#Url.Action("CompleteFrameBrandDetails", "PacCompleteFrame")',
data: { item: model },
success: function (xml) {
if (xml.Success) {
$.p({
url: '#Url.Action("GlassCompleteFrame", "PacModule")',
data: JSON.stringify({ b2bXml: xml.Data }),
success: function (model) {
var pacModuleModel = {
CustomerNumber: model.Data.CustomerNumber,
Language: model.Data.Language,
Comission: model.Data.Comission,
GlassXml: model.Data.GlassXml,
Price: model.Data.Price,
ReadOnly: model.Data.ReadOnly,
Mode: model.Data.Mode,
IframeUrl: model.Data.Mode
};
var url = '#Url.Action("GlassCompleteFrameView", "PacModule", "__view__")';
window.location.href = url.replace("__view__", JSON.stringify(pacModuleModel));
}
});
} else {
$.alert({
message: 'error while trying to load xml details'
});
}
}
});
}
public ActionResult GlassCompleteFrame(string b2bXml)
{
string mode = "5";
//If the Store isn't selected, redirect to HomePage
if (string.IsNullOrEmpty(_workContext.SelectedCustomerNumber))
{
return RedirectToRoute("HomePage");
}
else
{
PacModuleModel model = new PacModuleModel();
model.CustomerNumber = _workContext.SelectedCustomerNumber;
model.Language = _workContext.WorkingLanguage.UniqueSeoCode;
model.Comission = "";
if (b2bXml == null || b2bXml == String.Empty)
{
return RedirectToRoute("HomePage");
}
else
{
model.GlassXml = b2bXml.Replace("\"", "\\\"");
}
int index = b2bXml.IndexOf("<price>") + "<price>".Length;
string p = b2bXml.Substring(index, b2bXml.IndexOf("</price>") - index);
model.Price = Convert.ToDouble(p, System.Globalization.CultureInfo.InvariantCulture);
model.ReadOnly = false;
model.Mode = ModuleMode.ByProduct;
model.IframeUrl = "http://ItkCompleteConfiEmbedded.aspx?lang=" + _workContext.WorkingLanguage.LanguageCulture; //_pacGeneralSettings.GlassModuleUrl + ;
return new JsonResult()
{
Data = new
{
Success = true,
Data = model
}
};
}
}
public ActionResult GlassCompleteFrameView(PacModuleModel model)
{
// here I get null model parameter
return View("Glass", model);
}
Curently I don't know how to pass model to the last action controller. Thank you nice people for help.
If I understand correctly, something like this should do the trick:
Let's say you have, in your controller MyModelController:
public ActionResult SomePage(MyModel myModel){
return View(myModel);
}
To naviguate to that page, you could do:
<script>
window.location.href = "#Url.Action("SomePage", "MyModel", myModelObject)";
</script>
I hope this helps!
I use Session variable to get model in GlassCompleteFrameView(PacModuleModel model) and works perfect. I set Session variable in public ActionResult GlassCompleteFrame(string b2bXml).
public ActionResult GlassCompleteFrameView(PacModuleModel model)
{
model = Session["xml"] as PacModuleModel;
return View("Glass", model);
}

Trying to refresh page using Jquery post and ActionResult

I've been trying to make the "RedirecttoAction" statement work here but it doesn't budge. Here is the method:
[HttpPost]
public ActionResult UpdateTech(int tech, int id)
{
Callout callout = db.Callouts.Find(id);
callout.TechnicianId = tech;
callout.TechStatus = "ASSIGNED";
db.Entry(callout).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("CalloutAdmin/Index/");
}
And it is called by the following JQuery, which works perfectly:
$(function () {
$(".techdropdown").change(function () {
var recordToUpdate = $(this).attr("id");
var selectedTech = $(".techdropdown option:selected").val();
window.alert(selectedTech);
$.post("/CalloutAdmin/UpdateTech?tech=" + selectedTech + "&id=" + recordToUpdate);
});
});
The only thing that does not happen is the page being refreshed, which was what the redirect should do. Can anyone advise?
UPDATE
What I am trying to do is update this Callout object, without redirecting to another view. I choose a technician from a dropdownlist and it automatically sets the callout's technician value to the one I chose from the dropdown.
You're returning the redirect to the AJAX request, and the AJAX request is loading the page in the background. If you want to have the entire page redirect you probably want to use the success callback in jQuery
$.post("/CalloutAdmin/UpdateTech?tech=" + selectedTech + "&id=" + recordToUpdate, function() { document.location = "CalloutAdmin/Index/"; } );
If you want to have the action control the location of the redirect, you probably want to use the return a JsonResult or ContentResult from your action with the URL outputted from there have jQuery's success callback redirect the user.
Assuming that UpdateTech and Index both belong to CallOutAdminController then change your UpdateTech Method to look like:
[HttpPost]
public ActionResult UpdateTech(int tech, int id)
{
Callout callout = db.Callouts.Find(id);
callout.TechnicianId = tech;
callout.TechStatus = "ASSIGNED";
db.Entry(callout).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index","CallOutAdmin");
}
Then make you jQuery function like this:
$(document).ready(function(e) {
$(".techdropdown").change(function () {
var recordToUpdate = $(this).attr("id");
var selectedTech = $(".techdropdown option:selected").val();
window.alert(selectedTech);
window.location = "/CallOutAdmin/UpdateTech?tech=" + selectedTech + "&id=" + recordToUpdate
});
});

Call MVC action method by javascript but not using AJAX

I have a MVC3 action method with 3 parameters like this:
var url = "/Question/Insert?" + "_strTitle='" + title + "'&_strContent='" + content + "'&_listTags='" + listTags.toString() + "'";
and I want to call this by normal javascript function not AJAX (because it's not necessary to use AJAX function)
I tried to use this function but it didn't work:
window.location.assign(url);
It didn't jump to Insert action of QuestionController.
Is there someone would like to help me? Thanks a lot
This is more detail
I want to insert new Question to database, but I must get data from CKeditor, so I have to use this function below to get and validate data
// insert new question
$("#btnDangCauHoi").click(function () {
//validate input data
//chủ đề câu hỏi
var title = $("#txtTitle").val();
if (title == "") {
alert("bạn chưa nhập chủ đề câu hỏi");
return;
}
//nội dung câu hỏi
var content = GetContents();
content = "xyz";
if (content == "") {
alert("bạn chưa nhập nội dung câu hỏi");
return;
}
//danh sách Tag
var listTags = new Array();
var Tags = $("#list_tag").children();
if (Tags.length == 0) {
alert("bạn chưa chọn tag cho câu hỏi");
return;
}
for (var i = 0; i < Tags.length; i++) {
var id = Tags[i].id;
listTags[i] = id;
//var e = listTags[i];
}
var data = {
"_strTitle": title,
"_strContent": content,
"_listTags": listTags.toString()
};
// $.post(url, data, function (result) {
// alert(result);
// });
var url = "/Question/Insert?" + "_strTitle='" + title + "'&_strContent='" + content + "'&_listTags='" + listTags.toString() + "'";
window.location.assign(url); // I try to use this, and window.location also but they're not working
});
This URL call MVC action "Insert" below by POST method
[HttpPost]
[ValidateInput(false)]
public ActionResult Insert(string _strTitle, string _strContent, string _listTags)
{
try
{
//some code here
}
catch(Exception ex)
{
//if some error come up
ViewBag.Message = ex.Message;
return View("Error");
}
// if insert new question success
return RedirectToAction("Index","Question");
}
If insert action success, it will redirect to index page where listing all question include new question is already inserted. If not, it will show error page. So, that's reason I don't use AJAX
Is there some one help me? Thanks :)
Try:
window.location = yourUrl;
Also, try and use Fiddler or some other similar tool to see whether the redirection takes place.
EDIT:
You action is expecting an HTTP POST method, but using window.location will cause GET method. That is the reason why your action is never called.
[HttpPost]
[ValidateInput(false)]
public ActionResult Insert(string _strTitle, string _strContent, string _listTags)
{
// Your code
}
Either change to HttpGet (which you should not) or use jQuery or other library that support Ajax in order to perform POST. You should not use GET method to update data. It will cause so many security problems for your that you would not know where to start with when tackling the problem.
Considering that you are already using jQuery, you might as well go all the way and use Ajax. Use $.post() method to perform HTTP POST operation.
Inside a callback function of the $.post() you can return false at the end in order to prevent redirection to Error or Index views.
$.post("your_url", function() {
// Do something
return false; // prevents redirection
});
That's about it.
You could try changing
var url = "/Question/Insert?" + "_strTitle='" + title + "'&_strContent='" + content + "'&_listTags='" + listTags.toString() + "'";
to
var url = "/Question/Insert?_strTitle=" + title + "&_strContent=" + content + "&_listTags=" + listTags.toString();
I've removed the single quotes as they're not required.
Without seeing your php code though it's not easy to work out where the problem is.
When you say "It didn't jump to Insert action of QuestionController." do you mean that the browser didn't load that page or that when the url was loaded it didn't route to the expected controller/action?
You could use an iframe if you want to avoid using AJAX, but I would recommend using AJAX
<iframe src="" id="loader"></iframe>
<script>
document.getElementById("loader").src = url;
</script>

Categories

Resources