locked
Design question, Web form with Drag and Drop jquery/static [webmethod] to db RRS feed

  • Question

  • User240536124 posted

    I have spent a couple of days on this and I'm just about ready to drop in a checkbox list control and be done with it. I am curious how other people handle this, though.

    I used the jquery from this link to make a drag and drop user roles selection (very similar to nopCommerce admin customer entry): ASP.NET HTML5 Drage and Drop

    See, what happens is, the user is going in the user table and the roles are going in a user role mapping table. It all works. This is where it doesn't.

    There is no user ID until the user is put in the user table. The Drag and Drop user roles are going in the mapping table with a jquery/static [webmethod].

    Because it is a static [webmethod], I can't pass it the ID. Also, I have timing issues, since the two things are independent.

    1) If I fire the jquery from my save button onclientclick, sometimes the roles go in before the user ID is even created.

    2) It's a static method and I can't easily pass it the user ID anyway.

    3) If I fire the roles function from codebehind w/ some version of Page.ClientScript.RegisterStartupScript(), it works but wipes out the user role selections.

    4) I can actually place the user ID in the roles <div> in a hidden class on Page_load and this works. Problem is, in actuality, I don't know the ID until the user is inserted into the table.

    5) Any version of placing the user ID into the page and passing it back to the [webmethod] using jquery always wipes out my drag and drop selections. It works, though, other than it doesn't.

    6) Using session variable to pass to the [webmethod] also don't work, because the user roles can be created before the user ID is put into the session variable.

    7) I have tried making the <div id="UserRoles" class="roles-class" runat="server" > and grabbing the contents of the div on the postback in codebehind. It gets the contents of the <div>, but not the roles that were selected via drag and drop.

    8) The one thing I can think of is using a user GUID that goes into the page at Page_load. The web service could get this and not put the roles into their map table until it gets an ID from the user table row that has this GUID in it. This just seems like a potential spot for errors that leave crap in tables that doesn't need to be there. Also, it seems like it would be slow, since it would have to sit there until it gets an ID from the user table.

    I know I'm not the only one to face this issue, I just haven't found anything that works...except that I know a checkbox list control will work just fine. :)

    Thanks,

    Jay

    Tuesday, November 5, 2019 2:42 PM

All replies

  • User475983607 posted

    A static web method has no bearing whatsoever on the order of database operations.  The code that you write determines order.  It is not clear why you are unable to create a user then add the user to a role within the scope of a the web method or across multiple HTTP requests like a wizard. 

    I think you need to take a step back and rethink the process.  

    Edit: perhaps the bug in the JavaScript application because you are using events.  If that's the problem then you need to use promises to control the order of the operations.

    Tuesday, November 5, 2019 3:41 PM
  • User240536124 posted

    I fail to see how it has no bearing whatsoever on the order of database operations. I have codebehind that is inserting the new user -- which creates a UserId -- and a static web method that inserts the roles.

    As far as I see, here are my choices. I can have the main save button do the user save with the OnClick= event AND fire the jquery/[webmethod] with the onclientclick event. This basically fires both at the same time. The web service seems to be the faster of the two, but I can't say that for sure. I have no control over the way both fire that I know of.

    I can remove the onclientclick event from the save button and fire it some other way. If you read above, I have tried firing it numerous ways. I spent a whole afternoon firing it at different points in the process. Yet here I am.

    In that regard, you are correct, if I register the jquery from the codebehind AFTER the user is created, it does fire the db insert afterward. However, for some reason during the process, I lose the roles that were dropped into the special drag and drop <div>, so what does that gain me?

    So, no control over timing that I know of, but it sort of works (minus a user id), or it absolutely works, but I lose the roles that were dropped into the drag and drop <div>. Thus here I am on here.

    -=-=-

    Also, I was trying to copy the nopCommerce interface, which is creating the user and user role mapping with one button click. It's using MVC now, though. And has more people working on it. Still, I would think what I'm trying to do would be possible.

    Thanks,

    Tuesday, November 5, 2019 6:30 PM
  • User240536124 posted

    Just for the sake of wondering, does anyone know if I take the time to install and learn the HtmlAgilityPack, could I use the html5/jquery drag and drop code on the client side and get the roles dropped in the <div> from codebehind using something like this:

    string stringThatKeepsYourHtml = "<div id=....";
    HtmlDocument doc = new HtmlDocument();
    doc.LoadHtml(stringThatKeepsYourHtml);
    string whatUrLookingFor = doc.GetElementbyId("myId").InnerHtml;

    If I could bypass the static web method, I'm sure the rest of it would be fairly easy.

    I have tried getting the contents of the div from codebehind by giving it an ID and runat="server" tag. If I hard code items in the HTML div, I can get them this way. If I drag and drop items to the <div>, nope.

    Is it even possible to get the contents of a div that a user has drug items into from straight codebehind?

    Thanks,

    Tuesday, November 5, 2019 7:18 PM
  • User475983607 posted

    So, no control over timing that I know of, but it sort of works (minus a user id), or it absolutely works, but I lose the roles that were dropped into the drag and drop <div>. Thus here I am on here.

    That's just crazy talk.   Code execution is not random and you have total control over how your code executes.  You have a deign bug.  I'm guessing it has to do with the fact that JavaScript events are asynchronous.   But you have not shared the code.  IS there anyway you can you share the code so we can see how your application works?

    Just for the sake of wondering, does anyone know if I take the time to install and learn the
    HtmlAgilityPack, could I use the html5/jquery drag and drop code on the client side and get the roles dropped in the <div> from codebehind using something like this:
    string stringThatKeepsYourHtml = "<div id=....";
    HtmlDocument doc = new HtmlDocument();
    doc.LoadHtml(stringThatKeepsYourHtml);
    string whatUrLookingFor = doc.GetElementbyId("myId").InnerHtml;

    If I could bypass the static web method, I'm sure the rest of it would be fairly easy.

    I have tried getting the contents of the div from codebehind by giving it an ID and runat="server" tag. If I hard code items in the HTML div, I can get them this way. If I drag and drop items to the <div>, nope.

    Is it even possible to get the contents of a div that a user has drug items into from straight codebehind?

    The browser does not post HTML to the server.  Use JavaScript/jQuery to parse the DOM and AJAX to submit name/values to the server.

    Tuesday, November 5, 2019 9:26 PM
  • User665608656 posted

    Hi jay,

    According to your description, can you explain your current code logic and design ideas from the beginning?

    You directly raised a lot of questions about your project, but we have no way to know what these are based on?

    Maybe I suggest that you can provide your current code, and then point out your problems in detail, which will help us solve your problems easily.

    Best Regards,

    YongQing.

    Wednesday, November 6, 2019 2:33 AM
  • User240536124 posted

    OK. Thanks everyone. I have managed to scrap the web service and get the drag and drop results from the codebehind. As long as I don't run into any timing issues again, I think this will work for me. If anyone needs to do HTML5 drag and drop with asp.net and save to a database without a static web service here is what to do:

    Download this guy's nice code: https://www.developer.com/lang/using-html5-drag-and-drop-in-asp.net.html

    This was a very good example, in my opinion, for the drag and drop part. It's clean and simple.

    I scrapped the entity framework and loaded the "products" from a MySql table. No changes were needed in his jquery.

    I simply added this one function and an asp.net button control:

    function SaveRoles() {
    var data = new Array();
    $("div .bag div").each(function (index) {
    data[index] = "'" + this.innerHTML + "'";
    });
    $(document.getElementById("hdnValue").value = data);
    }

    <asp:Button ID="Button4" runat="server" OnClick="Button4_Click" OnClientClick="SaveRoles();" Text="aspControl" />

    Add a hiddenfield called: hdnValue, also Label1.

    in codebehind:

    string Test = hdnValue.Value;
    Label1.Text = Test;

    Instead of using the web service, I added the above function that just sets the value of a hidden field (hdnValue) to what would have been passed to the web service in the sample code.

    Hitting the asp.net control button, I am able to get the products that were drug into the "cart" and set them to the text of Label1.Text.

    I can just split that string in the codebehind and process/insert it into the database.

    Thanks again.

    Wednesday, November 6, 2019 5:59 PM
  • User240536124 posted

    mgebhard

    That's just crazy talk.   Code execution is not random and you have total control over how your code executes.  You have a deign bug.  I'm guessing it has to do with the fact that JavaScript events are asynchronous.   But you have not shared the code.  IS there anyway you can you share the code so we can see how your application works?

    True, but I posted a link to the exact demo I was trying out and explained my problem.

    <asp:Button ID="Button4" runat="server" OnClick="Button4_Click" OnClientClick="SaveRoles();" Text="aspControl" />

    I didn't have a user id until I did a db insert (OnClick), but OnClientClick was putting in the drag and drop selected roles in the roles table first. This is a mapping table and has to have a user id. It was a static [webmethod] and not only was it trying to insert first, it is very difficult to pass something -- the needed user id -- from codebehind to a static [webmethod], even if I had the user id.

    Code execution may not be random, but every single thing I did to try and execute the jquery after the user id was created made it lose the values of the items drug into the special div. Everything I could think of to generate the user id ahead of time and pass it back to the server along with the selected user roles was really hokey.

    mgebhard

    The browser does not post HTML to the server.  Use JavaScript/jQuery to parse the DOM and AJAX to submit name/values to the server.

    I thought that was what the htmlagilitypack was supposed to do. Also, I was able to set the special div with an ID and runat="server" and get the div's inner html. However, only hard coded things worked. I could not get the contents of something drug into the special div with the drag and drop html5.

    Wednesday, November 6, 2019 6:20 PM
  • User475983607 posted

    jay8anks

    True, but I posted a link to the exact demo I was trying out and explained my problem.

    <asp:Button ID="Button4" runat="server" OnClick="Button4_Click" OnClientClick="SaveRoles();" Text="aspControl" />

    The first step in troubleshooting is reproducing the problem.  The community cannot reproduce your problem by looking at a demo then guessing how your code works.   We need the actual code.

    The line above shows a fundamental design bug.  The ASP button causes a full page refresh.  Everything on the current page including JavaScript  is overwritten by the server's response.  The OnClientClick will invoke the SaveRoles() JavaScript function but the results are not deterministic.   The page could refresh before function completes.   Also there are two separate HTTP requests coming from the same UI.  One is the button click and there other is the Web Method call.  These requests do not know about each other.  The two requests execute in two separate threads on the server and there is no easy way to sync the two HTTP requests.  

    A simpler approach is what you ultimately desiged above.  Use the drag and drop library to populate a hidden field then use the ASP.NET Button to submit everything to the server at one time.  Doing so lets you control the order of DB operations.

    Wednesday, November 6, 2019 8:40 PM