Commit ff642c83 by swdanielli

v0.1 + ux modified

parent 3a0df065
...@@ -92,39 +92,41 @@ class RecommenderXBlock(XBlock): ...@@ -92,39 +92,41 @@ class RecommenderXBlock(XBlock):
@XBlock.json_handler @XBlock.json_handler
def handle_upvote(self, data, suffix=''): def handle_upvote(self, data, suffix=''):
''' untested ''' ''' untested '''
resource = data['resource'] resource = data['resource']
idx = self.getRecommendationIndex(resource) idx = self.getRecommendationIndex(resource)
if resource in self.upvotes: if resource in self.upvotes:
print "Upvote failed!" del self.upvotes[self.upvotes.index(resource)]
return {"Success": False} self.recommendations[idx]['upvotes'] -= 1
elif resource in self.downvotes:
if resource in self.downvotes: del self.downvotes[self.downvotes.index(resource)]
del self.downvotes[self.downvotes.index(resource)] self.recommendations[idx]['downvotes'] -= 1
self.recommendations[idx]['downvotes'] -= 1 self.upvotes.append(resource)
else: self.recommendations[idx]['upvotes'] += 1
self.upvotes.append(resource) else:
self.recommendations[idx]['upvotes'] += 1 self.upvotes.append(resource)
print "Upvote clicked!" self.recommendations[idx]['upvotes'] += 1
return {"Success": True} print "Upvote clicked!"
return {"Success": True}
@XBlock.json_handler @XBlock.json_handler
def handle_downvote(self, data, suffix=''): def handle_downvote(self, data, suffix=''):
''' untested ''' ''' untested '''
resource = data['resource'] resource = data['resource']
idx = self.getRecommendationIndex(resource) idx = self.getRecommendationIndex(resource)
if resource in self.downvotes: if resource in self.downvotes:
print "Downvote failed!" del self.downvotes[self.downvotes.index(resource)]
return {"Success": False} self.recommendations[idx]['downvotes'] -= 1
elif resource in self.upvotes:
if resource in self.upvotes: del self.upvotes[self.upvotes.index(resource)]
del self.upvotes[self.upvotes.index(resource)] self.recommendations[idx]['upvotes'] -= 1
self.recommendations[idx]['upvotes'] -= 1 self.downvotes.append(resource)
else: self.recommendations[idx]['downvotes'] += 1
self.downvotes.append(resource) else:
self.recommendations[idx]['downvotes'] += 1 self.downvotes.append(resource)
print "Downvote clicked!" self.recommendations[idx]['downvotes'] += 1
return {"Success": True} print "Downvote clicked!"
return {"Success": True}
@XBlock.json_handler @XBlock.json_handler
...@@ -148,7 +150,8 @@ class RecommenderXBlock(XBlock): ...@@ -148,7 +150,8 @@ class RecommenderXBlock(XBlock):
new_resource['upvotes'] = 0 new_resource['upvotes'] = 0
new_resource['downvotes'] = 0 new_resource['downvotes'] = 0
new_resource['id'] = self.getResourceNewId() new_resource['id'] = self.getResourceNewId()
new_resource['isMisuse'] = "notMisuse" new_resource['isProblematic'] = "notProblematic"
new_resource['problematicReason'] = ""
print "before append" print "before append"
# self.resources.append(new_resource) # self.resources.append(new_resource)
self.recommendations.append(new_resource) self.recommendations.append(new_resource)
...@@ -185,7 +188,7 @@ class RecommenderXBlock(XBlock): ...@@ -185,7 +188,7 @@ class RecommenderXBlock(XBlock):
print "Flag failed!" print "Flag failed!"
return {"Success": False} return {"Success": False}
self.recommendations[idx]['isMisuse'] = data['isMisuse'] self.recommendations[idx]['isProblematic'] = data['isProblematic']
return {"Success": True} return {"Success": True}
# TO-DO: change this view to display your data your own way. # TO-DO: change this view to display your data your own way.
...@@ -208,19 +211,15 @@ class RecommenderXBlock(XBlock): ...@@ -208,19 +211,15 @@ class RecommenderXBlock(XBlock):
# TODO: Sort by votes # TODO: Sort by votes
# Ideally, we'd estimate score based on votes, such that items with 1 vote have a sensible ranking (rather than a perfect rating) # Ideally, we'd estimate score based on votes, such that items with 1 vote have a sensible ranking (rather than a perfect rating)
# #
resources = [{'id' : r['id'], 'title' : r['title'], "votes" : r['upvotes'] - r['downvotes'], 'url' : r['url'], 'description' : r['description'], 'isMisuse': r['isMisuse']} for r in self.recommendations] resources = [{'id' : r['id'], 'title' : r['title'], "votes" : r['upvotes'] - r['downvotes'], 'url' : r['url'], 'description' : r['description'], 'isProblematic': r['isProblematic'], 'problematicReason': r['problematicReason']} for r in self.recommendations]
resources = sorted(resources, key = lambda r: r['votes'], reverse=True) resources = sorted(resources, key = lambda r: r['votes'], reverse=True)
print resources frag = Fragment(self.template_lookup.get_template("recommender.html").render(resources = resources, upvotes = self.upvotes, downvotes = self.downvotes))
frag = Fragment(self.template_lookup.get_template("recommender.html").render(resources = resources))
frag.add_css_url("//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css") frag.add_css_url("//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css")
frag.add_css_url("//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css") frag.add_css_url("//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css")
frag.add_javascript_url("//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js") frag.add_javascript_url("//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js")
frag.add_css(self.resource_string("static/css/recommender.css")) frag.add_css(self.resource_string("static/css/recommender.css"))
frag.add_css(self.resource_string("static/css/colorbox.css"))
frag.add_javascript(self.resource_string("static/js/src/recommender.js")) frag.add_javascript(self.resource_string("static/js/src/recommender.js"))
frag.add_javascript(self.resource_string("static/js/src/jquery.colorbox.js"))
frag.initialize_js('RecommenderXBlock') frag.initialize_js('RecommenderXBlock')
return frag return frag
...@@ -234,15 +233,15 @@ class RecommenderXBlock(XBlock): ...@@ -234,15 +233,15 @@ class RecommenderXBlock(XBlock):
"""<vertical_demo> """<vertical_demo>
<html_demo><img class="question" src="http://people.csail.mit.edu/swli/edx/recommendation/img/pset.png"></img></html_demo> <html_demo><img class="question" src="http://people.csail.mit.edu/swli/edx/recommendation/img/pset.png"></img></html_demo>
<recommender> <recommender>
{"id": 1, "title": "Covalent bonding and periodic trends", "upvotes" : 15, "downvotes" : 5, "url" : "https://courses.edx.org/courses/MITx/3.091X/2013_Fall/courseware/SP13_Week_4/SP13_Periodic_Trends_and_Bonding/", "description" : "http://people.csail.mit.edu/swli/edx/recommendation/img/videopage1.png", "isMisuse": "notMisuse"} {"id": 1, "title": "Covalent bonding and periodic trends", "upvotes" : 15, "downvotes" : 5, "url" : "https://courses.edx.org/courses/MITx/3.091X/2013_Fall/courseware/SP13_Week_4/SP13_Periodic_Trends_and_Bonding/", "description" : "http://people.csail.mit.edu/swli/edx/recommendation/img/videopage1.png", "isProblematic": "notProblematic", "problematicReason": ""}
{"id": 2, "title": "Polar covalent bonds and electronegativity", "upvotes" : 10, "downvotes" : 7, "url" : "https://courses.edx.org/courses/MITx/3.091X/2013_Fall/courseware/SP13_Week_4/SP13_Covalent_Bonding/", "description" : "http://people.csail.mit.edu/swli/edx/recommendation/img/videopage2.png", "isMisuse": "notMisuse"} {"id": 2, "title": "Polar covalent bonds and electronegativity", "upvotes" : 10, "downvotes" : 7, "url" : "https://courses.edx.org/courses/MITx/3.091X/2013_Fall/courseware/SP13_Week_4/SP13_Covalent_Bonding/", "description" : "http://people.csail.mit.edu/swli/edx/recommendation/img/videopage2.png", "isProblematic": "notProblematic", "problematicReason": ""}
{"id": 3, "title": "Longest wavelength able to to break a C-C bond ...", "upvotes" : 1230, "downvotes" : 7, "url" : "https://answers.yahoo.com/question/index?qid=20081112142253AA1kQN1", "description" : "http://people.csail.mit.edu/swli/edx/recommendation/img/dispage1.png", "isMisuse": "notMisuse"} {"id": 3, "title": "Longest wavelength able to to break a C-C bond ...", "upvotes" : 1230, "downvotes" : 7, "url" : "https://answers.yahoo.com/question/index?qid=20081112142253AA1kQN1", "description" : "http://people.csail.mit.edu/swli/edx/recommendation/img/dispage1.png", "isProblematic": "notProblematic", "problematicReason": ""}
{"id": 4, "title": "Calculate the maximum wavelength of light for ...", "upvotes" : 10, "downvotes" : 3457, "url" : "https://answers.yahoo.com/question/index?qid=20100110115715AA6toHw", "description" : "http://people.csail.mit.edu/swli/edx/recommendation/img/dispage2.png", "isMisuse": "notMisuse"} {"id": 4, "title": "Calculate the maximum wavelength of light for ...", "upvotes" : 10, "downvotes" : 3457, "url" : "https://answers.yahoo.com/question/index?qid=20100110115715AA6toHw", "description" : "http://people.csail.mit.edu/swli/edx/recommendation/img/dispage2.png", "isProblematic": "notProblematic", "problematicReason": ""}
</recommender> </recommender>
</vertical_demo> </vertical_demo>
"""), """),
# {"id": 5, "title": "Covalent bond - wave mechanical concep", "upvotes" : 10, "downvotes" : 7, "url" : "", "description" : "http://people.csail.mit.edu/swli/edx/recommendation/img/textbookpage1.png", "isMisuse": "notMisuse"} # {"id": 5, "title": "Covalent bond - wave mechanical concep", "upvotes" : 10, "downvotes" : 7, "url" : "", "description" : "http://people.csail.mit.edu/swli/edx/recommendation/img/textbookpage1.png", "isProblematic": "notProblematic"}
# {"id": 6, "title": "Covalent bond - Energetics of covalent bond", "upvotes" : 10, "downvotes" : 7, "url" : "", "description" : "http://people.csail.mit.edu/swli/edx/recommendation/img/textbookpage2.png", "isMisuse": "notMisuse"} # {"id": 6, "title": "Covalent bond - Energetics of covalent bond", "upvotes" : 10, "downvotes" : 7, "url" : "", "description" : "http://people.csail.mit.edu/swli/edx/recommendation/img/textbookpage2.png", "isProblematic": "notProblematic"}
# </recommender> # </recommender>
# </vertical_demo> # </vertical_demo>
# """), # """),
......
...@@ -11,9 +11,15 @@ ...@@ -11,9 +11,15 @@
float: left; float: left;
} }
.recommender_row_top {
/* overflow:scroll;
max-height:200px;*/
font-size: 20px;
background-color:rgb(204, 198, 198);
}
.recommender_row { .recommender_row {
overflow:scroll; height: 380px;
max-height:200px;
} }
.question { .question {
...@@ -21,17 +27,23 @@ ...@@ -21,17 +27,23 @@
} }
.recommender_resource { .recommender_resource {
border : 1; /* border : 1;*/
padding : 1; padding-top : 0.25em;
margin : 1; padding-bottom : 0.25em;
/* margin : 1;*/
/* display:table-cell;*/ /* display:table-cell;*/
float:left; float:left;
/* width:340px;*/ /* width:340px;*/
width : 95%; width : 100%;
border-color:gray; /* border-color:gray;
border-width:1px; border-width:1px;
border-style:solid; border-style:solid;
border-radius:5px; border-radius:5px;*/
}
.recommender_panel {
float: right;
width: 50px;
} }
.resource_list_less, .resource_list_more { .resource_list_less, .resource_list_more {
...@@ -56,7 +68,7 @@ ...@@ -56,7 +68,7 @@
} }
.recommender_modify { .recommender_modify {
width: 500px; width: 700px;
float: left; float: left;
} }
...@@ -64,36 +76,34 @@ ...@@ -64,36 +76,34 @@
height: 400px; height: 400px;
overflow-x: scroll; overflow-x: scroll;
margin-top: 2em; margin-top: 2em;
float: left;
} }
.recommender_vote_arrow_down { .recommender_vote_arrow_down {
color: red; width: 100%;
cursor: pointer;
float: left;
width: 20px;
margin-left:auto; margin-left:auto;
margin-right:auto; margin-right:auto;
text-align:center; text-align:center;
} }
.recommender_vote_arrow_up { .recommender_vote_arrow_up {
color: green; width: 100%;
cursor: pointer;
float: left;
width: 20px;
margin-left:auto; margin-left:auto;
margin-right:auto; margin-right:auto;
text-align:center; text-align:center;
} }
.recommender_vote_score { .recommender_vote_score {
float: left; width: 100%;
width: 50px;
text-align: center; text-align: center;
cursor: default;
} }
.recommender_recommendations { .recommender_recommendations { display: table; }
display:table;
.pagination {
display: table;
margin: 0 auto;
} }
.recommender_blurb { .recommender_blurb {
...@@ -111,77 +121,105 @@ ...@@ -111,77 +121,105 @@
.recommender_vote_box { .recommender_vote_box {
display:inline-block; display:inline-block;
vertical-align: middle; vertical-align: middle;
width:90px; width:50px;
} }
.recommender_edit{ .recommender_edit{
display:inline-block; display:inline-block;
vertical-align: top; vertical-align: top;
float: right;
width: 40px;
} }
.redTxt { .redTxt {
color: red; color: red;
} }
.resource_edit_button { float:left; } .recommender_vote_arrow_down, .recommender_vote_arrow_up, .recommender_title, .resource_edit_button, .flagResource, .resource_add_button, .hide-show, .paginationCell, .backToViewButton { cursor: pointer; }
.resource_add_button { float: left; font-weight: bold; }
.resource_edit_button { float: left; }
/*.hide-show {
float: left;
font-size: small;
}*/
.addSourceBlockTitle, .editSourceBlockTitle { .addSourceBlockTitle, .editSourceBlockTitle {
margin-bottom: 1em; margin-bottom: 1em;
} }
.editSourceBlock, .recommender_add { .editSourceBlock, .recommender_add {
padding: 1em; padding-left: 1em;
}
.paginationCell {
display:table-cell;
text-align:center;
vertical-align: middle;
width:25px;
} }
.ui-icon.misuse { .backToViewButton { color: #1d9dd9; float: left; }
.recommender_modify_title { position: relative; left: 50px; overflow: auto; }
.ui-icon.problematic {
background-image: url(http://download.jqueryui.com/themeroller/images/ui-icons_ff0000_256x240.png); background-image: url(http://download.jqueryui.com/themeroller/images/ui-icons_ff0000_256x240.png);
} }
.resource_hovered { background: #1d9dd9; } .resource_hovered { background-color:#F2F7FA }
.recommender_modify { margin-left: 2em; }
.recommender_modify_title_container { background: rgb(204, 198, 198); font-size: 20px; }
.nonevoting { color: rgb(204, 198, 198); }
.hide-show-icon { margin-left: 0.5em; }
.recommender_vote_score.upvoting, .recommender_vote_arrow_up.upvoting { color: rgb(69, 194, 10); }
.recommender_vote_score.downvoting, .recommender_vote_arrow_down.downvoting { color: red; }
.recommender_vote_arrow_up.downvoting, .recommender_vote_arrow_down.upvoting { color: rgb(204, 198, 198); }
a:link { color: black; }
form { margin: 0em; } form { margin: 0em; }
</style> </style>
<div class="recommender_block"> <div class="recommender_block">
<div class="recommender_header">
<div class="recommender_title">Helpful resources</div>
<a class="inline cboxElement resource_add_button" href="#recommender_add"><span class="ui-icon ui-icon-plusthick"></span></a>
</div>
<div class="recommender_recommendations"> <div class="recommender_recommendations">
<div class="recommender_content"> <div class="recommender_content">
<div class="recommender_row"> <div class="recommender_row_top hide-show">
<input type="button" class="resource_list_less" value="Show less"> Related resources<div class='recommender_panel'><span class="resource_add_button">+</span> <span class='hide-show-icon'></span> </div>
% for elem in resources: </div>
<%include file="resourcebox.html" args="id=elem['id'],title=elem['title'],votes=elem['votes'],url=elem['url'],description=elem['description'],isMisuse=elem['isMisuse']" /> <div class='recommender_row_inner'>
% endfor <div class="recommender_row">
<input type="button" class="resource_list_more" value="Show more"> % for elem in resources:
</div> % if elem['id'] in downvotes:
<div class="recommender_description"> <%include file="resourcebox.html" args="id=elem['id'],title=elem['title'],votes=elem['votes'],url=elem['url'],description=elem['description'],isProblematic=elem['isProblematic'],voteMode='downvoting'" />
<div class="descriptionImg"></div> % elif elem['id'] in upvotes:
<%include file="resourcebox.html" args="id=elem['id'],title=elem['title'],votes=elem['votes'],url=elem['url'],description=elem['description'],isProblematic=elem['isProblematic'],voteMode='upvoting'" />
% else:
<%include file="resourcebox.html" args="id=elem['id'],title=elem['title'],votes=elem['votes'],url=elem['url'],description=elem['description'],isProblematic=elem['isProblematic'],voteMode='nonevoting'" />
% endif
% endfor
</div>
<div class='pagination'> </div>
<div class="recommender_description">
<div class="descriptionImg"></div>
</div>
</div>
</div> </div>
</div>
<div class='recommender_modify'> <div class='recommender_modify'>
<div class='recommender_modify_title_container'><div class='backToViewButton'>&lt; Related resources</div><div class='recommender_modify_title'></div></div>
<div class="editSourceBlock" id="editSourceBlock"> <div class="editSourceBlock" id="editSourceBlock">
</div> </div>
<div class="recommender_add" id="recommender_add"> <div class="recommender_add" id="recommender_add">
<div class="addSourceBlockTitle">Recommend a new helpful resource for this problem with a short description, hyperlink, and previewing screenshot to the new resource.</div> <div class="addSourceBlockTitle">Recommend a new helpful resource for this problem with a short description, hyperlink, and previewing screenshot to the new resource.</div>
Description: <input type="text" class="in_title"><br> Description: <input type="text" class="in_title" style="height: 25px; position: relative; left: 10px;"><br>
HyperLink: <input type="text" class="in_url"><br> HyperLink: <input type="text" class="in_url" style="height: 25px; position: relative; left: 22px;"><br>
<form id="addResourceForm" action="http://danielswli.s3.amazonaws.com/" method="post" enctype="multipart/form-data"> <form id="addResourceForm" action="http://danielswli.s3.amazonaws.com/" method="post" enctype="multipart/form-data">
<input type="hidden" name="acl" value="public-read"> <input type="hidden" name="acl" value="public-read">
<input type="hidden" name="Content-Type" value="image/jpeg"> <input type="hidden" name="Content-Type" value="image/jpeg">
<input type="hidden" name="AWSAccessKeyId" value="AKIAIRDHSV6YZJZ4RFGA"> <input type="hidden" name="AWSAccessKeyId" value="AKIAIRDHSV6YZJZ4RFGA">
<input type="hidden" name="key" value=""> <input type="hidden" name="key" value="">
</form> </form>
<!-- Resource description: <input type="text" class="in_description"><br>-->
</div> </div>
</div> </div>
</div> </div>
<!--
<div class="recommender_description">
<div class="descriptionImg"></div>
</div>-->
</div> </div>
<%page args="title,votes,url,description,id,isMisuse"/> <%page args="title,votes,url,description,id,isProblematic,voteMode"/>
<div class="recommender_resource hidden"> <div class="recommender_resource">
<div class="recommender_vote_box"> <div class="recommender_vote_box">
<div class="recommender_vote_arrow_up" role="button" aria-label="upvote" tabindex="0"></div> <div class="recommender_vote_arrow_up ${voteMode}" role="button" aria-label="upvote" tabindex="0"><b></b></div>
<!--div class="recommender_vote_score_dislikes">2927</div--> <div class="recommender_vote_score ${voteMode}"><b>${votes}</b></div>
<div class="recommender_vote_score">${votes}</div> <div class="recommender_vote_arrow_down ${voteMode}" role="button" aria-label="downvote" tabindex="0"><b></b></div>
<!--div class="recommender_vote_score_likes">2927</div-->
<div class="recommender_vote_arrow_down" role="button" aria-label="downvote" tabindex="0"></div>
</div> </div>
<div class="recommender_blurb"><div class="recommender_title">${title}</div><div class="recommender_url">${url}</div><div class="recommender_descriptionSlot">${description}</div><div class="recommender_entryId">${id}</div></div> <div class="recommender_blurb"><div class="recommender_title"><a href="${url}" target="_blank">${title}</a></div><div class="recommender_descriptionSlot">${description}</div><div class="recommender_entryId">${id}</div></div>
<div class="recommender_edit"><a class="inline cboxElement resource_edit_button" href="#editSourceBlock"><span class="ui-icon ui-icon-pencil editResource"></span></a><span class="ui-icon ui-icon-flag flagResource ${isMisuse}"></span></div> <div class="recommender_edit"> <span class="ui-icon ui-icon-pencil resource_edit_button"></span> <span class="ui-icon ui-icon-flag flagResource ${isProblematic}"></span></div>
</div> </div>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment