VueJS handle URL fragment to action without Vue Router and without jQuery - vue.js

I am currently using VueJS 2.x and have not gone VueRouter yet (and am not able anyway).
Quite simply, I want Vue to detect a URL fragment like https://example.com/mypage#record-17 and for example simulate the click of the following modal link:
<a :id="record.id" :click="openModal(record.id)">Open this record</a>
Should I just parse window.location myself or is there a more elegant way to do it? I also want to not use jQuery.

This is our script for parsing args from the hash. It lets you put a query string after the hash, that will be parsed by the script. If, like us, you also need to pass an url that you don't want parsed, put it at the end in a 'src' argument.
var args = (function () {
var returnVal = {};
var argString = window.location.hash;
//everything after src belongs as part of the url, not to be parsed
var argsAndSrc = argString.split(/src=/);
returnVal["src"] = argsAndSrc[1];
//everything before src is args for this page.
var argArray = argsAndSrc[0].split("&");
for (var i = 0; i < argArray.length; i++) {
var nameVal = argArray[i].split("=");
//strip the hash
if (i == 0) {
var name = nameVal[0];
nameVal[0] = name.slice(1);
}
returnVal[nameVal[0]] = decodeURI(nameVal[1]);
}
return returnVal
})();

Related

is there a way to add LinkedIn insights code so it gets properly triggered in Vue

is there a way to add LinkedIn insights code so it gets properly triggered in a Vue project? or does adding the code before the closing body tag suffice?
If you want to include LinkedIn insights code into the whole app then use it in the main.js file. Else you can use where you want for specific pages.
Below is the example code that you can use and it will work.
(function () {
var s = document.getElementsByTagName("script")[0];
var b = document.createElement("script");
b.type = "text/javascript";
b.async = true;
b.src = "https://snap.licdn.com/li.lms-analytics/insight.min.js";
s.parentNode.insertBefore(b, s);
})();
window._linkedin_partner_id = "0000000"; //paste your id here
window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];
window._linkedin_data_partner_ids.push(window._linkedin_partner_id);

Adding embedded mode in docusaurus

I am using docusaurus 1.14.4
I need to create embedded mode for each document which remove header, footer and left navigation.
Page url look like this http://localhost:3000/...../?mode=emb
I figure out a way by adding this piece of script to each md file
<script>
function getParameterByName(name) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}
var mode = getParameterByName('mode');
if (mode === 'emb') {
setTimeout(()=>{
let list = ['fixedHeaderContainer', 'docsNavContainer', 'nav-footer', 'docs-prevnext'];
for (var itemClassName of list) {
var item = document.getElementsByClassName(itemClassName)[0]
item.parentNode.removeChild(item)
}
document.getElementsByClassName('navPusher')[0].style.paddingTop = 0;
document.getElementsByClassName('mainContainer')[0].style.paddingTop = 0;
}, 0)
}
</script>
It work but does not look like a proper way. Can anyone suggest a better way?
Docusaurus maintainer here. There's no supported way of doing this. May I know what your motivations for doing this are?

formData get() Doesn't seem to work in Safari

This is my code. It works in Firefox and Chrome but not Safari. I get no errors.
<script>
var cleanData = new FormData();
cleanData.append("test", "test");
alert(cleanData.get("test"));
</script>
Does anyone know a workaround?
Apparently, Safari has no means of getting values stored in FormData objects at this time. There is no workaround at this time, and apparently it's not practical to polyfill.
Sorry :(
Notes:
https://developer.mozilla.org/en-US/docs/Web/API/FormData/get#Browser_compatibility
https://www.bountysource.com/issues/27573236-is-it-possible-to-polyfill-missing-formdata-methods
I solved this by conditionally (if Safari is the browser) iterating through the elements property of an actual form. For all other browser, my wrapper just iterates through FormData entries(). The end result of my function, in either case, is a simple javascript object (JSON) which amounts to name/value pairs.
function FormDataNameValuePairs(FormName)
{
var FormDaytaObject={};
var FormElement=$('#'+FormName).get(0);
if (IsSafariBrowser())
{
var FormElementCollection=FormElement.elements;
//console.log('namedItem='+FormElementCollection.namedItem('KEY'));
var JQEle,EleType;
for (ele=0; (ele < FormElementCollection.length); ele++)
{
JQEle=$(FormElementCollection.item(ele));
EleType=JQEle.attr('type');
// https://github.com/jimmywarting/FormData/blob/master/FormData.js
if ((! JQEle.attr('name')) ||
(((EleType == 'checkbox') || (EleType == 'radio')) &&
(! JQEle.prop('checked'))))
continue;
FormDaytaObject[JQEle.attr('name')]=JQEle.val();
}
}
else
{
var FormDayta=new FormData(FormElement);
for (var fld of FormDayta.entries())
FormDaytaObject[fld[0]]=fld[1];
}
return FormDaytaObject;
}
where IsSafariBrowser() is implemented by whatever your favorite method is, but I chose this:
function IsSafariBrowser()
{
var VendorName=window.navigator.vendor;
return ((VendorName.indexOf('Apple') > -1) &&
(window.navigator.userAgent.indexOf('Safari') > -1));
}
Example usage in OP's case, assuming that you have an actual form called CleanDataForm instead of creating a FormData from scratch:
var cleanData=FormDataNameValuePairs('CleanDataForm');
alert(cleanData.test);

How do I force razor to switch back to client side code?

I've got the following code in one of my views
#if (ViewBag.LoginInfo != null)
{
var loginToken = "#ViewBag.LoginInfo.Token";
var loginUser = "#ViewBag.LoginInfo.UserNameJs";
var notifyUrl = "#ViewBag.LoginInfo.NotificationUrl";
}
The code between { } should be rendered to the page as javascript, however it seems to be getting run as serverside code. I'm aware razor switches back to client code when it sees html in this case the code is valid as C# and javascript. How to I force everthing between { } to be written to the page as javasript?
Thanks
Alternatively use #:
#if (ViewBag.LoginInfo != null)
{
#:var loginToken = #Html.Raw(Json.Encode(ViewBag.LoginInfo.Token);
#:var loginUser = #Html.Raw(Json.Encode(ViewBag.LoginInfo.UserNameJs);
#:var notifyUrl = #Html.Raw(Json.Encode(ViewBag.LoginInfo.NotificationUrl);
}
You could wrap them in <text> tags:
#if (ViewBag.LoginInfo != null)
{
<text>
var loginToken = #Html.Raw(Json.Encode(ViewBag.LoginInfo.Token);
var loginUser = #Html.Raw(Json.Encode(ViewBag.LoginInfo.UserNameJs);
var notifyUrl = #Html.Raw(Json.Encode(ViewBag.LoginInfo.NotificationUrl);
</text>
}
Also notice how I have safely encoded the values. Your example will produce invalid javascript if for example your token contains the " character. You should never be mixing javascript and server side values without using a safe serializer as shown in my example.

ExpressJS: Inject Include into Jade using Javascript

Say I have files such as follows
include/person.jade
.person
.name= name
.desc= desc
Now I want to have a button on my page that, when clicked, injects the previous into the document. I want this because I need to add people to the page. How would I go about doing this?
Should I just use an HTML file in this case?
Jade renders on server side. So you should call method with ajax that will return rendered html. Another option is to do this with JavaScript:
function addPerson(name, desc, parentId){
var container = document.createElement('div');
container.className = 'person';
var nameContainer = document.createElement('div');
nameContainer.className = 'name';
nameContainer.innerHTML = name;
container.appendChild(nameContainer);
var descContainer = document.createElement('div');
descContainer.className = 'desc';
descContainer.innerHTML = desc;
container.appendChild(descContainer);
var parent = document.getElementById(parentId);
parent.appendChild(container);
}
Jade:
#personContainer
input(onclick="addPerson('#{name}', '#{desc}', 'personContainer');", type="button")
So similar to the previous example, I use express to host the Jade HTML for the person input in its own url something like this...
self.app.get('/person/:name/:desc',adddoc.person2);
Of course the person2 implementation is just a render of the Jade.
.person
mixin personField(desc,name,valuefname,valuelname)
Then in my Javascript (using JQuery)
function stump(name, desc){
$.get(
"/person/"+desc+"/"+name,
"{}",
function(data) {
var $parents = $( "#parents" );
$parents.append($(data).filter('.person'));
},
"html"
);
}