javascript on product page causes reload

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
3 years ago
I've added javascript to my product page to show a birthday card opening effect.
pressing a button to open the card causes the page to refresh.

I've included four files below.
- card.css
- card.js
- ProductTemplateCustom.Simple.cshtml
- _CardProductDetailsPictures.cshtml


--card.css
@import url(https://fonts.googleapis.com/css?family=Nobile:400italic,700italic);
@import url(https://fonts.googleapis.com/css?family=Dancing+Script);

* {
    box-sizing: border-box;
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
}

body {
    background: #fff;
    //background-image: url("/gray-floral.png");
    padding: 50px;
}

#card-front {
    //color: #FFDFDF;
}

#card, #card-front, #card-inside {
    height: 490px;
}

.wrap {
    padding: 1.5em 2.5em;
    height: 100%;
}

#card-front, #card-inside {
    width: 50%;
    -webkit-box-shadow: 2px 2px 30px rgba(0, 0, 0, .25), 0 0 1px rgba(0, 0, 0, .5);
    -moz-box-shadow: 2px 2px 30px rgba(0, 0, 0, .25), 0 0 1px rgba(0, 0, 0, .5);
    box-shadow: 2px 2px 30px rgba(0, 0, 0, .25), 0 0 1px rgba(0, 0, 0, .5);
    position: absolute;
    left: 50%;
}


    #card-inside .wrap {
        background: #FFEFEF;
        -webkit-box-shadow: inset 2px 0 1px rgba(0, 0, 0, .05);
        -moz-box-shadow: inset 2px 0 1px rgba(0, 0, 0, .05);
        box-shadow: inset 2px 0 1px rgba(0, 0, 0, .05);
    }

#card {
    max-width: 960px;
    width: 700px;
    margin: 0 auto;
    transform-style: preserve-3d;
    -moz-transform-style: preserve-3d;
    -webkit-transform-style: preserve-3d;
    perspective: 5000px;
    -moz-perspective: 5000px;
    -webkit-perspective: 5000px;
    position: relative;
}

    #card h1 {
        text-align: center;
        font-family: 'Nobile', sans-serif;
        font-style: italic;
        font-size: 70px;
        text-shadow: 4px 4px 0px rgba(0, 0, 0, .15), 1px 1px 0 rgba(255, 200, 200, 255), 2px 2px 0 rgba(255, 150, 150, 255), 3px 3px 0 rgba(255, 125, 125, 255);
        color: #FFF;
    }

#card-inside {
    font-size: 1.1em;
    line-height: 1.4;
    font-family: 'Nobile';
    color: #331717;
    font-style: italic;
}

p {
    margin-top: 1em;
}

    p:first-child {
        margin-top: 0;
    }

    p.signed {
        margin-top: 1.5em;
        text-align: center;
        font-family: 'Dancing Script', sans-serif;
        font-size: 1.5em;
    }

#card-front {
    background-color: #FF5555;
    //background-image: url("/images/cards/HappyBirthdayGumball.PNG");
    background-size: 350px;
    background-repeat: no-repeat;
    //background-image: linear-gradient(top, #FF5555 0%, #FF7777 100%);
    // background-image: -moz-linear-gradient(top, #FF5555 0%, #FF7777 100%);
    // background-image: -webkit-linear-gradient(top, #FF5555 0%, #FF7777 100%);
    transform-origin: left;
    -moz-transform-origin: left;
    -webkit-transform-origin: left;
    transition: transform 1s linear;
    -moz-transition: -moz-transform 1s linear;
    -webkit-transition: -webkit-transform 1s linear;
    position: relative;
}

    #card-front .wrap {
        transition: background 1s linear;
        -moz-transition: background 1s linear;
        -webkit-transition: background 1s linear;
    }

    #card-front button {
        position: absolute;
        bottom: 1em;
        right: -12px;
        background: #F44;
        color: #FFF;
        font-family: 'Nobile', sans-serif;
        font-style: italic;
        font-weight: bold;
        font-size: 1.5em;
        padding: .5em;
        border: none;
        cursor: pointer;
        box-shadow: 2px 2px 3px rgba(0, 0, 0, .25), 0 0 1px rgba(0, 0, 0, .4);
        -moz-box-shadow: 2px 2px 3px rgba(0, 0, 0, .25), 0 0 1px rgba(0, 0, 0, .4);
        -webkit-box-shadow: 2px 2px 3px rgba(0, 0, 0, .25), 0 0 1px rgba(0, 0, 0, .4);
    }

        #card-front button:hover,
        #card-front button:focus {
            background: #F22;
        }

#close {
    display: none;
}

#card.open-fully #close,
#card-open-half #close {
    display: inline;
}

#card.open-fully #open {
    display: none;
}


#card.open-half #card-front,
#card.close-half #card-front {
    transform: rotateY(-90deg);
    -moz-transform: rotateY(-90deg);
    -webkit-transform: rotateY(-90deg);
}

    #card.open-half #card-front .wrap {
        background-color: rgba(0, 0, 0, .5);
    }

#card.open-fully #card-front,
#card.close-half #card-front {
    background: #FFEFEF;
}

#card.open-fully #card-front {
    transform: rotateY(-180deg);
    -moz-transform: rotateY(-180deg);
    -webkit-transform: rotateY(-180deg);
}

    #card.open-fully #card-front .wrap {
        background-color: rgba(0, 0, 0, 0);
    }

        #card.open-fully #card-front .wrap *,
        #card.close-half #card-front .wrap * {
            display: none;
        }

footer {
    max-width: 500px;
    margin: 40px auto;
    font-family: 'Nobile', sans-serif;
    font-size: 14px;
    line-height: 1.6;
    color: #888;
    text-align: center;
}



--card.js
(function () {
    function $(id) {
        return document.getElementById(id);
    }

    var card = $('card'),
        openB = $('open'),
        closeB = $('close'),
        timer = null;
    //console.log('wat', card);
    debugger
    openB.addEventListener('click', function () {
        card.setAttribute('class', 'open-half');
        if (timer) clearTimeout(timer);
        timer = setTimeout(function () {
            card.setAttribute('class', 'open-fully');
            timer = null;
        }, 1000);
    });

    closeB.addEventListener('click', function () {
        card.setAttribute('class', 'close-half');
        if (timer) clearTimerout(timer);
        timer = setTimeout(function () {
            card.setAttribute('class', '');
            timer = null;
        }, 1000);
    });

}());



--ProductTemplateCustom.Simple.cshtml
@model ProductDetailsModel
@using Nop.Core.Domain.Seo;
@inject Nop.Core.IWebHelper webHelper
@inject SeoSettings seoSettings
@{
    Layout = "_ColumnsOne";

    //title
    Html.AddTitleParts(!string.IsNullOrEmpty(Model.MetaTitle) ? Model.MetaTitle : Model.Name);
    //meta
    Html.AddMetaDescriptionParts(Model.MetaDescription);
    Html.AddMetaKeywordParts(Model.MetaKeywords);
    //page class
    Html.AppendPageCssClassParts("html-product-details-page");

    //canonical URL
    if (seoSettings.CanonicalUrlsEnabled)
    {
        var productUrl = Url.RouteUrl("Product", new { SeName = Model.SeName }, webHelper.CurrentRequestProtocol).ToLowerInvariant();
        Html.AddCanonicalUrlParts(productUrl, seoSettings.QueryStringInCanonicalUrlsEnabled);
    }

    //open graph META tags
    if (seoSettings.OpenGraphMetaTags)
    {
        Html.AddHeadCustomParts("<meta property=\"og:type\" content=\"product\" />");
        Html.AddHeadCustomParts("<meta property=\"og:title\" content=\"" + Html.Encode(Model.Name) + "\" />");
        Html.AddHeadCustomParts("<meta property=\"og:description\" content=\"" + Html.Encode(Nop.Core.Html.HtmlHelper.StripTags(Model.MetaDescription)) + "\" />");
        Html.AddHeadCustomParts("<meta property=\"og:image\" content=\"" + Model.DefaultPictureModel.ImageUrl + "\" />");
        Html.AddHeadCustomParts("<meta property=\"og:image:url\" content=\"" + Model.DefaultPictureModel.ImageUrl + "\" />");
        Html.AddHeadCustomParts("<meta property=\"og:url\" content=\"" + webHelper.GetThisPageUrl(false) + "\" />");
        Html.AddHeadCustomParts("<meta property=\"og:site_name\" content=\"" + Html.Encode(Model.CurrentStoreName) + "\" />");
    }

    //Twitter META tags
    if (seoSettings.TwitterMetaTags)
    {
        Html.AddHeadCustomParts("<meta property=\"twitter:card\" content=\"summary\" />");
        Html.AddHeadCustomParts("<meta property=\"twitter:site\" content=\"" + Html.Encode(Model.CurrentStoreName) + "\" />");
        Html.AddHeadCustomParts("<meta property=\"twitter:title\" content=\"" + Html.Encode(Model.Name) + "\" />");
        Html.AddHeadCustomParts("<meta property=\"twitter:description\" content=\"" + Html.Encode(Nop.Core.Html.HtmlHelper.StripTags(Model.MetaDescription)) + "\" />");
        Html.AddHeadCustomParts("<meta property=\"twitter:image\" content=\"" + Model.DefaultPictureModel.ImageUrl + "\" />");
        Html.AddHeadCustomParts("<meta property=\"twitter:url\" content=\"" + webHelper.GetThisPageUrl(false) + "\" />");
    }
}
<!--product breadcrumb-->
@section Breadcrumb
{
    @await Html.PartialAsync("_ProductBreadcrumb", Model.Breadcrumb)
}
@await Component.InvokeAsync("Widget", new { widgetZone = PublicWidgetZones.ProductDetailsAfterBreadcrumb, additionalData = Model })
<div class="page product-details-page">
    <div class="page-body">
    
        <form asp-route="Product" asp-route-sename="@Model.SeName" method="post" id="product-details-form">
            @if (seoSettings.MicrodataEnabled)
            {
                @await Html.PartialAsync("_Microdata", Model)
            }
            <div data-productid="@Model.Id">
                <div class="product-essential">
                  
                    <!--product pictures-->
                    @await Html.PartialAsync("_CardProductDetailsPictures", Model)
                    <div class="overview">
                        @await Html.PartialAsync("_Discontinued", Model)
                        <div class=”product-name” style=”background-color:yellow;border: 1px solid red; border-radius: 12px; padding:10px;”>
                            <h1 itemprop=”name”>
                                @Model.Name
                              
                            </h1>
                        </div>
                      
                      
                        <!--attributes-->
                        
                        <!--gift card-->
                      
                      
                        <!--price & add to cart & estimate shipping-->
                        
                        <!--wishlist, compare, email a friend-->
                        <div class="overview-buttons">
                            
                        </div>
                        
                    </div>
                    @if (!string.IsNullOrEmpty(Model.FullDescription))
                    {
                        <div class="full-description">
                            @Html.Raw(Model.FullDescription)
                        </div>
                    }
                    
                </div>
              
                <div class="product-collateral">xxx
                  
                </div>
              
            </div>
        </form>
        
    </div>
</div>

-- _CardProductDetailsPictures.cshtml
@model ProductDetailsModel

    <div class="gallery" style="height:300px">
      
        
        @{
            Html.AddCssFileParts(ResourceLocation.Head, "~/css/card/card.css");
         }
        <br />
        <br />
        <br />
        <br />
        <div id="card">
            <div id="card-inside">
                <div class="wrap">
                    <p>
                        @Html.Raw(Model.ShortDescription)
                    </p>
                    <p>always.</p>
                    <p><a href="http://pandey47.0fees.us/index4.html">NEXT</a></p>
                    <p class="signed">ZEF</p>

                </div>
            </div>

            <div id="card-front" style=" background-image: url('@Model.DefaultPictureModel.ImageUrl')">
                <div class="wrap">

                </div>
                <button id="open">&gt;</button>
                <button id="close">&lt;</button>
            </div>
        </div>

      
    </div>

@{
    Html.AppendScriptParts(ResourceLocation.Footer, "~/js/card.js");
}
3 years ago
I'm guessing that your button is triggering the POST to the form, and the product controller doesn't know what to do with it so it sends it back to the view, which looks like a page refresh.  

Try passing in the js event to your open function and preventing the default action of the form (submit):


    openB.addEventListener('click', function (e) {
        e.preventDefault();
        card.setAttribute('class', 'open-half');
        if (timer) clearTimeout(timer);
        timer = setTimeout(function () {
            card.setAttribute('class', 'open-fully');
            timer = null;
        }, 1000);
    });
3 years ago
That worked! Thank you for your help :)
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.