I am writing an ASP.Net application that allows anonymous people to post prayers and others to comment on/confirm to pray for these objects. Prayers are stored in a SQL Server 2008 database with a unique identifier.
They are displayed using a repeater control and a hidden field to store the ID of the row. Each item in the repeater contains a button that allows anonymous people to pray and this is incremented as a counter inside the database.
Basically, once a user has confirmed that he/she is praying for this item, I want to disable the button and display the total count for that row.
It is my understanding that I can store data in cookies/sessions so the only solution I could come up with so far would be to store the ID of the row into one of these objects and then use custom logic inside of my repeater control to check to see which are present.
Can anyone offer some insight as to what the most efficient way to accomplish something like this might be? If there are options other than cookie or session I'd be glad to hear that too.
EDIT:
I am trying to implement this solution using the following logic.
Codebehind:
protected bool IsPrayerInCookie(string prayerId)
{
if(Request.Cookies["prayers"][prayerId] != null)
{
return false;
}
else
{
return true;
}
}
ASPX:
<span class="confirmed_prayers"><span class="trans">
<asp:Label runat="server" ID="lblConfirmedPrayers" Text='<%# Eval("ConfirmedPrayers") %>' />
people have prayed for this.</span></span>
<% if(!IsPrayerInCookie(Eval("PrayerId").ToString()))
{
%>
<asp:LinkButton ID="btnPray" CssClass="but_styled" runat="server" TabIndex="8" CommandName="IncrementPrayer">
<span><span class="check">
Pray for This</span></span></asp:LinkButton>
<%
}
%>
This isn't working however. Can anyone help me figure out how to make the if statement work inside of the aspx file to properly call the code behind method with the correct ID?
Session will only last as long as the user is on the site. Therefore, if they close their browser and come back, it will be gone.
Cookies would be the better choice, and only if they clear their cookies will this data be gone.
If you don't require the user to log in, I'm thinking this is all you could do.
Heres the MSDN page on cookies:
http://msdn.microsoft.com/en-us/library/ms178194.aspx
For the actual cookie storage, I would do something like:
Response.Cookies["prayerlist"][CurrentPrayerItemID].Value = "something"; //All that matters is that they have the cookie with this ID.
Response.Cookies["prayerlist"].Expires = DateTime.MaxValue;
So when someone clicks to add that item, you will first want to check to see if they already have that id in their cookie, like so:
if(Response.Cookies["prayerlist"][CurrentPrayerItemID] != null)
{
Response.Cookies["prayerlist"][CurrentPrayerItemID].value = "something";
// Add prayer to Database
}
And likewise, you would check the cookie whenever you bind the repeater. If they have that cookie, you would disable the corresponding pray button.
I'm not sure how to approach this, since idk how your binding, but it will look something like this:
foreach(Item item in YourListOfItemsThatYouAreBindingToTheRepeater)
{
if(Response.Cookies["prayerlist"][CurrentPrayerItemID] != null)
{
//Disable Button - Set "HasPrayed" = true
}
}
To actually disable the button, what i would do is set a value in your list to false, and then in the aspx page, do something like this:
<asp:Button ID="button1" runat="server" Enabled='<%# !(bool)Eval("HasPrayed") %>' />
Using !(bool)Eval("HasPrayed") since you want to set enabled to false if HasPrayed is true.
You can use sessions to store the prayer items that the user has clicked on, but when they come back to your site it will forget all the previous items because the session has been lost.
In this case you can use a cookie to store all the prayer item ids that the user has clicked the "I'll pray for this" button. I'd go this route if you don't want to require user logins.
For the code you're describing, I think you could use an ASP.NET UpdatePanel which will allow you to update/show the number of people praying for the item and to disable the button.
Related
In our current scheme we have an Crystal Report that can be shown once a record has been saved/changed.
What we want to do is add a 'print' button to the main data management form - allowing the user to print an existing report "as is". However, I want to disable/hide the print button if the user changes any of the 20+ fields (these controls are a mixture of check, text, & pull-down boxes).
Without having to add code change events for EVERY control, is there a way (assuming javascript) to capture a change to any one of the controls and then hide/disable the print button until the changes have been saved?
Edit:
Using the answer offered by #Bosco, the below code is a sample of our solution:
<asp:DropDownList ID="TypeDDL" CssClass="dropDownList1 ChangeClass" runat="server"
<asp:TextBox ID="DescriptionTextBox" runat="server" class="descriptionText ChangeClass" TextMode="MultiLine"></asp:TextBox>
$(".ChangeClass").on("change", ManagePrintButton);
function ManagePrintButton() {
//debugger;
var btn = document.getElementById("btnPrintExport");
btn.style.display = "none";
}
You can use jQuery wildcard selectors.
Give you inputs same class names and bind the change event to them this way
$(".theClass").on("change");
Another way is to use the id
Let's say that the IDs starts with a particular text/character or ends with a particular text/character
$("[id^=theText]")
//This gets all the elements that the id starts with theText
$("[id$=theText]")
//This gets all the elements that the id ends with theText
also the JQuery documentation https://api.jquery.com/category/selectors/
I'm trying to prevent users without Administrative access from saving a form with the "complete" status selected, if it was not already selected (e.g. users are allowed to open up forms and make edits to their data, even if the status is set to complete, they just cannot initially mark their documents as complete).
The reason users are allowed to make changes to 'completed' documents is that the electronic record is just a reflection of a behinds the scenes work process. In order for an item to be marked as complete, several other processes have to have been completed. The information can be edited after the fact to account for errors in transcription or verbiage.
I'm thinking that it would be sufficient to just utilize an onChange event that re-selects the previous selection if a user tries to change the status to complete . I'm looking for an elegant way to do it, hopefully without storing the previous selection in a separate field on the page, as it is already stored elsewhere.
the grantBacking.editGrant.statusCode is the saved/current status code for the form. Also, there are at least three different role types including just read access, 'Add', and 'Administrator'. Read - self explanatory, Add - Can make changes to the form but should not be able to complete a form, and Administrator - can make changes and can mark a form status as "complete".
This is what I have so far:
<t:panelGroup>
<sec:authorize ifNotGranted="ADMINISTRATOR">
<h:selectOneMenu id="grantStatus" onchange="#checkGrantStatusPermissions(this,grantBacking.editGrant.statusCode)" onmouseover="Tip('#{msg_bundle.grant_status_help}')" value="#{grantBacking.editGrant.statusCode}">
<f:selectItems value="#{grantBacking.grantSelectStatusForNonAdmin}" />
</h:selectOneMenu>
</sec:authorize>
<sec:authorize ifAnyGranted="ADMINISTRATOR">
<h:selectOneMenu id="grantStatusForAdmin" onmouseover="Tip('#{msg_bundle.grant_status_help}')" value="#{grantBacking.editGrant.statusCode}">
<f:selectItems value="#{grantBacking.grantSelectStatus}" />
</h:selectOneMenu>
</sec:authorize>
<sec:authorize ifAnyGranted="ADD">
<a4j:commandLink id="qsave2" render="#all" onmouseover="Tip('Click to quick save')" action="#{grantBacking.saveGrant}">
<h:graphicImage title="Click this to quick save the grant/contract" style="border-style:none;" height="20px" width="15px" library="default" name="img/icons/disk.png" />
</a4j:commandLink>
</sec:authorize>
<script type="text/javascript">
function checkGrantStatusPermissions(field, originalValue){
if(originalValue.equalsIgnoreCase("complete")){
return
}
else{
document.getElementByID(field).value = originalValue.value;
}
}
</script>
Prior to the item being marked as complete you can disable the option by building your selectItems like so:
<f:selectItems value="#{grantBacking.grantSelectStatusForNonAdmin}" var="v"
itemDisabled="#{grantBacking.shouldDisableOption(v)}"/>
If your version of the EL doesn't include the ability to pass parameters you can accomplish the same by using an inner class that holds your value, label, and has a parameterless method for shouldDisable.
When it comes to submitting a completed form if the user can't change it from Complete to some other status, then just make the selectMenu readonly. If they can, then your shouldDisable logic should return false in this case.
Doing something like this prevents the users from selecting known bad values and avoids you coding behavior that the users wouldn't expect leading to potential bug reports.
Title isn't that clear, so let me see if I can explain what I'm doing.
I'm listing off users' posts, and have a like/comment button with those posts.
What I need to do, is capture when the like button is clicked (<span> tags), and then grab the post id from the hidden input field, and use that to post to the PHP script.
The PHP is doing all of the checking for if they're friends, privacy level is correct, etc. before actually submitting the like to the database, but I am currently just having the javascript/jquery be generated when the post is shown (naming each js variable/DOM element according to post id), but that's not very efficient and looks messy when viewing the source (But, it's the only way I can get it to work).
I want to be able to use an external javascript file to check when just the like button is clicked, and know what post that is being liked, and work that way.
I've been looking into this for quite some time, and it's to my understanding that this might work, but I have had no luck. I'm generating multiple posts on one page using foreach() loop, so the names/ids/classes of the elements are the same.
For a little better understanding, here's an example of what a post might look like:
<div class="feedPost">
<img src="#" class="feedProfile"/>
FirstName LastName
<div class="feedPostBody">Hello, world!</div>
<input type="hidden" value="24772" name="feedPostID">
<span class="feedLikeButton">Like</span> | Comment | 2 mins ago
</div>
and, using javascript/jquery, I want to be able to do something like this in an external js file:
$('.feedLikeButton').on('click',function(){
var post_id = 0; //I need to get the ID from the post that the like button is related to.
//If I just did $('.feedPostID').val() it wouldn't work
$.post("https://mysite/path/to/like.php", {post: post_id}).done(function(data){
if(data == "success"){
//This will set text from "Like" to "Unlike"
//Again, I can't just do $('.feedLikeButton') to access
//I guess I could do this.innerHTML? Would still need to access feed post id
} else {
//Probably will just flash error to user if error, or something similar
}
});
});
You should get the like button
var likeButton = $(this);
Then get it's container
var container = likeButton.parent();
Then find the hidden field
var idInput = container.find('[name="feedPostID"]');
Then get it's value:
var id = idInput.val();
With all these references you can do whatever you want.
I have a field called ProductName that has a specific product name in it. When logged in any user can update the product name by clicking on the text and hitting save.
The code came from http://www.appelsiini.net/projects/jeditable for this to be possible.
I have roles set up in ASP.net VB for admins and non-admins and was wondering if there is any way in the Javascript to state that only admins are allowed to edit that field.
This is the Javascript code for the editable field:
$('.productName.edit').editable(function (value, settings) {
var ProductID = $('input#body_ProductID').val();
var result = SubmitProductName(ProductID, value);
return (value);
}, {
width: '350',
submit: 'Save Changes',
cancel: 'Cancel',
onBlur: 'ignore'
});
Here is the field itself in ASP:
<asp:FormView ID="fvProduct" runat="server" DataSourceID="dsProduct">
<ItemTemplate>
<h1 class="productName edit"><%# Eval("ProductName")%></h1>
</ItemTemplate>
</asp:FormView>
I would really appreciate any help. Thanks.
You could do this in javascript, but this will be bypass-able for anyone disabling/hacking javascript (which is very easily doable). You should do this on server-side.
If you really want to do this in javascript, just check permission through an ajax call.
You should do this on server side but still if you want to do this on client side then when a user logs in you can store a cookie that keeps track of whether he is an admin or non-admin.Now when someone tries to edit the field check whether that cookie you stored says he is an admin or not. If he is admin then allow editing otherwise not.
I have some code on my ASP page which looks like this:
<asp:UpdatePanel runat="server" id="updatepanel1" UpdateMode="Conditional" onload="updatepanel1_Load" ChildrenAsTriggers="false">
<ContentTemplate>
<asp:HiddenField id="sendingRequest" runat="server" Value="0" />
....
</ContentTemplate>
</asp:UpdatePanel>
I also have some javascript on my page which does this, to trigger the update of the updatepanel:
var sendingRequest = document.getElementById("<%=sendingRequest.ClientID%>");
sendingRequest.value = "1";
__doPostBack('<%= updatepanel1.ClientID %>', '');
Everything works fine up to now, but in my updatepanel1_Load event, I try to set the value back to "0" :
sendingRequest.Value = "0";
This value never gets updated and set back to 0 on the client after the postback, and I can't figure out why!
Can anyone help? Thanks
If you're having problems with a hidden field, you could use a TextBox instead. Hide the textbox with css (display: none;) to achieve similar results to a hidden field. Its not exactly pretty, but its a workable workaround.
Try to call registerstartupscript or something like that from server side. I can't remember exactly the method name but its part of page object. This will register any javascript you would like to execute after postback on the client side.
This similar scenario is done here successfully:
http://encosia.com/easily-refresh-an-updatepanel-using-javascript/
Ensure you are following the same steps - I can't see all of your code. Try with a label first to make sure it gets updated as a visible control. If that works then narrow it down with your hidden value to make sure the behavior isn't different for a hidden control.
I had an issue with three HiddenFields being set in Code-Behind, but their values were not set when polled from JQuery.
My issue turned out being that my Master Page uses an UpdatePanel, and in my ASP.Net Init event I was purposing that UpdatePanel with conditional rendering.
Private Sub Page_Init(sender As Object, e As System.EventArgs) Handles Me.Init
mstr = CType(Master, Site)
'setup partial rendering so Log can update asynchronously
scriptManager = CType(mstr.FindControl("ScriptManager1"), ScriptManager)
scriptManager.EnablePartialRendering = True
scriptManager.AsyncPostBackTimeout = 28800
CType(mstr.FindControl("UpdatePanel1"), UpdatePanel).UpdateMode = UpdatePanelUpdateMode.Conditional
CType(mstr.FindControl("UpdatePanel1"), UpdatePanel).ChildrenAsTriggers = False
End Sub
The issue was that I forgot to then call update on my panel after setting the HiddenFields. I had to do this because my button was a partial-postback control (UseSubmitBehaviour=False)
hfParams.Value = paramlist.ToString()
hfForms.Value = formlist.ToString()
hfStartJob.Value = "True"
CType(mstr.FindControl("UpdatePanel1"), UpdatePanel).Update()