Big fan of your work.
I am building a Blazor WASM application utilizing the HTML5 Drag and Drop API. I am having the strangest issue that I've been trying to fix for hours.
This app allows one to put objects into "groups". A group can contain other groups, and so on.
I've got it mostly working, but two issues are leaving me scratching my head.
SOLVED See comment 1) When I drag a group UP from underneath into another group, the group is migrated into the destination but the subitems in the original group disappear.
Before I drag the bottom group up:
https://i.imgur.com/t7rGReI.png
After:
https://i.imgur.com/t5rIS1Y.png
When I drag a group DOWN from above into another group, the destination group's GUID overwrites the source and I am left with one group.
Before:
https://i.imgur.com/zC34cyT.png
After:
https://i.imgur.com/lSr4hGk.png
Groups are the orange shapes, Interfaces are the blue shapes. They are rendered via the Field class.
I've tried every permutation of the code I can think of and nothing has made it any better. I must be missing something here.
Group.razor
#inherits Item
<div id=#Uid class="tb-group tb-draggable #CssClass"
draggable = "true"
ondragover="event.preventDefault()"
#ondragstart:stopPropagation
#ondragstart="#(()=>HandleOnDragStart(this))"
#ondragend="HandleOnDragEnd"
#ondragenter="HandleOnDragEnter"
#ondragleave="HandleOnDragLeave"
#ondrop:stopPropagation
#ondrop="HandleOnDrop"
#onclick:stopPropagation
#onclick="Debug_Output">#Title : #Uid : #Parent.Uid
#foreach(Item item in Items){
if(item.GetType() == typeof(Group)){
<Group Uid=#item.Uid Title="#item.Title" Field=#Field Parent=#this></Group>
} else if(item.GetType() == typeof(Interface)){
<Interface Uid=#item.Uid Title="#item.Title" Field=#Field Parent=#this></Interface>
}
}
</div>
This code is responsible for OnDrop behavior (HandleOnDrop)
Group.razor.cs -
public partial class Group : Item {
public List<Item> Items;
protected override void OnInitialized()
{
Items = new List<Item>();
base.OnInitialized();
}
public void HandleOnDrop(){
if(Payload.Uid != this.Uid){
Console.WriteLine("Removing item " + Payload.Uid);
Items.Add(Payload);
Payload.Parent.Items.Remove(Payload.Parent.Items.Find(x => x.Uid == Payload.Uid));
}
CssClass = "";
this.Field.Refresh();
Payload.Parent = this;
}
...
Interface.razor
#inherits Item
<div id=#Uid draggable="true" class="tb-interface tb-draggable #CssClass"
#ondragstart:stopPropagation
#ondragstart="#(()=>HandleOnDragStart(this))"
#onclick:stopPropagation>#Title : #Uid : #Parent.Uid</div>
Could it be how I initialize these components (via constructor)? Maybe they're getting cleaned up by the GC?
Field.razor.cs -
public partial class Field : Group {
protected override void OnInitialized()
{
base.OnInitialized();
}
public void AddGroup(){
Group grp = new Group();
grp.Parent = this;
Items.Add(grp);
StateHasChanged();
}
public void AddInterface(){
Interface iface = new Interface();
iface.Parent = this;
Items.Add(iface);
StateHasChanged();
}
public void Refresh(){
StateHasChanged();
}
}
I'm at my wits end here. If anyone could give me some advice it would be much appreciated.
Issue #1: Needed to pass the Items object into Group on instantiation
Issue #2: Needed to use #key to maintain reference
Related
I'm quite new in web development, have only couple of weeks of experience.
Currently working on C# website and can't get ReCaptchaV3 to work.
I have a subscribe form that shows up as a modal when user clicks on a "subscribe" button on the bulletin page.
In the form I have hidden input field: <input type="hidden" name="Google-captcha-token" id="GoogleCaptchaToken">
It generates the token when "Sign Up" button of the form is clicked.
My problem is - how to I get a hold of that value on the backend in C#? and then send it to google for verification? I also need to check if value I got from Google is within needed range and everything is good continue submitting the form.
This is where I stuck. I understand that I need to catch that value and work with it in the controller, but don't know how to do that.
Hope someone can help me out on this one.
This is how the code in the controller looks
public class BulletinController : _SharedController {
public ActionResult Index(int p = 0) {
var perPage = 10;
if (p < 1) {
p = 1;
}
var starting = (p * perPage) - perPage;
if (starting < 0) {
starting = 0;
}
var token = HttpContext.Request.Form["Google-captcha-token"];
var ns = new NewsServices();
var newsArticles = ns.GetNewsArticles(starting, perPage);
var count = ns.GetNewsArticlesCount();
ViewBag.Paging = Pagination.Generate(count, starting, perPage);
return View(newsArticles);
}
public ActionResult Details(int id) {
var article = new NewsServices().GetNewsArticleByID(id);
if (article == null) {
return HttpNotFound();
}
return View(article);
}
}
I watched a lot of videos on how it should be done, but none of them worked.
It seems to be a problem that view of the page is already using a model and that model is autogenerated. So looks like I can't use another model. Current model is also a list model (not sure what that exactly means though).
The other thing is that submission of the form is not going through the back-end and done through the constantcontact JavaScript sign up script.
Hope somebody will be able to help. Thanks.
I have a web application in Vaadin 7, I use JavaScript and it works on Google Chrome, but doesn't on IE 11. This is my way of to use JavaScript (I don't want doing it with Java if it's possible)
com.vaadin.ui.JavaScript.getCurrent().addFunction("left", new JavaScriptFunction(){
private static final long serialVersionUID = 1L;
#Override
public void call(JsonArray arguments) {
zinkonaux.executeJs(""
+ "var box = document.querySelector('.divobjetos');"
+ "var pos = window.getComputedStyle(box,null).getPropertyValue('left');"
+ "pos = parseInt(pos);"
+ "pos = pos + 300;"
+ "box.style.left = pos+'px';"
);
}
});
My problem is:
In IE the javascript function does not work, I want to click on one of the previous div, another scroll, like a carousel effect, but in IE when clicking does not make the effect and in the development window there are no errors
I would suggest moving your Javascript into a separate file. If you want the JS method to be available throughout your application you could use the #JavaScript annotation on your UI class.
package com.company
#JavaScript("test.js")
public class MyUI extends UI
{
...
Then you need to put test.js into your resources folder (if you're using maven) in the folder /com/company/test.js which would look something like this.
function left()
{
var box = document.querySelector('.divobjetos');"
var pos = window.getComputedStyle(box,null).getPropertyValue('left');"
pos = parseInt(pos);"
pos = pos + 300;"
box.style.left = pos+'px';
}
I could not solve the JavaScript error in IE, specifically to change the position of the inner div between the left and right containers, use in each one a button that in its ClickListener modified the style with:
Styles styles = Page.getCurrent().getStyles();
styles.add(".divscroll .divobjects { left: "+positionInfoTags+"px !important }");
My html code was this:
<div class="container">
<div class="left" location="moveLeft"></div>
<div class="right" location="moveRight"></div>
<div class="divscroll">
<div class="divobjects" location="infoTags">
</div>
</div>
</div>
I was trying to dragging a canvas within a canvas. To handle the dragging events I was using
addDragRepositionStartHandler,
addDragRepositionMoveHandler,addDragRepositionStopHandler
handlers.
I need to restrict dragging on few condition. Lets say I want to restrict dragging when we'll get event.getX() more than 500 in public void onDragRepositionMove(DragRepositionMoveEvent event).
I tried event.cancel();, but it don't serve the purpose. All I need is to restrict the dragging.
Any kind of help is appreciated.
Take a look at this showcase demo. Some relevant code extracted from the demo:
DragPiece green = new DragPiece("pawn_green.png"){
#Override
protected boolean setDragTracker() {
String html = Canvas.imgHTML("pieces/24/pawn_green.png", 24, 24);
EventHandler.setDragTracker(html);
return false;
}
};
green.setID("greenPiece");
green.setTitle("Green Piece");
green.setLeft(150);
green.setTop(50);
final Label label = new Label("Drop Here");
label.setLeft(250);
label.setTop(50);
label.setShowEdges(true);
label.setAlign(Alignment.CENTER);
label.setCanAcceptDrop(true);
label.addDropOverHandler(new DropOverHandler() {
public void onDropOver(DropOverEvent event) {
label.setBackgroundColor("#FFFF88");
}
});
label.addDropOutHandler(new DropOutHandler() {
public void onDropOut(DropOutEvent event) {
label.setBackgroundColor("#ffffff");
}
});
label.addDropHandler(new DropHandler() {
public void onDrop(DropEvent event) {
Canvas target = EventHandler.getDragTarget();
SC.say("You dropped the " + target.getID());
}
});
Some notes about this code:
Notice how a label is used to define the drop region, but you could use other Canvas objects for that purpose.
The addDropOverHandler, addDropOutHandler and addDropHandler methods allow you to add the required handlers to this Label or Canvas object to produce the desired results.
DragPiece is just a subclass of Img that has setCanDragReposition(true) and setCanDrop(true), so that the element is draggable.
hi i create simple app to display html page in webview i use the webview and display the page load time like this.
After this Disable the scroll and use the next and previous button to back and forward contain.
So my code is below.
First onCreate display add webview and load the html file.
mainWebView = (WebView) findViewById(R.id.mainWebView);
mainWebView.setVerticalScrollBarEnabled(false);
mainWebView.setHorizontalScrollBarEnabled(false);
mainWebView.getSettings().setJavaScriptEnabled(true);
mainWebView.setWebViewClient(new MyWebClient());
mainWebView.setPictureListener(new MyPictureClass());
mainWebView.loadUrl("file:///android_asset/chapter-001.html");
after use the MyWebclient Class for get the Height and width for mainwebview.
class MyWebClient extends WebViewClient
{
#Override
public void onPageFinished(WebView view, String url)
{
System.err.println("Page Finish Call");
lanscapHeight = protraitHeight = findHeight = mainWebView.getHeight();
System.err.println("Find Height->"+findHeight);
System.err.println("Portait Height->"+protraitHeight);
System.err.println("Landscap Height->"+lanscapHeight);
}
}
after this use the myPictureClass to get the webView contain length.
class MyPictureClass implements PictureListener
{
#Override
public void onNewPicture(WebView view, Picture picture)
{
proTraitContain = mainWebView.getContentHeight();
System.err.println("picture Class Call-->"+proTraitContain);
}
}
after this.create button next and previous to display the next and previous page.so use the SimpleOnGestureListener to Detect touch event.
btnNext = (Button) findViewById(R.id.btnNext);
btnNext.setOnTouchListener(this);
btnPrev = (Button) findViewById(R.id.btnPrev);
btnPrev.setOnTouchListener(this);
Override touch Method.
#Override
public boolean onTouch(View view, MotionEvent event)
{
if (view == btnNext)
{
btnClickFlage = true;
gestureDetector.onTouchEvent(event);
} else
{
btnClickFlage = false;
gestureDetector.onTouchEvent(event);
}
return false;
}
implement the SimpleGestureListener class as Below.
class MyGesture extends SimpleOnGestureListener
{
#Override
public boolean onSingleTapUp(MotionEvent e)
{
super.onSingleTapUp(e);
System.err.println("Display Total Contain For Protrait -->"+proTraitContain);
System.err.println("Before Height-->" + findHeight);
if (btnClickFlage)
{
if (findHeight > (proTraitContain+protraitHeight))
{
if(restProtraitFlag)
{
System.err.println("If part In side Flag-->"+findHeight);
findHeight=findHeight+protraitHeight;
restProtraitFlag=false;
//findHeight=findHeight+protraitHeight;
mainWebView.scrollTo(0, findHeight);
System.err.println("If part In side Flag-->"+findHeight);
}else
{
mainWebView.loadUrl("file:///android_asset/chapter-002.html");
restProtraitFlag=true;
}
}
else
{
if(protraitFlag)
{
if(findHeight==protraitHeight)
{
findHeight = protraitHeight;
}else
{
findHeight = findHeight + protraitHeight;
}
protraitFlag=false;
}else
{
findHeight = findHeight + protraitHeight;
}
mainWebView.scrollTo(0, findHeight);
}
}
else
{
restProtraitFlag=true;
if (findHeight<=0)
{
mainWebView.loadUrl("file:///android_asset/chapter-001.html");
System.err.println("Load Previous page");
}
else
{
findHeight = findHeight - protraitHeight;
mainWebView.scrollTo(0, findHeight);
}
}
System.err.println("After Height-->" + findHeight);
}
return true;
}
}
but i can't Display the last page of current html page path.now what to do.any solution please give.it's urgent.
i get the content width properly and use the scrollTo method to display but i can't do it.after last page rest of some contain can't display.
Please saw me the any way.
Thank in advance..
Hi Friends Finally i got my question answer.i use the ScrollTo method to scroll the contain and Display next contain of current page.but problem is there webView Display all contain according device.so all time contain display is higher then this current value.so i use the Webview.getScale(); method to Display how much scale use by webview.according to this i use this method and get current contain of webview in and use Display page wise.its finally its work for me..
Name For CalenderOuthenticationDe
Hello You have to put your HTML in res and then in that you have to keep it in raw after then you can access it like this...
webviewTips.loadUrl("file:///android_res/raw/tips.html");
You are showing the web page stored in your assets folder or from sd card.
So, My advice is that leave this approach and this way to show the web page to user..
And Edit your HTML files and put Anchor Tags in that...using that the user can traverse through the web page easily. (Example for that)
I have the following code to smooth animation on a collapsiblepanel, and it works splendidly:
<script type="text/javascript">
function pageLoad(sender, args) {
smoothAnimation();
}
function smoothAnimation() {
var collPanel = $find(("<%= CollapsiblePanelExtender.ClientID %>"));
collPanel._animation._fps = 30;
collPanel._animation._duration = 0.5;
}
</script>
Now, I also have a listview, separate from the above panel, that has a collapsible panel extender inside each of its items. I would like to apply that "smoothAnimation()" function to each of them, but I don't know how to do that, since databinding gives each item a unique ID.
Does anybody know how to approach this in javascript? Any help is greatly appreciated.
Use the OnItemCreated event, and use the following:
protected void ListItems_Created(object sender, ListViewItemEventArgs e)
{
CollapsiblePanelExtender cpe = (CollapsiblePanelExtender)e.Item.FindControl("collapsePanelID");
cpe.Attributes.Add("onload", cpe.ClientID + "._animation._fps = 30;");
cpe.Attributes.Add("onload", cpe.ClientID + "._animation._duration = 0.5;");
}
This code is untested but it's all you should need to get this working.