@stratusjs/idx
Version:
AngularJS idx/property Service and Components bundle to be used as an add on to StratusJS
300 lines (276 loc) • 22.5 kB
HTML
<!-- TODO needs a close button for small resolutions -->
<div id="{{elementId}}" class="property-details property-details-classic" data-ng-cloak>
<div data-ng-if="model.pending" data-layout="row" data-layout-padding data-layout-margin data-layout-align="space-around center" data-layout-wrap>
<md-progress-circular md-mode="indeterminate"></md-progress-circular>
</div>
<div data-ng-if="model.completed && !model.pending && !model.data.ListingId && !model.data.ListingKey"
class="no-results"
data-layout="row" data-layout-padding data-layout-margin data-layout-align="space-around center" data-layout-wrap
>
This listing is no longer available
</div>
<div data-ng-if="model.completed && (model.data.ListingId || model.data.ListingKey)">
<div class="details-container" data-md-whiteframe="1">
<div class="details-header dotted-spaced-underline" data-layout="row" data-layout-align="space-between start" data-layout-wrap>
<div class="address-container" data-flex="100" data-flex-gt-xs="80">
<h3 class="address">
<!--span data-ng-bind="::model.data.UnparsedAddress"></span-->
<span data-ng-bind="::model.data.InternetAddressDisplayYN === false ? 'Address Not Disclosed' : getStreetAddress()"></span><!--Address not yet available-->
</h3>
<div class="address2" role="text">
<span data-ng-bind="::model.data.City | lowercase" aria-label="City"></span><span data-ng-if="::model.data.StateOrProvince">, <span data-ng-bind="::model.data.StateOrProvince" aria-label="State"></span></span>
<span data-ng-bind="::model.data.PostalCode" aria-label="Postal Code"></span>
<span data-ng-bind="::model.data.Country" aria-label="Country"></span>
</div>
</div>
<div class="contact-container" data-flex="100" data-flex-gt-xs="20" data-ng-show="::contactUrl || Idx.sharedValues.contactUrl">
<!-- TODO data-ng-click="return cms.obj.listtrac.track('lead');"-->
<!--a data-ng-href="/site/contact?comments={{::getFullAddress(true)}}" target="_blank">Contact</a-->
<md-button class="button" target="_blank" aria-label="Website Contact"
data-ng-href="{{::contactUrl || Idx.sharedValues.contactUrl}}{{(Idx.sharedValues.contactCommentVariable ? '?' + Idx.sharedValues.contactCommentVariable + '=' + getFullAddress(true) : '')}}"
>
Contact
</md-button>
</div>
</div>
<section class="open-house-section dotted-spaced-underline" data-ng-if="model.data.OpenHouses && model.data.OpenHouses.length" role="region" aria-label="Open Houses">
<h4 class="section-title">Open House</h4>
<div class="open-house-container dotted-spaced-sideline" role="list" aria-label="Open Houses">
<span class="description" data-ng-if="::model.data.OpenHouses[0].OpenHouseRemarks" data-ng-bind="::model.data.OpenHouses[0].OpenHouseRemarks"></span>
<div class="open-house" id="{{'open_house_' + openHouse.OpenHouseId}}" data-ng-repeat="openHouse in model.data.OpenHouses" role="listitem" aria-label="{{::(openHouse.OpenHouseStartTime | moment:{unix:false,format:'dddd MMM Do, h:mm a'})}}">
<time data-ng-bind="::openHouse.OpenHouseStartTime | moment:{unix:false,format:'dddd MMM Do, h:mm a'}" datetime="{{::openHouse.OpenHouseStartTime}}"></time>
<span data-ng-if="::openHouse.OpenHouseEndTime"> —
<time data-ng-bind="::openHouse.OpenHouseEndTime | moment:{unix:false,format:'h:mm a'}" datetime="{{::openHouse.OpenHouseEndTime}}"></time>
</span>
<!-- openHouse._unmapped.OpenHouseType && openHouse._unmapped.OpenHouseType === 'Virtual' -->
<span data-ng-if="::openHouse._unmapped.VirtualOpenHouseURL">
<a data-ng-href="{{::openHouse._unmapped.VirtualOpenHouseURL}}" target="_blank" data-ng-bind="::(openHouse._unmapped.VirtualOpenHouseURLLinkText || 'Virtual Open House')" aria-label="Open House Virtual Tour Link"></a>
</span>
<span data-ng-if="::openHouse.ShowingAgentFirstName">
with <span data-ng-bind="::openHouse.ShowingAgentFirstName"></span> <span data-ng-bind="::openHouse.ShowingAgentLastName"></span>
</span>
</div>
</div>
</section>
<div class="image-specs-container" data-layout="row" data-layout-align="space-between start" data-layout-wrap>
<div class="image-container" data-flex="100" data-flex-gt-xs="75">
<div class="price-banner" data-ng-if="::model.data.ClosePrice || model.data.ListPrice">
<div class="price-banner-corner" aria-hidden="true"></div>
<div class="list-price-container" role="text">
<span class="list-price-label" data-ng-bind="model.data.ClosePrice ? 'Sold for' : 'Listed at'"></span>
<span class="list-price" data-ng-bind="'$' + (model.data.ClosePrice || model.data.ListPrice | number)"></span>
</div>
</div>
<div class="details-image">
<img
data-stratus-src="{{model.data.Images[0].MediaURL ? model.data.Images[0].MediaURL : '/content/mls/images/no_photo_details.jpg'}}"
data-stratus-src-version="{{::(model.data.Images[0].Lazy == 'stratus-src' ? 'best' : 'false')}}"
alt="{{::model.data.UnparsedAddress}}"
aria-label="{{::model.data.Images[0].ShortDescription || model.data.Images[0].LongDescription || 'Main Image of the Listing'}}"
>
</div>
</div>
<section class="details-specs-container" data-flex="100" data-flex-gt-xs="20" role="region" aria-label="Detail Highlights">
<div class="details-specs">
<span role="text">Status: <span data-ng-bind="::Idx.getFullStatus(model.data, preferredStatus)"></span></span>
<span data-ng-if="::model.data.BedroomsTotal > 0" role="text"><br><span data-ng-bind="::model.data.BedroomsTotal"></span> Beds</span>
<span data-ng-if="::model.data.BathroomsFull > 0 || model.data.BathroomsTotalInteger > 0" role="text">
<br><span data-ng-bind="::model.data.BathroomsFull || model.data.BathroomsTotalInteger"></span> Baths
</span>
<span data-ng-if="::model.data.BathroomsHalf > 0" role="text">
<br><span data-ng-bind="::model.data.BathroomsHalf"></span> Half Baths
</span>
<span data-ng-if="::model.data.BathroomsOneQuarter > 0" role="text">
<br><span data-ng-bind="::model.data.BathroomsOneQuarter"></span> Quarter Baths
</span>
<span data-ng-if="::model.data.BathroomsThreeQuarter > 0" role="text">
<br><span data-ng-bind="::model.data.BathroomsThreeQuarter"></span> Three Quarter Baths
</span>
<span data-ng-if="::model.data.BathroomsPartial > 0" role="text">
<br><span data-ng-bind="::model.data.BathroomsPartial"></span> Partial Baths
</span>
<span data-ng-if="::model.data.CloseDate && Idx.getFriendlyStatus(model.data) == 'Closed'" role="text">
<br><span data-ng-bind="::Idx.getFriendlyStatus(model.data, preferredStatus)"></span> on
<time data-ng-bind="::model.data.CloseDate | moment:{unix:false,format:'MMM Do YYYY'}" datetime="{{::model.data.CloseDate}}"></time>
</span>
<span data-ng-if="::model.data.OnMarketDate" role="text">
<br>Listed on
<time data-ng-bind="::model.data.OnMarketDate | moment:{unix:false,format:'MMM Do YYYY'}" datetime="{{::model.data.OnMarketDate}}"></time>
</span>
<span data-ng-if="::model.data.CloseDate && model.data.ClosePrice && model.data.ListPrice" role="text">
<br>Listed at <span data-ng-bind="'$' + (model.data.ListPrice | number)"></span>
</span>
<span data-ng-if="::model.data.OnMarketDate && Idx.getFriendlyStatus(model.data) === 'Closed' && model.data.CloseDate">
<!-- Closed with start and end Dates. Give number of days between -->
<br>Days on Market:
<span data-ng-bind="::model.data.OnMarketDate | moment:{unix:false,diff:model.data.CloseDate,duration:'days'}"></span>
</span>
<span data-ng-if="::model.data.OnMarketDate && Idx.getFriendlyStatus(model.data) !== 'Closed'" role="text">
<!-- Not Closed Yet, Days since open -->
<br>Days on Market:
<span data-ng-bind="::model.data.OnMarketDate | moment:{unix:false,diff:true,duration:'days'}"></span>
</span>
<span data-ng-if="::model.data.DaysOnMarket && !model.data.OnMarketDate" role="text">
<!-- MLS provides DaysOnMarket, but we weren't given a Start time, use MLS provided times (may be inaccurate) -->
<br>Days on Market: <span data-ng-bind="::model.data.DaysOnMarket | number"></span>
</span>
<span data-ng-if="::model.data.ArchitecturalStyle" role="text">
<br>Style: <span data-ng-repeat="item in ::model.data.ArchitecturalStyle" class="repeatedArray"><span data-ng-bind="::item"></span><span class="hideLastChild">, </span></span>
</span>
<span data-ng-if="::model.data.YearBuilt" role="text">
<br>Built in <span data-ng-bind="::model.data.YearBuilt"></span>
</span>
<span data-ng-if="::model.data.LivingArea" role="text">
<br>Living Area:
<span data-ng-bind="::model.data.LivingArea | number"></span>
<span data-ng-if="::model.data.LivingAreaUnits">
<span data-ng-bind="::model.data.LivingAreaUnits"></span>
</span>
<span data-ng-if="::!model.data.LivingAreaUnits">
Square Feet
</span>
</span>
<span data-ng-if="::model.data.LeasableArea" role="text">
<br>Leasable:
<span data-ng-bind="::model.data.LeasableArea | number"></span>
<span data-ng-if="::model.data.LeasableAreaUnits">
<span data-ng-bind="::model.data.LeasableAreaUnits"></span>
</span>
<span data-ng-if="::!model.data.LeasableAreaUnits">
Square Feet
</span>
</span>
<span data-ng-if="::model.data.BuildingAreaTotal" role="text">
<br>Building:
<span data-ng-bind="::model.data.BuildingAreaTotal | number"></span>
<span data-ng-if="::model.data.BuildingAreaUnits">
<span data-ng-bind="::model.data.BuildingAreaUnits"></span>
</span>
<span data-ng-if="::!model.data.BuildingAreaUnits">
Square Feet
</span>
</span>
<span data-ng-if="::model.data.LotSizeArea" role="text">
<br>Lot: <span data-ng-bind="::model.data.LotSizeArea | number"></span>
<span data-ng-if="::model.data.LotSizeUnits">
<span data-ng-bind="::model.data.LotSizeUnits"></span>
</span>
<span data-ng-if="::!model.data.LotSizeUnits">
Square Feet
</span>
</span>
<span data-ng-if="!model.data.LotSizeArea && model.data.LotSizeAcres" role="text">
<br>Lot: <span data-ng-bind="::model.data.LotSizeAcres"></span> Acres
</span>
<span data-ng-if="!model.data.LotSizeArea && model.data.LotSizeSquareFeet" role="text">
<br>Lot: <span data-ng-bind="::model.data.LotSizeSquareFeet | number"></span> SqFt
</span>
<span data-ng-if="::model.data.PoolPrivateYN" role="text"><br>With Pool</span>
<span data-ng-if="::model.data.Stories" role="text"><br>Stories: <span data-ng-bind="::model.data.Stories"></span></span>
<!--{if !empty($data.standard.subdivision)}<br/>Subdivision: {$data.standard.subdivision}{/if}-->
<!--span data-ng-if="::model.data.PetsAllowed"><br>Pets Allowed:
<ul>
<li data-ng-repeat="pets in ::model.data.PetsAllowed" data-ng-bind="::pets"></li>
</ul>
</span-->
<!--{if !empty($data.standard.sale_type) && !empty($data.standard.sale_type && $data.standard.sale_type != "NONE")}<br/>Sale Condition: {$data.standard.sale_type}{/if}-->
<span data-ng-if="::model.data.PropertyType"><br><span data-ng-bind="::model.data.PropertyType"></span></span>
<span data-ng-if="::model.data.PropertySubType"><br><span data-ng-bind="::model.data.PropertySubType"></span></span>
</div>
<div class="links-container dotted-spaced-underline" data-ng-if="::model.data.VirtualTourURLUnbranded || model.data.VirtualTourURLBranded">
<div class="response-link vtour" data-ng-if="::model.data.VirtualTourURLUnbranded || model.data.VirtualTourURLBranded">
<a data-ng-href="{{::model.data.VirtualTourURLUnbranded || model.data.VirtualTourURLBranded}}" target="_blank" aria-label="Virtual Tour Link">Virtual Tour</a>
</div>
</div>
<div class="mls-service-container">
<div class="mls-service" data-ng-if="::model.data.ListingId || model.data.ListingKey" role="text">
<span data-ng-bind="getMLSName()" aria-label="Providing MLS"></span>#
<span data-ng-bind="::model.data.ListingId || model.data.ListingKey" aria-label="Property MLS Id or Number"></span>
</div>
</div>
</section>
</div>
<section class="listing-credit-container" data-layout="row" data-layout-xs="column" data-layout-align="space-around stretch" role="region" aria-label="Listing Credits">
<div class="presenting-agent-container" data-ng-if="::Idx.sharedValues.contact.name" data-flex data-layout="column" aria-label="Advertising Broker">
<h4 class="listing-credit-title">Presented By</h4>
<!--p class="listing-credit-contact">Realtor Name | Brokerage Name</p-->
<p class="listing-credit-contact" data-ng-bind="::Idx.sharedValues.contact.name"></p>
<p class="listing-credit-contact" data-ng-if="::Idx.sharedValues.contact.emails && Idx.sharedValues.contact.emails.Main" aria-label="Advertising Broker Contact">
<!--a href="mailto:email@address.com">email@address.com</a-->
<a data-ng-href="mailto:{{::Idx.sharedValues.contact.emails.Main}}" target="_blank" data-ng-bind="::Idx.sharedValues.contact.emails.Main"></a>
</p>
<p class="listing-credit-contact" data-ng-if="::(Idx.sharedValues.contact.phones && Idx.sharedValues.contact.phones.Main) && !(Idx.sharedValues.contact.emails && Idx.sharedValues.contact.emails.Main)">
<a data-ng-href="tel:{{::Idx.sharedValues.contact.phones.Main}}" data-ng-bind="::Idx.sharedValues.contact.phones.Main" aria-label="Advertising Broker Contact"></a>
</p>
</div>
<div class="listing-credit-divider" data-ng-if="getListAgentName() && Idx.sharedValues.contact.name" data-flex="10" data-hide-xs></div>
<div class="listing-agent-container" data-ng-if="getListAgentName()" data-flex data-layout="column" aria-label="Listing Broker">
<h4 class="listing-credit-title">Listing Agent</h4>
<p class="listing-credit-contact">
<span data-ng-bind="::getListAgentName()"></span> | <span data-ng-bind="::model.data.ListOfficeName"></span>
</p>
<p class="listing-credit-contact" data-ng-if="model.data.ListAgentEmail" aria-label="Listing Broker Contact">
<!--a href="mailto:email@address.com">email@address.com</a-->
<a data-ng-href="mailto:{{::model.data.ListAgentEmail}}" target="_blank" data-ng-bind="::model.data.ListAgentEmail"></a>
</p>
<p class="listing-credit-contact" data-ng-if="getListAgentPhone() && !model.data.ListAgentEmail">
<a data-ng-href="tel:{{::getListAgentPhone()}}" data-ng-bind="::getListAgentPhone()" aria-label="Listing Broker Contact"></a>
</p>
</div>
</section>
</div>
<section class="additional-photos details-container" role="region" aria-label="Image Slideshow" data-ng-if="model.data.Images && model.data.Images.length > 0" data-md-whiteframe="1">
<stratus-swiper-carousel
init-now="model.completed"
slides="images"
></stratus-swiper-carousel>
<!-- autoplay="true" -->
<!-- pagination='{"clickable":true,"render":"numberBullet"}' -->
</section>
<section class="additional-details details-container" role="region" aria-label="Additional Details" data-md-whiteframe="1">
<div class="description" data-ng-if="::model.data.PublicRemarks" data-ng-bind-html="::getPublicRemarksHTML()" aria-label="Description"></div>
<!-- TODO Missing quite a number of minor details -->
<!-- TODO Wishlist, would love to replace sections with Masonry ability https://passy.github.io/angular-masonry/ -->
<div class="detail-sections">
<stratus-idx-property-details-sub-section
ng-model="model"
data-ng-repeat="detail in ::minorDetails"
section-name="{{::detail.section}}"
items="{{::detail.items | json}}"
>
</stratus-idx-property-details-sub-section>
</div>
<section class="agent-section" role="region" aria-label="Source Agents">
<div class="agent dotted-spaced-underline underline-top" data-ng-if="getListAgentName()" role="text">
<strong>Listing Agent: </strong>
<span data-ng-bind="::getListAgentName()" aria-label="List Agent Name"></span><span data-ng-if="::model.data.ListAgentStateLicense"> (DRE# <span data-ng-bind="::model.data.ListAgentStateLicense" aria-label="List Agent State License"></span>)</span><span data-ng-if="::model.data.ListAgentKey && !model.data.ListAgentStateLicense"> (Agent #<span data-ng-bind="::model.data.ListAgentKey" aria-label="List Agent MLS Key"></span>)</span><span data-ng-if="::model.data.ListOfficeName">, <span data-ng-bind="::model.data.ListOfficeName" aria-label="List Office Name"></span></span>
</div>
<div class="agent dotted-spaced-underline underline-top" data-ng-if="getCoListAgentName()" role="text">
<strong>Co-Listing Agent: </strong>
<span data-ng-bind="::getCoListAgentName()" aria-label="CoList Agent Name"></span><span data-ng-if="::model.data.CoListAgentStateLicense"> (DRE# <span data-ng-bind="::model.data.CoListAgentStateLicense" aria-label="CoList Agent State License"></span>)</span><span data-ng-if="::model.data.CoListAgentKey && !model.data.CoListAgentStateLicense"> (Agent #<span data-ng-bind="::model.data.CoListAgentKey" aria-label="CoList Agent MLS Key"></span>)</span><span data-ng-if="::model.data.CoListOfficeName">, <span data-ng-bind="::model.data.CoListOfficeName" aria-label="CoList Office Name"></span></span>
</div>
<div class="agent dotted-spaced-underline underline-top" data-ng-if="getBuyerAgentName()" role="text">
<strong>Buyer Agent: </strong>
<span data-ng-bind="::getBuyerAgentName()" aria-label="Buyer Agent Name"></span><span data-ng-if="::model.data.BuyerAgentStateLicense"> (DRE# <span data-ng-bind="::model.data.BuyerAgentStateLicense" aria-label="Buyer Agent State License"></span>)</span><span data-ng-if="::model.data.BuyerAgentKey && !model.data.BuyerAgentStateLicense"> (Agent #<span data-ng-bind="::model.data.BuyerAgentKey" aria-label="Buyer Agent MLS Key"></span>)</span><span data-ng-if="::model.data.BuyerOfficeName">, <span data-ng-bind="::model.data.BuyerOfficeName" aria-label="Buyer Office Name"></span></span>
</div>
<div class="agent dotted-spaced-underline underline-top" data-ng-if="getCoBuyerAgentName()" role="text">
<strong>Co-Buyer Agent: </strong>
<span data-ng-bind="::getCoBuyerAgentName()" aria-label="CoBuyer Agent Name"></span><span data-ng-if="::model.data.CoBuyerAgentStateLicense"> (DRE# <span data-ng-bind="::model.data.CoBuyerAgentStateLicense" aria-label="CoBuyer Agent State License"></span>)</span><span data-ng-if="::model.data.CoBuyerAgentKey && !model.data.CoBuyerAgentStateLicense"> (Agent #<span data-ng-bind="::model.data.CoBuyerAgentKey" aria-label="CoBuyer Agent MLS Key"></span>)</span><span data-ng-if="::model.data.CoBuyerOfficeName">, <span data-ng-bind="::model.data.CoBuyerOfficeName" aria-label="CoBuyer Office Name"></span></span>
</div>
</section>
</section>
<div class="map-location details-container" data-md-whiteframe="1" data-ng-if="::getGoogleMapEmbed()" role="presentation" aria-label="Google Maps Display">
<iframe data-ng-src="{{::getGoogleMapEmbed()}}" class="google-map-embed"></iframe>
</div>
<!--div class="disclaimer details-container dotted-spaced-underline underline-top" data-ng-bind-html="::getMLSDisclaimer(true)"></div-->
<stratus-idx-disclaimer
class="details-container dotted-spaced-underline underline-top"
data-service="{{::options.service}}"
data-modification-timestamp="::model.data.ModificationTimestamp"
></stratus-idx-disclaimer>
</div>
<div data-ng-if="model.data.length == 0 || model.error" class="error details-container">
Sorry, the property you requested could not be found. Perhaps there was an error and trying again will solve the
problem.
</div>
</div>