1 2function showReviewDialog(element,event){ 3 4 console.log.call(console,"showReviewDialog",element,event); 5 6 if(event){ 7 8 event.preventDefault(); 9 event.stopPropagation(); 10 11 } 12 13 var container=element.parentNode; 14 15 // Make sure dialog closed if one already open 16 hideReviewDialog(); 17 18 // Get ratings for all products and company 19 var request=new XMLHttpRequest(); 20 request.open("get","https://shop.rerootedorganic.co.uk/api/website/reviews/?product="+container.id+"&t="+new Date().getTime(),true); 21 request.onload=function(){ 22 23 var result=JSON.parse(request.responseText); 24 if(result&&result.reviews){ 25 26 var reviews=result.reviews; 27 28 // Show dialog 29 var screen=document.body.appendChild(document.createElement("div")); 30 screen.className="review-dialog"; 31 screen.style.cssText="position:fixed; top:0px; left:0px; width:100%; height:100%; background-color:rgba(87,178,91,0.7); z-index:2147483647; display:table;"; 32 33 var cell=screen.appendChild(document.createElement("div")); 34 cell.style.cssText="display:table-cell; text-align:center; vertical-align:middle;"; 35 36 var dialog=cell.appendChild(document.createElement("div")); 37 dialog.style.cssText="position:relative; display:inline-block; width:100%; max-width:640px; background-color:#fff; border-radius:8px; box-sizing:border-box; padding:12px; text-align:left; box-shadow:0px 12px 24px 1px rgba(0,0,0,0.2);"; 38 39 // Close button 40 var button=dialog.appendChild(document.createElement("a")); 41 button.style.cssText="position:absolute; top:8px; right:8px; font-size:36px; line-height:36px; width:36px; text-align:center; display:inline-block; cursor:pointer; color:#716253; font-weight:400;"; 42 button.innerHTML="×"; 43 button.onclick=hideReviewDialog; 44 45 var heading=dialog.appendChild(document.createElement("h2")); 46 heading.innerText=result.name+" Reviews"; 47 heading.style.cssText="display:block; font-size:23px; text-transform:uppercase; line-height:1em; font-family:Montserrat,sans-serif; font-weight:900; color:#716253; margin:10px 12px 16px 12px;"; 48 49 var list=dialog.appendChild(document.createElement("div")); 50 list.style.cssText="overflow-y:auto; box-sizing:border-box; padding:0px 12px; max-height:75vh;"; 51 52 // Review button 53 var button=dialog.appendChild(document.createElement("button")); 54 button.className="fusion-button button-flat button-medium button-default button-4 fusion-button-default-span fusion-button-default-type"; 55 button.style.cssText="margin:16px 0px 4px 8px;"; 56 button.innerHTML='<span class="fusion-button-text">Leave a Review</span>'; 57 result.id=container.id; 58 button.onclick=showAddReviewDialog.bind(null,result); 59 60 // Loop reviews 61 for(var i=0;i<reviews.length;i++) 62 list.appendChild(createReviewElement(reviews[i])); 63 64 } 65 } 66 67 request.send(); 68 69} 70 71function formatTimespan(date){ 72 73 //console.log.call(console,"formatTimespan",date); 74 75 var seconds=Math.floor((new Date().getTime()-date.getTime())/1000); 76 var interval=seconds/31536000; 77 if(interval>1) 78 return (Math.floor(interval)+" years ago").replace(/^1 years/gi,"1 year"); 79 80 interval=seconds/2592000; 81 if(interval>1) 82 return (Math.floor(interval)+" months ago").replace(/^1 months/gi,"1 month"); 83 84 interval=seconds/86400; 85 if(interval>1) 86 return (Math.floor(interval)+" days ago").replace(/^1 days/gi,"1 day"); 87 88 interval=seconds/3600; 89 if(interval>1) 90 return (Math.floor(interval)+" hours ago").replace(/^1 hours/gi,"1 hour"); 91 92 interval=seconds/60; 93 if(interval>1) 94 return (Math.floor(interval)+" minutes ago").replace(/^1 minutes/gi,"1 minute"); 95 96 return (Math.floor(seconds)+" seconds ago").replace(/^(0|1) seconds/gi,"1 second"); 97 98} 99 100function createReviewElement(review){ 101 102 var element=document.createElement("div"); 103 element.style.cssText="border-top:1px solid #ddd; box-sizing:border-box; padding:16px 0px 16px 0px; margin:0px 12px 0px 0px; text-align:left;"; 104 105 // Create stars 106 var rating=review.rating; 107 var stars=element.appendChild(document.createElement("div")); 108 for(var i=0;i<5;i++){ 109 110 var star=stars.appendChild(document.createElement("span")); 111 star.className="far"; 112 star.innerHTML=""; 113 star.style.color="#ccc"; 114 star.style.fontSize="20px"; 115 116 if(rating>i){ 117 118 star.className="fa"; 119 star.style.color="#57b25b"; 120 star.style.fontWeight="bold"; 121 122 } 123 } 124 125 var details=element.appendChild(document.createElement("div")); 126 details.style.cssText="margin-top:12px;"; 127 128 var customer=details.appendChild(document.createElement("b")); 129 customer.style.cssText="font-weight:800;"; 130 customer.innerText=review.customer_name; 131
132 var timeStamp=details.appendChild(document.createElement("span")); 133 timeStamp.style.cssText=""; 134 timeStamp.innerText=" - "+formatTimespan(new Date(review.created)); 135 136 if(review.review){ 137 138 var text=element.appendChild(document.createElement("div")); 139 text.style.cssText="margin-top:3px; line-height:1.4em;"; 140 141 if(review.review.length>256){ 142 143 text.innerText=review.review.slice(0,256)+"... "; 144 var more=text.appendChild(document.createElement("a")); 145 more.href=""; 146 more.innerText="more"; 147 more.onclick=expandReviewText.bind(null,text,review.review); 148 149 } 150 else 151 text.innerText=review.review; 152 153 } 154 155 return element; 156 157} 158 159function expandReviewText(element,fullText,event){ 160 161 event.preventDefault(); 162 163 element.precisContent=element.innerHTML; 164 element.innerHTML=''; 165 element.innerText=fullText+" "; 166 167 var less=element.appendChild(document.createElement("a")); 168 less.href=""; 169 less.innerText="less"; 170 less.onclick=collapseReviewText.bind(null,element,fullText); 171 172} 173 174function collapseReviewText(element,fullText,event){ 175 176 event.preventDefault(); 177 178 element.innerHTML=element.precisContent; 179 element.querySelector("a[href]").onclick=expandReviewText.bind(null,element,fullText); 180 181} 182 183function hideReviewDialog(){ 184 185 var dialog=document.querySelector(".review-dialog"); 186 if(dialog){ 187 188 document.body.removeChild(dialog); 189 dialog=null; 190 191 } 192} 193 194function showAddReviewDialog(product){ 195 196 console.log.call(console,"showAddReviewDialog",product); 197 198 // Make sure dialog closed if one already open 199 hideReviewDialog(); 200 hideAddReviewDialog(); 201 202 // Show dialog 203 var screen=document.body.appendChild(document.createElement("div")); 204 screen.className="add-review-dialog"; 205 screen.style.cssText="position:fixed; top:0px; left:0px; width:100%; height:100%; background-color:rgba(87,178,91,0.7); z-index:2147483647; display:table;"; 206 207 var cell=screen.appendChild(document.createElement("div")); 208 cell.style.cssText="display:table-cell; text-align:center; vertical-align:middle;"; 209 210 var dialog=cell.appendChild(document.createElement("div")); 211 dialog.style.cssText="position:relative; display:inline-block; width:100%; max-width:640px; background-color:#fff; border-radius:8px; box-sizing:border-box; padding:12px; text-align:left; box-shadow:0px 12px 24px 1px rgba(0,0,0,0.2);"; 212 213 // Close button 214 var button=dialog.appendChild(document.createElement("a")); 215 button.style.cssText="position:absolute; top:8px; right:8px; font-size:36px; line-height:36px; width:36px; text-align:center; display:inline-block; cursor:pointer; color:#716253; font-weight:400;"; 216 button.innerHTML="×"; 217 button.onclick=hideAddReviewDialog; 218 219 var heading=dialog.appendChild(document.createElement("h2")); 220 heading.innerText="As a valued customer we'd love your feedback..."; 221 heading.style.cssText="display:block; font-size:23px; line-height:1em; font-family:Montserrat,sans-serif; font-weight:900; color:#716253; margin:10px 32px 16px 12px;"; 222 223 var scroller=dialog.appendChild(document.createElement("div")); 224 scroller.style.cssText="overflow-y:auto; box-sizing:border-box; padding:0px 12px; max-height:68vh;"; 225 226 var form=scroller.appendChild(document.createElement("form")); 227 form.style.cssText="margin:12px 0px 12px 0px;"; 228 form.onsubmit=submitRating.bind(null,product,form,dialog); 229 form.innerHTML='' 230 +'<style>' 231 +' .form .field{' 232 +' margin:24px 0px 24px 0px;' 233 +' max-width:480px;' 234 +' text-align:left;' 235 +' }' 236 +' .form .field:first-child{ margin-top:11px; }' 237 +' .form .field:last-child{ margin-bottom:22px; }' 238 +' .form .field label{' 239 +' display:block;' 240 +' margin:0px 0px 8px 0px;' 241 +' line-height:1.4em;' 242 +' }' 243 +' .form .field:focus-within label{ color:#57b25b; }' 244 +' .form .field input,.form .field textarea{' 245 +' box-sizing:border-box;' 246 +' width:100%;' 247 +' border:1px solid #c6c6c5;' 248 +' border-radius:6px;' 249 +' height:42px;' 250 +' padding:0px 12px 0px 12px;' 251 +' }' 252 +' .form .field input.error,.form .field textarea.error,.form .field select.error{ border-color:#f00000; }' 253 +' .form .field textarea{' 254 +' padding:11px 12px;' 255 +' resize:none;' 256 +' height:84px;' 257 +' }' 258 +' .form .field input:focus,.form .field textarea:focus,.form .field select:focus{ border:1.5px solid rgba(87,178,91,0.6); }' 259 +' .form .field.stars a{' 260 +' display:inline-block;' 261 +' color:#ccc;' 262 +' font-size:30px;' 263 +' margin-right:2px;' 264 +' cursor:pointer;'
265 +' }' 266 +' .form .field.stars .error a{ color:rgba(224,0,0,0.5); }' 267 +' .form .field.stars a:hover{' 268 +' text-decoration:none; ' 269 +' color:#57b25b;' 270 +' }' 271 +' .form .field.stars a.selected{' 272 +' font-weight:bold; ' 273 +' color:#57b25b;' 274 +' }' 275 +'</style>' 276 +' <div class="form">' 277 +' <div class="field stars">' 278 +' <label>Please rate our <span class="product-name">'+product.name+'</span></label>' 279 +' <input type="hidden" name="product_rating"/>' 280 +' <div>' 281 +' <a class="far" onclick="toggleStar(this.parentNode.parentNode,1,event)"></a>' 282 +' <a class="far" onclick="toggleStar(this.parentNode.parentNode,2,event)"></a>' 283 +' <a class="far" onclick="toggleStar(this.parentNode.parentNode,3,event)"></a>' 284 +' <a class="far" onclick="toggleStar(this.parentNode.parentNode,4,event)"></a>' 285 +' <a class="far" onclick="toggleStar(this.parentNode.parentNode,5,event)"></a>' 286 +' </div>' 287 +' </div>' 288 +' <div class="field">' 289 +' <label>Please leave a review of our <span class="product-name">'+product.name+'</span></label>' 290 +' <textarea name="product_review" maxlength="4000" autocomplete="off" onfocus="this.className=\'\';"></textarea>' 291 +' </div>' 292 +' <div class="field stars">' 293 +' <label>Please rate ReRooted as a company</label>' 294 +' <input type="hidden" name="company_rating"/>' 295 +' <div>' 296 +' <a class="far" onclick="toggleStar(this.parentNode.parentNode,1,event)"></a>' 297 +' <a class="far" onclick="toggleStar(this.parentNode.parentNode,2,event)"></a>' 298 +' <a class="far" onclick="toggleStar(this.parentNode.parentNode,3,event)"></a>' 299 +' <a class="far" onclick="toggleStar(this.parentNode.parentNode,4,event)"></a>' 300 +' <a class="far" onclick="toggleStar(this.parentNode.parentNode,5,event)"></a>' 301 +' </div>' 302 +' </div>' 303 +' <div class="field">' 304 +' <label>We\'re always looking for ways to improve. What do we do well? What can we do better?</label>' 305 +' <textarea name="company_review" maxlength="4000" autocomplete="off" onfocus="this.className=\'\';"></textarea>' 306 +' </div>' 307 +' <div class="field">' 308 +' <label>Your name</label>' 309 +' <input name="customer_name" maxlength="100" autocomplete="off" onfocus="this.className=\'\';"/>' 310 +' </div>' 311 +' </div>'; 312 313 // Review button 314 var button=dialog.appendChild(document.createElement("button")); 315 button.className="fusion-button button-flat button-medium button-default button-4 fusion-button-default-span fusion-button-default-type"; 316 button.style.cssText="margin:16px 0px 4px 8px;"; 317 button.innerHTML='<span class="fusion-button-text">Submit</span>'; 318 button.onclick=submitRating.bind(null,product,form,dialog); 319 320} 321 322function toggleStar(element,rating,event){ 323 324 console.log.call(console,"toggleStar",element,rating,event); 325 326 if(event){ 327 328 event.preventDefault(); 329 event.stopPropagation(); 330 331 } 332 333 element.querySelector("input").value=(rating>0)?rating:""; 334 335 var stars=element.querySelectorAll("a"); 336 for(var i=0;i<stars.length;i++) 337 stars[i].className=(i<rating)?"fa selected":"far"; 338 339 element.querySelector("div").className=""; 340 341} 342 343function submitRating(product,form,dialog,event){ 344 345 console.log.call(console,"submitRating",product,form,dialog,event); 346 347 if(event) 348 event.preventDefault(); 349 350 // Validate all fields contain a value 351 form.querySelectorAll(".field.stars > div")[0].className=(form.product_rating.value)?"":"error"; 352 form.querySelectorAll(".field.stars > div")[1].className=(form.company_review.value.trim()&&!form.company_rating.value)?"error":""; 353 form.product_review.className=(form.product_review.value.trim())?"":"error"; 354 form.customer_name.className=(form.customer_name.value.trim())?"":"error"; 355 form.company_review.className=""; 356 357 if(!form.querySelector(".error")){ 358 359 // Add rating on server 360 var request=new XMLHttpRequest(); 361 request.open("post","https://shop.rerootedorganic.co.uk/api/website/reviews/",true); 362 request.onload=function(){ 363 364 var result=JSON.parse(request.responseText); 365 if(result&&result.rated){ 366 367 // Show message
368 dialog.querySelector("h2").innerText="Thank you!"; 369 dialog.querySelector("form").innerHTML='Your review has been submitted.'; 370 dialog.querySelector("button").onclick=hideAddReviewDialog; 371 dialog.querySelector("button span").innerText="Close"; 372 373 374 } 375 } 376 377 request.send(JSON.stringify({ 378 "product_id":product.id, 379 "product_rating":form.product_rating.value, 380 "product_review":form.product_review.value.trim(), 381 "company_rating":form.company_rating.value, 382 "company_review":form.company_review.value.trim(), 383 "customer_name":form.customer_name.value.trim() 384 })); 385 386 } 387 388} 389 390function hideAddReviewDialog(){ 391 392 var dialog=document.querySelector(".add-review-dialog"); 393 if(dialog){ 394 395 document.body.removeChild(dialog); 396 dialog=null; 397 398 } 399}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.