I'm using a custom jScrollPane and dynamically populate it using jQuery from a returned partial view.
I'm populating it like this:
var pane = $('.mainContainingDiv').jScrollPane(settings);
var api = pane.data('jsp');
// Populate function
api.getContentPane().html(someData);
api.reinitialise();
This is great and works exactly as I expect it to, but this content pain currently contains content that only needs to be set once so I do not want to return more than i have to on every server call. Rather, i'd like to move it out of the partial view and into the main view that contains the javascript.
Here's some html to illustrate this better:
BEFORE:
<div class="myContainingDiv">
<div class="staticContentDivThatIDontWantReturnedOnEveryServerCall">
Info
</div>
<div class="dynamicDiv">
More Info
</div>
</div>
so right now I'm replacing both divs with the getContentPane() function. How can I only replace one. e.g.
CALL 1
// some controller calls
api.getContentPane().html(NEWDATAFROMWHEREVER);
Here's what this results in (as expected), and the result I want.
UNDESIRED RESULT
<div class="myContainingDiv">
NEWDATAFROMWHEREVER
</div>
DESIRED RESULT
<div class="myContainingDiv">
<div class="staticContentDivThatIDontWantReturnedOnEveryServerCall">
Info
</div>
NEWDATAFROMWHEREVER
</div>
So how can I replace only one div in the container with the getContentPane() call via jScrollPane
Thanks
Figured it out:
api.getContentPane().children('.dynamicDiv').html(NEWDATAFROMWHEREVER);
api.reinitialise();
hopefully this helps someone else
Related
I am converting a jQuery code to vuejs. I have a hard time doing it. I tried to search but I can't find anything clear.
Sample jQuery code is to get the last div top position. The code is like this:
var top = parseInt($(".d1 > .d2> div").last().css("top"));
My template code is :
<template>
<div class="div1" >
<div class="div2" ref="busstop">
<div v-html="renderEl()"></div>
</div>
<button #click='test()'>testing</button>
</div>
</template>
Any Idea on how to convert in to vuejs? Any help is much appreciated. Thank you.
in ur case, i will using ref to get lastChildElement div by using lastElementChild
First, to get the last child element
this.$refs.busstop.lastElementChild
and to style for this element
this.$refs.busstop.lastElementChild.style.fontSize = "30px";
like that
Alright, so if I understand properly, you want to:
have a parent w/ a reference
select the last element of this specific parent
get it's window's position from the top ?
Here is a demo on how to do this in CSS + Vue.
https://codesandbox.io/s/jovial-fog-td190?file=/src/App.vue
I'm using ng2-modal to create a modal dialog in Angular 2. I am unable to get an element that has a condition on it (#myModalScrollPanel).
Template (modal.html):
<modal #myModal title="{{title}}"
cancelButtonLabel="Close"
submitButtonLabel="Ok"
modalClass="#modal-md"
[hideCloseButton]="false"
[closeOnEscape]="false"
[closeOnOutsideClick]="false"
>
<modal-header></modal-header>
<modal-content>
<div class="row">
<div *ngIf="logOutput" class="col-md-12">
<div id="myModalScrollPanel" #myModalScrollPanel class="panel-body fixed-panel">
<p *ngFor="let entry of logOutput.entries">{{entry.log}}</p>
</div>
</div>
</div>
</modal-content>
<modal-footer></modal-footer>
</modal>
In my component I get View Children (modal.component.ts):
#ViewChild('myModal') myModalModal;
#ViewChild('myModalScrollPanel') myModalScrollPanel;
After a users clicks a button, I show the modal and get log text from the server, I call updateScrollPosition() once I have updated logOutput (modal.component.ts):
updateScrollPosition() {
console.log("modal:");
console.log(this.myModalModal);
console.log("log scroll panel:");
console.log(this.myModalScrollPanel);
if(this.myModalScrollPanel){
console.log("Scrolling the panel down");
this.myModalScrollPanel.nativeElement.scrollTop = this.myModalScrollPanel.nativeElement.scrollHeight;
} else {
console.log("No log scroll panel.");
}
}
The console shows a valid object for "modal" and 'undefined' for log scroll panel.
I also tried calling that method from ngAfterViewInit(), but it only gets called when the parent component is loaded, and not the actual modal being shown, so the if statement results in false and element doesn't exist yet. If I remove/move the if statement, so that the element exists I can then access that object, but the changes I make do not take any effect, although that might be a whole different issue (most likely to do with change detection).
In the end, I just want to scroll to the bottom of the panel. Something like this (which works in the browser console):
var scrollPanel = document.getElementById('myModalScrollPanel');
scrollPanel.scrollTop = scrollPanel.scrollHeight;
Thanks in advance!
So to answer my own question, I had to use #ViewChildren instead of #ViewChild.
#ViewChildren annotation will assign a QueryList object to your variable, giving you access to the elements you require (I use .toArray() to get an array of elements, which in this case will be just one).
Speaking of the change detection problem I had, thanks to this answer, using the ngAfterViewChecked() method I was able to implement the scroll down I needed.
I am editing my blog theme and I need to move (cut and paste) multiple specific divs under itself within a specific blog post.
The current HTML would be
<div class="blog_post text_post">
<div class="post_container">
<div class="bottom_meta"></div>
<div class="post_date"></div>
<div class="moreinfo"></div>
<!-- I need .bottom_meta here -->
</div>
</div>
I managed to make it work like this:
$(".blog_post.text_post .bottom_meta").insertAfter(".blog_post.text_post .moreinfo");
And on first sight it looks okay,but when I wrote another text post (usually posts are images) it makes a mess on my blog.
The code now moves .bottom_meta from both posts under both .moreinfo .
I tried using each function but I failed multiple times...
$(".blog_post.text_post").each(function(){
$(this).children(".bottom_meta").insertAfter.$(this).children(".moreinfo");
});
I tried the same with 'find' function instead of 'children',still a fail.
Can anyone help me out with this or at least point me out to the right direction.
It should be:
$(".blog_post.text_post").each(function(){
$(this).find(".bottom_meta").insertAfter($(this).find(".moreinfo"));
});
Example Here
Change .insertAfter.$(this).children(...) to: .insertAfter($(this).children(...))
Also, since the .moreinfo/.bottom_meta elements aren't direct children, you need to use .find() rather than .children().
You can also simplify it to the following:
$(".blog_post.text_post").each(function () {
$(".bottom_meta", this).insertAfter($(".moreinfo", this));
});
Example Here
I have a list of Questions, and each of those Questions has a list of Answers (which can be any integer from 1-5). I would like to dynamically create a chart for each Question, using the count of all answers that match a specific "rank"; i.e. all the answers that were a '1', '2', '3', etc.
So what I've done is set a for loop that creates an element for each question; this element is used as a placeholder for the chart. (As an aside, I am using flot charts).
The problem I'm having is trying to name the placeholders dynamically; what I really want is to create something that ends up looking like this:
<div id='chart1'/>
<div id='chart2'/>
etc
The closest I've managed is this:
<div id="'chart'#currentQuestion"/>
which of course gives an id like this: 'chart'1
Later, when I try to append the chart to the div I've created, the following doesn't work:
$("#'chart'"+i).append(div); //where i is the current loop counter
If I use
$("#chart"+i).append(div);
it correctly finds the element 'chart1', 'chart2' etc; but I'm struggling to name the div to match.
Can anyone help? It seems trivial unless you know how to solve it :-)
Edit: As requested, here is the relevant HMTL:
<div id="'chart#currentQuestion'">CHART</div>
SOLVED:
Like this: id="chart#(currentQuestion)" (via a colleague) Thanks for your efforts.
You haveen't close your div correctly. try this code
<div id='chart1' style="border:dashed">
</div>
<br />
<div id='chart2' style="border:dotted">
</div>
<script type="text/javascript" src="jquery_library.js">
</script>
<script type="text/javascript">
function fnc(value){
$("#chart"+value).append('1');
}
</script>
<input type="button" onclick="fnc(1)" value="for div1"/>
<input type="button" onclick="fnc(2)"value="for div2" />
You are using razor syntax, so here how it should be.
// Define your counter
#{long i = 0;}
// On document ready dynamically add your items
$("document").ready(function(){
// Create red divs starting by zero
// after 5 divs stop creating red divs
#for (i = 0;i<5;i++){
#:$("#form").append('<div id="chart' + #(i) + '">Red</div>');
}
});
// I made a button for action, you can choose other ways to invoke this function
$("#form>input").click(function(){
// Your counter is at 4 now
// lets change it to 2
#(i = 2;) // Now your counter is at 2
// Put a blue div into 2nd div starting by 0
$("#chart"+#(i)).append('<div class="blue">blue</div>');
});
this is how you use razor syntax with scripts
I am creating a mobile app (Phonegap/Cordova 1.5.0, JQM 1.1.0) and testing on iOS 5.1. I have a list of items that the user "owns" or wants to own. Throughout the app, the user can edit their list by adding and removing items. Whenever items are added or removed, the list updates, and it is displaying fine, with all of the JQuery CSS intact except the corners are no longer rounded (I'm thinking because data-inset is getting set to "false").
Here is my html for the list-headers:
<div data-role="page" id="profile">
<div data-role="header" data-position="fixed">
<...>
</div><!-- /header -->
<div data-role="content" data-theme="a">
<...>
<ul id="user-wants-list" data-role="listview" data-inset="true" data-theme="d" data-dividertheme="d" >
</ul> <!--/Wants list-->
</br>
<ul id="user-haves-list" data-role="listview" data-inset="true" data-theme="d" data-dividertheme="d" >
</ul> <!--/Has list-->
</br></br>
</div> <!--/content-->
</div> <!--/Profile-->
And here is the Javascript where I remove the old list and dynamically add the new one (the parameter 'haves' is an array of objects):
function displayHaves(haves){
var parent = document.getElementById('user-haves-list');
removeChildrenFromNode(parent);
parent.setAttribute('data-inset','true');
$(parent).listview("refresh");
var listdiv = document.createElement('li');
listdiv.setAttribute('id','user-haves-list-divider');
listdiv.setAttribute('data-role','list-divider');
listdiv.innerHTML = "I Have (" + haves.length + ")";
parent.appendChild(listdiv);
//create dynamic list
for(i=0;i<haves.length;i++){
var sellListing = haves[i].listing;
var userInfo = haves[i].user;
var itemData = haves[i].item;
//create each list item
var listItem = document.createElement('li');
listItem.setAttribute('id','user-haves-list-item-'+i);
parent.appendChild(listItem);
var link = document.createElement('a');
link.setAttribute('id','user-haves-link-' + i);
new FastButton(link, function(listing) {
return function() { displaySellListingPage(listing); }
}(sellListing));
listItem.appendChild(link);
var link = document.getElementById('user-haves-link-' + i);
var pic = document.createElement('img');
pic.setAttribute('src',itemData.pictureURL);
pic.setAttribute('width','80px');
pic.setAttribute('height','100px');
pic.setAttribute('style','padding-left: 10px');
link.appendChild(pic);
var list = document.getElementById('user-haves-list');
$(list).listview("refresh");
}
}
and my function removeChildrenFromNode(parent) is as follows:
function removeChildrenFromNode(node){
while (node.hasChildNodes()){
node.removeChild(node.firstChild);
}
}
So my question is, why does the listview lose the data-inset attribute?
Or, equally valid: is there another way I could/should be achieving corner rounding besides "data-inset='true'"?
Here are things I have tried:
using .trigger("create") on both the listview and the page
adding the listview with explicit styling each time by using $("#page-ID").append(...)
I read another post on StackOverflow that said that JQM creates some inner elements when you create an item (this post had to do with dynamic buttons not being the right size), and that there are some classes (like .ui-btn) that you can access (that may be losing styling when I remove the children from the node?), but I was unable to make any headway in that direction.
Thanks in advance for the help!
I figured out the answer to my question, but not a solution (yet).
$(list).listview('refresh') was getting called on some elements before they had been put on the page, so it was essentially being called on nothing (or another way to think about it is that each list item being appended happens after the refresh call, so it overrides some of the visual styling).
I know the problem has to do with asynchronous loading in javascript. Essentially, the .listview('refresh) executes before the earlier code, which creates the elements but takes longer to execute. I understand the reasoning behind the design, but is there some way to get around this in this case?
I am thinking some conditional that I could set, like:
var doneLoading = false;
//Then when finished set doneLoading to 'true'
if(doneLoading) $(list).listview('refresh');
but if the refresh gets called first, I figure that doneLoading will just evaluate to false and then not execute once the list is actually done loading.
Is there any kind of onComplete callback I can use, or a way to make it happen synchronously?
Try calling listview(refresh) after updating the HTML.