I'm making a forum web site(html+Vue3+php+sql), and there have a post system.
Mostly, when we need to custom dropdown object, it always needs to initial the fake dropdown object with js. (or have the other way that IDK)
for example, I'm using the css framework「Tocas-UI」,and I got the some html objects below:
<div class="ts floating dropdown icon button">
<i class="vertical ellipsis icon"></i>
<div class="menu">
<div class="item">Add</div>
<div class="item">Edit</div>
<div class="item">Share</div>
</div>
</div>
And <div class="ts floating dropdown icon button">...</div> can be used js ts('.ts.dropdown:not(.basic)').dropdown(); to make it be a "dropdown" object.
Although it can only be used once to initial every object which have class .ts.dropdown, but I'm using the js framework Vue3, and when I using v-for to render every post (have one fake dropdown object in every post), it's not working on the object which are be created after I call the function .dropdown().
So I was tried to put ts('.ts.dropdown:not(.basic)').dropdown(); into loop, it stupid and also not working.
Here is the code in the v-for loop:
<template v-for="post in posts">
<div class="item">
<div class="ts mini circular image">
<img src="default.png">
</div>
<div class="content">
<div class="header">{{ post.poster.nickname || post.poster.username }}</div>
<div class="middoted meta">
<a>#{{ post.poster.username }}</a>
<div>{{ Init.timeToStatus(post.datetime) }}</div>
</div>
</div>
<div class="actions">
<div class="ts separated secondary icon buttons">
<div class="ts floating dropdown icon button">
<i class="vertical ellipsis icon"></i>
<div class="menu">
<div class="item">Add</div>
<div class="item">Edit</div>
<div class="item">Share</div>
</div>
</div>
</div>
</div>
</div>
</template>
So the question is... How can I make those fake dropdown object be initial with ts('.ts.dropdown:not(.basic)').dropdown(); even have new post be added after page loaded.
Related
I'm pretty sure this one is silly but I can't seem to figure it out myself.
This is a Django website containing a little bit of Javascript.
In my HTML, I have a button that should send a few values to a Javascript function. The javascript function should then find and update some divs in the HTML.
The strange thing is that the value assigned to the setAttribute statement is automatically also used for the following innerHTML statement (overruling whatever was configured there).
HTML Button:
<button class="btn btn-outline-dark" onclick="monthStats(
{{simple_total_monthly_sent_volume}},
{{average_monthly_delivery_rate}},
{{average_monthly_unique_open_rate}},
{{total_monthly_unique_open_volume}},
{{average_monthly_unique_click_rate}},
{{average_monthly_rejection_rate}},
)">Month</button>
Javascript:
function monthStats (sentvolume,
deliveryrate,
uniqueopenrate,
uniqueopenvolume,
uniqueclickrate,
rejectionrate
) {
document.getElementById("sent").innerHTML = (sentvolume).toLocaleString("en-US");
document.getElementById("delivered").innerHTML = deliveryrate+"%";
document.getElementById("uniqueopened").innerHTML = uniqueopenrate+"%";
document.getElementById("uniqueopened").setAttribute("title", uniqueopenvolume.toString());
document.getElementById("uniqueclicked").innerHTML = uniqueclickrate+"%";
document.getElementById("rejected").innerHTML = rejectionrate+"%";
}
HTML divs that should get updated:
<div class="container">
<div class="row">
<div class="col">
<div id="sent" class="keymetric">{{simple_total_monthly_sent_volume|intcomma}}</div><div class="text-muted keymetricexplanation">sent volume</div>
</div>
<div class="col">
<div id="delivered" class="keymetric">{{average_monthly_delivery_rate}}%</div><div class="text-muted keymetricexplanation">delivery rate</div>
</div>
<div class="col">
<div id="uniqueopened" class="keymetric" data-bs-toggle="tooltip" data-bs-placement="top" title="{{total_monthly_unique_open_volume|intcomma}}">{{average_monthly_unique_open_rate}}%</div><div class="text-muted keymetricexplanation">unique open rate</div>
</div>
<div class="col">
<div id="uniqueclicked" class="keymetric">{{average_monthly_unique_click_rate}}%</div><div class="text-muted keymetricexplanation">unique click rate</div>
</div>
<div class="col">
<div id="rejected" class="keymetric">{{average_monthly_rejection_rate}}%</div><div class="text-muted keymetricexplanation">rejection rate</div>
</div>
</div>
</div>
Clicking on the Month button in the HTML results in the title and textvalue of the div with ID "uniqueopened" to be updated correctly by the Javascript. However, the setAttribute statement in the javascript is seemingly also updating the value of the following div with ID "uniqueclicked", overruling the Javascript statement targeting that div.
I'm still not sure what caused the original problem. But could solve my issue by using an alternative approach: instead of pushing all the values to one single javascript function, I created a separate javascript function that does only the setAttribute updates.
I have a website that i am trying to personalize and I am trying to use the AnimatedModal.js framework. I have been able to display some content in one modal, but when it comes to make several modal it gets tricky, because there is just one ID. My question i, how can i use the same ID and change the content for other modals(demo03,demo04..etc.), in order to personalize each.
I will put some code in order to understand the problem
I have been reading the documentation but I am still stuck in this problem.
<!-- single work -->
<div class="col-md-4 col-sm-6 ads graphics">
<a id="demo02" href="#animatedModal" class="portfolio_item">
<img src="img/portfolio/03.jpg" alt="image" class="img-responsive" />
<div class="portfolio_item_hover">
<div class="portfolio-border clearfix">
<div class="item_info">
<span>Should open here </span> <em> ads / Graphics </em>
</div>
</div>
</div>
</a>
</div>
<!-- end single work -->
Then I have the demo where it displays the content of the modal, where it has the #animatedmodal ID
<div id="animatedModal" class="popup-modal ">
<!--THIS IS IMPORTANT! to close the modal, the class name has to match the name given on the ID -->
<div id="btn-close-modal" class="close-animatedModal close-popup-modal">
<i class="ion-close-round"></i>
</div>
<div class="clearfix"></div>
<div class="modal-content ">
<div class="container">
<div class="portfolio-padding" >
Hello World
</a>
</div>
</div>
</div>
</div>
this is my Js file where there is just one element assigned to it, to avoid showing the same content into all different classes.
$("#demo02").animatedModal();
I don't think it can be done without hacking the plugin.
As a matter of fact, the script jQuery.animatedModal ALWAYS TARGETS the page element which has id="animatedModal"
You can see the plugin source code here:
https://cdn.jsdelivr.net/npm/animatedmodal#1.0.0/animatedModal.js
...
//Defaults
var settings = $.extend({
modalTarget:'animatedModal',
...
Here is the AnimatedModal reference:
https://joaopereirawd.github.io/animatedModal.js/
At the bottom of the page, I can't see any OPTION regarding how to specify a different target, all options are about styles and animation features.
At this point, I think the only way to allow multiple modals on the same page is to rewrite the plugin, but I'm pretty sure you don't want to choose this way.
I am working on Angular Js web app using Laravel 5.2 as API and I have a big issue in the performance specially in the load time of the home page.
I have a request that get 5 sections from database, each section has one or tow items and each item has many comments. I loop through sections then items then comments to render it via nested ng-repeat directive.
I also have a list of filters and another of friends each has its own request and ng-repeat to render it as well.
Is this considerable as huge data to use over Angular JS, How I can enhance the performance of it?
I also have about 20 modules in the dependencies of the main module, Is there a better way to load this module only when I need them?
Notes:
Angular Js version 1.5.1
Angular Js and jQuery loaded via CDN
all other js files are concatenated by GULP.js in one file and it about 66000 lines of code
there is 25 module in the dependencies array of the main module
the time of load is about 25-35 seconds
here is code of my home page section that cause the issue:
<div ng-class="{'col-sm-6':currentUser,'col-sm-9':!currenUser}" fc-loading="getCoupons" class="allCoupons lbm">
<section class="fc-section text-center fc-direction" ng-init='current="all"'>
<button type="button" class='btn btnp btnm0 srm' ng-class='{"btnr":current=="all"}' ng-click='updateCoupons();current="all"' name="button">كل الكوبونات</button>
<button type="button" class='btn btnp btnm0' ng-class='{"btnr":current=="my"}' ng-click='updateCoupons("user");current="my"' name="button">الكوبونات المخصصة لك </button>
</section>
<div ng-repeat='(key,section) in coupon_sections' class="{{key}} fc-programs">
<div class="header">
<div class="clearfix">
<h3 class="pull-left">{{::section.type}}</h3>
<ul ng-init="active = 'newset'" class="pull-right">
<li ng-click="sortCoupons(1,key); active='newset'" ng-class="{active:active == 'newset'}"><span>{{::'sort_by.newest'| translate}}</span></li>
<li ng-click="sortCoupons(2,key); active='oldset'" ng-class="{active:active == 'oldset'}"><span>{{::'sort_by.oldest'| translate}}</span></li>
<li ng-click="sortCoupons(3,key); active='popular'" ng-class="{active:active == 'popular'}"><span>{{::'sort_by.popular'| translate}} </span></li>
</ul>
</div>
</div>
<div class="fc-section">
<p>
{{::section.description}}
</p>
</div>
<div class="lucky_hour centerContainer" ng-if='key =="luckyHour"' ng-init='getTimeRemaining("December 31 2016 23:59:59 GMT+0200")'>
<div class="centerContent">
<ul>
<li class="hh" ng-repeat='hour in hours track by $index'>{{hour}}</li>
<li class="dots">:</li>
<li class="mm" ng-repeat="minute in minutes track by $index">{{minute}}</li>
<li class="dots">:</li>
<li class="ss" ng-repeat="second in seconds track by $index">{{second}}</li>
</ul>
</div>
</div>
<section class="fc-section text-center" ng-if="!section.coupons.length ">
<p class="title">{{::'no_coupons'| translate}}</p>
</section>
<div ng-repeat="coupon in section.coupons">
<fc-coupon ng-init='showCarousel();'></fc-coupon>
</div>
<div class="text-center" ng-if="section.coupons.length ">
<button class="btnloadmore icon-plus-circled btni lbm" ng-click="loadMore(key)">{{::'load_more'| translate}}</button>
</div>
</div>
</div>
here is the fc-coupon template
<div class="fc-coupon lbm" id='{{coupon.coupon_data.slug}}'>
<div class="header bb">
<div class="rippon">
{{::coupon.coupon_data.type}} </div>
<img style="background-image: url('{{::absolute_url+'images/brands/100x100/'+ coupon.brand_data.logo }}')" />
<h3>{{::coupon.brand_data.name}}</h3>
<fc-stars rating="{{::coupon.coupon_data.rate}}" ></fc-stars>
<div class="pull-right">
<!-- <label>{{::'available_for'| translate}}</label> -->
<div class="fc-badge sPadges" ng-repeat="customer in ::coupon.coupon_data.users_type">
<img uib-tooltip="{{:: 'available_for' | translate}} {{::customer.name.name}}" ng-src="{{::absolute_url}}/images/customer-types/50x50/{{customer.image}}">
</div>
</div>
</div>
<div class="sp" ng-if='key !="challenges"'>
<h4>{{::coupon.coupon_data.title}}</h4>
<p hm-read-more
hm-text="{{:: coupon.coupon_data.description }}"
hm-limit="100"
hm-more-text="{{::'read_more'|translate}}"
hm-less-text="{{::'read_less'|translate}}"
hm-dots-class="dots"
hm-link-class="links" class="sbm mtp "></p>
</div>
<div class="sp mtp" ng-if='key =="challenges"'>
<p>
<i class="fc-red icon-award"></i> <span class="fc-purple srm">التحدي </span>
{{::coupon.coupon_data.challenges.name}}
</p>
<p>
<i class="fc-red icon-gift"></i> <span class="fc-purple srm">الجائزة </span>
<span>{{::coupon.coupon_data.type}}</span>
</p>
</div>
<div class="couponImage">
<div class="fc-overlay centerContainer">
<div class="centerContent">
<i ng-if="coupon.coupon_data.in_wallet" class="icon-heart"></i>
<i ng-if="!coupon.coupon_data.in_wallet" ng-click="addToMyCoupons(coupon.coupon_data)" class="icon-heart-empty"></i>
<label>{{::coupon.coupon_data.no_of_users_in_wallet }}</label>
</div>
<div class="couponFooter">
{{::'details'| translate}}
<ul class="socials">
<li><span ng-click="shareCoupon(coupon.coupon_data.slug,'facebook')" spantarget="_blank" class="icon-facebook"></span> </li>
<li><span ng-click="shareCoupon(coupon.coupon_data.slug,'twitter')" class="icon-twitter"></span> </li>
<li><span ng-click="shareCoupon(coupon.coupon_data.slug,'gplus')" class="icon-gplus"></span> </li>
</ul>
</div>
</div>
<img ng-src="{{::absolute_url}}/images/coupons/747x390/{{coupon.coupon_data.image}}"/>
</div>
<div class="couponDetails sp">
<div class="owl-carousel mbm">
<div class="item " ng-repeat="friend in ::coupon.coupon_data.coupon_users">
<div style="background-image: url('{{::absolute_url}}/images/users/75x75/{{friend.picture}}')" class="roundImages mProfilePics"></div>
</div>
</div>
<div ng-init="coupon.coupon_data.isMapCollapsed =true;coupon.coupon_data.isMapOpened=false">
<div class="clearfix bb mbp mtp bt sbm" >
<div class="pull-left srm" ng-click="openBranches(coupon.coupon_data)">
<i class="icon-location"></i>
<label>{{::'branches'| translate}} {{::coupon.coupon_data.no_of_branches}}</label>
</div>
<div class="pull-left">
<i ng-class="{'icon-cancel':coupon.coupon_data.feed_w_estafeed_id ==null,'icon-ok':coupon.coupon_data.feed_w_estafeed_id != null}"></i>
<label>{{::'benefit'| translate}}</label>
</div>
<div class="pull-right">
<i class="icon-share"></i>
<label for="">{{::'share'| translate}} :</label>
<i class="icon-facebook" ng-click='shareCoupon(coupon.coupon_data.slug,"facebook")'></i>
<i class="icon-twitter" ng-click='shareCoupon(coupon.coupon_data.slug,"twitter")'></i>
</div>
</div>
<div class="fc-map " uib-collapse="coupon.coupon_data.isMapCollapsed" >
</div>
</div>
<div class="clearfix">
<div class="buttons add_to_my_coupones pull-right">
<button ng-if="coupon.coupon_data.in_wallet " type="button" class="btn btnr btnp btni" ng-click='couponConditions(coupon.coupon_data.slug)'>{{::'in_my_coupons'| translate}}</button>
<a ng-if="!coupon.coupon_data.in_wallet && key=='challenges' " href='{{absolute_url}}/{{lang}}/coupons/{{coupon.coupon_data.slug}}/{{coupon.coupon_data.challenges.title}}' class="btn btnr btnp btni" >ابدء التحدي</a>
<button ng-if="!coupon.coupon_data.in_wallet && key!='challenges'" analytics-on="click" analytics-event="addToMyCoupons" analytics-properties="{coupon_id:{{coupon.coupon_data.coupon_id}}}" ng-click="addToMyCoupons(coupon.coupon_data)" class="btn btnr btnp btni icon-heart">{{::'add_to_my_coupones'| translate}}</button>
</div>
<div class="pull-left">
<i class="icon-calendar"></i>
<label class="srm">{{::'available_to' | translate}}</label>
<!-- <fc-countdown date='coupon.coupon_data.available_to.date'></fc-countdown> -->
</div>
</div>
<div class="fc-couponComments" >
<!-- <span>{{coupon.comments.length}} {{::'comments'|translate}}</span> -->
<button ng-init="isCollapsed = true;" ng-click="isCollapsed = !isCollapsed;"><i class="icon-comment-1"></i> </button>
<ul uib-collapse="isCollapsed" >
<li>
<img src="{{ currentUser?absolute_url+'/images/users/50x50/'+currentUser.picture:absolute_url+'/images/user.png'}}"/>
<div class="userComment">
<textarea ng-model="addComment.newComment" ng-enter="sendComment(coupon)"></textarea>
</div>
</li>
<li ng-repeat="comment in coupon.coupon_data.comments track by $index">
<img ng-src="{{::absolute_url}}/images/users/50x50/{{::comment.user.picture}}"/>
<p>
<label>{{::comment.user.firstname}} {{::comment.user.lastname}}</label>
<span> {{::comment.comment}} </span>
<label>{{::comment.created_at}}</label>
</p>
</li>
</ul>
</div>
</div>
</div>
home controller js :
var url = user ? "user/home/coupons" : "home/coupons";
fcDB.query(url, "GET", data).success(function(res) {
console.log('home', res);
$scope.coupon_sections = res;
});
You seem to have way too many bindings. Back in the days of Angular 1.2, I remember it was a rule of thumb to have up to 2000 bindings on the page. That's gone up by now, but I doubt it scaled exponentially.
You have 5 sections, each having numerous ng-click bindings, several nested ng-repeats which multiply this, then undetermined number of comments per coupon.
You can deal with all this in several different ways. Some of them:
join the click listeners,
lazy-load the nested comments, hours etc, if possible,
also render as html those social shares,
pre-translate content,
one-time-bind more then you do now,
reduce dependencies.
E.g. you can have one top-level ng-click instead of a dozen per section (+ possibly more in those fc-coupon repeats). So create a single top-level ng-click, and have that function find out its intended target and act accordingly. I'd say you can shave off a little bit of time, but not significant there.
Lazy-load the nested repeats - ie. don't render them immediately. When you initially render the sections, you go on and render those hours, minutes and seconds. Dunno why, but it seems like you do really a lot of those. Have those not even show until the main content is rendered. Just one way to do that is to hide the whole block with an ng-if switch and when you know you've loaded and rendered the initial 5 sections, flip one (or all) the switches and wait for those to be rendered too. You can even leave those hidden ("Loading comments...") until you know they're rendered with a single css flip. Furthermore, maybe you can do them one-at-a-time. First fully resolve the top section, then the second, then the third etc.
Remember, a lot of performance is in perceived performance.
I see you have many of the social shares that you bind to a function. Why not render those as simple HTML directly? Depending on those coupons, you can again remove a lot of bindings.
I see you use ng-translate - which introduces yet more bindings. If you know the user's language in advance, (ie. settings), maybe you can have pre-translated per-language template? E.g. If the user initially chose english, he'd load a page called home-en.html and fc-coupon-en.html instead of one generic one. Don't know if this is viable though, but considering you have a lot of nested content, it might prove useful. And you don't even have to do it by hand, I bet you can write a one-time script where you write your source template like this, and the additional build-step would generate per-language template for all this on build time.
Also try to one-time bind the nested content. E.g. ng-repeat="hour in ::hours" might help a bit. Depending on how many times you have to bind hours, minutes and seconds, there may be thousands of bindings to introduce into the page.
Reduce dependencies if you can. E.g. I see you use a "read-more" module. Maybe you can do without it. Just use a css elipsis. And have a second click listener that finds the targeted section and extends/collapses on demand. I bet that's what the original module does anyway, but yours would be one-time top-level click listener, and not a per-item angular binding that has to get sorted out.
Now, these are all guesses, because you don't show how many actual items and what exactly does it do. So take your pick on one of the suggestions, and try it or open up a new question with more details on it.
Personally, I'd think lazy-loading everything will grant you the most "perceived" performance.
I would put a language picker in this section:
<section id="logo-section" class="text-center">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="logo text-center">
<h1>Batpeppa</h1>
<span>Web Designer Trio</span>
</div>
</div>
</div>
</div>
</section>
I would insert two flag icons under "Web Designer Trio" subtitle.
I would use the class="icon-flag" from Bootstrap 3.
I think I have to use something like this:
<span class="icon-flag">
Well, the native Bootstrap 3.x icons are named glyphicon-<name>. So in your case:
<i class="glyphicon glyphicon-flag"></i>
<i class="glyphicon glyphicon-flag"></i>
Demo. Your code does not work because you are referring to the "old" Twitter Bootstrap 2.x icons, named icon-<name>. If you want to use those, you must download and include the .png and .css from here. Then you should be fine.
I am creating a menu for mobile devices and am trying to use Bootstrap 3's collapse feature.
I already have a collapse working on a different page, so I copied over the structure, gave the panel group a different id, and changed the 'data-parent's and 'panel-collapse' ids appropriately. However, this new accordion just does not work. The 'in' class does not get applied to the target .panel-collapse div, and the hrefs (ex: #navCollapse(x) ) are appearing in the address bar, instead of the normal functionality.
Here is the problematic code. (trimmed to 2 panels for brevity. Still not working as is)
<div class='panel-group' id='accordionNav' >
<div class='panel'>
<div class='panel-heading'>
<a data-parent='#accordionNav' data-toggle='collapse' href="#navCollapse1"> <h3>About</h3></a>
</div>
<div class='panel-collapse collapse in' id='navCollapse1'>
<div class='panel-body'>
<p>Test test ets ejkfbduskfgsalf jydasl</p>
</div>
</div>
</div>
<div class='panel'>
<div class='panel-heading'>
<a data-parent='#accordionNav' data-toggle='collapse' href="#navCollapse2"><h3>Donors</h3></a>
</div>
<div class='panel-collapse collapse' id='navCollapse2'>
<div class='panel-body'>
<p>Test test ets ejkfbduskfgsalf jydasl</p>
</div>
</div>
</div>
</div>