Routing don't work as expected - javascript

I have the following route definition:
routes.MapRoute(
"FormPreview",
"Forhandsgranska/{FormId}/{action}/{id}",
new { controller = "FormPreview", action = "Introduction", id = UrlParameter.Optional }
);
I have the following code that triggers the route and It works perfect:
$('#previewButton').on('click', function(){
document.location = '#Url.Action("","formPreview", new { formId = Model.Id })';
});
But now I have the following code that don't work. My route definition is not triggered and I'm redirected to a wrong page, and I don't know why:
var formId = $(this).closest('tr').data('formId');
document.location = "#Url.Action("", "formPreview")/" + formId;
What Is the difference between these two? Why Is the first one working and not the second one?

You have to use .replace method.
document.location = '#Url.Action("", "formPreview",new {formId ="formId"})'.replace("formId",formId);
In Razor every content using a # block is automatically HTML encoded by Razor.

What you have specified: #Url.Action("", "formPreview"), is not the same as #Url.Action("","formPreview", new { formId = Model.Id }). It doesn't match because in the route table you have a required formId, but you haven't specified it in #Url.Action.
Since your URL generated by routing happens before the JavaScript has a chance to interact with it, I suppose one (hacky) way to do it would be to create a dummy formId value and replace it on the client side with a real value.
document.location = '#Url.Action("", "formPreview",new {formId ="DUMMY"})'.replace("DUMMY",formId);
Alternative
Or you could add the dummy as a default value when the formId is not supplied.
routes.MapRoute(
"FormPreview",
"Forhandsgranska/{FormId}/{action}/{id}",
new { controller = "FormPreview", FormId = "DUMMY", action = "Introduction", id = UrlParameter.Optional }
);
Then you could replace the value on the client when needed.
document.location = '#Url.Action("", "formPreview")'.replace("DUMMY",formId);
However, as a side effect that means whenever you create a URL without specifying the FormId it will come out as /Forhandsgranska/DUMMY.

Related

i have problem with multiple form with the same id with google tag manager

Hi i have many forms inside multiple pages all of them the with the same id (success message) after submitted and same class names when i'm sending the form which e.g inside home page i put element selector through id with Page PATH with match regex something like that \/(en|es)\/ it works good without problem ... but when i'm going to page www.something.com/send-something/233?search=profile the form submitted through old id which was for home page i tried to inject custom javascript something like :
function() {
var els = document.querySelectorAll('#sendReqSurgyForm1');
for (var i = 0; i < els.length; i += 1) {
if (els[i] === {{Page URL}}) {
return i;
}
}
return '(nothing sent)';
}
with adding matching Page URL with match regex something like that to https:\/\/www\.something\.com\/(ar|en)\/send-something\/[0-9]+\?source=[a-zA-Z]+\_?[a-zA-Z]+
to matching the url: www.something.com/send-something/233?search=profile
the trigger always works with home page but trigger which located in www.something.com/send-something/233?search=profile not success and the result of javascript always returns nothing sent .. please help to fix this problem
Hi the Answer is SPA Angular using SPA so it can be multiple form with the same component so i solved this problem through setting id for every form with different urls
for example if you have multiple forms in angular inside multiple routing page as i explained in the main topic question .. to fix this problem you can setting id for every form submissions through js by setting new id for every form submission by setting Attribute for id based different urls.
main_id = exampleForm
function(){
var ids = document.getElementById("exampleForm");//main id
var current_url = window.location.href;//current url of visitor
var dir_match = location.pathname+location.search;//the path of website after .com
var send_req = 'https://www.example.com/'+dir_match.match(/[ar][r]|[en]n/)+'/surgery-request/'+dir_match.match(/[0-9]+/)+'?source=profile';//link1 which have form1
var send_req2 = 'https://www.example.com/'+dir_match.match(/[ar][r]|[en]n/)+'/surgery-request/'+dir_match.match(/[0-9]+/)+'?source=profile2';//link2 which have form2
var home_url = 'https://www.example.com/'+dir_match.match(/[ar][r]|[en][n]/)+'/';//link3 which have form3
if(current_url == send_req){
/* if current_url equal to link1 set new id e.g = `forms_req_surgery` */
last_send_req = ids.setAttribute("id", "forms_req_surgery");
var elm = document.getElementById('forms_req_surgery');
var last_var = elm.id;/* get the name of id */
return last_var; // return the name of id after changed set
}else if(current_url == home_url){
last_home_url = ids.setAttribute("id", "home_req");
var elm2 = document.getElementById('home_req');
var last2_var = elm2.id;
return last2_var;
}else if(current_url == send_req2){
last_send_req2 = ids.setAttribute("id", "forms_req_surgery2");
var elm3 = document.getElementById('forms_req_surgery2');
var last3_var = elm3.id;
return last3_var;
}
}

ContentTools - How can I pass additional data from a DIV to the payload object, to be passed into the POST array?

I use ContentTools for my content editor/PHP CMS.
I'm trying to pass additional values from a "editable div" to the POST array (then it will be stored in a database).
The script uses Javascript to get the data and to make the call to my server side code.
Relevant JS code for the saving process:
// Collect the contents of each editable region into a FormData instance
payload = new FormData();
//payload.append('__page__', window.location.pathname);
payload.append('page_id', page_id); // Page ID from the Meta Property
for (name in regions) {
payload.append(name, regions[name]);
//payload.append('template', 'template');
}
// Send the updated content to the server to be saved
onStateChange = function(ev) {
// Check if the request is finished
if (ev.target.readyState == 4) {
editor.busy(false);
if (ev.target.status == '200') {
// Save was successful, notify the user with a flash
if (!passive) {
new ContentTools.FlashUI('ok');
}
} else {
// Save failed, notify the user with a flash
new ContentTools.FlashUI('no');
}
}
};
xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', onStateChange);
xhr.open('POST', 'update-page.php'); // Server side php file, which will catch the $_POST array.
xhr.send(payload);
Below you see an example editable div which will be in the POST array when page is saved after editing.
Note that the div has additional custom html tags 'data-template'.
<div id="content_4" class="content" data-template="5" data-editable data-name="1">
This is some example website text.
This is some other example website text.
</div>
I'm trying to pass along the values from "data-template".
What I've tried so far does not work:
// Added in: editor.addEventListener('saved', function (ev) {
var template = document.querySelector("div[data-template]"); // Get Template name from editable div
// Or
var template = document.getElementsByTagName("[data-template]")[0].getAttribute('[data-template]');
// Added in: the For In Loop
for (name in regions) {
payload.append(name, regions[name]);
payload.append('template', template); // added but does not work
}
Also, I don't want to use the div ID as value to be passed on.
I'm still trying other ways, but my JavaScript knowledge is not (yet!) as strong as my PHP knowledge.
Does someone know a solution to this issue?
There must be simple solution to get the value from the data-template, passed on to the POST (only the data-template value of the changed content in the div).
Right?
You can select the template data for each region by selecting the region's DOM element by it's editable name (e.g data-name):
for (var name in regions) {
// Select the region DOM element
var regionDOM = document.querySelector('[data-name="' + name + '"]');
// Get the `data-template` attribute
var tpl = regionDOM.getAttribute('data-template');
// Add the region HTML and template to the payload
payload.append(name, regions[name]);
payload.append('template_' + name, tpl);
}
The reason you get no value for for template at all in your code is that you're calling the getAttribute method with the CSS selector and not just the attribute name you want, e.g .getAttribute('[data-template]') should be .getAttribute('data-template').
The other difference in the code I've posted is that the template for each region is saved. If it will be the same template for all regions then you could modify the code to be:
for (var name in regions) {
// Select the region DOM element
var regionDOM = document.querySelector('[data-name="' + name + '"]');
// Get the `data-template` attribute
var tpl = regionDOM.getAttribute('data-template');
// Add the region HTML and template to the payload
payload.append(name, regions[name]);
}
// Set the template value for the payload to that of the last region
// found.
payload.append('template', tpl);

How do I Call a URL Action from Javascript?

I am doing:
var url = '#Url.Action("Attachments", "Transactions")';
url += '/?id=' + 3201;
$("#attachments").load(url);
However, on load it doesn't do anything. Am i missing something?
I essentially want to call something similar to:
#{Html.RenderAction("Attachments", "Transactions", new { id = 3301 });}
I get the following error on console:
http://server:54137/Transactions/#Url.Action(%22Attachments%22,
You must be using an external JavaScript file which will not parse your razor syntax hence the error in your console of #Url.Action(%22Attachments%22..
You have a couple of options:
Create a JavaScript function and pass in the url:
function loadUrl(url) {
$("#attachments").load(url);
}
Then in your razor call it within a script tag:
loadUrl(#Url.Action("Attachments", "Transactions", new { id = #Model.Id })
Add the url to the html element as data and read it from your JavaScript with the data method.
In your razor markup add this:
<button data-url="#Url.Action("Attachments", "Transactions", new { id = #Model.Id })" />
From your JavaScript event handler read it with:
var url = $(this).data('url');
$("#attachments").load(url);
I prefer the second option.
You Need to use Html.Raw check below
var url = "#Html.Raw(Url.Action("Attachments", "Transactions"))";
url += '/?id=' + 3201;
$("#attachments").load(url);

JavaScript - How do I open a new page and pass JSON data to it?

I have a page called search.jsp. When the user selects a record and the presses an edit button, I would like to open a new page (in the same window) with the record data (that is stored in a json object and passed to the new page). How do I use Javascript (or jQuery) to open a new page and pass the JSON data?
If the two pages are on the same domain, a third way is to use HTML5 localStorage: http://diveintohtml5.info/storage.html
In fact localStorage is precisely intended for what you want. Dealing with GET params or window/document JS references is not very portable (even if, I know, all browsers do not support localStorage).
Here's some very simple pure JavaScript (no HTML, no jQuery) that converts an object to JSON and submits it to another page:
/*
submit JSON as 'post' to a new page
Parameters:
path (URL) path to the new page
data (obj) object to be converted to JSON and passed
postName (str) name of the POST parameter to send the JSON
*/
function submitJSON( path, data, postName ) {
// convert data to JSON
var dataJSON = JSON.stringify(data);
// create the form
var form = document.createElement('form');
form.setAttribute('method', 'post');
form.setAttribute('action', path);
// create hidden input containing JSON and add to form
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", postName);
hiddenField.setAttribute("value", dataJSON);
form.appendChild(hiddenField);
// add form to body and submit
document.body.appendChild(form);
form.submit();
}
Use some PHP like this on the target page to get the JSON:
$postVarsJSON = $_POST['myPostName'];
$postVars = json_decode( $postVarsJSON );
Or, more simply for JavaScript:
var postVars = JSON.parse( <?php $_POST['myPostName']; ?> );
Assuming the two pages are on the same domain, you can use the returned object created by window.open() to access (and edit) the window object of a newly opened window.
Hmm, for example, you have object
var dataObject = {
param : 'param',
param2 : 'param2'
};
You can translate it into string, using JSON.stringify method
var dataObjectString = JSON.stringify(dataObject);
Then you should use Base64 encoding to encode you data (base64 encode/decode methods can be easely found in search engines)
var dataObjectBase64 = base64encode(dataObjectString);
You will get something like this
e3BhcmFtIDogJ3BhcmFtJyxwYXJhbTIgOiAncGFyYW0yJ307
Then you can pass this string as a parameter:
iframe src="http://page.com/?data=e3BhcmFtIDogJ3BhcmFtJyxwYXJhbTIgOiAncGFyYW0yJ307"
Finally, reverse actions on the loaded page.
You can create "on the fly" a form with a hidden/text input value this will hold the json value, then you can submit this form via javascript.
Something like this...
Im using JQUERY AND UNDERSCORE(for template purpose)
this is the template
<form method='<%= method %>' action="<%= action %>" name="<%= name %>" id="<%= id %>" target="_blank">
<input type='hidden' name='json' id='<%= valueId %>' />
</form>
you can then post use it on javascript
function makePost(){
var _t = _.template("use the template here");
var o = {
method : "POST",
action :"someurl.php",
name : "_virtual_form",
id : "_virtual_form_id",
valueId : "_virtual_value"
}
var form = _t(o); //cast the object on the template
//you can append the form into a element or do it in memory
$(".warp").append(form);
//stringify you json
$("#_virtual_value").val(JSON.stringify(json));
$("#_virtual_form_id").submit();
$("#_virtual_form_id").remove();
}
now you dont have to be worry about the lenght of you json or how many variables to send.
best!
If the the JSON is small enough you can just include it as a GET parameter to the URL when you open the new window.
Something like:
window.open(yourUrl + '?json=' + serializedJson)
Assume if your json data
var data={"name":"abc"};
The page which sends JSON data should have the following code in the script tag.
$.getJSON( "myData.json", function( obj ) {
console.log(obj);
for(var j=0;j
<obj.length;j++){
tData[j]=obj;
//Passing JSON data in URL
tData[j]=JSON.stringify(tData[j]);
strTData[j]=encodeURIComponent(tData[j]);
//End of Passing JSON data in URL
tr = $('\
<tr/>
');
//Send the json data as url parameter
tr.append("
<td>" + "
" +Click here+ "" + "
</td>
");
}
});
The page which receives the JSON data should have the code.
<html>
<head></head>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.js"></script>
<body>
<p id="id"></p>
</body>
<script type="text/javascript">
function getQuery() {
var s=window.location.search;
var reg = /([^?&=]*)=([^&]*)/g;
var q = {};
var i = null;
while(i=reg.exec(s)) {
q[i[1]] = decodeURIComponent(i[2]);
}
return q;
}
var q = getQuery();
try {
var data = JSON.parse(q.jsonDATA);
var name=data.name;
console.log(name);
document.getElementById("id").innerHTML=name;
} catch (err) {
alert(err + "\nJSON=" + q.team);
}
</script>
</html>

ASP.NET MVC 3 Razor: How to get Action URL in a Javascript string variable?

#(Html.ActionLink("Link Label",
"ActionMethodName",
"ControllerName",
null, // parameter object, then html object
null))
produces
Link Label
If I want to reference the /ControllerName/ActionMethodName/id in a JavaScript template for the Edit or New link, how would I assign that to a JavaScript variable?
attempt:
<script type="text/javascript">
var actionUrl = '#(Html.ActionLink("","ActionMethodName",
"ControllerName",null,null))';
</script>
but at that point, I would have to use Javascript to remove the unwanted <a href... characters in the string.
#Url.Action("ActionMethodName", "ControllerName") will generate a path.
<script type="text/javascript">
var actionUrl = #Html.Raw(Json.Encode(Url.Action("ActionMethodName", "ControllerName")));
</script>
or if you already have this actionLink somewhere inside the page you could use it directly:
var actionUrl = $('#mylink').attr('href');
Just ensure to provide a unique id in order to simplify the selection:
#(Html.ActionLink(
"Link Label",
"ActionMethodName",
"ControllerName",
null,
new { id = "mylink" })
)

Categories