Django - Dynamic number of ModelForms based on dropdown value - javascript

I have a form that registers teams of people. Based on a dropdown to select the number of members in the team, the form should show that many model forms, one for each member.
I am not particularly sure what the correct design patter for this is. Here are the solutions that I have come up with:
Use JS to generate the HTML for each member form and then use the Django ModelForm backend to parse each form. However, in this case I cannot use the inbuilt rendering functions of Django and validation notification becomes bothersome.
Send a GET request whenever the user changes the dropdown value, and the GET request specifies the number of members you want to add. But here it would result in any previously entered data being cleared.
Send a POST request via JS whenever the dropdown is updated, and then re-render the form with the appropriate values picked up from the POST request. I am not sure if this is the right way to do this and seems to be easy to get wrong.
Can you please advise on what is the best solution for this scenario?
I am pretty sure this has already been answered somewhere, but I can't seem to find it anywhere. If you have the link to the answer, please go ahead and mark this question as a duplicate.

Related

Efficiently validate that data on a page hasn't been changed by someone else since you loaded?

We have a page which contains a lot of user editable data that is populated from various tables in a database. The data is in all different forms, dropdowns, checkboxes, input boxes, text areas, etc...
There have been some conflicts where two users load a record around the same time, one makes changes, and then another makes a set of changes. When they save they are unaware someone else made a change and may have just broken a change they made or overwrote their change.
I am trying to implement a solution to mitigate this problem, such as flashing the user an error when the data was changed by someone else.
I am wondering if there is a best practice way to check for this problem? Some ideas I had are
Submit both 'current' data present in the field, and the 'original' data. Then check which are changed and compare them in the database to see if the defaults differ from what is currently saved. This would work, but seems to be the least performance friendly.
Use jquery/javascript to detect when a field has been edited, and if it has changed from defaultValue then set a hidden field which will be submitted to indicate it's original value. Then it would do similar to what the previous idea did.
Set a hidden field with a timestamp of when the user loaded their page. When they submit, use that timestamp and check our history table to see if any data on the page was changed since that timestamp. This seems to be the most efficient idea and likely easiest to implement.
Are there any better options or a best practice way to do this? I feel like I am reinventing the wheel for a common problem.
You are solving a common problem. But it's common because it needs repeatedly solved so frequently. "Optimistic Record Locking" is your path forward. It looks like yii (which I am not familiar with) has capabilities to incorporate handling this. I found this link.
Whether the yii infrastructure does this for you, or you have to build it yourself, what you want to do (to support Optimistic Record Locking) is the following:
Make and Keep an unchanged copy of your data when you retrieve it to the Client.
The Client must submit the changes together with the unchanged copy of the data back to the server.
The Server's 'update' routine compares the unchanged
copy to the current record(s). If something has been changed, then it must
return an error msg and the 'new' current record.
If nothing was changed, then the Server does the update.
The alternative is Pessimistic Record Locking, which you can check out. I avoid it due to other issues it has, but there are scenarios where it is more appropriate.

Populate form with previous data

I'm looking to add a feature to my application which currently, you enter your first name and last name and a few other details.
What I want to add is the ability to start typing the first name in the form and instantly output those with a similar name and if the name is there then use those details rather than entering the name again.
Once you've selected the name of a previous entry you can carry on adding the data to the form for the fields not populated.
I'm currently working with laravel any insight to tackling this one would be greatly appreciated.
Thanks
I have done this before but not in Laravel. The concepts should be mostly the same. The issue you will run into is how you want to qualify similar. If similar means you can use a "like" query against values the start with what has been typed against a database table, it's super easy. The simple way is going to perform a query like this:
$users = DB::table('users')
->where('name', 'like', 'rob%')
->get();
Because the wildcard is at the end, you can still use a standard database index to prevent your lookups from killing your database.
If you want something more advanced, you'll have to figure out indexing schemes and possibly use a full-text index server like Lucene. We ended up with the latter.
In either case, you will need an API endpoint that works with a front-end widget. I believe we used the JQuery plugin Select2. It has an example to make it work for a remote data set with Ajax.

Displaying a JS var across different pages

This is a kind of difficult question because I'm not sure how to word it. I'm making a shopping cart website using HTML5 and JS and I've got most of it down, but need help with one important aspect.
At the moment my "Buy Now" buttons are in tags that link to 1 page where the user can enter his info and make the purchase, this page is called "checkout". I want this "checkout" page to display the price of the item he wishes to purchase.
For ex) The user clicks on an book worth $10.00 and clicks the buy now button. This button will send him to the confirmation page where it will show a fill form, but the page does not show the price of the item he is purchasing.
This is where my problem lies. I can't think of any solution for this besides making a different page for each product (I only have 9 products).
Also, if it isn't blatantly obvious, I'm still a beginner with JS. Any help would be appreciated in helping me figure out how to display the price on the "checkout" page of each specific item without creating 9 separate pages. Thank You.
If I understand correctly, you are asking how to store a variable in Javascript that can be retrieved by multiple pages.
The canonical way to do this is to use cookies. The native cookie library is rather messy, so I recommend using a cookie library, like this.
However, since your question is tagged html5, you might be open to the sessionStorage HTML5 solution for this, which is much simpler than cookies.
sessionStorage.setItem("price", 100);
var price = sessionStorage.getItem("price");
The best way is to use some serverside solution. The client sends his form to your server, where the form gets evaluated and an according html-page is rendered.
The only other way is either using cookies or local Storage - but that's rather ugly.
You definitely should read some tutorials about php and mysql, but I'll give you rough overview on how to achieve this.
You provide a form on your page like this:
<form method="post" action="your-serverside-phpscript-that-processes-your-form.php>
How many Ipads you wanna buy:<input type="number" name="ipads">
<button type="submit">
</form>
now on serverside your php-script can evaluate the form.
all formfields are stored in a $_POST array. ( $_POST["ipads"] ) gets the value the user entered in the form. You don't need to store these values in the database yet.
You evaluate the formvalues and create the checkout-page with the according data (total price). Now the user submits the checkout-form, which you again process and store in the database.
I won't write down (sry, too tired) how this serverside part works, there are tons of tuts out there, just search google for php+mysql.
Since you're wanting to persist this data all on the client-end, I would encourage you to check out Amplify.Store. In full disclosure, I am currently employed by the company behind it - but it's great, and free.
Saving data is easy:
amplify.store( 'cart', { name: 'Book Title', price: 10.99 } );
To access this a little later, you can simply call:
amplify.store( 'cart' );
This will return your object from which you can get all of the products currently loaded. Amplify will evaluate your system and determine which storage method is best, and use it. This removes all of the guess-work form your plate, and let's you just do what it is you're wanting to do.
Please understand that while it is convenient to persist data client-side, it is by no means secure. When dealing with transactions and issues of a financial nature, you should always keep figures out of the hands of the consumer.
Generally data like this is stored server-side, within a session, a database, or a combination of both. However, if you understand the risks, and your model permits this type of persistence, then by all means feel free to use this as a solution.

Checkbox Captcha

I'm initiating my first start-up. I can't stand attempting to read captchas when signing up for websites, don't want my users to. I looked for alternatives, and I found the checkbox captcha. How is this done, using JavaScript to load a checkbox, and validate it with the same code as would normally be used to make a sign up form?
Thanks.
I looked at the example linked from the article you posted. At first glance, it seems like this can be easily bypassed.
The checkbox captcha works on the basis that spam-bots don't parse or use JavaScript code embedded in webpages. Because of this, they will not find the captcha checkbox element within the form it is searching, and therefore will not send a post value for the checkbox along with the form, and on the server side, you would reject the form if the checkbox value wasn't sent.
The problem with this is:
The checkbox name is always the same (gasp_checkbox)
A bot could easily be "trained" to detect this javascript on your page and act accordingly
Even if you output a random name and value that must be used for the checkbox, it could still be detected
The outcome of those 3 problems means that this is much easier to break than image captchas or other methods. All a bot has to do when they submit your form is add: gasp_checkbox=on to their HTTP request.
That said, if you implement this for yourself on your own site, it is unlikely that any bots will able to get past it because its use is not widespread.
You could make it more secure by doing the following:
Generate unique name/value pairs for the checkbox on the server side, and output those values in obfuscated javascript to the client
Serve the script away from your form, preferably in an external javascript file that is generated by a script.
Verify that the values sent for the checkbox match a pair that was previously generated, and not used before.
If you do those things, I think you could have an effective checkbox captcha. If someone does catch on to it on your site, it may still be trivial to defeat, even with the above safeguards in place, but it may take a while, and still be effective for you most of the time.

Exposing server-side state through client-side controls in ASP.net

Hopefully this isn't a redundant question--I'm not really sure how to word it. Let's say I have a list of items on an ASP.net page. That list is selectable in that whenever the user clicks on one, the page does a postback and the server code stores the index or some unique identifier of the picture in a ViewState property indicating that it is currently selected.
I would like to minimize the load on the server and therefore I would like to store the index or unique identifier representing the image in some way on the client side. The best way I can think to do this is to store said information in a hidden field ), however I had two questions about this before I go crazy:
Is this a security risk in any way, shape or form (i.e., exposing implementation details of the page)?
Is there a better/best way to do this that is more industry-standard? Does ASP.net provide a framework to do this that is cleaner than my idea? Seems like this would be a fairly common requirement to me...
I have been working in ASP.net for about two years now. Please, be kind :-)
Best,
Patrick Kozub
The only security risk would be if some list items must remain non-selectable. It sounds like that is not the case in your situation. The user already knows the information, because he or she already selected the item.
NOTE: If the server ever does anything with that information and pulls it back from the user, then you must validate the index value. Otherwise, the user could change it to an invalid index, such as (-2), and trigger an exception.
You can store the index (or related value) in a global javascript variable. If you're avoiding a trip back to the server, .NET doesn't really have a role to play.

Categories