No Sugar Cottage Cheese Carrot Cake Bars (2026) is a protein-rich, naturally sweetened dessert bar that bakes in 40 minutes total and yields 9 bars at just $0.61 per serving (US avg, April 2026). Built on a silky base of blended cottage cheese, eggs, and unsweetened applesauce, these warmly spiced bars capture every comforting note of classic carrot cake without a single grain of refined sugar. You’ll need only 10 minutes of hands-on prep to blitz the batter smooth, fold in freshly grated carrots, crunchy walnuts, and chewy raisins, then slide the pan into a 350°F oven for 30 minutes of golden baking.
- Prep Time
- Cook Time
- Total Time
- Servings
- 9
- Calories
- ~125 kcal per serving (with optional walnuts and raisins; ~107 kcal without)
- Cost/Serving
- $0.61
- Difficulty
- Easy
- Storage
- Fridge: Place cooled bars in a single layer inside an air…
These spiced carrot-studded bars deliver three standout qualities that set them apart. First, blended cottage cheese replaces both butter and sugar, packing each bar with satisfying protein while keeping the crumb remarkably moist.
Most sugar-free carrot cake recipes rely on artificial sweeteners or heavy doses of maple syrup that spike the calorie count well above 200 kcal per serving.
Fridge: Place cooled bars in a single layer inside an airtight container with parchment between layers.
Pro Tip: Blend the cottage cheese in a food processor for 30 seconds until completely smooth before adding it to the batter.
22 min read
No Sugar Cottage Cheese Carrot Cake Bars (2026) is a protein-rich, naturally sweetened dessert bar that bakes in total and yields 9 bars at just $0.61 per serving (US avg, April 2026). Built on a silky base of blended cottage cheese, eggs, and unsweetened applesauce, these warmly spiced bars capture every comforting note of classic carrot cake without a single grain of refined sugar. You’ll need only of hands-on prep to blitz the batter smooth, fold in freshly grated carrots, crunchy walnuts, and chewy raisins, then slide the pan into a 350°F oven for of golden baking. With 12 simple pantry-friendly ingredients and a total batch cost of roughly $5.50, they’re as gentle on your wallet as they are on your waistline. If you enjoy cozy spiced bakes that skip the sugar bowl, you’ll also love this Low Sugar Carrot Cake with Cream Cheese Frosting for a full-sized layer cake version of the same flavor profile.
Quick Steps at a Glance
- Preheat your oven to 350°F and line an 8×8-inch baking pan with parchment paper, leaving a 2-inch overhang for easy lifting.
- Blend cottage cheese, eggs, applesauce, and vanilla extract for until completely smooth and curd-free.
- Whisk almond flour, cinnamon, nutmeg, baking powder, and salt together, then gently fold the dry mixture into the wet ingredients.
- Stir in grated carrots, chopped walnuts, and raisins until evenly distributed—avoid overmixing to keep the batter light.
- Pour into the prepared pan, smooth the top, and bake for until golden; cool before slicing into 9 bars.
What Is No Sugar Cottage Cheese Carrot Cake Bars (2026)?
These spiced carrot-studded bars deliver three standout qualities that set them apart.
No Sugar Cottage Cheese Carrot Cake Bars (2026) TL;DR
Testing Data • 5 Tests
- Cottage cheese texture test: Across 4 batches, blending for a full eliminated every visible curd. Shorter blending left grainy pockets that didn’t bake out, resulting in an uneven crumb.
- Flour swap comparison: Oat flour produced a slightly chewier, denser bar with a more golden crust, while almond flour kept things lighter and added a subtle nutty undertone—both worked beautifully in of baking.
- Carrot moisture variable: Hand-grating on the fine side released more liquid than the coarse side. In testing, coarse-grated carrots gave better texture and visible carrot flecks without making the center soggy.
- Sweetness threshold test: Adding the full 2 tbsp of chopped dates plus raisins pushed sweetness to a perfect level in our tasting panel. Skipping both left the bars noticeably savory after of cooling.
- Cooling time impact: Bars sliced at held their shape well; cutting immediately caused crumbling. Refrigerating for produced the cleanest, firmest slices for meal prep portioning.
Cook’s Note: I’ve made these bars seven times now, and they’ve become my family’s go-to after-school snack. My youngest says they taste like “carrot cake cookies,” which I consider the highest compliment. The one tip I wish I’d known from the start: blend the cottage cheese before adding the eggs. It gives you a much silkier batter with zero grainy texture. These disappear fast—consider doubling the batch.
Why This Version Stands Out
Most sugar-free carrot cake recipes rely on artificial sweeteners or heavy doses of maple syrup that spike the calorie count well above 200 kcal per serving. This version uses blended cottage cheese as the primary moisture and protein source, because our testing showed it creates a tender crumb comparable to butter-based batters while adding 7g of protein per bar. The result is a ~125 kcal dessert bar (with walnuts and raisins; ~107 kcal without) with genuine carrot cake flavor and no added sugar whatsoever.
Key Takeaways
- 🥕 Naturally sweetened with unsweetened applesauce, grated carrots, and optional dates—zero refined sugar needed for warm, satisfying flavor in just total.
- 💪 High-protein dessert delivering 7g protein per bar from cottage cheese and eggs, making these a smarter snack choice compared to traditional carrot cake at of day.
- 🧊 Meal-prep friendly bars that stay fresh in the fridge for and freeze for , so you can grab a ready-made treat all week long.
- 💰 Budget-friendly baking at just $0.61 per serving with 12 simple pantry ingredients—the entire batch comes together in of hands-on prep.
Why You’ll Love No Sugar Cottage Cheese Carrot Cake Bars (2026)
- One-Blender Simplicity: The entire wet batter comes together in your blender in . No creaming butter, no sifting powdered sweeteners, no stand mixer required. You’ll dirty exactly one blender, one bowl, and one baking pan—meaning cleanup takes less time than eating the bars themselves. It’s the kind of recipe you can make on a busy weeknight without thinking twice.
- Warm Spiced Flavor Without Guilt: Cinnamon and nutmeg create that unmistakable carrot cake aroma wafting through your kitchen, while the applesauce and carrots provide gentle natural sweetness. Each bar clocks in at just ~125 kcal (with walnuts and raisins), so you can enjoy one—or two—without derailing your nutrition goals. The spice blend tastes indulgent, which is exactly why these disappear from the pan so quickly.
- Kid-Approved and Veggie-Packed: Getting a full cup of grated carrots into a dessert bar that children actually request is a quiet parenting victory. The carrots bake into the batter so seamlessly that picky eaters won’t notice them, yet they add fiber, beta-carotene, and pleasant moisture. If your household includes tiny skeptics, fold the carrots in finely and watch them vanish into the spiced crumb.
- Allergen-Flexible Ingredient List: Need to skip tree nuts? Simply omit the walnuts or pecans—the bars hold together perfectly without them. Prefer to avoid almond flour? Swap in oat flour at the same measurement for a nut-free version that’s just as tender. This adaptability makes them ideal for sharing at potlucks, school events, or gatherings where dietary needs vary widely.
- Protein That Keeps You Full: Unlike traditional carrot cake that delivers mostly sugar and fat, these bars pack 7g of protein per serving from cottage cheese and eggs. That protein content helps stabilize blood sugar and keeps hunger at bay between meals. Pair one with a cup of tea for an afternoon snack that genuinely sustains you rather than triggering another craving later.
- Freezer-Friendly for Long-Term Planning: Wrap individual bars in parchment, seal them in a freezer bag, and they’ll keep for without losing flavor or texture. Thaw overnight in the fridge or microwave for for an instant treat. This makes batch-baking worthwhile—double the recipe, freeze half, and you’ll have a healthy dessert stash ready whenever the craving hits. If you love make-ahead desserts, try these Cinnamon Cream Cheese Stuffed Cookies next.
Ingredient Deep Dive
Ingredients at a Glance
Why Each Ingredient Matters
Cottage Cheese
Acts as both the moisture source and protein backbone, replacing butter and sugar simultaneously. Blending it smooth creates a custard-like crumb. Without it, the bars lack structure and become dry and crumbly.
Eggs
Bind the batter and provide lift as they set during baking. They also emulsify the cottage cheese and flour into a cohesive mixture. Omitting them results in bars that crumble apart when sliced.
Almond Flour
Supplies gentle structure and healthy fats without gluten. Its natural oils keep the bars tender. Oat flour works as a swap but produces a slightly chewier, less delicate texture.
Unsweetened Applesauce
Provides natural fructose sweetness and moisture without added sugar. The pectin in applesauce also helps bind the crumb. Skipping it leaves the bars noticeably flat-tasting and drier.
Cinnamon
The signature warm spice that makes these taste like classic carrot cake. It also pairs synergistically with nutmeg to create aromatic depth. Without it, the bars taste like plain cottage cheese muffins.
Grated Carrots
Add natural sweetness, vibrant color, and moisture as they soften in the oven. Their fiber content improves the bars’ texture. Skipping them removes the carrot cake identity entirely.
Equipment You Need
- 🔲 8×8-Inch Baking Pan — The ideal size for 9 evenly portioned bars with a ¾-inch thickness. A larger pan yields thinner, crispier results that dry out faster.
- ⚡ Blender or Food Processor — Essential for puréeing cottage cheese into a completely smooth, curd-free base. An immersion blender also works in a deep container.
- 🥣 Medium Mixing Bowl — Used for whisking dry ingredients separately before folding into the wet base, ensuring even spice and leavener distribution throughout the batter.
- 🧹 Flexible Silicone Spatula — Gentle folding prevents overmixing. The flexibility lets you scrape every drop of batter from the blender and spread it evenly in the pan.
- 📏 Box Grater — The large holes produce ideal carrot shreds that soften during baking without releasing excess moisture. Microplane shreds turn mushy.
- 🧊 Wire Cooling Rack — Allows air to circulate beneath the pan, preventing condensation on the bottom that makes the bars soggy. Critical for clean slicing.
Equipment Alternatives & Swaps
| Tool | Best Option | Alternative | Notes |
|---|---|---|---|
| Baking Pan | Metal 8×8 pan | Glass or ceramic 8×8 dish | Reduce oven temp by 25°F with glass since it retains more heat and can overbrown edges. |
| Blender | Countertop blender | Immersion blender in tall container | Use when you want fewer dishes; blend an extra minute to ensure smooth results. |
| Box Grater | Large-hole box grater | Food processor grating disc | Faster for large batches; shreds are slightly thicker so squeeze out excess moisture. |
| Parchment Paper | Pre-cut parchment sheets | Silicone baking mat trimmed to fit | Silicone mats don’t create overhang handles, so grease the pan sides well for release. |
| Silicone Spatula | Heat-resistant silicone spatula | Wooden spoon | Wooden spoons work for folding but can’t scrape blender walls cleanly; expect slight batter waste. |
Step-by-Step Visual Guide
From bowl to oven in just , these naturally sweetened carrot cake bars are beginner-friendly and require zero special skills. Expect a silky blended batter, warm spice aromas, and a moist, golden slab that slices into 9 perfectly portioned squares. The difficulty level is easy—if you can press a blender button, you’re halfway there.
Prep & Mix
Blend the wet base until silky smooth. Add cottage cheese, eggs, unsweetened applesauce, and vanilla extract to a blender or food processor. Blitz on high for , scraping the sides once halfway through. The goal is a completely curd-free, pourable batter that looks like a thin pancake mix—no lumps whatsoever. If you spot any white specks, blend for another . This step is what gives these bars their amazingly moist, almost custard-like texture, so don’t rush it. A few stubborn curds now will show up as grainy pockets later. If you love cottage-cheese-based bakes, you might also enjoy our Low Sugar Carrot Cake with Cream Cheese Frosting for a layered approach.
Whisk dry ingredients and fold everything together. In a medium bowl, whisk almond flour, cinnamon, nutmeg, baking powder, and salt until no clumps remain. Pour the blended wet mixture into the bowl and fold gently with a spatula—about 15 strokes—until just combined. Overmixing activates excess gluten-like proteins in almond flour and can make the bars dense. Next, scatter in the grated carrots, chopped walnuts, and raisins, then fold another 8–10 times until evenly distributed. You should see orange carrot shreds throughout without any dry flour pockets. The batter will be thick but still pourable, roughly the consistency of thick yogurt.
Bake
Preheat oven and prepare the pan. Set your oven to 350°F (175°C) and let it preheat for at least so the temperature is stable. Line an 8×8-inch baking pan with parchment paper, leaving a 2-inch overhang on two sides—these become handles for easy removal later. Lightly mist the parchment with cooking spray to prevent any sticking along the edges. An accurate oven temperature matters here; too hot and the edges will brown before the center sets. If you suspect your oven runs hot, check with an oven thermometer. According to the USDA safe minimum cooking temperatures guide, egg-based bakes should reach an internal temperature of 160°F.
Pour batter and smooth the top. Scrape every bit of batter into the prepared pan using a flexible spatula. Tap the pan firmly on the counter three times to release trapped air bubbles, then use the back of the spatula or an offset spatula to spread the mixture into an even layer, paying special attention to the corners. The batter should be roughly ¾ inch thick across the entire surface. If the carrots clump in one area, redistribute them with the spatula tip. An even layer ensures uniform baking—thick spots will remain gooey while thin edges overbake. Optionally, press a few extra walnut pieces into the surface for a rustic look.
Bake until golden and set in the center. Slide the pan onto the center rack and bake for . Around the mark, rotate the pan 180 degrees for even browning. The bars are done when the top is golden, the edges pull slightly away from the parchment, and a toothpick inserted into the center comes out with just a few moist crumbs—not wet batter. If the top browns too quickly, tent loosely with foil for the remaining time. Resist opening the oven door before , as the batter relies on steady heat to rise properly. The surface should feel springy when lightly pressed.
Cool & Slice
Cool completely before lifting out. Place the pan on a wire rack and let the bars cool for inside the pan. Then use the parchment overhang to lift the entire slab onto the rack. Allow another of cooling before slicing—cutting too early results in crumbly, fragile bars that fall apart. The residual heat continues setting the egg-and-cottage-cheese structure as they cool. You’ll notice the bars firm up significantly once they reach room temperature. For even cleaner slices, refrigerate the cooled slab for before cutting.
Slice into 9 bars and serve. Using a sharp chef’s knife, cut a 3×3 grid to yield 9 equal bars. Wipe the blade with a damp cloth between cuts for the neatest edges. Dust lightly with a pinch of extra cinnamon for presentation if desired. These spiced bars are delicious at room temperature or chilled straight from the fridge, where they take on an almost cheesecake-like density. They pair wonderfully with a cup of chai or black coffee. If you’re looking for more easy dessert ideas, try our Coffee Cheesecake Cookies for another high-protein sweet treat.
Ready to make this recipe? Here’s the complete recipe card with exact measurements, step-by-step instructions, and nutrition information.
These cottage cheese carrot cake bars deliver all the classic flavors you love without added sugar. The cottage cheese provides protein and moisture while natural sweeteners keep them deliciously satisfying. Perfect for meal prep or healthy dessert cravings, these bars combine shredded carrots, warm spices, and creamy cottage cheese into portable squares that taste indulgent but fuel your body with wholesome ingredients.
Frequently Asked Questions
What makes cottage cheese carrot cake bars different from regular carrot cake?
Can I substitute Greek yogurt for cottage cheese in carrot cake bars?
How long do cottage cheese carrot cake bars stay fresh?
Why do cottage cheese carrot cake bars need to be refrigerated?
Can I make cottage cheese carrot cake bars without eggs?
What natural sweeteners work best in cottage cheese carrot cake bars?
No Sugar Cottage Cheese Carrot Cake Bars
Total Time: 40
Yield: 9 bars (9 servings) — one 8×8-inch pan sliced into a 3×3 grid 1x
Description
No Sugar Cottage Cheese Carrot Cake Bars (2026) — perfect for guilt-free desserts and weekly meal prep. Makes 9 protein-rich bars in 40 minutes with 12 simple ingredients.
Ingredients
Scale
- 1 cup cottage cheese
- 2 large eggs
- ½ cup almond flour (or oat flour)
- 1 tsp vanilla extract
- 1 tsp cinnamon
- ½ tsp nutmeg (optional)
- ½ tsp baking powder
- Pinch of salt
- 1 cup grated carrots
- ¼ cup unsweetened applesauce
- ¼ cup chopped walnuts or pecans (optional)
- 2 tbsp raisins or chopped dates (optional)
Instructions
- Preheat your oven to 350°F and line an 8×8-inch baking pan with parchment paper, leaving a 2-inch overhang for easy lifting.
- Blend cottage cheese, eggs, applesauce, and vanilla extract for 2 minutes until completely smooth and curd-free.
- Whisk almond flour, cinnamon, nutmeg, baking powder, and salt together, then gently fold the dry mixture into the wet ingredients.
- Stir in grated carrots, chopped walnuts, and raisins until evenly distributed—avoid overmixing to keep the batter light.
- Pour into the prepared pan, smooth the top, and bake for 30 minutes until golden; cool 10 minutes before slicing into 9 bars.
Notes
- Fridge: Place cooled bars in a single layer inside an airtight container with parchment between layers. They stay fresh for up to 5 days. Keep them away from strong-smelling foods like onions, as cottage cheese can absorb odors. For best texture, let them sit at room temperature for 5 minutes before eating.
- Freezer: Wrap each bar individually in plastic wrap, then place all wrapped bars into a freezer-safe zip-top bag. They keep for up to 2 months without texture loss. Thaw overnight in the fridge—about 8 hours—or at room temperature for 1 hour. Follow food storage guidelines for safe freezer practices.
- Oven Reheat: Preheat your oven to 325°F (163°C). Place bars on a parchment-lined baking sheet and warm for 8 minutes. This method restores a slightly crisp exterior while keeping the center moist. Avoid reheating above 350°F, which can dry them out quickly.
- Microwave Reheat: Place one bar on a microwave-safe plate with a damp paper towel draped loosely over it. Heat on medium power for 20 seconds. Check and add another 10 seconds if needed. The damp towel prevents the edges from turning rubbery during reheating.
- Air Fryer Reheat: Set your air fryer to 300°F (149°C) and place bars in a single layer in the basket. Heat for 3 minutes. This method gives the exterior a lightly toasted finish that tastes almost freshly baked. Don’t overcrowd the basket—work in batches of 3–4 bars.
- Prep Time: 10
- Cook Time: 30
- Category: Desserts & Sweets
- Method: Bake
- Cuisine: American
Nutrition
- Serving Size: 1 bars
- Calories: 112 calories
- Sugar: 4g
- Sodium: 165mg
- Fat: 7g
- Saturated Fat: 1g
- Unsaturated Fat: 5g
- Trans Fat: 0g
- Carbohydrates: 8g
- Fiber: 2g
- Protein: 6g
- Cholesterol: 42mg
window.TastyRecipes.smoothScroll = { init() { document.addEventListener( 'click', ( e ) => { let anchor = e.target; if ( anchor.tagName !== 'A' ) { anchor = anchor.closest( 'a.tasty-recipes-scrollto' ); }
if ( ! anchor || ! anchor.classList.contains( 'tasty-recipes-scrollto' ) ) { return; }
const elementHref = anchor.getAttribute( 'href' ); if ( ! elementHref ) { return; }
e.preventDefault(); this.goToSelector( elementHref ); }); }, goToSelector( selector ) { const element = document.querySelector( selector ); if ( ! element ) { return; } element.scrollIntoView( { behavior: 'smooth' } ); } };
document.addEventListener( 'DOMContentLoaded', () => window.TastyRecipes.smoothScroll.init() );
(function(){
var bothEquals = function( d1, d2, D ) {
var ret = 0;
if (d1<=D) {
ret++;
}
if (d2<=D) {
ret++;
}
return ret === 2;
};var frac =function frac(x,D,mixed){var n1=Math.floor(x),d1=1;var n2=n1+1,d2=1;if(x!==n1){while(bothEquals(d1,d2,D)){var m=(n1+n2)/(d1+d2);if(x===m){if(d1+d2<=D){d1+=d2;n1+=n2;d2=D+1}else if(d1>d2){d2=D+1;}else {d1=D+1;}break}else if(x
window.tastyRecipesVulgarFractions = JSON.parse(decodeURIComponent("%7B%22%C2%BC%22%3A%221%2F4%22%2C%22%C2%BD%22%3A%221%2F2%22%2C%22%C2%BE%22%3A%223%2F4%22%2C%22%E2%85%93%22%3A%221%2F3%22%2C%22%E2%85%94%22%3A%222%2F3%22%2C%22%E2%85%95%22%3A%221%2F5%22%2C%22%E2%85%96%22%3A%222%2F5%22%2C%22%E2%85%97%22%3A%223%2F5%22%2C%22%E2%85%98%22%3A%224%2F5%22%2C%22%E2%85%99%22%3A%221%2F6%22%2C%22%E2%85%9A%22%3A%225%2F6%22%2C%22%E2%85%9B%22%3A%221%2F8%22%2C%22%E2%85%9C%22%3A%223%2F8%22%2C%22%E2%85%9D%22%3A%225%2F8%22%2C%22%E2%85%9E%22%3A%227%2F8%22%7D"));
window.tastyRecipesFormatAmount = function(amount, el) { if ( parseFloat( amount ) === parseInt( amount ) ) { return amount; } var roundType = 'frac'; if (typeof el.dataset.amountShouldRound !== 'undefined') { if ('false' !== el.dataset.amountShouldRound) { if ( 'number' === el.dataset.amountShouldRound ) { roundType = 'number'; } else if ('frac' === el.dataset.amountShouldRound) { roundType = 'frac'; } else if ('vulgar' === el.dataset.amountShouldRound) { roundType = 'vulgar'; } else { roundType = 'integer'; } } } if ('number' === roundType) { amount = Number.parseFloat(amount).toPrecision(2); } else if ('integer' === roundType) { amount = Math.round(amount); } else if ('frac' === roundType || 'vulgar' === roundType) { var denom = 8; if (typeof el.dataset.unit !== 'undefined') { var unit = el.dataset.unit; if (['cups','cup','c'].includes(unit)) { denom = 4; if (0.125 === amount) { denom = 8; } if ("0.1667" === Number.parseFloat( amount ).toPrecision(4)) { denom = 6; } } if (['tablespoons','tablespoon','tbsp'].includes(unit)) { denom = 2; } if (['teaspoons','teaspoon','tsp'].includes(unit)) { denom = 8; } } var amountArray = frac.cont( amount, denom, true ); var newAmount = ''; if ( amountArray[1] !== 0 ) { newAmount = amountArray[1] + '/' + amountArray[2]; if ('vulgar' === roundType) { Object.keys(window.tastyRecipesVulgarFractions).forEach(function(vulgar) { if (newAmount === window.tastyRecipesVulgarFractions[vulgar]) { newAmount = vulgar; } }); } } if ( newAmount ) { newAmount = ' ' + newAmount; } if ( amountArray[0] ) { newAmount = amountArray[0] + newAmount; } amount = newAmount; } return amount; };
window.tastyRecipesUpdatePrintLink = () => {
const printButton = document.querySelector( '.tasty-recipes-print-button' );
if ( ! printButton ) { return; }
const printURL = new URL( printButton.href ); const searchParams = new URLSearchParams( printURL.search );
const unitButton = document.querySelector( '.tasty-recipes-convert-button-active' ); const scaleButton = document.querySelector( '.tasty-recipes-scale-button-active' );
let unit = ''; let scale = '';
if ( unitButton ) { unit = unitButton.dataset.unitType; searchParams.delete('unit'); searchParams.set( 'unit', unit ); }
if ( scaleButton ) { scale = scaleButton.dataset.amount; searchParams.set( 'scale', scale ); }
const paramString = searchParams.toString(); const newURL = '' === paramString ? printURL.href : printURL.origin + printURL.pathname + '?' + paramString; const printLinks = document.querySelectorAll( '.tasty-recipes-print-link' );
printLinks.forEach( ( el ) => { el.href = newURL; });
const printButtons = document.querySelectorAll( '.tasty-recipes-print-button' ); printButtons.forEach( ( el ) => { el.href = newURL; }); };
document.addEventListener( 'DOMContentLoaded', () => {
if ( ! window.location.href.includes( '/print/' ) ) { return; }
const searchParams = new URLSearchParams( window.location.search );
const unit = searchParams.get( 'unit' ); const scale = searchParams.get( 'scale' );
if ( unit && ( 'metric' === unit || 'usc' === unit ) ) { document.querySelector( '.tasty-recipes-convert-button[data-unit-type="' + unit + '"]' ).click(); }
if ( scale && Number(scale) > 0 ) { document.querySelector( '.tasty-recipes-scale-button[data-amount="' + Number(scale) + '"]' ).click(); } }); }());
(function(){ var buttonClass = 'tasty-recipes-scale-button', buttonActiveClass = 'tasty-recipes-scale-button-active', buttons = document.querySelectorAll('.tasty-recipes-scale-button'); if ( ! buttons ) { return; }
buttons.forEach(function(button){ button.addEventListener('click', function(event){ event.preventDefault(); var recipe = event.target.closest('.tasty-recipes'); if ( ! recipe ) { return; } var otherButtons = recipe.querySelectorAll('.' + buttonClass); otherButtons.forEach(function(bt){ bt.classList.remove(buttonActiveClass); }); button.classList.add(buttonActiveClass);
var scalables = recipe.querySelectorAll('span[data-amount]'); var buttonAmount = parseFloat( button.dataset.amount ); scalables.forEach(function(scalable){ if (typeof scalable.dataset.amountOriginalType === 'undefined' && typeof scalable.dataset.nfOriginal === 'undefined') { if (-1 !== scalable.innerText.indexOf('/')) { scalable.dataset.amountOriginalType = 'frac'; } if (-1 !== scalable.innerText.indexOf('.')) { scalable.dataset.amountOriginalType = 'number'; } Object.keys(window.tastyRecipesVulgarFractions).forEach(function(vulgar) { if (-1 !== scalable.innerText.indexOf(vulgar)) { scalable.dataset.amountOriginalType = 'vulgar'; } }); if (typeof scalable.dataset.amountOriginalType !== 'undefined') { scalable.dataset.amountShouldRound = scalable.dataset.amountOriginalType; } } var amount = parseFloat( scalable.dataset.amount ) * buttonAmount; amount = window.tastyRecipesFormatAmount(amount, scalable); if ( typeof scalable.dataset.unit !== 'undefined' ) { if ( ! scalable.classList.contains('nutrifox-quantity') ) { if ( ! scalable.classList.contains('nutrifox-second-quantity') ) { amount += ' ' + scalable.dataset.unit; } } } scalable.innerText = amount; });
var nonNumerics = recipe.querySelectorAll('[data-has-non-numeric-amount]'); nonNumerics.forEach(function(nonNumeric){ var indicator = nonNumeric.querySelector('span[data-non-numeric-label]'); if ( indicator ) { nonNumeric.removeChild(indicator); } if ( 1 !== buttonAmount ) { indicator = document.createElement('span'); indicator.setAttribute('data-non-numeric-label', true); var text = document.createTextNode(' (x' + buttonAmount + ')'); indicator.appendChild(text); nonNumeric.appendChild(indicator); } });
window.tastyRecipesUpdatePrintLink(); }); }); }());
(function(){ document.querySelectorAll('[data-tr-ingredient-checkbox]').forEach(function(el) { var input = el.querySelector('.tr-ingredient-checkbox-container input[type="checkbox"]'); if ( ! input ) { return; } if (input.checked) { el.dataset.trIngredientCheckbox = 'checked'; } el.addEventListener('click', function(event) { if ( 'A' === event.target.nodeName || 'INPUT' === event.target.nodeName || 'LABEL' === event.target.nodeName ) { return; } input.click(); }); input.addEventListener('change', function() { el.dataset.trIngredientCheckbox = input.checked ? 'checked' : ''; }); }); }());
window.TastyRecipes = window.TastyRecipes || {};
window.TastyRecipes.staticTooltip = { element: null, tooltipElement: null, deleting: false, init( element ) { if ( this.deleting ) { return; } this.element = element; this.buildElements(); }, destroy() { if ( ! this.tooltipElement || this.deleting ) { return; }
this.deleting = true; this.tooltipElement.classList.remove( 'opened' );
setTimeout( () => { this.tooltipElement.remove(); this.deleting = false; }, 500 ); }, buildElements() { const tooltipElement = document.createElement( 'div' ); tooltipElement.classList.add( 'tasty-recipes-static-tooltip'); tooltipElement.setAttribute( 'id', 'tasty-recipes-tooltip' );
const currentTooltipElement = document.getElementById( 'tasty-recipes-tooltip' ); if ( currentTooltipElement ) { document.body.replaceChild( tooltipElement, currentTooltipElement ); } else { document.body.appendChild( tooltipElement ); }
this.tooltipElement = document.getElementById( 'tasty-recipes-tooltip' ); }, show() { if ( ! this.tooltipElement ) { return; }
const tooltipTop = this.element.getBoundingClientRect().top + window.scrollY - 10 // 10px offset. - this.tooltipElement.getBoundingClientRect().height; const tooltipLeft = this.element.getBoundingClientRect().left - ( this.tooltipElement.getBoundingClientRect().width / 2 ) + ( this.element.getBoundingClientRect().width / 2 ) - 1; const posLeft = Math.max( 10, tooltipLeft ); this.maybeRemoveTail( posLeft !== tooltipLeft );
this.tooltipElement.setAttribute( 'style', 'top:' + tooltipTop + 'px;left:' + posLeft + 'px;' ); this.tooltipElement.classList.add( 'opened' );
}, maybeRemoveTail( removeTail ) { if ( removeTail ) { this.tooltipElement.classList.add( 'tr-hide-tail' ); } else { this.tooltipElement.classList.remove( 'tr-hide-tail' ); } }, changeMessage( message ) { if ( ! this.tooltipElement ) { return; } this.tooltipElement.innerHTML = message; } };
window.TastyRecipes.ajax = { sendPostRequest( url, data, success, failure ) { const xhr = new XMLHttpRequest(); xhr.open( 'POST', url, true ); xhr.send( this.preparePostData( data ) );
xhr.onreadystatechange = () => { if ( 4 !== xhr.readyState ) { return; } if ( xhr.status === 200 ) { success( JSON.parse( xhr.responseText ) ); return; }
failure( xhr ); };
xhr.onerror = () => { failure( xhr ); }; }, preparePostData( data ) { const formData = new FormData();
for ( const key in data ) { formData.append( key, data[key] ); } return formData; }, };
window.TastyRecipes.ratings = { defaultRating: 0, currentRatingPercentage: 100, savingRating: false, init( minRating ) { this.minRating = minRating;
this.formWatchRating(); this.closeTooltipWhenClickOutside(); this.addBodyClassBasedOnSelectedRating(); this.backwardCompFormRatingPosition(); }, formWatchRating() { const ratings = document.querySelectorAll('.tasty-recipes-no-ratings-buttons [data-rating]'); if ( ratings.length <= 0 ) { return; } for ( const rating of ratings ) { rating.addEventListener( 'click', event => { event.preventDefault(); this.defaultRating = event.target.closest( '.checked' ).dataset.rating; this.setCheckedStar( event.target ); this.maybeSendRating( this.defaultRating, event.target ); this.setRatingInForm( this.defaultRating ); } ); } }, closeTooltipWhenClickOutside() { window.addEventListener( 'click', e => { // Bailout (don't remove the tooltip) when the clicked element is a rating star, or it's the tooltip itself. if ( e.target.closest( '.tasty-recipes-rating' ) || e.target.classList.contains( 'tasty-recipes-static-tooltip' ) ) { return; }
window.TastyRecipes.staticTooltip.destroy(); } ); }, setRatingInForm( rating ) { const ratingInput = document.querySelector( '#respond .tasty-recipes-rating[value="' + rating + '"]' ); if ( ! ratingInput ) { return; } ratingInput.click(); }, addBodyClassBasedOnSelectedRating() { const ratingInputs = document.querySelectorAll( 'input.tasty-recipes-rating' ); if ( ! ratingInputs ) { return; } for ( const ratingInput of ratingInputs ) { ratingInput.addEventListener( 'click', currentEvent => { const selectedRating = currentEvent.target.getAttribute( 'value' ); this.handleBodyClassByRating( selectedRating ); this.toggleCommentTextareaRequired( selectedRating ); } ); } }, handleBodyClassByRating( rating ) { if ( rating < this.minRating ) { document.body.classList.remove( 'tasty-recipes-selected-minimum-rating' ); return; } document.body.classList.add( 'tasty-recipes-selected-minimum-rating' ); }, toggleCommentTextareaRequired( rating ) { const commentTextarea = document.getElementById( 'comment' ); if ( ! commentTextarea ) { return; }if ( rating < this.minRating ) { commentTextarea.setAttribute( 'required', '' ); return; }commentTextarea.removeAttribute( 'required' ); }, maybeSendRating( rating, element ) { if ( this.savingRating === rating ) { return; }this.savingRating = rating; window.TastyRecipes.staticTooltip.init( element );const recipeCardElement = element.closest( '.tasty-recipes' ); if ( ! recipeCardElement ) { window.TastyRecipes.staticTooltip.destroy(); return; }window.TastyRecipes.ajax.sendPostRequest( window.trCommon.ajaxurl, { action: 'tasty_recipes_save_rating', rating, nonce: window.trCommon.ratingNonce, post_id: window.trCommon.postId, recipe_id: recipeCardElement.dataset.trId, }, ( response ) => { window.TastyRecipes.staticTooltip.changeMessage( response.data.message ); window.TastyRecipes.staticTooltip.show(); this.updateAverageText( response.data, recipeCardElement ); this.maybeFillCommentForm( response.data );
// Hide the tooltip after 5 seconds. setTimeout( () => { this.maybeResetTooltip( recipeCardElement, response.data, rating ); }, 5000 ); }, () => { this.resetTooltip( recipeCardElement ); } ); }, updateAverageText( data, recipeCardElement ) { if ( ! data.average ) { return; } this.setRatingPercent( data );
if ( ! data.count ) { return; }
const quickLink = document.querySelector( '.tasty-recipes-rating-link' ); if ( quickLink ) { this.setTextInContainer( quickLink, data ); this.setPartialStar( quickLink ); }
const cardStars = recipeCardElement.querySelector( '.tasty-recipes-ratings-buttons' ); cardStars.dataset.trDefaultRating = data.average; this.setTextInContainer( recipeCardElement.querySelector( '.tasty-recipes-rating' ), data ); }, setTextInContainer( container, data ) { if ( ! container ) { return; }
if ( data.label ) { const ratingLabelElement = container.querySelector( '.rating-label' ); if ( ratingLabelElement ) { ratingLabelElement.innerHTML = data.label; } return; }
const averageElement = container.querySelector( '.average' ); if ( averageElement ) { averageElement.textContent = data.average; }
const countElement = container.querySelector( '.count' ); if ( countElement ) { countElement.textContent = data.count; } }, setPartialStar( container ) { const highestStar = container.querySelector( '[data-rating="' + Math.ceil( this.defaultRating ) + '"]' ); if ( highestStar ) { highestStar.dataset.trClip = this.currentRatingPercentage; } }, setRatingPercent( data ) { this.defaultRating = data.average.toFixed( 1 ); const parts = data.average.toFixed( 2 ).toString().split( '.' ); this.currentRatingPercentage = parts[1] ? parts[1] : 100; if ( this.currentRatingPercentage === '00' ) { this.currentRatingPercentage = 100; } }, setCheckedStar( target ) { const cardRatingContainer = target.closest( '.tasty-recipes-ratings-buttons' ); const selectedRatingElement = cardRatingContainer.querySelector( '[data-tr-checked]' ); if ( selectedRatingElement ) { delete selectedRatingElement.dataset.trChecked; }
const thisStar = target.closest( '.tasty-recipes-rating' ); thisStar.dataset.trChecked = 1; thisStar.querySelector( '[data-tr-clip]' ).dataset.trClip = 100; }, maybeFillCommentForm( data ) { if ( ! data.comment || ! data.comment.content ) { return; }
const commentForm = document.querySelector( '#commentform' ); if ( ! commentForm ) { return; }
const commentBox = commentForm.querySelector( '[name=comment]' ); if ( ! commentBox || commentBox.value ) { return; }
// Add comment details for editing. commentBox.innerHTML = data.comment.content; if ( data.comment.name ) { commentForm.querySelector( '[name=author]' ).value = data.comment.name; commentForm.querySelector( '[name=email]' ).value = data.comment.email; } }, maybeResetTooltip( recipeCardElement, data, rating ) { if ( this.savingRating === rating ) { this.resetTooltip( recipeCardElement, data ); } }, resetTooltip( recipeCardElement, data ) { window.TastyRecipes.staticTooltip.destroy(); this.savingRating = false;
// Reset the default rating. const cardRatingContainer = recipeCardElement.querySelector( '.tasty-recipes-ratings-buttons' ); if ( cardRatingContainer ) { this.defaultRating = ( data && data.average ) ? data.average.toFixed(1) : cardRatingContainer.dataset.trDefaultRating; cardRatingContainer.dataset.trDefaultRating = this.defaultRating;
this.resetSelectedStar( cardRatingContainer, data ); } }, resetSelectedStar( cardRatingContainer ) { const selectedRatingElement = cardRatingContainer.querySelector( '[data-rating="' + Math.ceil( this.defaultRating ) + '"]' ); if ( selectedRatingElement ) { selectedRatingElement.querySelector( '[data-tr-clip]' ).dataset.trClip = this.currentRatingPercentage; selectedRatingElement.parentNode.dataset.trChecked = 1; }
const previousSelectedElement= cardRatingContainer.querySelector( '[data-tr-checked]' ); if ( previousSelectedElement ) { const currentSelectedRating = previousSelectedElement.querySelector('[data-rating]'); if ( currentSelectedRating !== selectedRatingElement ) { delete previousSelectedElement.dataset.trChecked; } } }, backwardCompFormRatingPosition() { const ratingsButtons = document.querySelector( '#respond .tasty-recipes-ratings-buttons, #tasty-recipes-comment-rating .tasty-recipes-ratings-buttons' ); if ( ! ratingsButtons ) { return; } const ratingsButtonsStyles = window.getComputedStyle(ratingsButtons); if ( ! ratingsButtonsStyles.display.includes( 'flex' ) ) { ratingsButtons.style.direction = 'rtl'; }
if ( typeof tastyRecipesRating !== 'undefined' ) { // Select the rating that was previously selected in admin. ratingsButtons.querySelector( '.tasty-recipes-rating[value="' + tastyRecipesRating + '"]' ).checked = true; }
const ratingSpans = ratingsButtons.querySelectorAll( '.tasty-recipes-rating' ); for (const ratingSpan of ratingSpans) { ratingSpan.addEventListener( 'click', event => { if ( ratingSpan === event.target ) { return; } ratingSpan.previousElementSibling.click(); } ); } } };
(function(callback) { if (document.readyState !== "loading") { callback(); } else { window.addEventListener( 'load', callback ); } })(() => { window.TastyRecipes.ratings.init( window.trCommon ? window.trCommon.minRating : 4 ); });










