Remove unwanted characters from URL - regex

I have used GetRouteUrl to create SEO friendly URLs but I now want to remove %20 ie spaces and replace with a dash ("-"). An example page from my website is shown below. I want to Title variable to be "madonna-item" and not "Madonna%20Item".
/ProductsByDepartment/Gracya/Madonna/Madonna%20Item?CategoryId=9&productId=8&departmentId=4
I have create a class (StringHelpers) to fix the url but I don't know where to call FixUrl
Public static class StringHelpers
{
public static string FixUrl(this string url)
{
string encodedUrl = (url ?? "").ToLower();
encodedUrl = Regex.Replace(encodedUrl, #"\+", "and");
encodedUrl = encodedUrl.Replace("'", "");
encodedUrl = Regex.Replace(encodedUrl, #"[^a-z0-9]", "-");
return encodedUrl;
}
}
The code which contains the link to update is below. I want to use FixUrl on the Title field, but this does not work.
Please can you advise me how to use FixUrl?
<td class="Product_title" height="20px" width="180px">
<a href='<%#: GetRouteUrl("ProductExtraRoute", new {CategoryId = Eval("catId"), productId = Eval("productId"), departmentId = Eval("depId"), Title = Eval("Title")}).FixUrl()%>' class="Product">
<asp:Literal ID="literal2" runat="server" Text='<%# Eval(("Title").FixUrl()) %>'></asp:Literal>

Try decodeURIComponent
Check this http://www.w3schools.com/jsref/jsref_decodeuricomponent.asp
After this replace all speces with -

Related

Docusign dynamic row generation in table

I have to dynamically generate the rows in Docusign template's table. Is there a way to achieve that ? I have to mention customer's detail which can vary from contract to contract and for that i don't want to keep static placeholders for that such that I preconfigure 100 rows and it will populate accordingly.
Your problem will be solved using tab from docusign official docs. Also please read examples here. API ref about envelops will also helps you. Further demonstrations will be following.
function document1(args) {
return (
<div>
<table style="width:100%">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr>
<td>{args.firstName}</td>
<td>{args.lastName}</td>
<td>{args.age}</td>
</tr>
</table>
</div>
);
}
use that document into makeEnvelope function.
function makeEnvelope(args) {
// create the envelope definition
let env = new docusign.EnvelopeDefinition();
env.emailSubject = "Please sign this document set";
// add the documents
let doc1 = new docusign.Document();
let doc1b64 = Buffer.from(document1(args)).toString("base64");
doc1.documentBase64 = doc1b64;
doc1.name = "YOUR markup doc name";
doc1.fileExtension = "html";
doc1.documentId = "1";
// The order in the docs array determines the order in the envelope
env.documents = [doc1];
// create a signer recipient to sign the document, identified by name and email
// We're setting the parameters via the object constructor
let signer1 = docusign.Signer.constructFromObject({
email: args.signerEmail,
name: args.signerName,
recipientId: "1",
routingOrder: "1",
});
// routingOrder (lower means earlier) determines the order of deliveries
// to the recipients. Parallel routing order is supported by using the
// same integer as the order for two or more recipients.
// create a cc recipient to receive a copy of the documents, identified by name and email
// We're setting the parameters via setters
let cc1 = new docusign.CarbonCopy();
cc1.email = args.ccEmail;
cc1.name = args.ccName;
cc1.routingOrder = "2";
cc1.recipientId = "2";
// Create signHere fields (also known as tabs) on the documents,
// We're using anchor (autoPlace) positioning
//
// The DocuSign platform searches throughout your envelope's
// documents for matching anchor strings. So the
// signHere2 tab will be used in both document 2 and 3 since they
// use the same anchor string for their "signer 1" tabs.
let signHere1 = docusign.SignHere.constructFromObject({
anchorString: "**signature_1**",
anchorYOffset: "10",
anchorUnits: "pixels",
anchorXOffset: "20",
}),
signHere2 = docusign.SignHere.constructFromObject({
anchorString: "/sn1/",
anchorYOffset: "10",
anchorUnits: "pixels",
anchorXOffset: "20",
});
// Tabs are set per recipient / signer
let signer1Tabs = docusign.Tabs.constructFromObject({
signHereTabs: [signHere1, signHere2],
});
signer1.tabs = signer1Tabs;
// Add the recipients to the envelope object
let recipients = docusign.Recipients.constructFromObject({
signers: [signer1],
carbonCopies: [cc1],
});
env.recipients = recipients;
// Request that the envelope be sent by setting |status| to "sent".
// To request that the envelope be created as a draft, set to "created"
env.status = args.status;
return env;
}
then make example worker function to use that envelope containing documents(either your table data or something else)
exampleSigningViaEmail.worker = async (args) => {
// Data for this method
// args.basePath
// args.accessToken
// args.accountId
let dsApiClient = new docusign.ApiClient();
dsApiClient.setBasePath(args.basePath);
dsApiClient.addDefaultHeader("Authorization", "Bearer " + args.accessToken);
let envelopesApi = new docusign.EnvelopesApi(dsApiClient),
results = null;
// Step 1. Make the envelope request body
let envelope = makeEnvelope(args.envelopeArgs);
// Step 2. call Envelopes::create API method
// Exceptions will be caught by the calling function
results = await envelopesApi.createEnvelope(args.accountId, {
envelopeDefinition: envelope,
});
let envelopeId = results.envelopeId;
console.log(`Envelope was created. EnvelopeId ${envelopeId}`);
return { envelopeId: envelopeId };
};

Replace parts of a URL in Greasemonkey

I'm trying to replace a part of url using a Greasemonkey script, but having hard time to achieve what I'm trying to do.
Original Urls are like:
http://x1.example.to/images/thumb/50/157/1571552600.jpg
http://x2.example.to/images/thumb/50/120/1201859695.jpg
http://x3.example.to/images/thumb/50/210/2109983330.jpg
What I want to achieve is this:
http://example.to/images/full/50/157/1571552600.jpg
http://example.to/images/full/50/120/1201859695.jpg
http://example.to/images/full/50/210/2109983330.jpg
I just want to replace thumb with full and cut out the x1.example.to, x2.example.to, x3.example.to, x4.example.to etc.. part completely from the original URL so new urls will be starting like example.to/images/full/
How do I achieve this?
I have found a Greasemonkey script from this answer and did try to work out but failed.
Here's what i did so far.
// ==UserScript==
// #name Example Images Fixer
// #namespace Example
// #description Fixes image galleries
// #include http://*.example.to/*
// ==/UserScript==
var links = document.getElementsByTagName("a"); //array
var regex = /^(http:\/\/)([^\.]+)(\.example\.to\/images\/thumb/\)(.+)$/i;
for (var i=0,imax=links.length; i<imax; i++) {
links[i].href = links[i].href.replace(regex,"$4full/$5");
}
Any help on that?
You're forgetting to put the http:// part in your replacement URL:
/^(https?:\/\/)[^.]+\.(example\.to\/images\/)thumb\/(.+)$/i
and then:
.replace(regex, "$1$2full/$3");
You can see the results here.
Here is an example of what can be done:
var urls = ['http://x1.example.to/images/thumb/50/157/1571552600.jpg',
'http://x2.example.to/images/thumb/50/120/1201859695.jpg',
'http://x3.example.to/images/thumb/50/210/2109983330.jpg'];
for (var i = 0, len = urls.length; i < len; i++) {
urls[i] =
urls[i].replace(/:\/\/[^\.]+\.(example.to\/images\/)thumb/, '://$1full');
console.log(urls[i]);
}
/* result
"http://example.to/images/full/50/157/1571552600.jpg"
"http://example.to/images/full/50/120/1201859695.jpg"
"http://example.to/images/full/50/210/2109983330.jpg"
*/
Here is the Fiddle

Customise Sitecore RichTextEditor to add default wrapper

The front end (html and css) is set up such a way that for the description text from a Sitecore content field needs to have a <p> tag wrapped around it.
So by default the RTE wraps texts in a <p> tag = TRUE. BUT the catch is you will need to hit Enter or copy/paste multiple paragraphs.
How can we force Sitecore to add a P tag if it's just one line?
Fortunately, From the dll, one particular function caught my eye:
protected virtual void SetupScripts()
{
foreach (XmlNode node in Factory.GetConfigNodes("clientscripts/htmleditor/script"))
this.Result.Scripts.AppendFormat("<script src=\"{0}\" language=\"{1}\"></script>\n", (object) XmlUtil.GetAttribute("src", node), (object) XmlUtil.GetAttribute("language", node));
}
NICE, eh? The developers of SITECORE are clever after all.
So I did this in the web.config,
<!— CLIENT SCRIPTS
These script files are included in the client, e.g. '<script src="/myscript.js" language="JavaScript"/>'
—>
<clientscripts>
<everypage />
<htmleditor>
<script src=”/assets/js/CustomRTE.js” language=”javascript”/>
</htmleditor>
</clientscripts>
And overrode scSendRequest function from EditorWindow.aspx.
window.scSendRequest = function(evt, command) {
var editor = scRichText.getEditor();
if (editor.get_mode() == 2) { //If in HTML edit mode
editor.set_mode(1); //Set mode to Design
}
var htmls = editor.get_html(true);
var regex = /<p[^>]*>.*?<\/p>/i;
var match = regex.exec(htmls);
if(match == null && htmls != null) {
htmls = "<p>" + htmls + "</p>";
}
//$("EditorValue").value = editor.get_html(true);
$("EditorValue").value = htmls;
scForm.browser.clearEvent(evt);
scForm.postRequest("", "", "", command);
return false;
}
AND YAY .. double rainbow and unicorn.
You could create your own custom solution for this requirement as well.
You could create a new pipeline event in the
<saveRichTextContent> pipeline - This could enable you to append the tag when you hit save on the rich text editor in sitecore
<renderField> pipeline - This could on the fly wrap your text into <p></p> tags while rendering the page, if the tag was not there in the original rtf text.
If you go for method 1: <saveRichTextContent>
You could add to the pipeline in web.config:
<processor type="Sitecore72.Classes.WrapRichTextInParagraphOnSave, Sitecore72" />
And you could use the following corresponding code:
namespace Sitecore72.Classes
{
public class WrapRichTextInParagraphOnSave
{
public void Process(SaveRichTextContentArgs args)
{
if (!(args.Content.Trim().StartsWith("<p>") && args.Content.Trim().EndsWith("</p>")))
args.Content = "<p>" + args.Content + "</p>";
}
}
}
Please note, that this pipeline gets triggered only when you use the Show Editor buttong of a rich text field:
If you go for method 2: <renderField>
To append to this pipeline you would use this config:
<processor type="Sitecore72.Classes.WrapRichTextInParagraphOnRender, Sitecore72" />
And you could use the following corresponding code:
namespace Sitecore72.Classes
{
public class WrapRichTextInParagraphOnRender
{
public void Process(RenderFieldArgs args)
{
if (args.FieldTypeKey == "rich text" && !(args.Result.FirstPart.Trim().StartsWith("<p>") && args.Result.FirstPart.Trim().EndsWith("</p>")))
args.Result.FirstPart = "<p>" + args.Result.FirstPart + "</p>";
}
}
}
For both these, ensure you add reference to Sitecore.Kernel.dll and HtmlAgilityPack.dll. Both of these are available with the sitecore package solution.

Tinymce editor gallery plugin Regexp problem?

I am using tinymce editor for inserting contents to mysql.
I have changed wordpress gallery editor plugin according to my system.
If there is gallery code in content. I convert this code to a symbolic photo, so that user understand there is a gallery , in stead of seeing a code. Like wordpress does.
If there is only 1 gallery in content, i convert this code to image successfully, but if there is more than 1 gallery it fails.
How can i convert all {gallery} code into a symbolic image before saving to db and convert these photos back to {gallery} code again while inserting or updating into mysql.
I am so bad on regular expression.
I think do_gallery RegExp has mistake. How should i change this.
initalising editor like:
ed.onBeforeSetContent.add(function(ed, o) {
ed.dom.loadCSS(url + "/css/gallery.css");
o.content = t._do_gallery(o.content);
});
ed.onPostProcess.add(function(ed, o) {
if (o.get)
o.content = t._get_gallery(o.content);
});
My "do and get gallery" codes like that:
_do_gallery : function(co) {
return co.replace(/\{gallery([^\]]*)\}/g, function(a,b){
var image = '<img src="gallery.gif" class="wpGallery mceItem" title="gallery'+tinymce.DOM.encode(b)+'" />';
console.log(image);
return image;
});
},
_get_gallery : function(co) {
function getAttr(s, n) {
n = new RegExp(n + '="([^"]+)"', 'g').exec(s);
return n ? tinymce.DOM.decode(n[1]) : '';
};
return co.replace(/(?:<p{^>}*>)*(<img[^>]+>)(?:<\/p>)*/g, function(a,im) {
var cls = getAttr(im, 'class');
if ( cls.indexOf('wpGallery') != -1 )
return '<p>{'+tinymce.trim(getAttr(im, 'title'))+'}</p>';
return a;
});
}
If Content is:
<p>Blah</p>
<p>{gallery Name="gallery1" id="82" galeryID="15" sizeId="6" galery_type="list"}</p>
<p>test</p>
this is ok
<img src="gallery.gif" class="wpGallery mceItem" title="gallery Name="tekne1" id="82" galeryID="15" sizeId="6" galery_type="liste"" />
But, if content is:
<p>Blah</p>
<p>{gallery Name="gallery1" id="82" galeryID="15" sizeId="6" galery_type="list"}</p>
<p>test</p>
<p>{gallery Name="gallery2" id="88" galeryID="11" sizeId="1" galery_type="slide"}</p>
<p>test2</p>
it logs
<img src="gallery.gif" class="wpGallery mceItem" title="gallery Name="gallery1" id="82" galeryID="15" sizeId="6" galery_type="list"}</p> <p>test</p> <p>{gallery Name="gallery2" id="88" galeryID="11" sizeId="1" galery_type="slide"" />
I hope i could explain my problem
Thank you.
I suspect that your original regex is a typo, looks like a missing Shift when you hit the ]. Try this:
/\{gallery([^\}]*)\}/g
Then the ([^\}]*) part will (greedily) eat up any sequence of characters that aren't }; your original one would consume any sequence of character that didn't include a ] and the result is that you'd grab everything between the first { and the last } rather than just grabbing the text between pairs of braces.

Problem Binding to GridView HiddenField

EDIT: I added in the hf from the first reply that was pointed out. This helped with a few other issues, but still did not fix the problem.
I am trying to bind a list to a gridview with a LOT of hidden fields (I'll only use 2 of the 50) for temporary holding so the user can create and delete multiple items without going back and forth to the database multiple times during creation. I'm fine with binding to and recalling from the BoundFields; however, when I try to recall the hidden field values it comes back as null. I may be having problems with the binding to the hidden fields. Here's my code
ASP:
<asp:GridView ID="grdOtherCarrier" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundField HeaderText="Sequence" DataField="Sequence"></asp:BoundField>
<asp:BoundField HeaderText="Pay ID" DataField="PayID"></asp:BoundField>
<asp:BoundField HeaderText="Provider" DataField="Provider"></asp:BoundField>
<asp:TemplateField HeaderText="Actions">
<ItemTemplate>
<asp:HiddenField ID="hfInsuredLastName" Value="<%#Eval("InsuredLastName")%>" runat="server" />
<asp:HiddenField ID="hfInsuredFirstName" Value="<%#Eval("InsuredFirstName")%>" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
C# / code behind:
protected void lblSubmitOtherCarrier_Click(object sender, EventArgs e)
{
List<OtherCarrier> OCList = new List<OtherCarrier>();
OtherCarrier OC;
foreach (GridViewRow row in grdOtherCarrier.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
OC = new OtherCarrier();
String Sequence = row.Cells[0].Text.ToString() ; // primary value
String PayID = row.Cells[1].Text.ToString(); // primary value
String Provider = row.Cells[2].Text.ToString(); // primary value
HiddenField InsuredLastName = (HiddenField)row.FindControl("hfInsuredLastName");
HiddenField InsuredFirstName = (HiddenField)row.FindControl("hfInsuredFirstName");
OC.Sequence = Sequence;
OC.PayID = PayID;
OC.Provider = Provider;
OC.InsuredLastname = InsuredLastName.Value.ToString();
OC.InsuredFirstName = InsuredFirstName.Value.ToString();
OCList.Add(OC);
}
}
OC = new OtherCarrier();
OC.Sequence = txtSequence.Text;
OC.PayID = txtPayID.Text;
OC.Provider = txtProvider.Text;
OC.InsuredLastname = txtInsuredLastname.Text;
OC.InsuredFirstName = txtInsuredFirstName.Text;
OCList.Add(OC);
TD.OtherCarrierList = OCList;
grdOtherCarrier.DataSource = OCList;
grdOtherCarrier.DataBind();
mpeAddOtherCarrier.Hide();
txtSequenceNo.Text = (grdOtherCarrier.Rows.Count + 1).ToString();
}
When it gets to assigning the OC.InsuredLastname from the hidden field the hidden field is coming up as null value. Either I'm not reading it correctly or it's not being written correctly.
so...
you are trying to find a control as
(HiddenField)row.FindControl("InsuredLastName");
as you can see, named InsuredLastName when you explicit say in the HTML that your control name is:
<asp:HiddenField
ID="hfInsuredLastName"
Value="<%#Eval("InsuredLastName")%>"
runat="server" />
named hfInsuredLastName
all you need to do is change the call to
(HiddenField)row.FindControl("hfInsuredLastName")