Monday, January 26, 2015

how to get my Variation data

this is a little control i created to extract all the Variation data i usually need, in this case i write it to the browser since its more client based web, but you can as well put all that data anywhere else.

note that if SPContext is null so is the Variations.Current

protected override void Render(HtmlTextWriter writer)
{
   string iso3 = System.Threading.Thread.
                 CurrentThread.CurrentCulture.
                 ThreeLetterISOLanguageName;

   if (iso3 == "eng")
   {
       writer.Write("<link rel=\"Stylesheet\" href=\"/Style Library/CSS/EN.css\"/>");

   }
   string VariationRoot = string.Empty;
   string VariationRootServerRelativeUrl = string.Empty;

   if (SPContext.Current.FormContext.FormMode == SPControlMode.Display)
   {
       foreach (VariationLabel label in Variations.Current.UserAccessibleLabels)
       {
           if (label.IsSource == true)
           {
               VariationRoot = "/" + label.TopWebUrl.Split(new char[] { '/' }).Last();
               break;
           }
       }
   string[] relUrlFragments =
        SPContext.Current.Web.ServerRelativeUrl.Split(new char[] { '/' });

   if (relUrlFragments.Length == 2)
   {
       VariationRootServerRelativeUrl = VariationRoot;
   }
   else
   {
       relUrlFragments[1] = VariationRoot.Replace("/", "");
       VariationRootServerRelativeUrl = string.Join("/", relUrlFragments);
   }
    writer.Write("<script>Cbs.Web = {}; " +
       "Cbs.Web.ISO3 = \"" + iso3 + "\"; " +
       "Cbs.Web.ServerRelativeUrl = \"" +
           SPContext.Current.Web.ServerRelativeUrl + "\"; " +
       "Cbs.Web.VariationRoot = \"" + VariationRoot + "\"; " +
       "Cbs.Web.VariationRootServerRelativeUrl = \"" +
           VariationRootServerRelativeUrl + "\"; " +
       "</script>");
   }
   base.Render(writer);
}

Monday, January 19, 2015

angular ng-show with slide

if you just want the final solution jump to the end, or this final jsBin: http://jsbin.com/jukogewobo/5/.

NOW IN GITHUB https://github.com/bresleveloper/bNgSlide

a common case in web dev is the "Mega Menu", while you have a menu bar that should open under it another big menu.

for this tutorial all my examples are shown in JSBINs, each part has its own link.
the basic html I am using for part 1 looks like this:

    <li ng-repeat="level1 in data"
        ng-mouseenter="toggle($event, true)"
        ng-mouseleave="toggle($event, false)">   
         <div> //html </div>
    </li>
the "li" is the repeater and event fire, and in the "div" the content to show/hide.

part 1: simple logic (JSBIN)

in Example 1 we see the "simple" solution with show/hide, nothing much to tell, it works great.
   
$scope.toggle = function (e, toggle) {
    $(e.currentTarget).find("div")[toggle ? 'show' : 'hide']();
};

in Example 2, where we want to start using animation, runing with the mouse on top of the menu items start making an animation queue.

$(e.currentTarget).find("div")[toggle ? 'slideDown' : 'slideUp']();

so, you should say, use jQuery stop! and you're right!

Examples 3 and 4 shows the wrong and right way to use it, and the right way is to stop everything before we start the new slideDown, while sending (true, true), to clean queue and finish the last "slideUp"

$(e.currentTarget).closest('ul').find("div").stop(true, true);
$(e.currentTarget).find("div")[toggle ? 'slideDown' : 'slideUp']();

but truly all that is not really enough, we want the slide to happen when the user actually stops the mouse on our item.

there is a pretty famous jQuery plugin named hoverIntent, that actually does some setTimeout, so we'll implement something pretty close, only in the angular way using $timeout.

Examples 5 and 6 shows the wrong and right way to use it, and the right way is remember that only slideDown needs to be delayed, but the slideUp needs to be instant.

$timeout.cancel($scope.lastToggleDownTimeout);
if (toggle) {
    $scope.lastToggleDownTimeout = $timeout(function () {
        $(e.currentTarget).find("div").slideDown();
    }, 300);
}
else {
    $(e.currentTarget).find("div").slideUp();
}





part 2: using directives (JSBIN)

so all that is cool, but I guess anyone would like to wrap all that into a nice directive that will simulate ng-show, after all in a more common case we would use ng-show.

for part 2 our case study will be a little more realistic mega menu, so my new html is:

   <div class="outer" ng-mouseleave="data2 = {}">
      <ul>
         <li ng-repeat="level1 in data"
             ng-mouseenter="$root.data2 = level1">
            <a href="#">{{ level1.name }}</a>
         </li>
      </ul>
      <div class="inner" ng-show="data2.data">
         <ul>
            <li ng-repeat="level2 in data2.data">
               <a href="#">{{ level2 }}</a>
            </li>
         </ul>
      </div>
   </div>
lets take a look at Example 1, i hope you like the green BG :)

so lets start by making our own ngShow, i'll name it bresleveloper-show1, and similar to ng-show i'll just toggle a slide instead of a class, Example 2:

* for sake oh honesty, I evolved this http://jsfiddle.net/g/Bs66R/1/.
(http://stackoverflow.com/questions/14775751/angular-js-how-can-i-animate-on-model-change)

directive('bresleveloperShow1',function(){
    return {
        link: function (scope, element, attrs) {
            element.hide();
                scope.$watch(
                    attrs.bresleveloperShow1,
                    function (val, oldVal) {
                        element[val ? 'slideDown' : 'slideUp'](300);
                    });
        }
    };
})
 


looks good!

but sometime the client wants it to close and open for each one, lets try just moving the "mouseout" event from the container to the "li" element itself, as shown in Example 3, which causes us the same original problem of queue animations, and with now with the new html even the data doesn't sync.

<li ng-repeat="level1 in data"
    ng-mouseenter="$root.data3 = level1.data"
    ng-mouseleave="$root.data3 = []">

so the technique I learned from our friend is change the data in the scope in a $timeout with the same time of the animation, as shown in Example 4, with directive bresleveloper-show2 where I changed the $watch

clearTimeout(scope.timeout);
if (!val) {
    element.slideUp(300);
}
else {
    scope.timeout = setTimeout(function () {
        element.slideDown(300);
    }, 200);
}


yet there is still a problem, in the example I made if you could see it, the data is still not synced well with the slide, you can create glitches while the slideUp is running.

the simple solution in Example 5 is to change the data with the same timeout:

<li ng-repeat="level1 in data"
    ng-mouseenter="changeData5(level1.data)" 
    ng-mouseleave="changeData5([])">

$scope.changeData5 = function (data5) {
   $scope.data5ChangeTimeout = $timeout(function () {
      $scope.data5 = data5;
   }, 300);
};



part 3: final directive

so all that is good... but we all want 1 directive to rule them all!

my thinking is to move the changing data function to the directive and let is manage all the timings

this is my final result:

http://jsbin.com/jukogewobo/5/

there are now 3 attribures
bresleveloper-ng-show="scope function name"
b-time="300"
b-delay="100"
b-test="children"

bresleveloper-ng-show takes a scope function name, override it, and toggleSlide before and after execution

b-time is the time for the animation, if not stated is 300

b-delay is the time for the delay before firing the animation (hover intent), if not stated is same as b-time

b-test is for a case where you don't want the animation to occur, in case of a null array or reference, so it loops all the argument of the scope function above and if it does not have this member (i.e. if (!args[b-test])) the slideDown will not occur





Wednesday, January 7, 2015

איך אני רואה את הדברים

הפוסט הזה הוא בעקבות קריאה של הפוסט של ידידי רון קליין, שאמנם אני מכיר אותו מעט אך מעריך הרבה.
כולל הפוסט של עופר שאינני מכיר, וכולל הפוסט שלו כשהוא עבר לפייתון.
זה לא שאני מגיב לדבריהם, זה שדבריהם עוררו בי המון מחשבה, והנה היא.

על מה מדובר? הויכוח הישן נושן הם להמשיך MS או לעבור לקוד פתוח.

אני חושב שיש בגו יותר ממה שבד"כ אומרים, פתרונות טובים, שפה קלה, כסף לא כסף, עתיד לא עתיד.

אקדים ואומר שאני מרגיש שינוי בחודשים האחרונים, אני חושב שאני סוף סוף מתחיל להיות קצת SENIOR. אחרי 3 שנות עבודה בדוט נט, מתוכם שנתיים אחרונות בSHAREPOINT, כולל ANGULAR, ושאר דברים שמסביב, ולאחרונה הכשרתי INTERN אני מתחיל לראות את ההבדל, בראש, במחשבה, ביכולות. אני גם פתאום ממש מרגיש שאני חייב ללמוד שפות חדשות, הן כדי להרחיב את המחשבה, והן כדי להתרענן.

ובכן דבר ראשון ששמתי לב והוא רלוונטי לפה הוא שהרבה מאוד מתכנתים, ואולי זה אני אבל הייתי אומר הרוב, וזה כולל גם אנשי MS וגם אנשי קוד פתוח, פשוט לא בקטע להתפתח ולזוז. כלומר איך שאני רואה את זה המסה הגדולה של איפה אנשים נמצאים ומפתחים מתחיל מהסיבה האקראית ביותר - לאן הם התקבלו לעבודה הראשונה, שהרבה מזה מתחיל מה הם למדו לפנ"ז מסודר או לא.

אפשר לראות את זה בתחום הCLIENT יותר ברור - רוב הקורסים או הלימודים למיניהם מאוד מזניח את javascript, ואני מתכוון לרמה גבוהה של פיתוח APP שלם בJS, אפילו רק עם JQ. ומיד אתה רואה את ההבדל בחומר האנושי - יש תכנתים שדי מהר יקלטו שקיים knockout או angular או פשוט ילמדו טוב JQ , ויש כאלה שכל משימה שהיא יעשו בasp.net, כי זה מה שהם יודעים.

אז ממילא הפוסט הזה ואלו שלעיל מדברים על החלק השני, ואני לא מתבייש לקרא לו בשמו: הקצפת של התכנתים, אלו שזזים קדימה.

אז פעם גם אני הייתי מאלה שמודדים פיצר'ים ויכולות בדוט נט מול ג'אווה וPHP, ואכן יש לאמר שטכנית דוט נט 3.5 וכ"ש 4 ניצחו בהמון מובנים, ואת זה אני שומע מהתכנתים שלהם.

לעומת זאת העולם ממשיך להתחדש, יותר שומעים על פייתון ורובי, וזה כולל תשתיות של ממש, והדבר שהכי גורם לי לרצות ללמוד רובי זה שזו שפה שבראש של מי שיצר אותה היה לבנות שפה שיהיה כיף לתכנת בה, כלומר עדיין יש שפות אחרות של קוד פתוח שמשתוות לדוט נט החדש ואולי עוקפות אותו.

אבל גם פה תלוי מאוד לפי מי מסתכלים.
אני אתחיל מהדוגמאות של רון בעיות כגון c10k, אלו בעיות של ארכיטקטורה, לא של תכנת, אז כשעובדים בסטארט אפ ואתה אחראי על הכל כולל הכל, או שהפיתוח שלך תלוי בבעיה מסויימת ממוקדת כזו, אז מילא לפעמים הקוד הפתוח הוא העדפה ברורה.

ENTERPRISE? להם בד"כ לא משנה הדברים הללו, יותר מענין אותם אחריות. מקרה שהיה אצלנו שחברת ענק מסויימת קיבלה מאיתנו הצעה על CMS מסויים, והמנכ"ל הורה לשלם הרבה יותר בשביל SHAREPOINT כי זה MS, זה אחריות, זה SUPPORT, זה שם, לכן במקומות כאלו, וכן חברות פרוייקטים שרוצים להציע להם שרותים הבחירה הברורה זה MS.

בכללי, אני בכלל לא חושב שMS הולכים ליפול בעתיד הקרוב גם בתחום הWEB הרגיל, הם מוכיחים פעם אחרי פעם שהם יודעים להמתין לרגע הנכון, אמנם לדעת רבים זה הדקה ה92 אבל בכ"ז, לראות מה הולך ומה מצליח, ולתת מוצר מתחרה פשוט יותר טוב. אם זה בימי הגאווה שיצא דוט נט, אם זה בימינו שהCLIENT מתחזק והם משפרים את הIIS, אם זה שהם סוף סוף הוציאו MVC, ואפילו בSHAREPOINT יש אותו ב365, עם REST להכל.

ושימו לב, בתחום הקפיטליסטי מדובר בחברה אחת בלבד שמחזיקה בערך את השוק כולו מול כמה וכמה מתחרים, כלומר יש את c/c++ הרוחבי שיש לכולם ואז זה דוט נט מול גאווה PHP רובי פייתון ועוד ועוד וMS עדיין עומדים איתן, אז נכון שזה כולל שיווק אגרסיבי וכו' וכ"ש בישראל שהם ממש מחזיקים פה את השוק, אבל בכ"ז, הם יודעים מה הם עושים והם לא דועכים כלל וכלל.

אציין בתוך זה שאם יש מוצר אחד שהולך ויורד מהשוק, ואני ממש מקווה שהוא יכחד כבר זה IE, כולל כל הגרסאות.

אבל מה באמת נותן לי הקוד הפתוח?
ובכן מי שבאמת יוצא לו לשפר משמעותית דברים כאלו זה הקצפת של הקצפת, אני מדבר על סוג התכנתים שכותבים פלאגינים בלי MIN ואני עדיין לא מסוגל להבין מה הם עשו שם, כ"ש כשזה מהנדסים ממש והם כותבים מודולים ממש חזקים, אז בד"כ תכנתי WEB לא שם, והרבה פעמים גם מהנדסים טובים לא שם.

לעומת זאת אם יש משהו שאני ממש מבין אותו זה השליטה. מי שכתב קצת דברים מתקדמים בדוט נט כבר ראה שהרבה פעמים לא רק שהמוצר לא עושה את מה שהוא אמור לעשות, אלא הוא עצמו דופק את המערכת, מלא בבאגים, ומרובה הנזק על התועלת, ואו שאתה יכול לכתוב משהו משלך או שאתה נאלץ לעשות WORKAROUND. אז אני ממש מבין את מי שמעדיף מערכת שאתה יכול לשלוט בה במלואה.

גם חייבים לציין שהרבה לקוחות הקוד הפתוח נמצאים שם בגלל...הכסף, חד משמעי, כולל מקומות שעבדתי בהם.

סופו של יום בתור תכנת שלא נמצא בסטארט אפ וחייב משהו HIGHEND שיש רק בקוד פתוח מה שיותר רלוונטי בשבילו זה נעימות כתיבה, שהרבה מזה זה IDE, ומהירות פיתוח.

מה שבעצם לוקח אותי שוב לJS
יש היום כמה ספריות CLIENT חזקות, jquery הידועה ביותר, ובלי לעבור על כל מה שבדרך אני אגיע לאנגולר. ספריה שקשה ללמוד, אבל כשיודעים אני פתחתי משהו ב4 שעות במקום יומיים שהוקצו לי.
כנ"ל מה שייעדו לי לשבועיים אחרי יומיים אני בחצי דרך, אפליקציה של ממש.

אני באמת צריך כבר ללמוד פייתון ורובי דחוף, אבל JS הולך להשאר עוד הרבה מאוד זמן, ויותר אני חושב שבWEB שרת צריך להיות משהו שכולל בתוכו REST וDB, חוצ"מ הכל כולל הכל CLIENT, וע"ז לא ממש מדברים משום מה, פרט לכך שאנשים לפעמים חושבים שאנגולר זה קוד פתוח כי זה מסובסד ע"י גוגל, אלא שגוגל זה MS בריבוע...הם פשוט עושים את הכסף אחרת.

לסיכום, אין לי משהו בעד MS, אין לי ידע באחרים, יש לי בעד אנגולר בצורה מובהקת.