Making a switching news feed for a web page - javascript

For a project i'm working on the users that are logged in with enough priveledge to post a new news item are able to see a button to add news items. I would like to show these news item with 'switching styles' (for the lack of a better word). I'm pulling the data from a database where the user submits it through a form on a seperate page. Then i'm requesting all of the news items back on the home page where it lists them as a 'news feed'. The feed fetches like a charm and can be seen here : http://prntscr.com/et39yp
I would like to make the second, fourth, sixth, etc have the first-image or first-video list on the left, like so : http://prntscr.com/et3akw
Is there an easy way of doing this?
#{
var db = Database.Open("Default");
var fetchRows = "SELECT * FROM Articles";
db.Execute(fetchRows);
var articles = db.Query("SELECT articleTitle, articleText, articleVideoUrl, articleImage FROM Articles ORDER BY id DESC");
var articleTitle = db.Query("SELECT articleTitle FROM Articles");
string lorem = "";
}
<div class="Articles">
<h2>Nieuws Feed</h2>
#foreach (var title in articles)
{
<div class="article">
#{
string text = title.articleText;
string firstLetters = new string(text.Take(50).ToArray());
<div class="col s6">
<h3>#title.articleTitle</h3>
<p>#firstLetters</p>
Lees meer...
</div>
<div class="col s6">
#{
if (title.articleVideoUrl != lorem)
{
//Iframe for youtube feed here
}
else if (title.articleVideoUrl == lorem && title.articleImage != "")
{
<div class="result">
<img src="#title.articleImage" alt="image"/>
</div>
}
}
</div>
}
</div>
}
</div>
Now the switching news article thing is something i would be able to work out, the thing i'm struggling with would be the following. The user is able to edit / remove news items. So i cant keep track of an index value or anything similar since it would be invalid should the user remove an item from the middle of the feed. My first guess would be to use the .toggleclass of javascript and that would probably work with originially loading the items but if the user would remove an item it wouldn't show them the right way after. Any help would be welcome.

It shouldn't matter that you are adding the items individually, the nth-child(odd|even) should still work.
You can see it working here: http://jsfiddle.net/Chairman_Mau/uap93rtL/4/ - notice when you click the move up/move down buttons the style changes automatically.
HTML
<div class="articles">
<h1>header</h1>
<div class="article">
paragraph
</div>
<div class="article">
paragraph
</div>
<div class="article">
paragraph
</div>
<div class="article">
paragraph
</div>
<div class="article movethis">
paragraph - move this one
</div>
<div class="article">
paragraph
</div>
<input type="button" value="add article" class="addarticle"/>
<input type="button" value="move up" class="moveup"/>
<input type="button" value="move down" class="movedown"/>
</div>
Javascript
$(".addarticle").click(function () {
$(".articles").append('<div class="article">added</div>');
});
$(".moveup").click(function(){
var prev = $(".movethis").prev('.article');
$(".movethis").detach().insertBefore(prev);
});
$(".movedown").click(function(){
var next = $(".movethis").next('.article');
$(".movethis").detach().insertAfter(next);
});
CSS
.articles .article:nth-of-type(even)
{
color: Green;
}
.articles .article:nth-of-type(odd)
{
color: Red;
}

Related

Add a Like + Sort Function to existing dynamic funcion

I wrote a function that dynamically creates a webpage for me based on a json database.
Now I want to add 2 functions:
If you click the like img (its got the id button) the like counter should increase on the webpage by 1. Pretty easy just a on(click) with jQuery variable++ and then .text(variable)
A sort function - based on the likes one item received, you should be able to sort it (most liked div first, 2nd, 3rd....
I can write it for each individually with individual variables when I give all the like buttons and outputs a separate id but I wanted to make it dynamic so if you add new data to json file it dynamically works with the like and sort function.
The likes are not saved anywhere for now.
Since sitting on it for 3h and google so much and so much stackoverflow I think I overloaded my brain with different stuff and now nothing seems to work ^^
function filmInsert(insert) {
$.each(film, function(i, data) { //.each statt loop
let box =
`<div class="boxwrapper">
<div class="imgbox">
<img src="${data.img}" alt="${data.titel}">
</div>
<div class="textbox">
<h3>${data.titel}</h3>
<p>${data.beschreibung}</p>
<p> <a id="button${data.id}">
<img src="img/budspencer_official.png"> Like
</a>
<span class="output${data.id}">${data.likes}</span>
</p>
</div>
</div>`;
insert.append(box);
});
}
I've added a container element for the boxwrapper items as I assume you have one and as it's better to have one instead of just adding the sorted items to the body of the HTML document.
$(document).on("click", ".textbox a", function() {
let likes = parseInt($(this).closest(".textbox").find("span").text());
$(this).closest(".textbox").find("span").text(likes + 1);
});
$("#sort").on("click", function() {
let divs = $(".boxwrapper")
let sorted = divs.sort(function(a, b) {
return $(a).find("span").text() < $(b).find("span").text() ? 1 : -1;
});
$(".container").html(sorted);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="boxwrapper">
<div class="imgbox">
<img src="example.gif" alt="Title">
</div>
<div class="textbox">
<h3>Titel</h3>
<p>Description</p>
<p> <a id="button1">
<img src="https://dummyimage.com/40x40/000/fff&text=1"> Like
</a>
<span class="output1">0</span>
</p>
</div>
</div>
<div class="boxwrapper">
<div class="imgbox">
<img src="example.gif" alt="Title">
</div>
<div class="textbox">
<h3>Titel 2</h3>
<p>Description 2</p>
<p> <a id="button2">
<img src="https://dummyimage.com/40x40/000/fff&text=2"> Like
</a>
<span class="output2">0</span>
</p>
</div>
</div>
</div>
<button id="sort">
Sort
</button>

Text not fully redrawing when I toggle between templates

On my AngularJS app I have a view that allows me to toggle between type of insurance cover and it works fine. However on iPhone in particular (Chrome & Safari), the text kind of scrambles when I toggle between the prices. To be very clear about it, it's only the top few pixels and those pixels generally belong to the price toggled away from, so it's like the page isn't properly redrawing it. This issue then goes away if I do anything in the Dev tools. Any help is appreciated here.
EDIT: This appears to only happen when I select an option that updates the value displayed, not when it switched to a different piece of template.
Here's a screenshot
And a slightly stripped down version of the template in question:
<div class="row quote-tab-container">
<div class="col">
<div class="quote__tab">
<button ng-click="selectedCoverType = 'Comp'; setCoverDetails()" class="quote__tab__button">
Comprehensive
<div class="active-selection" ng-show="selectedCoverType === 'Comp'"></div>
</button>
<button ng-click="selectedCoverType = 'Tpft'; setCoverDetails()" class="quote__tab__button">
Third Party,<br />Fire & Theft
<div class="active-selection-tpft" ng-show="selectedCoverType === 'Tpft'"></div>
</button>
</div>
</div>
</div>
<div class="quote-details row">
<div class="col">
<div class="answer--radio">
<input ng-click="paymentType = 'CC'" type="radio" ng-checked="paymentType == 'CC'" id="singlePayment" name="payment-type">
<label for="singlePayment">Single Payment</label>
</div>
<div class="answer--radio answer--radio--right">
<input ng-click="paymentType = 'DD'" type="radio" ng-checked="paymentType == 'DD'" id="monthlyPayments" name="payment-type">
<label for="monthlyPayments">Monthly Payments</label>
</div>
<section class="selected-product answer--checkbox" ng-show="paymentType == 'CC'">
<div class="your-online-price">
Your online price is
</div>
<div class="selected-product__price">
{{totalPremium | signedCurrencyFilter}}
</div>
<div class="selected-product__includes">
Price includes online discount of {{onlineDiscount | signedCurrencyFilter}}
</div>
</section>
<section class="selected-product answer--checkbox" ng-show="paymentType == 'DD'">
<div class="your-online-price">
Your online price is
</div>
<div class="selected-product__price">
{{instalmentAmount | signedCurrencyFilter}}
</div>
<div class="selected-product__includes">
Price includes online discount of {{onlineDiscount | signedCurrencyFilter}}
</div>
</section>
</div>
</div>
So because the browser would correct this glitch whenever the screen resized or had to redraw I had to force a redraw any time these options were selected. The best way to do this seemed to be to clone the element and replace the original with the clone in order to force a redraw, this was enclosed in a timeout in order to send this to the end of the execution queue.
This answer helped with this: https://stackoverflow.com/a/8840703/1999035
var n = document.createTextNode(' ');
var opacity = element.style.opacity;
element.appendChild(n);
element.style.opacity = '0.5';
setTimeout(function(){
element.style.display = opacity;
n.parentNode.removeChild(n);
}, 20);
My edit of the proposed solution is to use the opacity property rather than display, because the display change causes a jitter/glitch/flash that looks really bad.Opacity just causes a slight fade.

Link simillary name classes so that when one is clicked the other is given a class

Basically, I'm asking for a way to optimize this code. I'd like to cut it down to a few lines because it does the same thing for every click bind.
$("#arch-of-triumph-button").click(function(){
$("#arch-of-triumph-info").addClass("active-info")
});
$("#romanian-athenaeum-button").click(function(){
$("#romanian-athenaeum-info").addClass("active-info")
});
$("#palace-of-parliament-button").click(function(){
$("#palace-of-parliament-info").addClass("active-info")
});
Is there a way to maybe store "arch-of-triumph", "romanian-athenaeum", "palace-of-parliament" into an array and pull them out into a click bind? I'm thinking some concatenation maybe?
$("+landmarkName+-button").click(function(){
$("+landmarkName+-info").addClass("active-info")
});
Is something like this even possible?
Thanks in advance for all your answers.
EDIT: Here's the full HTML.
<div class="landmark-wrapper">
<div class="page-content landmark">
<div class="heading span-after">
<span>Arch of Triumph</span>
</div>
<div class="landmark-button" id="arch-of-triumph-button"></div>
</div>
</div>
<div class="landmark-wrapper">
<div class="page-content landmark">
<div class="heading span-after">
<span>Romanian Athenaeum</span>
</div>
<div class="landmark-button" id="romanian-athenaeum-button"></div>
</div>
</div>
----------------------------------------------------------
<div class="landmarks-info-wrapper">
<div class="landmark-info" id="arch-of-triumph-info">
<div class="info-landmark section">
<span class="landmark-title">Arch of Triumph</span>
<span class="landmark-coord">44°28′1.99″N 26°4′41.06″E</span>
</div>
</div>
<div class="landmark-info" id="romanian-athenaeum-info">
<div class="info-landmark section">
<span class="landmark-title">The Romanian Athenaeum</span>
<span class="landmark-coord">44.4413°N 26.0973°E</span>
</div>
</div>
Assuming you're not able to modify your HTML markup (in which case with use of CSS classes would be cleaner), a solution to your question would be as shown below:
// Assign same click handler to all buttons
$("#arch-of-triumph-button, #romanian-athenaeum-button, #palace-of-parliament-button")
.click(function() {
// Extract id of clicked button
const id = $(this).attr("id");
// Obtain corresponding info selector from clicked button id by replacing
// last occurrence of "button" pattern with info.
const infoSelector = "#" + id.replace(/button$/gi, "info");
// Add active-info class to selected info element
$(infoSelector).addClass("active-info");
});
Because each .landmark-button looks to be in the same order as its related .landmark-info, you can put both collections into an array, and then when one is clicked, just find the element with the same index in the other array:
const buttons = [...$('.landmark-button')];
const infos = [...$('.landmark-info')];
$(".landmark-button").click(function() {
const i = buttons.indexOf(this);
$(infos[i]).addClass('active-info');
});
This does not rely on IDs at all - feel free to completely remove those from your HTML to declutter, because they don't serve any purpose now that they aren't being used as selectors.
Live snippet:
const buttons = [...$('.landmark-button')];
const infos = [...$('.landmark-info')];
$(".landmark-button").click(function() {
const i = buttons.indexOf(this);
$(infos[i]).addClass('active-info');
});
.active-info {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="landmark-wrapper">
<div class="page-content landmark">
<div class="heading span-after">
<span>Arch of Triumph</span>
</div>
<div class="landmark-button" id="arch-of-triumph-button">click</div>
</div>
</div>
<div class="landmark-wrapper">
<div class="page-content landmark">
<div class="heading span-after">
<span>Romanian Athenaeum</span>
</div>
<div class="landmark-button" id="romanian-athenaeum-button">click</div>
</div>
</div>
----------------------------------------------------------
<div class="landmarks-info-wrapper">
<div class="landmark-info" id="arch-of-triumph-info">
<div class="info-landmark section">
<span class="landmark-title">Arch of Triumph</span>
<span class="landmark-coord">44°28′1.99″N 26°4′41.06″E</span>
</div>
</div>
<div class="landmark-info" id="romanian-athenaeum-info">
<div class="info-landmark section">
<span class="landmark-title">The Romanian Athenaeum</span>
<span class="landmark-coord">44.4413°N 26.0973°E</span>
</div>
</div>
Older answer, without knowing the HTML: You can extract the ID of the clicked button, slice off the button part of it, and then select it concatenated with -info:
$(".landmark-button").click(function() {
const infoSel = this.id.slice(0, this.id.length - 6) + 'info';
$(infoSel).addClass('active-info');
});
A much more elegant solution would probably be possible given the HTML, though.

if statement logic not producing the desired result

I have a page called 'services'. When you go to that page from the navigation menu I do not want any of the services to show up (too complicated to explain it). Then on my index page I have links for each type of service there is. If you click on a link it will take you to the services page and only show that service.
For the individual service links, they look like this:
Service 1
Service 2
Service 3
This aspect of this system works. It takes me to the services page and only shows the service I clicked on, from the link.
The part that doesn't work is not showing the services OR the service-display-box from the navigation menu. Right now all of the services show and the service-display-box does as well.
I tried to create logic to prevent this from happening, but it isn't working. In the javascript below you will see comments like //added, this is what I added to try and create logic that it would show the service-display-box and specific service item if there was a hash in the browser, or else it would not show the service-display-box at all.
What is wrong with my logic?
$(function(){
//get the section name from hash
var sectionName = window.location.hash.slice(1);
if (sectionName != null) { //added
//then show the section
$('#service-display-box').show();
$(window.location.hash).show().scroll().siblings().hide();
} else { //added
$('#service-display-box').hide(); //added
} //added
})
#service-display-box {
display: none;
}
<div id="service-display-box">
<div id="service-display-box-container">
<div class="service-item-box" id="service1">
<div class="service-item-title">1</div>
<h2 class="service-item-description"> Service</div>
</h2>
<h2 class="service-item-box" id="service2">
<div class="service-item-title">2</div>
<div class="service-item-description"> Service</div>
</h2>
<h2 class="service-item-box" id="service3">
<div class="service-item-title">3</div>
<div class="service-item-description"> Service</div>
</h2>
<h2 class="service-item-box" id="service4">
<div class="service-item-title">4</div>
<div class="service-item-description"> Service</div>
</h2>
<h2 class="service-item-box" id="service5">
<div class="service-item-title">5</div>
<div class="service-item-description"> Service/div>
</h2>
<h2 class="service-item-box" id="service6">
<div class="service-item-title">6</div>
<div class="service-item-description"> Service</div>
</h2>
<div style="clear:both;"></div>
<div id="service-top"><span id="service-top-border">Back to all services</span></div>
</div>
</div>
I've also tried
if (sectionName > 1) {
window.location.hash.slice(1) returns an empty string, which is not the same as null. I think you want to check .length == 0 instead.

How to disabled "Next" button of wizardpane in DOJO

I am using dojo 1.5. I am creating a sample wizard. Below is code
<div class="floater">
<p>This example shows a wizard with customized button labels.</p>
<div id="wizard1" dojoType="dojox.widget.Wizard" hideDisabled="true" previousButtonLabel="test" nextButtonLabel="Go on" doneButtonLabel="Finish">
<div dojoType="dojox.widget.WizardPane" >
// Here some html form , User has to fill all information
</div>
<div dojoType="dojox.widget.WizardPane">
<h1>Tab 2</h1>
</div>
<div dojoType="dojox.widget.WizardPane">
<h1>Tab 3</h1>
You won't be able to come back, but you can finish now...
</div>
<div dojoType="dojox.widget.WizardPane" >
<h1>Tab 4</h1>
... and now you can't go back.
</div>
<div dojoType="dojox.widget.WizardPane" doneFunction="done" >
<h1>Tab 5</h1>
... and now you can finish up.
</div>
</div>
</div>
I want to hide next button which has label "Go on" for first pane of wizard til user fill all information from first pane. So can you please suggest how to disabled "Next" button from wizard when it was initially loaded.
I don't know exactly what the best way to do this is. If you use dijit.form.Form, you can use its onValidStateChange method, and toggle the button enabled/disabled there.
var toggleWizardButton = function(valid) {
dijit.byId("theWizard").nextButton.set("disabled",!valid);
//if(valid) { /* enable "Go on" button here.. */ }
//else { /* opposite.. */ }
};
var form = dijit.byId("theFormInWizardPane1"),
wiz1 = dijit.byId("theWizard");
dojo.connect(form, "onValidStateChange", toggleWizardButton);
wiz1.nextButton.set("disabled",true); // button disabled by default
Example fiddle: http://jsfiddle.net/VQM2k/1/
An alternative, possibly better way, is to just use the WizardPane's passFunction, which when returning false, will prevent the wizard from moving forward. In it, you can get the form and check whether it is valid or not (kind of like your other question :) ).
<div dojoType="dojox.widget.WizardPane" passfunction="passfunction" >
// Here some html form , User has to fill all information<br/><br/>
<form id="myForm" dojoType="dijit.form.Form">
Name: <input dojoType="dijit.form.ValidationTextBox" required="true" />
</form>
</div>
The passfunction can simply be something like this:
var passfunction = function() {
var form = dijit.byId("myForm");
return form && form.validate();
};
Fiddle: http://jsfiddle.net/VQM2k/

Categories

Resources