Feb 27 2015

IE11 Transitions wobbly or expanding in a weird fashion

 

 

I have a few radiobuttons that are styled as a togglers with a quick animation to give the toggling feel. Like this image shows

smoker

 

It works great on pretty much every browser….. but hold and behold! IE11 want’s to be different!  Every time I clicked on the toggler, it would ”wobble”. Expanding itself quickly and back .

The issue was that the parent, holding the radiobuttons had it’s side paddings in percentage. Somehow, IE11 forgets the padding when it does a transition and therefor it felt like it expanded, which it did, cause it grew to fill the entire width of the parent.

I simply changed from % to em and IE11 could then animate it without a problem.

 


Mar 15 2012

Get ContentType from files

I love HttpPostedFileBase! Why? Because it gives me the contenttype from files! But what about the files that I have on my disc and I need to get the ContentType? Unfortunely, you’ll either have to have a huge list with all extensions and their contenttypes which is a major pain. There’re some open source .dlls that will give you this aswell but I don’t fancy using that for such a little thing.

But I really do need to get the ContentType! So, after some searching around I found this rather comfortable way to get the ContentType without having a huge list or getting another dll to do it for me.


private string GetContentType(string fileName)
{
string strcontentType = "application/octetstream";
string ext = Path.GetExtension(fileName).ToLower();
Microsoft.Win32.RegistryKey registryKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
if (registryKey != null && registryKey.GetValue("Content Type") != null)
strcontentType = registryKey.GetValue("Content Type").ToString();
return strcontentType;
}

So, what is the code above? Well.. I said it was comfortable, not the best 🙂 We do have to check the registry to get our contenttypes and that’s pretty much the same as having an entire list, the difference is that we don’t have to maintain it nor create it (if we can’t find one that has all the extensions, and then you have to think about .ppt and .pptx and so forth)

If we, for some reason, don’t get a valid contentype, we’ll just use ”application/octetstream” to return a binary contenttype.

A quick and dirty post, on a quick and dirty fix to get contenttype! 😀


Dec 15 2011

nHibernate not updating child records when using Merge()

I had to run an update on some posts before I would do an insert. Then when I was about to do my insert, I got the error that the object was already in use.

SaveOrUpdate gave me that error, and ofc Update too. Merge worked BUT it only saved the parent object and not the child objects.

The connection though is that the child object is the one responsible to perform the save in the mapobject.


HasMany(x => x.Info)
.Cascade.SaveUpdate();

so I guess to be fair, it kinda works as intended.

The annoying part is that if you use SaveOrUpdate on a parent object, it will actually update the childs too as it understands the connection. But if you use Merge, it wont understand the connection at all!

Here’s a bit of that code


public AlertEntity InsertCapAlerts(AlertEntity capMessage)
{

using (var transaction = _session.BeginTransaction(IsolationLevel.ReadCommitted))
{
var getCap = GetCapAlert(capMessage.Id);
if (getCap != null)
{
InfoEntity infoToSave = capMessage.Infos.FirstOrDefault();
_session.Merge(infoToSave);
_session.Merge(capMessage);
}
else
_session.Save(capMessage);

transaction.Commit();
return capMessage;
}
}

Basicly, what I did is that when I get my new capMessage that I’m going to save, I first check if it already exists in the db. If it doesnt, then fine, just do a Save(). But if it does exist (here’s where SaveOrUpdate always crashed) then I just make a new instance of the child record (we only have one child, therefor FirstOrDefault()).

The first attempt I just saved the Child object to the db by using Merge (because SaveOrUpdate still gives me the error due the object being used in a previous session, and yes I did try session.Clear() and Flush and what not). It worked peachy but then I noticed that my childobject no longer points at its parent. So the childobject is now an orphan crying on the streets of the database. So what we need to do is to point the Parent ID again to the child object.


InfoEntity infoToSave = capMessage.Infos.FirstOrDefault();
infoToSave.AlertEntity_id = capMessage.Id;
_session.Merge(infoToSave);
_session.Merge(capMessage);

Why you ask? Because nHibernate is soooo cute that when it runs Merge, it doesn’t give a flying dutch about the childrecords (as it does when you run SaveOrUpdate as I mentioned before). So when you use Merge, you have to update all childposts yourself AND you have to point out the Parent again.

If anyone knows a better solution to this. Please do inform me. Otherwise, I hope that this little code example helped anyone in any way 🙂


Feb 1 2011

Blank page after login on a WordPress page, wp-login.php

So I kinda screwed up and changed my database password and totally forgot about my page. This caused the page to be down for a few days without me noticing it until a kind soul told me it was down. (Yes… I’m a bad blogger and I only blog when I feel like it). Anyway. After changing the password in wp-config.php I got the page up and running, but I just coulnd’t login. I kept coming to a blank page after trying too. The problem was that I opened the file with notepad and upon saving it, it truncated it.

how to fix it? Just simply download wordpress again and take wp-config-sample.php (or if you have yours untouched) and insert your settings there, making sure to not add extra spaces anywhere or truncating the file. Silly error but still 🙂


Dec 6 2010

Making Polls with Xforms in a usercontrol

XForm is a somewhat of a lazy way out. You know you should do the forms yourself but XForm is simple for the editors and also saves you a lot of job. Anyway, if you want to use XForm to make a poll, you’ll need to make a few adjustments.

First:
Create your new control and add an XForm property to the controls pagetype

Second:
Here you can take the template code from EPiServer to get the basic XForm functions.

Third:
Create your XForm in EPiServer and assign it to your page. Make sure to let anonymous post and also multiple times (Because all your users will be anonymous and you want anonymous to be able to vote more than once)

Fourth:
Create a cookie so people only vote once (they can delete their cookies and vote over and over so if you want a more secure way, go ahead and do it =D) and also so you can display the results insetad of the poll whenever they visit the page again.

The cookie could look something like this:

private void SetCookie()
{
var cookie = new HttpCookie("Poll-" + page.PageLink.ID);
cookie.Values.Add("voted", "true");
cookie.Expires = DateTime.Now.AddYears(24);
Response.Cookies.Add(cookie);
}

and then you can check for the cookie and give the user different views depending if they voted or not. And that code could look something like this

return;
var cookie = Request.Cookies.Get("Poll-" + page.PageLink.ID);
if (cookie== null)
SetupForm();
else
SwitchView(null,null);

Fifth:
If you’re using your XForm directly on a page, then you probably don’t need this step and you’re pretty much set. But if you want to use this as a usercontrol and add the poll with webparts or anything alike you’ll need to do this step.

The thing with EPiServers Statistics is that it will always fetch ”this.PageLink” so if you’re using this as a webpart/control it will try to get the currentpages xform property which will be null. Even if you load the XForm correctly and fetch it from your usercontrol path, the statistics won’t do it. In order to make Statistics work you’ll have to do this:

Statistics.PageLink = page.PageLink;
Statistics.PageGuid = Form.PageGuid;

Otherwise it will take the currentpage pagelink and pageguid. So basicly, you need to set up the Statistics just as you need to set up XForms.

Good luck!


Maj 8 2010

FindPagesWithCriteria with PropertyCriteria and PropertyDataType.Boolean set to false

Huge title but pretty much what this post is about.

To optimize your FindPagesWithCriteria, it’s good to be as specific as you can. i.e not use one criteria, get 500 hits back and then just use the top 5 out of those. Anyway, when using a PropertyDataType.Boolean and you want to get back those pages that has this set to ”false” you can’t really set the value to ”false”. Why? Because when the property is false, it has never been set which makes it null.

Let’s see the code:

PropertyCriteria crit = new PropertyCriteria{
            Condition = CompareCondition.Equal,
            Name = ContentPropertyStrings.Finished,
            Type = PropertyDataType.Boolean,
            Value = "false",
            Required = true
};

The code above won’t give you any hits since there won’t be any property set to false, because those properties are null. What you need to do is what you can see below.

PropertyCriteria crit = new PropertyCriteria{
            Condition = CompareCondition.Equal,
            Name = ContentPropertyStrings.Finished,
            Type = PropertyDataType.Boolean,
            IsNull = true,
            Required = true
};

An old problem but I still get this question from time to time so might aswell post it 🙂


Apr 28 2010

How to modify and publish a page programmatically in EPiServer

When you want to alter a page programmatically you need to use EPiServers CreateWriteableClone on the working page. This is because the Page itself is readonly. Now, there’s plenty of info out there how to do this, but just to refresh your mind, here’s some code:

PageData clone = pd.CreateWritableClone();
clone.Property["MyProperty"] = "New value";
DataFactory.Instance.Save(clone, SaveAction.Publish);

Simple enough, right?

Now, here’s the catch. If you are for example saving page ID’s into a customproperty, simply like this ”42 43 553 23” and so forth and you want to change this programmatically by removing one and adding one. So for example, going from ”42 43 553 23” to ”42 43 55” won’t work with the code above. The result will be ”42 43 553 23 55” as it will only add it up to your current value. So you want to clear your value before you set it although that is also not enough. You’ll have to save the page after you clear it and THEN you can set your new value and save the page. Something like this

PageData clone = pd.CreateWritableClone();
clone.Property["MyProperty"].Clear();
DataFactory.Instance.Save(clone, SaveAction.Publish);
clone.Property["MyProperty"] = "New value";
DataFactory.Instance.Save(clone, SaveAction.Publish);

If someone has a better way to override values without having to doublesave, please do let me know.


Apr 28 2010

Using FindPagesWithCriteria with CustomProperties

FindPagesWithCriteria is a very handy way to pick up pages that are spread out around your site but there’s a tiny thing that is good to remember when using FindPagesWithCriteria to find pages based on a CustomProperites that you’ve made. Never ever forget to click ”searchable property”  when you add the customproperty to your page. Why? Because if this is not checked, FindPagesWithCriteria won’t be able to find it, simple 🙂

Tiny post for a tiny problem that can cause a lot of headache 😉


Jan 14 2010

How to prevent EPiServer to inherit categories to childrenpages

One of the pages I’ve been working on uses EPiServers categories a lot. But the annoying part with EPiServers categories is the way they inherit down to all children, which leads to the problem that categories can be deleted without someone meaning too. e.g you create a page called ”Books” and you have a control that creates a category using the pagename. Below ”Books” you’ll add all the books you want, but all those books will get the category ”books” aswell. But to prevent dead categories, you might want to make a check that once you delete a page, you’ll also delete the category. Then, when deleting a childpage, you’ll also delete the real category, since the childpage also had this category. There are of course ways to prevent this but this can easily be forgotten and cause future problems. It will also mess up search results that uses categories to find information and so on.

Enough with examples, let’s get on the easy solution.


EPiServer.DataFactory.Instance.PublishingPage += CreateCategory;

EPiServer.DataFactory.Instance.SavedPage += CreateCategory;

EPiServer.DataFactory.Instance.SavingPage += CreateCategory;

EPiServer.DataFactory.Instance.CreatingPage += CreateCategory;

static void CreateCategory(object sender, EPiServer.PageEventArgs e)

{

if (!ValidPage(e.Page.PageTypeID))

{

e.Page.Property["PageCategory"].Value = string.Empty;

}

}

Basicly, you’ll call the method ”CreateCategory” whenever you create, save or publish a page. Then use a method to determinate if the pagetypeid of the page you are creating is a validpage (i.e you don’t want these pages to inherit categories) and then just give it a string.Emtpy as PageCategory value.  Whatever the situation, just make a method to check if you want the page to inherit the category or not, then use the code above.

Hope this helps

EPiServer.DataFactory.Instance.PublishingPage += Instance_SavingPage;
EPiServer.DataFactory.Instance.SavedPage += Instance_SavingPage;
EPiServer.DataFactory.Instance.SavingPage += Instance_SavingPage;
EPiServer.DataFactory.Instance.CreatingPage += Instance_SavingPage;

Okt 8 2009

HTML5 fix for Internet Explorer And Doctype fix for EPiServer solutions

HTML 5 introduces new elements to use such as <header> <section> <nav> and many more. The problem is that no version of Internet Explorer recognizes the new elements, but Firefox, chrome and many others does. The solution is easy but a bit boring when you think about it, since it’s about replacing all new elements to div instead. Which means that IE users won’t be able to appreciate HTML5 but users that use Firefox, Chrome and so on will.

Anyway, on with the solution! What you need to do is modify the writer and basically find all elements and change them with a div.  A good place to do it on is on your masterpage.

protected override void Render(HtmlTextWriter writer)
{
if(Request.Browser.Browser == "IE")
HTML5Replace(writer);
else
base.Render(writer);
}

private void HTML5Replace(HtmlTextWriter writer)
{
MemoryStream memoryStream = new MemoryStream();
StreamWriter streamWriter = new StreamWriter(memoryStream);
HtmlTextWriter memoryWriter = new HtmlTextWriter(streamWriter);
base.Render(memoryWriter);
memoryWriter.Flush();
memoryStream.Position = 0;
TextReader reader = new StreamReader(memoryStream);
string output = reader.ReadToEnd();
output = Regex.Replace(output, RegExStrings.HTML5_BLOCK_ELEMENTS , RegExStrings.HTML5_BLOCK_ELEMENTS_REPLACEMENT );
writer.Write(output);
}

But what REALLY does the magic is the RegEx, since it will find the elements for you and replace them correctly.

public const string HTML5_BLOCK_ELEMENTS = @"<(\/)?(nav|section|header|aside|footer)";
public const string HTML5_BLOCK_ELEMENTS_REPLACEMENT = @"<$1div";

The reason why I use $1 on the replacement string, is because I want to add a ”/” if there is one in the element I found. This to close the tag correctly. So basically, when it finds ”<nav” it will replace it with ”<div” and when it finds ”</nav” it will replace it with ”</div”. Closing tag and class/id names will still be there so the div can take on the behavior of the replaced element.

Another problem that you will run into, if you’re running your site with EPiServer that is, is that EPiServers friendlyurlrewriter doesn’t recognize the doctype and it will try to fix it for you. For HTML 5 you’ll need the following doctype  ”<!DOCTYPE html>” but EPiServer will change it to the following ”<!DOCTYPE HTML PUBLIC ”” ””>”. Mohsen Pirouzfar found a great solution for this which you can read here. It’s in swedish but the code itself is usable to anyone 🙂