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>
Related
I currently have a servlet setup to send over a list of our active servers. The method grabs the servlet data, processes it, then injects the html into the datalist tag. HTML injection process works, but when I'm splitting the array by the concat separator (which I've done before), I get no values. Below I'll explain with code examples:
HTML:
<label for="server_id_text">Server ID: </label>
<input id="server_id_text" list="server_names" name="server_id" required>
<datalist id="server_names">
<!--This gets injected with the active servers grabbed through a get request-->
</datalist>
Javascript connecting to server to get data:
Note: serverList is a global variable.
var serverList = "";
function setupAutoComplete() {
$.get(baseURL + "/SupportPortal", function (data, status) {
console.debug("Status with auto comp id: " + status);
serverList = data;
console.debug("server list auto comp at post mailing: " + serverList);
});
}
This method is called in the function that is called when the onload event is called in the body tag
Here are the two methods that inject the html:
function setupServerName() {
document.getElementById("server_names").innerHTML = getServerListHTML();
}
function getServerListHTML(){
console.debug("Autocomplete process running...");
var servArr = String(serverList).split('*');
var html = '';
var temp = '<option value="{serverName}">';
console.debug("Array:" + servArr.toString());
if (serverList == 'undefined' || servArr.length == 0){
console.debug("serverList is empty...");
return '';
}
for (var i =0; i < servArr.length; ++i){
html += temp.replace("{serverName}", servArr[i]);
}
console.debug("html: " + html);
console.debug("ServList size " + servArr.length);
return html;
}
When the page loads, setupAutoCompelte() is called first. Then, setupServerName() is called.
My issue is that after I load the page, I get the correct response from the server. For instance, I'll get server1*server2 as a response to the jQuery $.get(...) call. Then I go to split the string into an array, and I get back an empty html tag (<option value="">);
Also, the debug console info are as follows:
Autocomplete process running...
Array:
html: <option value="">
ServList size 1
Status with auto comp id: success
server list auto comp at post mailing: server1*server2
Thanks for the help!
I believe that your setupServerName() function is being called before the AJAX request in setupAutoComplete() returns, so your serverList is an empty string at that point. What you need to do is populate your <datalist> from inside your AJAX callback in setupAutoComplete().
// setup autocomplete datalist
function setupAutoComplete() {
var $datalist = $('#server_names');
$.get(baseURL + '/SupportPortal').then(function (data) {
// update datalist
if (!data || !data.length) {
// no servers, empty list
$datalist.html('');
} else {
// create options html:
// reduce array of server names
// to HTML string, and set as
// innerHTML of the dataset
$datalist.html(data.split('*').reduce(function (html, server) {
return html + '<option value="' + server + '">\n';
},''));
}
});
}
// on page load, setup autocomplete
$(function () {
setupAutoComplete();
});
As you can see from "debug console info":
the get function is asyncrhonous so you need to change your setupAutoComplete get part to:
$.get(baseURL + "/SupportPortal", function (data, status) {
console.debug("Status with auto comp id: " + status);
serverList = data;
setupServerName();
console.debug("server list auto comp at post mailing: " + serverList);
});
On page load try to call directly the setupServerName function within the success event of get function. A different approach is to divide the setupServerName function so that the part related to the serverList variable becomes part of another function.
The serverList variable is global but its content is filled after the setupServerName is executed.
This is the js function:
var onContentChange = function () {
var content =
$("#blogpost-content").data("kendoEditor").value($("#value").val());
console.log(content);
$http.post("/Map/SaveBlogPostContent?destinationId=" +
$("#currentDestinationId").val() +
"&blogPostId=" + $("#currentBlogPost").val() + "&content=" + content)
.then(onSaveBlogPostContent, onError);
}
This method is triggered on change of a textarea.
When it hits the console.log it writes out the correct text that is currently in the textarea but when it posts the data to my controller method it only receives a bit of the content.
Why is this?
It's quite possible you have 'illegal characters' in your textarea, try to escape the content variable, change it like so:
var onContentChange = function () {
var content = $("#blogpost-content").data("kendoEditor").value($("#value").val());
console.log(content);
$http.post("/Map/SaveBlogPostContent?destinationId=" + encodeURIComponent($("#currentDestinationId").val()) + "&blogPostId=" + encodeURIComponent($("#currentBlogPost").val()) + "&content=" + encodeURIComponent(content))
.then(onSaveBlogPostContent, onError);
}
The encodeURIComponent() is the important part there.
Since this is a get and not a post, there are limits to the length of data you can send in the get request, it will depend by browser. you also want to make sure you dont have any characters that need to be escaped. eg. charters used in the url such as ? or & or /. you can escape these by using.
var contentToPass = encodeURIComponent(content);
see here encodeURIComponent
Try this:
var onContentChange = function () {
var content =
$("#blogpost-content").data("kendoEditor").value($("#value").val());
console.log(content);
$http.post("/Map/SaveBlogPostContent", {
destinationId: $("#currentDestinationId").val(),
blogPostId: $("#currentBlogPost").val(),
content: content
}).then(onSaveBlogPostContent, onError);
}
I am trying without success to use the $.post function to test (via a webservice that calls a PHP function "is_dir") if a folder already exists on a server and then I want it to return a string or boolean value back to my javascript page before I proceed to dynamically write the new files that will be placed there. The file path of the folder to be tested is "built" using jQuery which captures form data. I need to define (in a variable) if the directory exists and then be able to access that variable from outside of the $.post function (not from within, using success callback). This is so I can proceed in javascript as follows:
if {directory exists} then
capture more form data (via jQuery) and
$.post to webservice that calls PHP to update database
Outside of the $.post function, the value of my return variable is undefined.
I think I may be over-complicating this. Any suggestions? Thank you, in advance.
Please see my comment to #Steve above:
<script type='text/javascript'>
//function gathers form data, validates constructed file path and then writes to DB
function post_FormData() {
var week_number = $("#form_week_number").val();
var program = $("#form_program").val();
var course = $.trim($("#form_course_number").val());
var form_content_type = $("input:radio[name=content_type]:checked").val();
var content_type = "";
var activity_title_Val = $.trim($("#form_activity_name").val());
var activity_title_Split = activity_title_Val.split(" ");
var activity_title_Clean = new Array();
//this for-loop constructs a valid directory folder name from form data
for(var i=0, l=activity_title_Split.length; i<l; i++) {
activity_title_Split[i] = activity_title_Split[i].replace(/[^a-z0-9\s]/gi,"");
activity_title_Clean[i] = activity_title_Split[i];
activity_title_Split[i] = activity_title_Split[i].replace(/\b[a-z]/g, function(letter){return letter.toUpperCase();});
}
var activity_title = activity_title_Split.join("");
var file_path = "";
file_path += "/CourseFiles/" + program + "/" + program + course + "/" + content_type + "/Week" + week_number + "/activity-" + activity_title;
var message = "<div id=\"confirmation_container_contents\"><p><b>Confirm Content Repository file path: </b><br></p>";
//begin web service call to PHP function
$.post('webservices/create_PA_webservices.php', {web_service: "go_check_if_exists", data_file_path: file_path}, function(data){
var exists = data.does_exist; //json_encoded RESPONSE FROM ASYNC REQUEST
if(exists == "Y") {
message += file_path;
message += "<br><br><br><center><b>An activity folder with this name already exists.</b></center>";
message += "<br><br><center>Please edit the activity title and resubmit.</center>";
message += "<br><br><br><center><input type=\"image\" src=\"pa_images/editButton.jpg\" id=\"editButton\" value=\"edit\"></center></div>";
$("#confirmation_container").empty();
$("#confirmation_container").append(message);
}
else if(exists == "N") {
message += file_path;
message += "<br><br><center><input type=\"image\" src=\"pa_images/editButton.jpg\" id=\"editButton\" value=\"edit\">";
message += " \; \; \;<input type=\"image\" src=\"pa_images/confirmButton.jpg\" id=\"confirmButton\" value=\"confirm\"></center></div>";
$("#confirmation_container").empty();
$("#confirmation_container").append(message);
}
$(function(){//edit proposed file path
$("#editButton").click(function() {
$("#confirmation_container").empty();
});//end function edit path button
});//end anonymous function
$(function(){//confirm proposed file path and write to DB
$("#confirmButton").click(function() {
go_post_FormData(activity_title_Val, file_path, week_number, program, course, content_type);
$("#create_practice_activity").hide();
$("#build_practice_activity").show();
$("#activity_is_new").val("N");
});//end function confirm path button
});//end anonymous function
}, "json").fail(function() {alert("The go_check_if_exists webservice call has failed");}); //end web service call
}//end function post_FormData declaration
</script>
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
});
});
Basically, I want to have an interactive button on my website, that, when clicked, sends some data to the server in order to be checked and display the response (without form sending / page reload).
I thought it would be something like:
function checkData()
{
var req = new XMLHttpRequest();
var conf = document.getElementById('my_text_area').value;
req.open("GET", 'check_data', true);
req.onreadystatechange = function ()
{
var pre = document.getElementById('check_data_out');
pre.innerHTML = req.responseText;
}
req.send(conf);
return false;
}
And on the server side:
#get('/check_data')
def check_data():
# Process the content and answer something...
content = str(request.is_ajax) + ' - ' + str(request.GET) + ' - ' + str(request.POST)
return content
But this obviously doesn't work. Either it is not the right way to send data via javascript or not the right way to access it in bottle.py.
Showing me how it works is highly appreciated.
You can use dojo for client side logic.
var button = dojo.byId('button_id'); // button_id refers to the id of the button you want to click
dojo.connect(button,'onclick',dojo.xhrGet({
url: '/check_data',
handleAs : 'text',
load : function(response){
dojo.byId('button_id').innerHTML = response;
}
}));